// // Called from the main thread during DoPulse // void CBassAudio::CompleteStreamConnect ( HSTREAM pSound ) { if ( pSound ) { m_pSound = pSound; BASS_ChannelGetAttribute ( pSound, BASS_ATTRIB_FREQ, &m_fDefaultFrequency ); BASS_ChannelSetAttribute ( pSound, BASS_ATTRIB_FREQ, m_fPlaybackSpeed * m_fDefaultFrequency ); if ( !m_b3D ) BASS_ChannelSetAttribute( pSound, BASS_ATTRIB_VOL, m_fVolume ); ApplyFxEffects (); // Set a Callback function for download finished or connection closed prematurely m_hSyncDownload = BASS_ChannelSetSync ( pSound, BASS_SYNC_DOWNLOAD, 0, &DownloadSync, m_uiCallbackId ); SetFinishedCallbacks (); if ( BASS_FX_BPM_CallbackSet ( pSound, (BPMPROC*)&BPMCallback, 1, 0, 0, m_uiCallbackId ) == false ) { g_pCore->GetConsole()->Print ( "BASS ERROR in BASS_FX_BPM_CallbackSet" ); } if ( BASS_FX_BPM_BeatCallbackSet ( pSound, (BPMBEATPROC*)&BeatCallback, m_uiCallbackId ) == false ) { g_pCore->GetConsole()->Print ( "BASS ERROR in BASS_FX_BPM_BeatCallbackSet" ); } // get the broadcast name const char* szIcy; szIcy = BASS_ChannelGetTags ( pSound, BASS_TAG_ICY ); if ( ( szIcy = BASS_ChannelGetTags ( pSound, BASS_TAG_ICY ) ) || ( szIcy = BASS_ChannelGetTags ( pSound, BASS_TAG_WMA ) ) || ( szIcy = BASS_ChannelGetTags ( pSound, BASS_TAG_HTTP ) ) ) { if ( szIcy ) { for ( ; *szIcy; szIcy += strlen ( szIcy ) + 1 ) { if ( !strnicmp ( szIcy, "icy-name:", 9 ) ) // ICY / HTTP { m_strStreamName = szIcy + 9; break; } else if ( !strnicmp ( szIcy, "title=", 6 ) ) // WMA { m_strStreamName = szIcy + 6; break; } //g_pCore->GetConsole()->Printf ( "BASS STREAM INFO %s", szIcy ); } } } // set sync for stream titles m_hSyncMeta = BASS_ChannelSetSync( pSound, BASS_SYNC_META, 0, &MetaSync, m_uiCallbackId ); // Shoutcast //g_pCore->GetConsole()->Printf ( "BASS ERROR %d in BASS_SYNC_META", BASS_ErrorGetCode() ); //BASS_ChannelSetSync(pSound,BASS_SYNC_OGG_CHANGE,0,&MetaSync,this); // Icecast/OGG //g_pCore->GetConsole()->Printf ( "BASS ERROR %d in BASS_SYNC_OGG_CHANGE", BASS_ErrorGetCode() ); //BASS_ChannelSetSync(pSound,BASS_SYNC_WMA_META,0,&MetaSync,this); // script/mid-stream tags //g_pCore->GetConsole()->Printf ( "BASS ERROR %d in BASS_SYNC_WMA_META", BASS_ErrorGetCode() ); //BASS_ChannelSetSync(pSound,BASS_SYNC_WMA_CHANGE,0,&WMAChangeSync,this); // server-side playlist changes //g_pCore->GetConsole()->Printf ( "BASS ERROR %d in BASS_SYNC_WMA_CHANGE", BASS_ErrorGetCode() ); } else g_pCore->GetConsole()->Printf ( "BASS ERROR %d in PlayStream b3D = %s path = %s", BASS_ErrorGetCode(), m_b3D ? "true" : "false", m_strPath.c_str() ); OutputDebugLine ( "[Bass] stream connect complete" ); AddQueuedEvent ( SOUND_EVENT_STREAM_RESULT, m_strStreamName, GetLength (), pSound ? true : false ); }
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; }
// // This will return false for non streams if the file is not correct // bool CBassAudio::BeginLoadingMedia ( void ) { assert ( !m_pSound && !m_bPendingPlay ); // Calc the flags long lFlags = BASS_STREAM_AUTOFREE | BASS_SAMPLE_SOFTWARE; #if 0 // Everything sounds better in ste-reo if ( m_b3D ) lFlags |= BASS_SAMPLE_MONO; #endif if ( m_bLoop ) lFlags |= BASS_SAMPLE_LOOP; if ( m_bStream ) { // // For streams, begin the connect sequence // assert ( !m_pVars ); m_pVars = new SSoundThreadVariables (); m_pVars->strURL = m_strPath; m_pVars->lFlags = lFlags; CreateThread ( NULL, 0, reinterpret_cast <LPTHREAD_START_ROUTINE> ( &CBassAudio::PlayStreamIntern ), m_uiCallbackId, 0, NULL ); m_bPendingPlay = true; OutputDebugLine ( "[Bass] stream connect started" ); } else { // // For non streams, try to load the sound file // // First x streams need to be decoders rather than "real" sounds but that's dependent on if we need streams or not so we need to adapt. /* We are the Borg. Lower your shields and surrender your ships. We will add your biological and technological distinctiveness to our own. Your culture will adapt to service us. Resistance is futile. */ long lCreateFlags = BASS_MUSIC_PRESCAN|BASS_STREAM_DECODE; if ( !m_pBuffer ) { m_pSound = BASS_StreamCreateFile ( false, m_strPath, 0, 0, lCreateFlags ); if ( !m_pSound ) m_pSound = BASS_MusicLoad ( false, m_strPath, 0, 0, BASS_MUSIC_RAMP|BASS_MUSIC_PRESCAN|BASS_STREAM_DECODE, 0 ); // Try again if ( !m_pSound && m_b3D ) m_pSound = ConvertFileToMono ( m_strPath ); // Last try if 3D } else { m_pSound = BASS_StreamCreateFile ( true, m_pBuffer, 0, m_uiBufferLength, lCreateFlags ); if ( !m_pSound ) m_pSound = BASS_MusicLoad ( true, m_pBuffer, 0, m_uiBufferLength, lCreateFlags, 0 ); } // Failed to load ? if ( !m_pSound ) { g_pCore->GetConsole()->Printf ( "BASS ERROR %d in LoadMedia path:%s 3d:%d loop:%d", BASS_ErrorGetCode(), *m_strPath, m_b3D, m_bLoop ); return false; } m_pSound = BASS_FX_ReverseCreate ( m_pSound, 2.0f, BASS_STREAM_DECODE | BASS_FX_FREESOURCE | BASS_MUSIC_PRESCAN ); BASS_ChannelSetAttribute ( m_pSound, BASS_ATTRIB_REVERSE_DIR, BASS_FX_RVS_FORWARD ); // Sucks. /*if ( BASS_FX_BPM_CallbackSet ( m_pSound, (BPMPROC*)&BPMCallback, 1, 0, 0, m_uiCallbackId ) == false ) { g_pCore->GetConsole()->Printf ( "BASS ERROR %d in BASS_FX_BPM_CallbackSet path:%s 3d:%d loop:%d", BASS_ErrorGetCode(), *m_strPath, m_b3D, m_bLoop ); }*/ if ( BASS_FX_BPM_BeatCallbackSet ( m_pSound, (BPMBEATPROC*)&BeatCallback, m_uiCallbackId ) == false ) { g_pCore->GetConsole()->Printf ( "BASS ERROR %d in BASS_FX_BPM_BeatCallbackSet path:%s 3d:%d loop:%d", BASS_ErrorGetCode(), *m_strPath, m_b3D, m_bLoop ); } if ( !m_pSound ) { g_pCore->GetConsole()->Printf ( "BASS ERROR %d in BASS_FX_ReverseCreate path:%s 3d:%d loop:%d", BASS_ErrorGetCode(), *m_strPath, m_b3D, m_bLoop ); return false; } m_pSound = BASS_FX_TempoCreate ( m_pSound, lFlags | BASS_FX_FREESOURCE ); if ( !m_pSound ) { g_pCore->GetConsole()->Printf ( "BASS ERROR %d in CreateTempo path:%s 3d:%d loop:%d", BASS_ErrorGetCode(), *m_strPath, m_b3D, m_bLoop ); return false; } BASS_ChannelGetAttribute ( m_pSound, BASS_ATTRIB_TEMPO, &m_fTempo ); BASS_ChannelGetAttribute ( m_pSound, BASS_ATTRIB_TEMPO_PITCH, &m_fPitch ); BASS_ChannelGetAttribute ( m_pSound, BASS_ATTRIB_TEMPO_FREQ, &m_fSampleRate ); // Validation of some sort if ( m_bLoop && BASS_ChannelFlags ( m_pSound, BASS_SAMPLE_LOOP, BASS_SAMPLE_LOOP ) == -1 ) g_pCore->GetConsole()->Printf ( "BASS ERROR %d in LoadMedia ChannelFlags LOOP path:%s 3d:%d loop:%d", BASS_ErrorGetCode(), *m_strPath, m_b3D, m_bLoop ); BASS_ChannelGetAttribute ( m_pSound, BASS_ATTRIB_FREQ, &m_fDefaultFrequency ); m_bPendingPlay = true; SetFinishedCallbacks (); OutputDebugLine ( "[Bass] sound loaded" ); } return true; }