bool BassPlayer::fileInfo(const QUrl & uri, IMediaInfo * info) { bool currently_played = media_url.isValid() && uri == media_url; int chUID; if (currently_played) chUID = chan; else { if (uri.isLocalFile()) chUID = open(uri.toLocalFile(), LOCAL_PLAY_ATTRS); else chUID = openRemote(uri.toString(), REMOTE_PLAY_ATTRS); if (!chUID) return false; } float time = BASS_ChannelBytes2Seconds(chUID, BASS_ChannelGetLength(chUID, BASS_POS_BYTE)); // playback duration qint64 len = BASS_StreamGetFilePosition(chUID, BASS_FILEPOS_END); // file length info -> setDuration(time); info -> setBitrate((len / (125 * time) + 0.5)); BASS_CHANNELINFO media_info; if (BASS_ChannelGetInfo(chUID, &media_info)) { info -> setSize(len + BASS_StreamGetFilePosition(chUID, BASS_FILEPOS_START)); info -> setSampleRate(media_info.freq); info -> setChannels(media_info.chans); } if (!currently_played) BASS_StreamFree(chUID); return true; }
QW Player::Length() const { if (stream != NULL) return BASS_ChannelGetLength(stream, BASS_POS_BYTE); else return 0; }
int Music_decode(text_t* path, MusicData* data) { QWORD len; thrd_t id; if (thrd_busy == mtx_trylock(&s_mutex)) { Dialog_showError(TEXT("Decoding of stream already in-progress. Re-open after it's been completed.")); return 1; } // now this will break if we already have a thread running. free(data->fftData); data->fftData = 0; int flags = BASS_STREAM_DECODE | BASS_SAMPLE_MONO | BASS_POS_SCAN; #ifdef _WIN32 flags |= BASS_UNICODE; #endif HSTREAM chan = BASS_StreamCreateFile(0, path, 0, 0, flags); if (!chan) { Dialog_showError(TEXT("Unable to open stream for decode. No music data will be available.")); mtx_unlock(&s_mutex); return 0; } len = BASS_ChannelGetLength(chan, BASS_POS_BYTE); if (len == -1) { Dialog_showError(TEXT("Stream has no length. No music data will be available.")); BASS_StreamFree(chan); mtx_unlock(&s_mutex); return 0; } ThreadFuncData* threadData = malloc(sizeof(ThreadFuncData)); threadData->stream = chan; threadData->data = data; data->percentDone = 1; data->fftData = 0; // So there is a race-condition here as the mutex is unclocked while the thread is crated but in practice // this won't be a problem mtx_unlock(&s_mutex); if (thrd_create(&id, decodeFunc, threadData) != thrd_success) { printf("Unable to create decode thread. Stalling main thread and running...\n"); decodeFunc(threadData); } return 1; }
int GetDuration(HSTREAM stream) { QWORD bytelength = BASS_ChannelGetLength(stream); float secs = BASS_ChannelBytes2Seconds(stream, bytelength); secs *= 1000; // to ms return (int)secs; }
void PlaybackWidget::changeSong(QString songPath) { stopSong(); curchan = BASS_StreamCreateFile(false,songPath.utf16(),0,0, BASS_SAMPLE_FLOAT | BASS_STREAM_AUTOFREE | BASS_UNICODE); BASS_ChannelPlay(curchan,false); cursongblength = BASS_ChannelGetLength(curchan, BASS_POS_BYTE); cursonglength = BASS_ChannelBytes2Seconds(curchan,cursongblength); changeState(PLAYING); }
unsigned int CClientSound::GetLength ( void ) { if ( m_pSound ) { QWORD length = BASS_ChannelGetLength( m_pSound, BASS_POS_BYTE ); if ( length != -1 ) return static_cast <unsigned int> ( BASS_ChannelBytes2Seconds( m_pSound, length ) * 1000 ); } return 0; }
HSTREAM CBassMusicEngine::LoadFile( LPCTSTR lpszFileName ) { tagMusicInfo _Info; ZeroMemory(&_Info,sizeof _Info); if (!(_Info.hStream = BASS_StreamCreateFile(FALSE, lpszFileName,0,0,BASS_SAMPLE_MONO))) { ShowError(TEXT("不能打开该文件")); return -1; } _Info.dwTime = BASS_ChannelBytes2Seconds(_Info.hStream,BASS_ChannelGetLength(_Info.hStream,BASS_POS_BYTE) ); TAG_ID3 *pTag = (TAG_ID3 *)BASS_ChannelGetTags(_Info.hStream,BASS_TAG_ID3); if ( pTag != NULL ) { #ifdef UNICODE MultiByteToWideChar(CP_ACP, 0, pTag->artist, -1, _Info.szArtist, 30); MultiByteToWideChar(CP_ACP, 0, pTag->title, -1, _Info.szTitle, 30); if ( lstrlen(_Info.szArtist) == 0 ) { lstrcpyn(_Info.szArtist,TEXT("未知"),CountArray(_Info.szArtist)); } if ( lstrlen(_Info.szTitle) == 0 ) { CString StrTitle(lpszFileName); StrTitle = StrTitle.Right(StrTitle.GetLength()-StrTitle.ReverseFind('\\')-1); StrTitle = StrTitle.Left(StrTitle.Find('.')); lstrcpyn(_Info.szTitle,StrTitle,CountArray(_Info.szTitle)); } #else lstrcpyn(_Info.szArtist,CString(pTag->artist),CountArray(_Info.szArtist)); lstrcpyn(_Info.szTitle,CString(pTag->title),CountArray(_Info.szTitle)); #endif } else { CString StrTitle(lpszFileName); StrTitle = StrTitle.Right(StrTitle.GetLength()-StrTitle.ReverseFind('\\')-1); StrTitle = StrTitle.Left(StrTitle.Find('.')); lstrcpyn(_Info.szArtist,TEXT("未知"),CountArray(_Info.szArtist)); lstrcpyn(_Info.szTitle,StrTitle,CountArray(_Info.szTitle)); } m_MusicEngineMap.insert(pair<HSTREAM,tagMusicInfo>(_Info.hStream,_Info)); //Play(_Info.hStream); return _Info.hStream; }
pascal OSStatus OpenEventHandler(EventHandlerCallRef inHandlerRef, EventRef inEvent, void *inUserData) { NavDialogRef fileDialog; NavDialogCreationOptions fo; NavGetDefaultDialogCreationOptions(&fo); fo.optionFlags=0; fo.parentWindow=win; NavCreateChooseFileDialog(&fo,NULL,NULL,NULL,NULL,NULL,&fileDialog); // if someone wants to somehow get the file selector to filter like in the Windows example, that'd be nice ;) if (!NavDialogRun(fileDialog)) { NavReplyRecord r; if (!NavDialogGetReply(fileDialog,&r)) { AEKeyword k; FSRef fr; if (!AEGetNthPtr(&r.selection,1,typeFSRef,&k,NULL,&fr,sizeof(fr),NULL)) { char file[256]; FSRefMakePath(&fr,(BYTE*)file,sizeof(file)); BASS_StreamFree(chan); // free old stream before opening new if (!(chan=BASS_StreamCreateFile(FALSE,file,0,0,BASS_SAMPLE_LOOP|BASS_SAMPLE_FLOAT))) { SetControlTitleWithCFString(inUserData,CFSTR("click here to open a file...")); { ControlRef cref=GetControl(11); SetControlData(cref,kControlNoPart,kControlStaticTextTextTag,0,""); DrawOneControl(cref); } SetControl32BitMaximum(GetControl(12),0); Error("Can't play the file"); } else { CFStringRef cs=CFStringCreateWithCString(0,file,kCFStringEncodingUTF8); SetControlTitleWithCFString(inUserData,cs); CFRelease(cs); { // display the file type and length QWORD bytes=BASS_ChannelGetLength(chan,BASS_POS_BYTE); DWORD time=BASS_ChannelBytes2Seconds(chan,bytes); BASS_CHANNELINFO info; BASS_ChannelGetInfo(chan,&info); sprintf(file,"channel type = %x (%s)\nlength = %llu (%u:%02u)", info.ctype,GetCTypeString(info.ctype,info.plugin),bytes,time/60,time%60); { ControlRef cref=GetControl(11); SetControlData(cref,kControlNoPart,kControlStaticTextTextTag,strlen(file),file); DrawOneControl(cref); } SetControl32BitMaximum(GetControl(12),time); // update scroller range } BASS_ChannelPlay(chan,FALSE); } } NavDisposeReply(&r); } } NavDialogDispose(fileDialog); return noErr; }
/* Добавление песни в плейлист */ VOID DlgPlayList::addSongToPlayList(HSTREAM stream, TCHAR* path) { TAG_ID3* id3 = (TAG_ID3*)BASS_ChannelGetTags(stream, BASS_TAG_ID3); //получение данных о песне std::wstringstream infoAboutTheSong; //Буфер строки (Название песни + Исполнитель + время) infoSong info; QWORD lengthSong = BASS_ChannelGetLength(stream, BASS_POS_BYTE); //длина песни в байтах INT seconds = BASS_ChannelBytes2Seconds(stream, lengthSong); //длина песни в секундах INT min = seconds / 60; //Определение минут seconds = seconds % 60; //Определение секунд /* Заполнение данных о песне */ if (id3 == NULL || strlen(id3->artist) == 0) { INT idx = lstrlen(path); INT length = idx; TCHAR name[MAX_PATH]; INT k = 0; while (path[idx] != '\\') { idx--; } for (INT i = idx + 1; i < length;i++) { name[k] = path[i]; k++; } name[k - 4] = '\0'; //Удаление формата песни infoAboutTheSong << name << " "; } else { strcpy(info.title, id3->title); //Name strcpy(info.artist, id3->artist); //Author strcpy(info.album, id3->album); //Album strcpy(info.year, id3->year); //Year infoAboutTheSong << info.artist << " " << info.title << " "; } info.minutes = min; //Minutes info.seconds = seconds; //Seconds info.hStream = stream; //Stream lstrcpy(info.path, path); //Path of the song /* Запись времени песни в строку */ infoAboutTheSong << info.minutes << ":"; if (seconds < 10) infoAboutTheSong << "0" << info.seconds; else infoAboutTheSong << info.seconds; ListBox_AddString(hPlayList, infoAboutTheSong.str().c_str()); //Add in PlayList songs.push_back(info); //Add in vector }
// Non-streams only void CBassAudio::SetPlayPosition ( double dPosition ) { // Only relevant for non-streams, which are always ready if valid if ( m_pSound ) { // Make sure position is in range QWORD bytePosition = BASS_ChannelSeconds2Bytes( m_pSound, dPosition ); QWORD byteLength = BASS_ChannelGetLength( m_pSound, BASS_POS_BYTE ); BASS_ChannelSetPosition( m_pSound, Clamp < QWORD > ( 0, bytePosition, byteLength - 1 ), BASS_POS_BYTE ); } }
// Non-streams only double CBassAudio::GetLength ( void ) { // Only relevant for non-streams, which are always ready if valid if ( m_pSound ) { QWORD length = BASS_ChannelGetLength( m_pSound, BASS_POS_BYTE ); if ( length != -1 ) return BASS_ChannelBytes2Seconds( m_pSound, length ); } return 0; }
// select a file to play, and start scanning it BOOL PlayFile() { char file[MAX_PATH]=""; OPENFILENAME ofn={0}; ofn.lStructSize=sizeof(ofn); ofn.hwndOwner=win; ofn.nMaxFile=MAX_PATH; ofn.lpstrFile=file; ofn.Flags=OFN_FILEMUSTEXIST|OFN_HIDEREADONLY|OFN_EXPLORER; ofn.lpstrTitle="Select a file to play"; ofn.lpstrFilter="Playable files\0*.mp3;*.mp2;*.mp1;*.ogg;*.wav;*.aif;*.mo3;*.it;*.xm;*.s3m;*.mtm;*.mod;*.umx\0All files\0*.*\0\0"; if (!GetOpenFileName(&ofn)) return FALSE; 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 { DWORD bpp1=BASS_ChannelSeconds2Bytes(chan,0.001); // minimum 1ms per pixel if (bpp<bpp1) bpp=bpp1; } BASS_ChannelSetSync(chan,BASS_SYNC_END|BASS_SYNC_MIXTIME,0,LoopSyncProc,0); // set sync to loop at end BASS_ChannelPlay(chan,FALSE); // start playing { // create another channel to scan 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); // start scanning in a new thread } return TRUE; }
/** * @brief Colled every 0.3 secinds and update text field where represented recording size. */ void Widget::timerProc() { // update the recording/playback counter QString text = "no data"; if (rchan) // recording text = QString::number(BASS_ChannelGetPosition(rchan,BASS_POS_BYTE)); else if (chan) { if (BASS_ChannelIsActive(chan)) // playing text = QString::number(BASS_ChannelGetPosition(chan,BASS_POS_BYTE))+"/"+QString::number(BASS_ChannelGetLength(chan,BASS_POS_BYTE)); else text = QString::number(BASS_ChannelGetLength(chan,BASS_POS_BYTE)); } ui->lineEdit->setText(text); }
int CAudio::GetLength() { if (m_bIsOnlineStream) return -1; if (m_dwChannel) { // get length long length = BASS_ChannelGetLength (m_dwChannel, BASS_POS_BYTE); // convert into seconds and return return BASS_ChannelBytes2Seconds(m_dwChannel, length); } return -1; }
HEFFECT CALL HGE_Impl::Effect_Load(const char *filename, DWORD size) { DWORD _size, length, samples; HSAMPLE hs; HSTREAM hstrm; BASS_CHANNELINFO info; void *buffer, *data; if(hBass) { if(bSilent) return 1; if(size) { data=(void *)filename; _size=size; } else { data=Resource_Load(filename, &_size); if(!data) return NULL; } hs=BASS_SampleLoad(TRUE, data, 0, _size, 4, BASS_SAMPLE_OVER_VOL); if(!hs) { hstrm=BASS_StreamCreateFile(TRUE, data, 0, _size, BASS_STREAM_DECODE); if(hstrm) { length=(DWORD)BASS_ChannelGetLength(hstrm); BASS_ChannelGetInfo(hstrm, &info); samples=length; if(info.chans < 2) samples>>=1; if((info.flags & BASS_SAMPLE_8BITS) == 0) samples>>=1; buffer=BASS_SampleCreate(samples, info.freq, 2, 4, info.flags | BASS_SAMPLE_OVER_VOL); if(!buffer) { BASS_StreamFree(hstrm); _PostError("Can't create sound effect: Not enough memory"); } else { BASS_ChannelGetData(hstrm, buffer, length); hs=BASS_SampleCreateDone(); BASS_StreamFree(hstrm); if(!hs) _PostError("Can't create sound effect"); } } } if(!size) Resource_Free(data); return hs; }
void InitAudio(const char *pFilename) { DWORD chan,act,time,level; QWORD pos; printf("--- MIDISYS-ENGINE: InitAudio()\n"); if (!BASS_Init(-1,44100,0,0,NULL)) BassError("InitAudio() - can't initialize device"); printf("\tInitAudio() - loading soundtrack from file \"%s\"\n", pFilename); int success = 0; if ((chan=BASS_StreamCreateFile(FALSE,pFilename,0,0,BASS_STREAM_PRESCAN)) || (chan=BASS_StreamCreateURL(pFilename,0,BASS_STREAM_PRESCAN,0,0))) { pos=BASS_ChannelGetLength(chan,BASS_POS_BYTE); if (BASS_StreamGetFilePosition(chan,BASS_FILEPOS_DOWNLOAD)!=-1) { // streaming from the internet if (pos!=-1) { printf("\tInitAudio() - streaming internet file [%I64u bytes]\n",pos); success = 1; } else { printf("\tstreaming internet file\n"); success = 1; } } else { printf("\tstreaming file [%I64u bytes]\n",pos); success = 1; } } if (success == 1) { music_channel = chan; } else { printf("InitAudio() error! could not load file."); exit(1); } }
double BassDecoder::length() const { #if defined(LIBTOOLS_WINDOWS) && !defined(BASS_H) if (!BASS_ChannelGetLength || !BASS_ChannelBytes2Seconds || !BASS_ErrorGetCode) { std::cerr << "Missing BASS_ChannelGetLength, BASS_ChannelBytes2Seconds or BASS_ErrorGetCode function" << std::endl; return -1; } #endif if (_music) { QWORD ret = BASS_ChannelGetLength((DWORD)_music,BASS_POS_BYTE); if (ret==-1) return -1; return BASS_ChannelBytes2Seconds((DWORD)_music,ret); } return -1; }
float BassPlayer::bpmCalc(const QUrl & uri) { int cochan; if (uri.isLocalFile()) cochan = open(uri.toLocalFile(), LOCAL_BPM_ATTRS);// BASS_StreamCreateFile(false, uri.toLocalFile().toStdWString().c_str(), 0, 0, LOCAL_BPM_ATTRS); else cochan = openRemote(uri.toString(), REMOTE_BPM_ATTRS); //BASS_StreamCreateURL(uri.toString().toStdString().c_str(), 0, REMOTE_BPM_ATTRS, NULL, 0); if (cochan) { int playBackDuration = BASS_ChannelBytes2Seconds(cochan, BASS_ChannelGetLength(cochan, BASS_POS_BYTE)); return BASS_FX_BPM_DecodeGet(cochan, 0, playBackDuration, MAKEWORD(20, 180), BASS_FX_FREESOURCE, //BASS_FX_BPM_BKGRND // BASS_FX_BPM_MULT2 NULL, NULL ); } else return 0; }
HRESULT CBSoundBuffer::SetLoopStart(DWORD Pos) { m_LoopStart = Pos; if (m_Stream) { if (m_Sync) { BASS_ChannelRemoveSync(m_Stream, m_Sync); m_Sync = NULL; } if (m_LoopStart > 0) { QWORD len = BASS_ChannelGetLength(m_Stream, BASS_POS_BYTE); m_Sync = BASS_ChannelSetSync(m_Stream, BASS_SYNC_POS | BASS_SYNC_MIXTIME, len, CBSoundBuffer::LoopSyncProc, (void*)this); } } return S_OK; }
void main(int argc, char **argv) { DWORD chan,act,time,level; BOOL ismod; QWORD pos; int a; printf("Simple console mode BASS example : MOD/MPx/OGG/WAV player\n" "---------------------------------------------------------\n"); // check the correct BASS was loaded if (HIWORD(BASS_GetVersion())!=BASSVERSION) { printf("An incorrect version of BASS was loaded"); return; } if (argc!=2) { printf("\tusage: contest <file>\n"); return; } // setup output - default device if (!BASS_Init(-1,44100,0,0,NULL)) Error("Can't initialize device"); // try streaming the file/url if ((chan=BASS_StreamCreateFile(FALSE,argv[1],0,0,BASS_SAMPLE_LOOP)) || (chan=BASS_StreamCreateURL(argv[1],0,BASS_SAMPLE_LOOP,0,0))) { pos=BASS_ChannelGetLength(chan,BASS_POS_BYTE); if (BASS_StreamGetFilePosition(chan,BASS_FILEPOS_DOWNLOAD)!=-1) { // streaming from the internet if (pos!=-1) #ifdef _WIN32 printf("streaming internet file [%I64u bytes]",pos); #else printf("streaming internet file [%llu bytes]",pos); #endif else printf("streaming internet file"); } else
/* WM_TIMER */ VOID Application::Cls_OnTimer(HWND hwnd, UINT id) { if (id == id_timer) { QWORD len = BASS_ChannelGetLength(hStream, BASS_POS_BYTE); INT seconds = BASS_ChannelBytes2Seconds(hStream, len); SendMessage(hTBPlayingSong, TBM_SETPOS, TRUE, (LPARAM)secPlaying); INT pos = SendMessage(hTBPlayingSong, TBM_GETPOS, 0, 0); if (secPlaying == seconds && IsRepeatSong == FALSE && playlist.songs.size() > 1) { next(); } else if (IsRepeatSong == TRUE && secPlaying == seconds) { SendMessage(hTBPlayingSong, TBM_SETPOS, TRUE, (LPARAM)0); secPlaying = 0; play(hStream); } else if (playlist.songs.size() == 1 && secPlaying == seconds) { secPlaying = 0; KillTimer(hwnd, id_timer); }else if (pos == seconds) { secPlaying = 0; stop(hStream); KillTimer(hwnd, id_timer); } /* Показ времени проигрывания */ showTimePlaying(hwnd, secPlaying); if (secPlaying == 0) showNameSong(hStream, hwnd); secPlaying++; } else if (id == idTimerBySpectr) { InvalidateRect(hwnd, &spectrRECT, TRUE); } }
unsigned int BassDecoder::frames() { #if defined(LIBTOOLS_WINDOWS) && !defined(BASS_H) if (!BASS_ChannelGetLength || !BASS_ChannelBytes2Seconds || !BASS_ErrorGetCode) { std::cerr << "Missing BASS_ChannelGetLength, BASS_ChannelBytes2Seconds or BASS_ErrorGetCode function" << std::endl; return -1; } #endif if (_music) { QWORD ret = BASS_ChannelGetLength((DWORD)_music,BASS_POS_BYTE); if (ret==-1) return -1; double seconds=BASS_ChannelBytes2Seconds((DWORD)_music,ret); unsigned int frames = (unsigned int)(seconds*(double)Signal::refreshRate+0.5); return frames; } return 0; }
// // Util use in BeginLoadingMedia // HSTREAM CBassAudio::ConvertFileToMono(const SString& strPath) { HSTREAM decoder = BASS_StreamCreateFile ( false, strPath, 0, 0, BASS_STREAM_DECODE | BASS_SAMPLE_MONO ); // open file for decoding if ( !decoder ) return 0; // failed DWORD length = static_cast <DWORD> ( BASS_ChannelGetLength ( decoder, BASS_POS_BYTE ) ); // get the length void *data = malloc ( length ); // allocate buffer for decoded data BASS_CHANNELINFO ci; BASS_ChannelGetInfo ( decoder, &ci ); // get sample format if ( ci.chans > 1 ) // not mono, downmix... { HSTREAM mixer = BASS_Mixer_StreamCreate ( ci.freq, 1, BASS_STREAM_DECODE | BASS_MIXER_END ); // create mono mixer BASS_Mixer_StreamAddChannel ( mixer, decoder, BASS_MIXER_DOWNMIX | BASS_MIXER_NORAMPIN | BASS_STREAM_AUTOFREE ); // plug-in the decoder (auto-free with the mixer) decoder = mixer; // decode from the mixer } length = BASS_ChannelGetData ( decoder, data, length ); // decode data BASS_StreamFree ( decoder ); // free the decoder/mixer HSTREAM stream = BASS_StreamCreate ( ci.freq, 1, BASS_STREAM_AUTOFREE, STREAMPROC_PUSH, NULL ); // create stream BASS_StreamPutData ( stream, data, length ); // set the stream data free ( data ); // free the buffer return stream; }
bool KNMusicBackendBassThread::loadFile(const QString &filePath) { //Stop the current thread first. stop(); //Remove all the previous sync handlers. removeChannelSyncs(); //Check is the file the current file. if(filePath==m_filePath) { //Reset the current state. resetChannelInformation(); //Update the duration. emit durationChanged(m_duration); //Emit the load success signal. emit loadSuccess(); //Mission complete. return true; } //Load the file path. if(!loadBassThread(filePath)) { //Load the file failed. return false; } //When loading the file complete, load the channel info to the thread. //Get the duration of the whole file. m_totalDuration= BASS_ChannelBytes2Seconds(m_channel, BASS_ChannelGetLength(m_channel, BASS_POS_BYTE)) *1000.0; //Emit the duration changed signal. emit durationChanged(m_totalDuration); //Reset the thread information. resetChannelInformation(); //Load complete. return true; }
BOOL CALLBACK dialogproc(HWND h,UINT m,WPARAM w,LPARAM l) { DWORD p; float freq; char c[30]; switch (m) { case WM_COMMAND: switch (LOWORD(w)) { case ID_OPEN: { char file[MAX_PATH]=""; ofn.lpstrFilter="playable files\0*.mo3;*.xm;*.mod;*.s3m;*.it;*.mtm;*.mp3;*.mp2;*.mp1;*.ogg;*.wav;*.aif\0All files\0*.*\0\0"; ofn.lpstrFile=file; if (GetOpenFileName(&ofn)) { memcpy(path,file,ofn.nFileOffset); path[ofn.nFileOffset-1]=0; // free decode bpm & stream BASS_FX_BPM_Free(hBPM); // free tempo, stream, music & bpm/beat callbacks BASS_StreamFree(chan); // create decode stream channel chan=BASS_StreamCreateFile(FALSE, file, 0, 0, BASS_STREAM_DECODE); // create decode music channel if (!chan) chan = BASS_MusicLoad(FALSE, file, 0, 0, BASS_MUSIC_RAMP|BASS_MUSIC_PRESCAN|BASS_MUSIC_DECODE, 0); if (!chan){ // not a WAV/MP3 or MOD MESS(ID_OPEN,WM_SETTEXT,0,"click here to open a file && play it..."); Error("Selected file couldn't be loaded!"); break; } // get current samplerate BASS_ChannelGetAttribute(chan, BASS_ATTRIB_FREQ, &freq); // update the position slider p = (DWORD)BASS_ChannelBytes2Seconds(chan, BASS_ChannelGetLength(chan, BASS_POS_BYTE)); MESS(IDC_POS,TBM_SETRANGEMAX,0,p); MESS(IDC_POS,TBM_SETPOS,TRUE,0); // create a new stream - decoded & resampled :) if (!(chan=BASS_FX_TempoCreate(chan, BASS_SAMPLE_LOOP|BASS_FX_FREESOURCE))){ MESS(ID_OPEN,WM_SETTEXT,0,"click here to open a file && play it..."); Error("Couldn't create a resampled stream!"); BASS_StreamFree(chan); BASS_MusicFree(chan); break; } // update the button to show the loaded file name MESS(ID_OPEN,WM_SETTEXT,0,GetFileName(file)); // set Volume p = MESS(IDC_VOL,TBM_GETPOS,0,0); BASS_ChannelSetAttribute(chan, BASS_ATTRIB_VOL, (float)(100 - p)/100.0f); // update tempo slider & view MESS(IDC_TEMPO,TBM_SETPOS,TRUE,0); MESS(IDC_STEMPO,WM_SETTEXT,0,"Tempo = 0%"); // set rate min/max values according to current frequency MESS(IDC_RATE,TBM_SETRANGEMAX,0,(long)(freq * 1.3f)); MESS(IDC_RATE,TBM_SETRANGEMIN,0,(long)(freq * 0.7f)); MESS(IDC_RATE,TBM_SETPOS,TRUE,(long)freq); MESS(IDC_RATE,TBM_SETPAGESIZE,0,(long)(freq * 0.01f)); // by 1% sprintf(c,"Samplerate = %dHz", (long)freq); MESS(IDC_SRATE,WM_SETTEXT,0,c); // update the approximate time in seconds view UpdatePositionLabel(); // play new created stream BASS_ChannelPlay(chan,FALSE); // set the callback bpm and beat SendMessage(win,WM_COMMAND,IDC_CHKPERIOD,l); SendMessage(win,WM_COMMAND,IDC_CHKBEAT,l); // get the bpm of 30 seconds from the start DecodingBPM(TRUE, 0.0f, 30.0f, file); } } return 1; case IDC_CHKPERIOD: if(MESS(IDC_CHKPERIOD,BM_GETCHECK,0,0)){ GetDlgItemText(win, IDC_EPBPM, c, 5); BASS_FX_BPM_CallbackSet(chan, (BPMPROC*)GetBPM_Callback, (double)atof(c), 0, BASS_FX_BPM_MULT2, 0); }else BASS_FX_BPM_Free(chan); return 1; case IDC_CHKBEAT: if(MESS(IDC_CHKBEAT,BM_GETCHECK,0,0)){ BASS_FX_BPM_BeatCallbackSet(chan, (BPMBEATPROC*)GetBeatPos_Callback, 0); }else BASS_FX_BPM_BeatFree(chan); return 1; } break; case WM_VSCROLL: if(GetDlgCtrlID((HWND)l) == IDC_VOL) BASS_ChannelSetAttribute(chan, BASS_ATTRIB_VOL, (float)(100 - MESS(IDC_VOL,TBM_GETPOS,0,0))/100.0f); break; case WM_HSCROLL: { if(!BASS_ChannelIsActive(chan)) break; switch (GetDlgCtrlID((HWND)l)) { case IDC_TEMPO: // set new tempo BASS_ChannelSetAttribute(chan, BASS_ATTRIB_TEMPO, (float)MESS(IDC_TEMPO, TBM_GETPOS, 0, 0)); // update tempo static text sprintf(c,"Tempo = %d%%", MESS(IDC_TEMPO, TBM_GETPOS, 0, 0)); MESS(IDC_STEMPO,WM_SETTEXT,0,c); case IDC_RATE: { // set new samplerate BASS_ChannelSetAttribute(chan, BASS_ATTRIB_TEMPO_FREQ, (float)MESS(IDC_RATE, TBM_GETPOS, 0, 0)); sprintf(c,"Samplerate = %dHz", MESS(IDC_RATE, TBM_GETPOS, 0, 0)); MESS(IDC_SRATE,WM_SETTEXT,0,c); // update the bpm view if (MESS(IDC_CHKPERIOD,BM_GETCHECK,0,0)) sprintf(c,"BPM: %0.2f", GetNewBPM(chan)); else sprintf(c,"BPM: %0.2f", GetNewBPM(hBPM)); MESS(IDC_SBPM,WM_SETTEXT,0,c); // update the approximate time in seconds view UpdatePositionLabel(); } break; case IDC_POS: // change the position if (LOWORD(w) == SB_ENDSCROLL) { // seek to new pos BASS_ChannelSetPosition(chan, (QWORD)BASS_ChannelSeconds2Bytes(chan, (double)MESS(IDC_POS,TBM_GETPOS,0,0)), BASS_POS_BYTE); // get the bpm of last IDC_EPBPM seconds GetDlgItemText(win, IDC_EPBPM, c, 5); DecodingBPM(FALSE, (double)MESS(IDC_POS,TBM_GETPOS,0,0) - (double)atof(c), (double)MESS(IDC_POS,TBM_GETPOS,0,0),""); } // update the approximate time in seconds view UpdatePositionLabel(); break; } } return 1; break; case WM_CLOSE: EndDialog(h, 0); return 1; break; case WM_INITDIALOG: win=h; GetCurrentDirectory(MAX_PATH,path); memset(&ofn,0,sizeof(ofn)); ofn.lStructSize=sizeof(ofn); ofn.hwndOwner=h; ofn.hInstance=inst; ofn.nMaxFile=MAX_PATH; ofn.Flags=OFN_HIDEREADONLY|OFN_EXPLORER; // setup output - default device, 44100hz, stereo, 16 bits if (!BASS_Init(-1,44100,0,win,NULL)) { Error("Can't initialize device"); DestroyWindow(win); return 1; } // volume MESS(IDC_VOL,TBM_SETRANGEMAX,0,100); MESS(IDC_VOL,TBM_SETPOS,TRUE,50); MESS(IDC_VOL,TBM_SETPAGESIZE,0,5); // tempo MESS(IDC_TEMPO,TBM_SETRANGEMAX,TRUE,30); MESS(IDC_TEMPO,TBM_SETRANGEMIN,TRUE,-30); MESS(IDC_TEMPO,TBM_SETPOS,TRUE,0); MESS(IDC_TEMPO,TBM_SETPAGESIZE,0,1); // rate MESS(IDC_RATE,TBM_SETRANGEMAX,0,(long)(44100.0f * 1.3f)); MESS(IDC_RATE,TBM_SETRANGEMIN,0,(long)(44100.0f * 0.7f)); MESS(IDC_RATE,TBM_SETPOS,TRUE,44100); MESS(IDC_RATE,TBM_SETPAGESIZE,0,(long)(44100.0f * 0.01f)); // by 1% // bpm detection process MESS(IDC_PRGRSBPM,PBM_SETRANGE32,0,100); // set the bpm period edit box, as a default of 10 seconds :) MESS(IDC_EPBPM,WM_SETTEXT,0,"10"); // set the bpm static text font Font = CreateFont(-12,0,0,0,FW_BOLD,FALSE,FALSE,FALSE,ANSI_CHARSET, OUT_STROKE_PRECIS,CLIP_STROKE_PRECIS,DRAFT_QUALITY, DEFAULT_PITCH | FF_DONTCARE,"Tahoma"); MESS(IDC_SBPM, WM_SETFONT, Font, TRUE); MESS(IDC_SBEAT, WM_SETFONT, Font, TRUE); return 1; } return 0; }
int decodeFunc(void* inData) { int a, b, r, g, i; //short waveData[8 * 1024]; unsigned int* fftPtr; unsigned int* fftOutput; float fftData[1024]; //double timeInSec = 0.0; const float maxIntensity = 500 * 2; const int COLOR_STEPS = 255; const int PALETTE_SIZE = 3 * COLOR_STEPS; const int spectrumLength = 1024; ThreadFuncData* threadData = (ThreadFuncData*)inData; unsigned int colors[255 * 3]; int imageHeight = 128; HSTREAM chan = threadData->stream; MusicData* data = threadData->data; float percentDone = 1.0f; float step = 0.0f; mtx_lock(&s_mutex); const int SAMPLING_FREQUENCY = 100; //warning: in TimelineImage this samplingfrequency is assumed to be 100 const double SAMPLING_RESOLUTION = 1.0 / SAMPLING_FREQUENCY; QWORD sampleLength = BASS_ChannelSeconds2Bytes(chan, SAMPLING_RESOLUTION); int numSamples = (int)((double)BASS_ChannelGetLength(chan, BASS_POS_BYTE) / (double)sampleLength); //printf("Num samples %d\n", (int)sampleLength); //printf("Num samples %d\n", numSamples); BASS_ChannelPlay(chan, 0); int j_table[128]; int pj_table[128]; int nj_table[128]; // TODO: Size optimize? data->sampleCount = numSamples; fftPtr = fftOutput = (unsigned int*)malloc(128 * 4 * (numSamples + 1)); //const int spectrumLength = 1024; //const int imageHeight = 256; //var spectrumImage = new Bitmap((int)numSamples, imageHeight); //var volumeImage = new Bitmap((int)numSamples, imageHeight); //s_editorData.waveViewSize = 128; //s_editorData.trackViewInfo.windowSizeX -= s_editorData.waveViewSize; //timeInSec =(DWORD)BASS_ChannelBytes2Seconds(chan, len); //printf(" %u:%02u\n", (int)timeInSec / 60, (int)timeInSec % 60); for (i = 0; i < PALETTE_SIZE; ++i) { a = 255; if (i < PALETTE_SIZE * 0.666f) a = (int)(i * 255 / (PALETTE_SIZE * 0.666f)); b = 0; if (i < PALETTE_SIZE * 0.333f) b = i; else if (i < PALETTE_SIZE * 0.666f) b = -i + 510; r = 0; if (i > PALETTE_SIZE * 0.666f) r = 255; else if (i > PALETTE_SIZE * 0.333f) r = i - 255; g = 0; if (i > PALETTE_SIZE * 0.666f) g = i - 510; colors[i] = Emgui_color32((uint8_t)r, (uint8_t)g, (uint8_t)b, (uint8_t)a); } float f = (float)(spectrumLength / log((float)(imageHeight + 1))); float f2 = (float)((PALETTE_SIZE - 1) / log(maxIntensity + 1)); (void)f2; for (int rowIndex = 0; rowIndex < imageHeight; ++rowIndex) { int j_ = (int)(f * log(rowIndex + 1)); int pj_ = (int)(rowIndex > 0 ? f * log(rowIndex - 1 + 1) : j_); int nj_ = (int)(rowIndex < imageHeight - 1 ? f * log(rowIndex + 1 + 1) : j_); j_table[rowIndex] = j_; pj_table[rowIndex] = pj_; nj_table[rowIndex] = nj_; } step = (float)(99.0f / numSamples); percentDone = 1.0f; for (int sampleIndex = 0; sampleIndex < numSamples; ++sampleIndex) { BASS_ChannelSetPosition(chan, sampleIndex * sampleLength, BASS_POS_BYTE); BASS_ChannelGetData(chan, fftData, BASS_DATA_FFT2048); data->percentDone = (int)(percentDone); //printf("%d/%d\n", sampleIndex, numSamples); for (int rowIndex = 0; rowIndex < imageHeight; ++rowIndex) { //int j_ = (int)(f * log(rowIndex + 1)); //int pj_ = (int)(rowIndex > 0 ? f * log(rowIndex - 1 + 1) : j_); //int nj_ = (int)(rowIndex < imageHeight - 1 ? f * log(rowIndex + 1 + 1) : j_); int j_ = j_table[(imageHeight - rowIndex) - 1]; int pj_ = pj_table[(imageHeight - rowIndex) - 1]; int nj_ = nj_table[(imageHeight - rowIndex) - 1]; //printf("index %d - %d %d %d\n", rowIndex, j_, pj_, nj_); float intensity = 125.0f * 4.0f * fftData[spectrumLength - pj_ - 1] + 750.0f * 4.0f * fftData[spectrumLength - j_ - 1] + 125.0f * 4.0f * fftData[spectrumLength - nj_ - 1]; if (intensity > maxIntensity) intensity = maxIntensity; if (intensity < 0.0f) intensity = 0.0f; int palettePos = (int)(f2 * log(intensity + 1)); *fftOutput++ = colors[palettePos]; } percentDone += step; } BASS_StreamFree(chan); free(threadData); data->percentDone = 100; data->fftData = fftPtr; mtx_unlock(&s_mutex); //printf("thread done\n"); return 1; }
int WINAPI WinMain( HINSTANCE instance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow ) //void entrypoint(void) { MSG msg; int done=0; WININFO *info = &wininfo; window_init(info); long st = GetTickCount(); CLogger* myLogger; myLogger = new CLogger(); GraphicsClass* m_Graphics; m_Graphics = new GraphicsClass(); m_Graphics->Initialize(XRES,YRES,info->hWnd); // BASS BASS_Init(-1,44100,0,0,NULL); //char filename[400]="C:\\My_Projects\\frmwrk\\Debug\\lemonade-merry_xmas_nectas.xm"; char filename[400]="C:\\My_Projects\\frmwrk\\Debug\\bass_system-questa_sera.xm"; //char * filename= "dark_rat-xmas.xm"; DWORD chan; float time; //chan=BASS_MusicLoad(FALSE,"dark_rat-xmas.xm",0,0,BASS_SAMPLE_LOOP|BASS_MUSIC_RAMPS|BASS_MUSIC_PRESCAN,0); if (!(chan=BASS_MusicLoad(FALSE,filename,0,0,BASS_MUSIC_RAMPS|BASS_MUSIC_PRESCAN,0))) { int k=5; } float dummy; int a; for (a=0;BASS_ChannelGetAttribute(chan,BASS_ATTRIB_MUSIC_VOL_CHAN+a,&dummy);a++); QWORD pos; pos=BASS_ChannelGetLength(chan,BASS_POS_BYTE); BASS_ChannelPlay(chan,FALSE); // programm loop long to=0; while( !done ) { pos=BASS_ChannelGetPosition(chan,BASS_POS_BYTE); time=BASS_ChannelBytes2Seconds(chan,pos); myLogger->LogThis("pos"); myLogger->LogThisFloat((float)pos); myLogger->LogThis("time"); myLogger->LogThisFloat((float)time); if (time!=0) { int k=6; } long t = GetTickCount(); if( !to ) to=t; t-=to; while( PeekMessage(&msg,0,0,0,PM_REMOVE) ) { if( msg.message==WM_QUIT ) done=1; TranslateMessage( &msg ); DispatchMessage( &msg ); } DrawTime( info, .001f*t ); m_Graphics->Frame(); m_Graphics->Render(); } window_end(info); ExitProcess( 0 ); }
//----------------------------------------------------------------------------- void LLFFTSound::update(float addedTime) { if(!m_bInitialized || !m_bPlaying) return; #ifdef _WINDOWS // update current waveform level #if BASSVERSION == 0x204 DWORD pos = BASS_ChannelGetPosition(m_dChannel, BASS_POS_BYTE); if (pos == BASS_ChannelGetLength(m_dChannel, BASS_POS_BYTE)) #else DWORD pos = BASS_ChannelGetPosition(m_dChannel); if (pos == BASS_ChannelGetLength(m_dChannel)) #endif { m_fCurrLevelLeft = 0.0f; m_fCurrLevelRight = 0.0f; m_bPlaying = false; BASS_ChannelStop(m_dChannel); // reset bands values for (int i=0; i< BANDS; i++) m_fBands[i] = 0.0f; // reset events queue resetEvent(); } else { // update lever for each channel DWORD level = BASS_ChannelGetLevel(m_dChannel); m_fCurrLevelLeft = ((double)LOWORD(level) / 32768); // range 0 to 1: left channel is low word m_fCurrLevelRight = ((double)HIWORD(level) / 32768); // range 0 to 1: right channel is high word // update band spectrum float fft[1024]; BASS_ChannelGetData(m_dChannel,fft,BASS_DATA_FFT2048); // get the FFT data int b0=0; int x,y; #define FFTCAP 256.0f for (x=0; x<BANDS; x++) { float sum=0; int sc,b1 = pow(2,x*10.0/(BANDS-1)); if (b1>1023) b1=1023; if (b1<=b0) b1=b0+1; // make sure it uses at least 1 FFT bin sc = 10 + b1 - b0; for (;b0<b1;b0++) sum+=fft[1+b0]; y=(sqrt(sum/log10((double)sc))*1.7*FFTCAP)-4; // scale it if (y>FFTCAP) y=FFTCAP; // cap it // store band value m_fBands[x] = y; m_fBands[x] /= FFTCAP; // normalized band value (0.0 - 1.0) } // check event associated with this sound file: use pos variable to detect timing... float elapsedTime = BASS_ChannelBytes2Seconds(m_dChannel,pos); if (m_iNumEvents && !m_bEventDone) { if (elapsedTime > 0.0f) { // there is possibility that multiple events have the same timestamp... // should do some kind of iteration. bool running = true; while(running) { if (m_fNextEventTime < elapsedTime) { // execute callback function i_CharacterEventCallback.execute(m_vEventVec[m_iNextEvent]); // move to next event m_iNextEvent++; if (m_iNextEvent == m_iNumEvents) { // reached the last event m_iNextEvent = 0; m_bEventDone = true; running = false; } m_fNextEventTime = m_vEventVec[m_iNextEvent]->eTime; } else running = false; } } } } #endif }
INT_PTR CALLBACK dialogproc(HWND h,UINT m,WPARAM w,LPARAM l) { switch (m) { case WM_COMMAND: switch (LOWORD(w)) { case IDCANCEL: DestroyWindow(h); break; case 10: { char file[MAX_PATH]=""; ofn.lpstrFile=file; ofn.nMaxFile=MAX_PATH; if (GetOpenFileName(&ofn)) { BASS_StreamFree(chan); // free the old stream if (!(chan=BASS_StreamCreateFile(FALSE,file,0,0,BASS_SAMPLE_LOOP))) { // it ain't playable MESS(10,WM_SETTEXT,0,"click here to open a file..."); MESS(11,WM_SETTEXT,0,""); Error("Can't play the file"); break; } MESS(10,WM_SETTEXT,0,file); { // display the file type and length QWORD bytes=BASS_ChannelGetLength(chan,BASS_POS_BYTE); DWORD time=BASS_ChannelBytes2Seconds(chan,bytes); BASS_CHANNELINFO info; BASS_ChannelGetInfo(chan,&info); sprintf(file,"channel type = %x (%s)\nlength = %I64u (%u:%02u)", info.ctype,GetCTypeString(info.ctype,info.plugin),bytes,time/60,time%60); MESS(11,WM_SETTEXT,0,file); MESS(12,TBM_SETRANGE,1,MAKELONG(0,time)); // update scroller range } BASS_ChannelPlay(chan,FALSE); } } break; } break; case WM_HSCROLL: if (l && LOWORD(w)!=SB_THUMBPOSITION && LOWORD(w)!=SB_ENDSCROLL) { // set the position int pos=SendMessage((HWND)l,TBM_GETPOS,0,0); BASS_ChannelSetPosition(chan,BASS_ChannelSeconds2Bytes(chan,pos),BASS_POS_BYTE); } break; case WM_TIMER: MESS(12,TBM_SETPOS,1,(DWORD)BASS_ChannelBytes2Seconds(chan,BASS_ChannelGetPosition(chan,BASS_POS_BYTE))); // update position break; case WM_INITDIALOG: win=h; // initialize default output device if (!BASS_Init(-1,44100,0,win,NULL)) { Error("Can't initialize device"); DestroyWindow(win); break; } // initialize file selector memset(&ofn,0,sizeof(ofn)); ofn.lStructSize=sizeof(ofn); ofn.hwndOwner=h; ofn.Flags=OFN_HIDEREADONLY|OFN_EXPLORER; ofn.lpstrFilter=filter; memcpy(filter,"BASS built-in (*.mp3;*.mp2;*.mp1;*.ogg;*.wav;*.aif)\0*.mp3;*.mp2;*.mp1;*.ogg;*.wav;*.aif\0",88); { // look for plugins (in the executable's directory) WIN32_FIND_DATA fd; HANDLE fh; char path[MAX_PATH],*fp=filter+88; GetModuleFileName(0,path,sizeof(path)); strcpy(strrchr(path,'\\')+1,"bass*.dll"); fh=FindFirstFile(path,&fd); if (fh!=INVALID_HANDLE_VALUE) { do { HPLUGIN plug; if (plug=BASS_PluginLoad(fd.cFileName,0)) { // plugin loaded... const BASS_PLUGININFO *pinfo=BASS_PluginGetInfo(plug); // get plugin info to add to the file selector filter... int a; for (a=0;a<pinfo->formatc;a++) { fp+=sprintf(fp,"%s (%s) - %s",pinfo->formats[a].name,pinfo->formats[a].exts,fd.cFileName)+1; // format description fp+=sprintf(fp,"%s",pinfo->formats[a].exts)+1; // extension filter } // add plugin to the list MESS(20,LB_ADDSTRING,0,fd.cFileName); } } while (FindNextFile(fh,&fd)); FindClose(fh); } if (!MESS(20,LB_GETCOUNT,0,0)) // no plugins... MESS(20,LB_ADDSTRING,0,"no plugins - visit the BASS webpage to get some"); memcpy(fp,"All files\0*.*\0\0",15); } SetTimer(h,0,500,0); // timer to update the position return 1; case WM_DESTROY: // "free" the output device and all plugins BASS_Free(); BASS_PluginFree(0); break; } return 0; }
INT_PTR CALLBACK dialogproc(HWND h,UINT m,WPARAM w,LPARAM l) { switch (m) { case WM_TIMER: { // update the recording/playback counter char text[30]=""; if (rchan) // recording sprintf(text,"%d",reclen-44); else if (chan) { if (BASS_ChannelIsActive(chan)) // playing sprintf(text,"%I64d / %I64d",BASS_ChannelGetPosition(chan,BASS_POS_BYTE),BASS_ChannelGetLength(chan,BASS_POS_BYTE)); else sprintf(text,"%I64d",BASS_ChannelGetLength(chan,BASS_POS_BYTE)); } MESS(20,WM_SETTEXT,0,text); } break; case WM_COMMAND: switch (LOWORD(w)) { case IDCANCEL: DestroyWindow(h); break; case 10: if (!rchan) StartRecording(); else StopRecording(); break; case 11: BASS_ChannelPlay(chan,TRUE); // play the recorded data break; case 12: WriteToDisk(); break; case 13: if (HIWORD(w)==CBN_SELCHANGE) { // input selection changed int i; input=MESS(13,CB_GETCURSEL,0,0); // get the selection // enable the selected input for (i=0;BASS_RecordSetInput(i,BASS_INPUT_OFF,-1);i++) ; // 1st disable all inputs, then... BASS_RecordSetInput(input,BASS_INPUT_ON,-1); // enable the selected UpdateInputInfo(); } break; case 16: if (HIWORD(w)==CBN_SELCHANGE) { // device selection changed int i=MESS(16,CB_GETCURSEL,0,0); // get the selection // initialize the selected device if (InitDevice(i)) { if (rchan) { // continue recording on the new device... HRECORD newrchan=BASS_RecordStart(FREQ,CHANS,0,RecordingCallback,0); if (!newrchan) Error("Couldn't start recording"); else rchan=newrchan; } } } break; } break; case WM_HSCROLL: if (l) { // set input source level float level=SendMessage((HWND)l,TBM_GETPOS,0,0)/100.f; if (!BASS_RecordSetInput(input,0,level)) // failed to set input level BASS_RecordSetInput(-1,0,level); // try master level instead } break; case WM_INITDIALOG: win=h; MESS(14,TBM_SETRANGE,FALSE,MAKELONG(0,100)); { // get list of recording devices int c,def; BASS_DEVICEINFO di; for (c=0;BASS_RecordGetDeviceInfo(c,&di);c++) { MESS(16,CB_ADDSTRING,0,di.name); if (di.flags&BASS_DEVICE_DEFAULT) { // got the default device MESS(16,CB_SETCURSEL,c,0); def=c; } } InitDevice(def); // initialize default recording device } SetTimer(h,0,200,0); // timer to update the position display return 1; case WM_DESTROY: // release all BASS stuff BASS_RecordFree(); BASS_Free(); break; } return 0; }