Witam. Przedstawiam tutaj żywcem skopiowane z projektu przykładowego biblioteki bass.dll przykład rysowania widma.
if (!(chan=BASS_StreamCreateFile(FALSE,file,0,0,0))
&& !(chan=BASS_MusicLoad(FALSE,file,0,0,BASS_MUSIC_RAMPS|BASS_MUSIC_POSRESET|BASS_MUSIC_PRESCAN,1))) {
Error("Can't play file");
return FALSE; // Can't load the file
}
{
BYTE data[2000]={0};
BITMAPINFOHEADER *bh=(BITMAPINFOHEADER*)data;
RGBQUAD *pal=(RGBQUAD*)(data+sizeof(*bh));
int a;
bh->biSize=sizeof(*bh);
bh->biWidth=WIDTH;
bh->biHeight=-HEIGHT;
bh->biPlanes=1;
bh->biBitCount=8;
bh->biClrUsed=bh->biClrImportant=HEIGHT/2+1;
// setup palette
for (a=1;a<=HEIGHT/2;a++) {
pal[a].rgbRed=(255*a)/(HEIGHT/2);
pal[a].rgbGreen=255-pal[a].rgbRed;
}
// create the bitmap
wavebmp=CreateDIBSection(0,(BITMAPINFO*)bh,DIB_RGB_COLORS,(void**)&wavebuf,NULL,0);
wavedc=CreateCompatibleDC(0);
SelectObject(wavedc,wavebmp);
}
bpp=BASS_ChannelGetLength(chan,BASS_POS_BYTE)/WIDTH; // bytes per pixel
if (bpp<BASS_ChannelSeconds2Bytes(chan,0.02)) // minimum 20ms per pixel (BASS_ChannelGetLevel scans 20ms)
bpp=BASS_ChannelSeconds2Bytes(chan,0.02);
BASS_ChannelSetSync(chan,BASS_SYNC_END|BASS_SYNC_MIXTIME,0,LoopSyncProc,0); // set sync to loop at end
BASS_ChannelPlay(chan,FALSE); // start playing
{ // start scanning peaks in a new thread
DWORD chan2=BASS_StreamCreateFile(FALSE,file,0,0,BASS_STREAM_DECODE);
if (!chan2) chan2=BASS_MusicLoad(FALSE,file,0,0,BASS_MUSIC_DECODE,1);
scanthread=_beginthread(ScanPeaks,0,(void*)chan2);
}
oraz
void __cdecl ScanPeaks(void *p)
{
DWORD decoder=(DWORD)p;
DWORD cpos=0,peak[2]={0};
while (!killscan) {
DWORD level=BASS_ChannelGetLevel(decoder); // scan peaks
DWORD pos;
if (peak[0]<LOWORD(level)) peak[0]=LOWORD(level); // set left peak
if (peak[1]<HIWORD(level)) peak[1]=HIWORD(level); // set right peak
if (!BASS_ChannelIsActive(decoder)) pos=-1; // reached the end
else pos=BASS_ChannelGetPosition(decoder,BASS_POS_BYTE)/bpp;
if (pos>cpos) {
DWORD a;
for (a=0;a<peak[0]*(HEIGHT/2)/32768;a++)
wavebuf[(HEIGHT/2-1-a)*WIDTH+cpos]=1+a; // draw left peak
for (a=0;a<peak[1]*(HEIGHT/2)/32768;a++)
wavebuf[(HEIGHT/2+1+a)*WIDTH+cpos]=1+a; // draw right peak
if (pos>=WIDTH) break; // gone off end of display
cpos=pos;
peak[0]=peak[1]=0;
}
}
BASS_StreamFree(decoder); // free the decoder
scanthread=0;
}
Jak dobrze rozumiem w kodzie #1 przedstawiony jest sposób rysowania "gradientu" i przygotowywanie do wypełnienia bitmapy widmem. kod #2 opisuje strukturę wątku, który rysuje widmo. Jak wielokrotnie przeleciałem przez ten wątek wywnioskowałem, że:
- na początku tworzymy zmienną przechowującą uchwyt utworu (zmienna decoder)
- następnie pobieramy dane utworu (nie wiem czy chodzi tu o wartości amplitud, natezenia dzwieku czy o coś innego jak możecie to pomóżcie) i zapisujemy je do zmiennej "level"
- peek[] zawierają wartości (czegoś tam) na każdym głośniku.
... Dalej nieogarniam xD Czarna magia :D Jeśli możecie wytłumaczcie mi w jaki sposob jest tworzona paleta kolorów. Przerabiałem kurs GDI i kurs o bitmapach, lecz nie spotkałem się z niektórymi pojęciami z kodu #1. Nastepnie w jaki sposób pobrać natężenie tego dźwięku i przelać je na obraz? Nie rozumiem jak to jest przedstawione.
Cały kod programu przedstawiam w załączniku