void RotateToggled(GtkToggleButton *obj, gpointer data) { // toggle "rotate" if (obj->active) { rotpos=0.7853981f; rotdsp=BASS_ChannelSetDSP(chan,&Rotate,0,2); } else BASS_ChannelRemoveDSP(chan,rotdsp); }
void EchoToggled(GtkToggleButton *obj, gpointer data) { // toggle "echo" if (obj->active) { memset(echbuf,0,sizeof(echbuf)); echpos=0; echdsp=BASS_ChannelSetDSP(chan,&Echo,0,1); } else BASS_ChannelRemoveDSP(chan,echdsp); }
void FlangerToggled(GtkToggleButton *obj, gpointer data) { // toggle "flanger" if (obj->active) { memset(flabuf,0,sizeof(flabuf)); flapos=0; flas=FLABUFLEN/2; flasinc=0.002f; fladsp=BASS_ChannelSetDSP(chan,&Flange,0,0); } else BASS_ChannelRemoveDSP(chan,fladsp); }
BOOL 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: { BASS_CHANNELINFO info; char file[MAX_PATH]=""; ofn.lpstrFilter="playable files\0*.mo3;*.xm;*.mod;*.s3m;*.it;*.mtm;*.umx;*.mp3;*.mp2;*.mp1;*.ogg;*.wav;*.aif\0All files\0*.*\0\0"; ofn.lpstrFile=file; if (GetOpenFileName(&ofn)) { // free both MOD and stream, it must be one of them! :) BASS_MusicFree(chan); BASS_StreamFree(chan); if (!(chan=BASS_StreamCreateFile(FALSE,file,0,0,BASS_SAMPLE_LOOP|floatable)) && !(chan=BASS_MusicLoad(FALSE,file,0,0,BASS_SAMPLE_LOOP|BASS_MUSIC_RAMPS|floatable,1))) { // whatever it is, it ain't playable MESS(10,WM_SETTEXT,0,"click here to open a file..."); Error("Can't play the file"); break; } BASS_ChannelGetInfo(chan,&info); if (info.chans!=2) { // only stereo is allowed MESS(10,WM_SETTEXT,0,"click here to open a file..."); BASS_MusicFree(chan); BASS_StreamFree(chan); Error("only stereo sources are supported"); break; } MESS(10,WM_SETTEXT,0,file); // setup DSPs on new channel and play it SendMessage(win,WM_COMMAND,11,0); SendMessage(win,WM_COMMAND,12,0); SendMessage(win,WM_COMMAND,13,0); BASS_ChannelPlay(chan,FALSE); } } break; case 11: // toggle "rotate" if (MESS(11,BM_GETCHECK,0,0)) { rotpos=0.7853981f; rotdsp=BASS_ChannelSetDSP(chan,&Rotate,0,2); } else BASS_ChannelRemoveDSP(chan,rotdsp); break; case 12: // toggle "echo" if (MESS(12,BM_GETCHECK,0,0)) { memset(echbuf,0,sizeof(echbuf)); echpos=0; echdsp=BASS_ChannelSetDSP(chan,&Echo,0,1); } else BASS_ChannelRemoveDSP(chan,echdsp); break; case 13: // toggle "flanger" if (MESS(13,BM_GETCHECK,0,0)) { memset(flabuf,0,sizeof(flabuf)); flapos=0; flas=FLABUFLEN/2; flasinc=0.002f; fladsp=BASS_ChannelSetDSP(chan,&Flange,0,0); } else BASS_ChannelRemoveDSP(chan,fladsp); break; } break; case WM_INITDIALOG: win=h; memset(&ofn,0,sizeof(ofn)); ofn.lStructSize=sizeof(ofn); ofn.hwndOwner=h; ofn.nMaxFile=MAX_PATH; ofn.Flags=OFN_HIDEREADONLY|OFN_EXPLORER; // enable floating-point DSP BASS_SetConfig(BASS_CONFIG_FLOATDSP,TRUE); // initialize - default device if (!BASS_Init(-1,44100,0,win,NULL)) { Error("Can't initialize device"); DestroyWindow(win); break; } // check for floating-point capability floatable=BASS_StreamCreate(44100,2,BASS_SAMPLE_FLOAT,NULL,0); if (floatable) { // woohoo! BASS_StreamFree(floatable); floatable=BASS_SAMPLE_FLOAT; } return 1; case WM_DESTROY: BASS_Free(); break; } return 0; }
HRESULT CBSoundBuffer::ApplyFX(TSFXType Type, float Param1, float Param2, float Param3, float Param4) { switch(Type) { case SFX_ECHO: #ifdef USE_BASS_FX if (m_EffectHandle != 0) { BASS_ChannelRemoveFX(m_Stream, m_EffectHandle); } m_EffectHandle = BASS_ChannelSetFX( m_Stream, BASS_FX_BFX_ECHO4, 0); if (m_EffectHandle != 0) { BASS_BFX_ECHO4 params; /* * try to be as close as possible to the DSFX echo, it will never be perfect though * * fDryMix = reverse of fWetDryMix (scaled from 0..100 into 0..1) * fWetMix = fWetDryMix (converted from logarithmic to linear) * fDelay = mean of fLeftDelay and fRightDelay (converted from milliseconds to seconds) * ignored = fFeedback (the BASS feedback parameter is used to create reverb) */ params.fDryMix = ((100.0f - Param1) / 100.0f); params.fWetMix = (Param1 / 100.0f); params.fFeedback = 0; params.fDelay = (Param3 + Param4) / 2.0f / 1000.0f; params.bStereo = false; params.lChannel = BASS_BFX_CHANALL; Game->LOG(0, "Echo params: Dry=%.2f Wet=%.2f Fedback=%.2f Delay=%.2f", params.fDryMix, params.fWetMix, params.fFeedback, params.fDelay); BOOL status = BASS_FXSetParameters( m_EffectHandle, (void *) ¶ms); Game->LOG(0, "Echo status=%s", (status == TRUE) ? "OK" : "ERROR"); if (status == FALSE) { Game->LOG(0, "Echo error=%d", BASS_ErrorGetCode()); } } #endif break; case SFX_REVERB: #ifdef USE_BASS_FX if (m_EffectHandle != 0) { BASS_ChannelRemoveFX(m_Stream, m_EffectHandle); } m_EffectHandle = BASS_ChannelSetFX( m_Stream, BASS_FX_BFX_ECHO4, 0); if (m_EffectHandle != 0) { BASS_BFX_ECHO4 params; /* * try to be as close as possible to the DSFX reverb, it will never be perfect though * * fDryMix = fInGain (converted from logarithmic to linear) * fWetMix = fReverbMix (converted from logarithmic to linear) multiplied ("attenuated") with fDryMix * fDelay = fReverbTime (converted from milliseconds to seconds) * ignored = fHighFreqRTRatio (no equivalent in BASS) */ params.fDryMix = pow(10.0f, (Param1 / 10.0f)); params.fWetMix = pow(10.0f, (Param2 / 10.0f)) * params.fDryMix; params.fFeedback = 0.7f; params.fDelay = ((Param3 / 1000.0f) / 10.0f); // test a different approach, where only the feedback parameter is affected by the fReverbTime params.fDryMix = 0.999f; params.fWetMix = 0.7f; params.fFeedback = 0.5f + ((Param3 / 3000.0f) * 0.2f); params.fDelay = 0.005f; params.bStereo = false; params.lChannel = BASS_BFX_CHANALL; Game->LOG(0, "Reverb params: Dry=%.2f Wet=%.2f Fedback=%.2f Delay=%.2f", params.fDryMix, params.fWetMix, params.fFeedback, params.fDelay); BOOL status = BASS_FXSetParameters( m_EffectHandle, (void *) ¶ms); Game->LOG(0, "Reverb status=%s", (status == TRUE) ? "OK" : "ERROR"); if (status == FALSE) { Game->LOG(0, "Reverb error=%d", BASS_ErrorGetCode()); } } #endif break; case SFX_REVERB_PRESET: // TODO need to check whether context is already in use #ifdef USE_LIBEFFECTS_REVERB int status; uint32_t replyCount; char replydata[8]; m_context.hInstance = NULL; m_context.boolAuxiliary = 0; m_context.boolPreset = 1; m_context.curPreset = REVERB_PRESET_LAST + 1; switch (int (Param1)) { case 0: m_context.nextPreset = REVERB_PRESET_NONE; break; case 1: m_context.nextPreset = REVERB_PRESET_SMALLROOM; break; case 2: m_context.nextPreset = REVERB_PRESET_MEDIUMROOM; break; case 3: m_context.nextPreset = REVERB_PRESET_LARGEROOM; break; case 4: m_context.nextPreset = REVERB_PRESET_MEDIUMHALL; break; case 5: m_context.nextPreset = REVERB_PRESET_LARGEHALL; break; case 6: m_context.nextPreset = REVERB_PRESET_PLATE; break; default: m_context.nextPreset = REVERB_PRESET_NONE; break; } Game->LOG(0, "====> Next preset=%d.\n", m_context.nextPreset); status = Reverb_init(&m_context); if (status != 0) { Game->LOG(0, "Reverb init error=%d", status); return S_FALSE; } m_context.config.outputCfg.accessMode = EFFECT_BUFFER_ACCESS_WRITE; m_context.InFrames32 = (LVM_INT32 *)malloc(LVREV_MAX_FRAME_SIZE * sizeof(LVM_INT32) * 2); if (m_context.InFrames32 == NULL) { Game->LOG(0, "Reverb malloc failed (1)!"); Reverb_free(&m_context); m_context.hInstance = NULL; return S_FALSE; } else { // Game->LOG(0, "Malloc inframes addr 0x%08X!", (uint32_t*) m_context.InFrames32); } m_context.OutFrames32 = (LVM_INT32 *)malloc(LVREV_MAX_FRAME_SIZE * sizeof(LVM_INT32) * 2); if (m_context.OutFrames32 == NULL) { Game->LOG(0, "Reverb malloc failed (2)!"); free(m_context.InFrames32); Reverb_free(&m_context); m_context.hInstance = NULL; return S_FALSE; } else { // Game->LOG(0, "Malloc outframes addr 0x%08X!", (uint32_t*) m_context.OutFrames32); } replyCount = sizeof(int); status = Reverb_command(&m_context, EFFECT_CMD_ENABLE, 0, NULL, &replyCount, replydata); if (status != 0) { Game->LOG(0, "Reverb command error=%d", status); free(m_context.OutFrames32); free(m_context.InFrames32); Reverb_free(&m_context); m_context.hInstance = NULL; return S_FALSE; } m_BASS_DSP_handle = BASS_ChannelSetDSP(m_Stream, DSPProc, (void *) this, 0); if (m_BASS_DSP_handle == 0) { Game->LOG(0, "BASS error: %d while adding DSP effect", BASS_ErrorGetCode()); free(m_context.OutFrames32); free(m_context.InFrames32); Reverb_free(&m_context); m_context.hInstance = NULL; return S_FALSE; } // Game->LOG(0, "Preset reverb active, ptr=0x%08X.", (uint32_t) m_pContext); Game->LOG(0, "Preset reverb active."); #endif break; default: #ifdef USE_BASS_FX if (m_EffectHandle != 0) { BASS_ChannelRemoveFX(m_Stream, m_EffectHandle); m_EffectHandle = 0; } #endif #ifdef USE_LIBEFFECTS_REVERB if (m_BASS_DSP_handle != 0) { if (BASS_ChannelRemoveDSP(m_Stream, m_BASS_DSP_handle) == FALSE) { Game->LOG(0, "BASS error: %d while removing old DSP effect", BASS_ErrorGetCode()); } m_BASS_DSP_handle = 0; } if (m_context.hInstance != NULL) { free(m_context.InFrames32); free(m_context.OutFrames32); Reverb_free(&m_context); m_context.hInstance = NULL; } #endif break; } return S_OK; }
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, 0, &fileProc, (void*)m_File); if (!m_Stream) { Game->LOG(0, "BASS error: %d while loading '%s'", BASS_ErrorGetCode(), Filename); return E_FAIL; } CBUtils::SetString(&m_Filename, Filename); #ifdef USE_BASS_FX if (m_EffectHandle != 0) { BASS_ChannelRemoveFX(m_Stream, m_EffectHandle); m_EffectHandle = 0; } #endif #ifdef USE_LIBEFFECTS_REVERB if (m_BASS_DSP_handle != 0) { if (BASS_ChannelRemoveDSP(m_Stream, m_BASS_DSP_handle) == FALSE) { Game->LOG(0, "BASS error: %d while removing ond DSP effect from '%s'", BASS_ErrorGetCode(), Filename); } m_BASS_DSP_handle = 0; } if (m_context.hInstance != NULL) { free(m_context.InFrames32); free(m_context.OutFrames32); Reverb_free(&m_context); m_context.hInstance = NULL; } #endif /* 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; }
BOOL CALLBACK dialogproc(HWND h,UINT m,WPARAM w,LPARAM l) { switch (m) { case WM_COMMAND: switch (LOWORD(w)) { case IDCANCEL: DestroyWindow(h); return 1; case 10: { char file[MAX_PATH]=""; ofn.lpstrFilter="playable files\0*.mo3;*.xm;*.mod;*.s3m;*.it;*.mtm;*.mp3;*.mp2;*.mp1;*.ogg;*.wav\0All files\0*.*\0\0"; ofn.lpstrFile=file; if (GetOpenFileName(&ofn)) { memcpy(path,file,ofn.nFileOffset); path[ofn.nFileOffset-1]=0; // free both MOD and stream, it must be one of them! :) BASS_MusicFree(chan); BASS_StreamFree(chan); if (!(chan=BASS_StreamCreateFile(FALSE,file,0,0,floatable?BASS_SAMPLE_FLOAT:0)) && !(chan=BASS_MusicLoad(FALSE,file,0,0,BASS_MUSIC_LOOP|BASS_MUSIC_RAMP|(floatable?BASS_MUSIC_FLOAT:0)))) { // whatever it is, it ain't playable MESS(10,WM_SETTEXT,0,"click here to open a file..."); Error("Can't play the file"); break; } if (BASS_ChannelGetFlags(chan)&BASS_SAMPLE_MONO) { // mono = not allowed MESS(10,WM_SETTEXT,0,"click here to open a file..."); BASS_MusicFree(chan); BASS_StreamFree(chan); Error("mono sources are not supported"); break; } MESS(10,WM_SETTEXT,0,file); // setup DSPs on new channel SendMessage(win,WM_COMMAND,11,0); SendMessage(win,WM_COMMAND,12,0); SendMessage(win,WM_COMMAND,13,0); // play both MOD and stream, it must be one of them! BASS_MusicPlay(chan); BASS_StreamPlay(chan,0,BASS_SAMPLE_LOOP); } } return 1; case 11: // toggle "rotate" if (MESS(11,BM_GETCHECK,0,0)) { rotpos=0.7853981f; rotdsp=BASS_ChannelSetDSP(chan,&Rotate,0); } else BASS_ChannelRemoveDSP(chan,rotdsp); break; case 12: // toggle "echo" if (MESS(12,BM_GETCHECK,0,0)) { memset(echbuf,0,sizeof(echbuf)); echpos=0; echdsp=BASS_ChannelSetDSP(chan,&Echo,0); } else BASS_ChannelRemoveDSP(chan,echdsp); break; case 13: // toggle "flanger" if (MESS(13,BM_GETCHECK,0,0)) { memset(flabuf,0,sizeof(flabuf)); flapos=0; flas=FLABUFLEN/2; flasinc=0.002f; fladsp=BASS_ChannelSetDSP(chan,&Flange,0); } else BASS_ChannelRemoveDSP(chan,fladsp); break; } 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.lpstrInitialDir=path; ofn.Flags=OFN_HIDEREADONLY|OFN_EXPLORER; // initialize - default device, 44100hz, stereo, 16 bits, floating-point DSP if (!BASS_Init(-1,44100,BASS_DEVICE_FLOATDSP,win)) { Error("Can't initialize device"); DestroyWindow(win); return 1; } BASS_Start(); // check for floating-point capability floatable=BASS_StreamCreate(44100,BASS_SAMPLE_FLOAT,NULL,0); if (floatable) BASS_StreamFree(floatable); // woohoo! return 1; } return 0; }