void BassPlayer::applyTempoToChannel() { quint64 tempo_chan = BASS_FX_TempoCreate(chan, BASS_FX_FREESOURCE); if (!tempo_chan) { //FIXME: block tempo func qCritical() << "e:" << BASS_ErrorGetCode(); } else chan = tempo_chan; }
AudioClip::AudioClip(unsigned char *data) { pan = 0.0f; volume = 1.0f; pitch = 0.0f; loop = false; play_once = false; oshot = false; hm = BASS_StreamCreate(44100, 2, BASS_STREAM_DECODE, 0, (void*)data); hm = BASS_FX_TempoCreate(hm, BASS_FX_FREESOURCE); }
AudioClip::AudioClip(std::string filename) { pan = 0.0f; volume = 1.0f; pitch = 0.0f; loop = false; play_once = false; oshot = false; std::wstring fname(filename.begin(), filename.end()); hm = BASS_StreamCreateFile(FALSE, fname.c_str(), 0, 0, BASS_STREAM_DECODE); hm = BASS_FX_TempoCreate(hm, BASS_FX_FREESOURCE); }
HFX CALLBACK SetCustFX (DWORD chan, DWORD type, int priority) { if (type!=CUST_FX_TYPE_ID) return NULL; BASS_CHANNELINFO info; BASS_ChannelGetInfo(chan, &info); HCustFX* hc = malloc(sizeof(HCustFX)); if (!hc) return NULL; hc->flags = info.flags&( BASS_SAMPLE_FLOAT | BASS_SAMPLE_8BITS ); hc->push = BASS_StreamCreate(info.freq, info.chans, hc->flags | BASS_STREAM_DECODE, STREAMPROC_PUSH, NULL); hc->pitch = BASS_FX_TempoCreate(hc->push, BASS_STREAM_DECODE); HFX hfx = bassfunc->SetFX(chan, CustFXDSPProc, hc, priority, &CustFXFuncs); if (hfx&&hc->pitch&&hc->push) return hfx; if (hfx) BASS_ChannelRemoveFX(chan, hfx); if (hc->pitch) BASS_StreamFree(hc->pitch); if (hc->push) BASS_StreamFree(hc->push); free(hc); return NULL; }
HSTREAM BassSoundEngine::ReadMusic(string filename) { HSTREAM sound; if(stream_pool.find(filename)!=stream_pool.end()) sound = stream_pool[filename]; else{ sound = BASS_StreamCreateFile(FALSE, filename.data(), 0, 0, BASS_STREAM_PRESCAN|BASS_STREAM_DECODE); sound = BASS_FX_TempoCreate(sound, BASS_FX_FREESOURCE); BOOL hr; float sequence_ms = systemIni.BASS_ATTRIB_TEMPO_OPTION_SEQUENCE_MS; hr = BASS_ChannelSetAttribute(sound, BASS_ATTRIB_TEMPO_OPTION_SEQUENCE_MS, sequence_ms); ERRCHECK(hr); float seekwindow_ms = systemIni.BASS_ATTRIB_TEMPO_OPTION_SEEKWINDOW_MS; hr = BASS_ChannelSetAttribute(sound, BASS_ATTRIB_TEMPO_OPTION_SEEKWINDOW_MS, seekwindow_ms); ERRCHECK(hr); float overlap_ms = systemIni.BASS_ATTRIB_TEMPO_OPTION_OVERLAP_MS; hr = BASS_ChannelSetAttribute(sound, BASS_ATTRIB_TEMPO_OPTION_OVERLAP_MS, overlap_ms); ERRCHECK(hr); stream_pool[filename] = sound; } return sound; }
void BassSoundEngine::Init() { nowChannel = 0; sampleRate_factor = pitch_factor = tempo_factor = 0; intended_pitch = 1.0; DWORD hr; hr = BASS_Init(-1, defaultSampleRate, BASS_DEVICE_LATENCY, base::hwnd, NULL); hr = BASS_FX_GetVersion(); hitWav = BASS_SampleLoad(false, "gamedata\\hit.wav", 0, 0, 16, 0); #if 1==0 HSTREAM fs1, fs2; fs1 = BASS_StreamCreateFile(false,"D:\\Project DIVA PC\\gamedata\\cg.mp3",0,0,BASS_STREAM_DECODE); fs2 = BASS_FX_TempoCreate(fs1, 0); hr = BASS_ErrorGetCode(); hr = BASS_ChannelPlay(fs2, FALSE); hr = BASS_ChannelSetAttribute(fs2, BASS_ATTRIB_TEMPO, 50); Sleep(100000); hr = BASS_ChannelStop(fs1); Sleep(2000); #endif hr = 0; }
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; }
HRESULT CBSoundBuffer::LoadFromFile(const char* Filename, bool ForceReload) { if (m_Stream) { BASS_StreamFree(m_Stream); m_Stream = NULL; } if (m_File) Game->m_FileManager->CloseFile(m_File); m_File = Game->m_FileManager->OpenFile(Filename); if (!m_File) { Game->LOG(0, "Error opening sound file '%s'", Filename); return E_FAIL; } BASS_FILEPROCS fileProc; fileProc.close = CBSoundBuffer::FileCloseProc; fileProc.read = CBSoundBuffer::FileReadProc; fileProc.seek = CBSoundBuffer::FileSeekProc; fileProc.length = CBSoundBuffer::FileLenProc; m_Stream = BASS_StreamCreateFileUser(STREAMFILE_NOBUFFER, BASS_STREAM_DECODE, &fileProc, (void*)m_File); if (!m_Stream) { Game->LOG(0, "BASS error: %d while loading '%s'", BASS_ErrorGetCode(), Filename); return E_FAIL; } m_Stream = BASS_FX_TempoCreate(m_Stream,BASS_SAMPLE_LOOP|BASS_FX_FREESOURCE); CBUtils::SetString(&m_Filename, Filename); /* HRESULT res; bool NewlyCreated = false; if(!m_SoundBuffer || ForceReload || m_Streamed){ if(!m_File) m_File = Game->m_FileManager->OpenFile(Filename); if(!m_File){ Game->LOG(0, "Error opening sound file '%s'", Filename); return E_FAIL; } // switch to streamed for big files if(!m_Streamed && (m_File->GetSize() > MAX_NONSTREAMED_FILE_SIZE && !Game->m_ForceNonStreamedSounds)) SetStreaming(true); } // create buffer if(!m_SoundBuffer){ NewlyCreated = true; res = InitializeBuffer(m_File); if(FAILED(res)){ Game->LOG(res, "Error creating sound buffer for file '%s'", Filename); return res; } } // store filename if(!m_Filename){ m_Filename = new char[strlen(Filename)+1]; strcpy(m_Filename, Filename); } // close file (if not streaming) if(!m_Streamed && m_File){ Game->m_FileManager->CloseFile(m_File); m_File = NULL; } */ return S_OK; }
pascal OSStatus OpenEventHandler(EventHandlerCallRef inHandlerRef, EventRef inEvent, void *inUserData) { DWORD p; NavDialogRef fileDialog; NavDialogCreationOptions fo; NavGetDefaultDialogCreationOptions(&fo); fo.optionFlags=0; fo.parentWindow=win; NavCreateChooseFileDialog(&fo,NULL,NULL,NULL,NULL,NULL,&fileDialog); 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 streams before opening new // create decode channel chan = BASS_StreamCreateFile(FALSE,file,0,0,BASS_SAMPLE_FLOAT|BASS_STREAM_DECODE|BASS_STREAM_PRESCAN); // check for MOD if (!chan) chan = BASS_MusicLoad(FALSE, file, 0, 0, BASS_SAMPLE_FLOAT|BASS_MUSIC_RAMP|BASS_STREAM_DECODE|BASS_MUSIC_PRESCAN,0); if (!chan) { SetControlTitleWithCFString(inUserData,CFSTR("click here to open a file && play it...")); Error("Selected file couldn't be loaded!"); } else { // create new stream - decoded & reversed // 2 seconds decoding block as a decoding channel if (!(chan=BASS_FX_ReverseCreate(chan, 2, BASS_STREAM_DECODE|BASS_FX_FREESOURCE))) { SetControlTitleWithCFString(inUserData,CFSTR("click here to open a file && play it...")); Error("Couldn't create a reversed stream!"); BASS_StreamFree(chan); BASS_MusicFree(chan); } else { // create a new stream - decoded & resampled :) if (!(chan=BASS_FX_TempoCreate(chan, BASS_SAMPLE_LOOP|BASS_FX_FREESOURCE))){ SetControlTitleWithCFString(inUserData,CFSTR("click here to open a file && play it...")); Error("Couldn't create a resampled stream!"); BASS_StreamFree(chan); BASS_MusicFree(chan); } else { // update the Button to show the loaded file c2pstrcpy((BYTE*)file,file); SetControlTitle(inUserData,(BYTE*)file); // update the position slider p = BASS_ChannelBytes2Seconds(chan, BASS_ChannelGetLength(chan, BASS_POS_BYTE)); SetControl32BitMaximum(GetControl(15),p); SetControl32BitValue(GetControl(15),p); // set Volume p = GetControl32BitValue(GetControl(11)); BASS_ChannelSetAttribute(chan, BASS_ATTRIB_VOL, (float)p/100.0f); // update tempo slider SetControl32BitValue(GetControl(13),0); SetStaticText(12,"Tempo = 0%"); // play new created stream BASS_ChannelPlay(chan,FALSE); } } } } NavDisposeReply(&r); } } NavDialogDispose(fileDialog); return noErr; }