Mercurial > foo_out_sdl
diff foosdk/sdk/foobar2000/foo_sample/dsp_sample.cpp @ 1:20d02a178406 default tip
*: check in everything else
yay
| author | Paper <paper@tflc.us> |
|---|---|
| date | Mon, 05 Jan 2026 02:15:46 -0500 |
| parents | |
| children |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/foosdk/sdk/foobar2000/foo_sample/dsp_sample.cpp Mon Jan 05 02:15:46 2026 -0500 @@ -0,0 +1,163 @@ +#include "stdafx.h" +#include "dsp_sample.h" + +#ifdef _WIN32 +#include <helpers/DarkMode.h> +#include "resource.h" + +static void RunDSPConfigPopup(const dsp_preset & p_data,HWND p_parent,dsp_preset_edit_callback & p_callback); +#endif + +#ifdef __APPLE__ +// fooSampleDSPView.mm +service_ptr ConfigureSampleDSP( fb2k::hwnd_t parent, dsp_preset_edit_callback_v2::ptr callback ); +#endif + +class dsp_sample : public dsp_impl_base +{ +public: + dsp_sample(dsp_preset const & in) : m_gain(parse_preset(in)) { + } + + static GUID g_get_guid() { + return dsp_sample_common::guid; + } + + static void g_get_name(pfc::string_base & p_out) { p_out = "Sample DSP";} + + bool on_chunk(audio_chunk * chunk,abort_callback &) { + // Perform any operations on the chunk here. + // The most simple DSPs can just alter the chunk in-place here and skip the following functions. + + + // trivial DSP code: apply our gain to the audio data. + chunk->scale( (audio_sample)audio_math::gain_to_scale( m_gain ) ); + + // To retrieve the currently processed track, use get_cur_file(). + // Warning: the track is not always known - it's up to the calling component to provide this data and in some situations we'll be working with data that doesn't originate from an audio file. + // If you rely on get_cur_file(), you should change need_track_change_mark() to return true to get accurate information when advancing between tracks. + + return true; //Return true to keep the chunk or false to drop it from the chain. + } + + void on_endofplayback(abort_callback &) { + // The end of playlist has been reached, we've already received the last decoded audio chunk. + // We need to finish any pending processing and output any buffered data through insert_chunk(). + } + void on_endoftrack(abort_callback &) { + // Should do nothing except for special cases where your DSP performs special operations when changing tracks. + // If this function does anything, you must change need_track_change_mark() to return true. + // If you have pending audio data that you wish to output, you can use insert_chunk() to do so. + } + + void flush() { + // If you have any audio data buffered, you should drop it immediately and reset the DSP to a freshly initialized state. + // Called after a seek etc. + } + + double get_latency() { + // If the DSP buffers some amount of audio data, it should return the duration of buffered data (in seconds) here. + return 0; + } + + bool need_track_change_mark() { + // Return true if you need on_endoftrack() or need to accurately know which track we're currently processing + // WARNING: If you return true, the DSP manager will fire on_endofplayback() at DSPs that are before us in the chain on track change to ensure that we get an accurate mark, so use it only when needed. + return false; + } + static bool g_get_default_preset(dsp_preset & p_out) { + make_preset(0, p_out); + return true; + } +#ifdef _WIN32 + static void g_show_config_popup(const dsp_preset & p_data,HWND p_parent,dsp_preset_edit_callback & p_callback) { + ::RunDSPConfigPopup(p_data, p_parent, p_callback); + } +#endif // _WIN32 +#ifdef __APPLE__ + static service_ptr g_show_config_popup( fb2k::hwnd_t parent, dsp_preset_edit_callback_v2::ptr callback ) { + return ConfigureSampleDSP( parent, callback ); + } +#endif // __APPLE__ + static bool g_have_config_popup() {return true;} +private: + float m_gain; +}; + +// Use dsp_factory_nopreset_t<> instead of dsp_factory_t<> if your DSP does not provide preset/configuration functionality. +static dsp_factory_t<dsp_sample> g_dsp_sample_factory; + +#ifdef _WIN32 + +class CMyDSPPopup : public CDialogImpl<CMyDSPPopup> { +public: + CMyDSPPopup(const dsp_preset & initData, dsp_preset_edit_callback & callback) : m_initData(initData), m_callback(callback) {} + + enum { IDD = IDD_DSP }; + + enum { + RangeMin = -20, + RangeMax = 20, + + RangeTotal = RangeMax - RangeMin + }; + + BEGIN_MSG_MAP_EX(CMyDSPPopup) + MSG_WM_INITDIALOG(OnInitDialog) + COMMAND_HANDLER_EX(IDOK, BN_CLICKED, OnButton) + COMMAND_HANDLER_EX(IDCANCEL, BN_CLICKED, OnButton) + MSG_WM_HSCROLL(OnHScroll) + END_MSG_MAP() + +private: + + BOOL OnInitDialog(CWindow, LPARAM) { + m_dark.AddDialogWithControls(m_hWnd); + m_slider = GetDlgItem(IDC_SLIDER); + m_slider.SetRange(0, RangeTotal); + + { + float val = parse_preset(m_initData); + m_slider.SetPos( pfc::clip_t<t_int32>( pfc::rint32(val), RangeMin, RangeMax ) - RangeMin ); + RefreshLabel(val); + } + return TRUE; + } + + void OnButton(UINT, int id, CWindow) { + EndDialog(id); + } + + void OnHScroll(UINT nSBCode, UINT nPos, CScrollBar pScrollBar) { + float val; + val = (float) ( m_slider.GetPos() + RangeMin ); + + { + dsp_preset_impl preset; + make_preset(val, preset); + m_callback.on_preset_changed(preset); + } + RefreshLabel(val); + } + + void RefreshLabel(float val) { + pfc::string_formatter msg; msg << pfc::format_float(val) << " dB"; + ::uSetDlgItemText(*this, IDC_SLIDER_LABEL, msg); + } + + const dsp_preset & m_initData; // modal dialog so we can reference this caller-owned object. + dsp_preset_edit_callback & m_callback; + + CTrackBarCtrl m_slider; + fb2k::CDarkModeHooks m_dark; +}; + +static void RunDSPConfigPopup(const dsp_preset & p_data,HWND p_parent,dsp_preset_edit_callback & p_callback) { + CMyDSPPopup popup(p_data, p_callback); + if (popup.DoModal(p_parent) != IDOK) { + // If the dialog exited with something else than IDOK,k + // tell host that the editing has been cancelled by sending it old preset data that we got initialized with + p_callback.on_preset_changed(p_data); + } +} +#endif
