annotate 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
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
1
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
1 #include "stdafx.h"
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
2 #include "dsp_sample.h"
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
3
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
4 #ifdef _WIN32
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
5 #include <helpers/DarkMode.h>
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
6 #include "resource.h"
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
7
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
8 static void RunDSPConfigPopup(const dsp_preset & p_data,HWND p_parent,dsp_preset_edit_callback & p_callback);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
9 #endif
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
10
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
11 #ifdef __APPLE__
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
12 // fooSampleDSPView.mm
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
13 service_ptr ConfigureSampleDSP( fb2k::hwnd_t parent, dsp_preset_edit_callback_v2::ptr callback );
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
14 #endif
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
15
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
16 class dsp_sample : public dsp_impl_base
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
17 {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
18 public:
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
19 dsp_sample(dsp_preset const & in) : m_gain(parse_preset(in)) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
20 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
21
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
22 static GUID g_get_guid() {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
23 return dsp_sample_common::guid;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
24 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
25
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
26 static void g_get_name(pfc::string_base & p_out) { p_out = "Sample DSP";}
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
27
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
28 bool on_chunk(audio_chunk * chunk,abort_callback &) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
29 // Perform any operations on the chunk here.
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
30 // The most simple DSPs can just alter the chunk in-place here and skip the following functions.
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
31
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
32
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
33 // trivial DSP code: apply our gain to the audio data.
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
34 chunk->scale( (audio_sample)audio_math::gain_to_scale( m_gain ) );
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
35
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
36 // To retrieve the currently processed track, use get_cur_file().
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
37 // 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.
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
38 // 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.
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
39
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
40 return true; //Return true to keep the chunk or false to drop it from the chain.
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
41 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
42
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
43 void on_endofplayback(abort_callback &) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
44 // The end of playlist has been reached, we've already received the last decoded audio chunk.
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
45 // We need to finish any pending processing and output any buffered data through insert_chunk().
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
46 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
47 void on_endoftrack(abort_callback &) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
48 // Should do nothing except for special cases where your DSP performs special operations when changing tracks.
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
49 // If this function does anything, you must change need_track_change_mark() to return true.
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
50 // If you have pending audio data that you wish to output, you can use insert_chunk() to do so.
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
51 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
52
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
53 void flush() {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
54 // If you have any audio data buffered, you should drop it immediately and reset the DSP to a freshly initialized state.
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
55 // Called after a seek etc.
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
56 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
57
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
58 double get_latency() {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
59 // If the DSP buffers some amount of audio data, it should return the duration of buffered data (in seconds) here.
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
60 return 0;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
61 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
62
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
63 bool need_track_change_mark() {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
64 // Return true if you need on_endoftrack() or need to accurately know which track we're currently processing
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
65 // 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.
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
66 return false;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
67 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
68 static bool g_get_default_preset(dsp_preset & p_out) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
69 make_preset(0, p_out);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
70 return true;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
71 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
72 #ifdef _WIN32
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
73 static void g_show_config_popup(const dsp_preset & p_data,HWND p_parent,dsp_preset_edit_callback & p_callback) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
74 ::RunDSPConfigPopup(p_data, p_parent, p_callback);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
75 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
76 #endif // _WIN32
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
77 #ifdef __APPLE__
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
78 static service_ptr g_show_config_popup( fb2k::hwnd_t parent, dsp_preset_edit_callback_v2::ptr callback ) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
79 return ConfigureSampleDSP( parent, callback );
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
80 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
81 #endif // __APPLE__
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
82 static bool g_have_config_popup() {return true;}
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
83 private:
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
84 float m_gain;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
85 };
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
86
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
87 // Use dsp_factory_nopreset_t<> instead of dsp_factory_t<> if your DSP does not provide preset/configuration functionality.
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
88 static dsp_factory_t<dsp_sample> g_dsp_sample_factory;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
89
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
90 #ifdef _WIN32
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
91
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
92 class CMyDSPPopup : public CDialogImpl<CMyDSPPopup> {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
93 public:
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
94 CMyDSPPopup(const dsp_preset & initData, dsp_preset_edit_callback & callback) : m_initData(initData), m_callback(callback) {}
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
95
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
96 enum { IDD = IDD_DSP };
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
97
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
98 enum {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
99 RangeMin = -20,
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
100 RangeMax = 20,
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
101
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
102 RangeTotal = RangeMax - RangeMin
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
103 };
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
104
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
105 BEGIN_MSG_MAP_EX(CMyDSPPopup)
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
106 MSG_WM_INITDIALOG(OnInitDialog)
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
107 COMMAND_HANDLER_EX(IDOK, BN_CLICKED, OnButton)
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
108 COMMAND_HANDLER_EX(IDCANCEL, BN_CLICKED, OnButton)
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
109 MSG_WM_HSCROLL(OnHScroll)
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
110 END_MSG_MAP()
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
111
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
112 private:
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
113
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
114 BOOL OnInitDialog(CWindow, LPARAM) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
115 m_dark.AddDialogWithControls(m_hWnd);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
116 m_slider = GetDlgItem(IDC_SLIDER);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
117 m_slider.SetRange(0, RangeTotal);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
118
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
119 {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
120 float val = parse_preset(m_initData);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
121 m_slider.SetPos( pfc::clip_t<t_int32>( pfc::rint32(val), RangeMin, RangeMax ) - RangeMin );
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
122 RefreshLabel(val);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
123 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
124 return TRUE;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
125 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
126
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
127 void OnButton(UINT, int id, CWindow) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
128 EndDialog(id);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
129 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
130
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
131 void OnHScroll(UINT nSBCode, UINT nPos, CScrollBar pScrollBar) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
132 float val;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
133 val = (float) ( m_slider.GetPos() + RangeMin );
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
134
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
135 {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
136 dsp_preset_impl preset;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
137 make_preset(val, preset);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
138 m_callback.on_preset_changed(preset);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
139 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
140 RefreshLabel(val);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
141 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
142
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
143 void RefreshLabel(float val) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
144 pfc::string_formatter msg; msg << pfc::format_float(val) << " dB";
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
145 ::uSetDlgItemText(*this, IDC_SLIDER_LABEL, msg);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
146 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
147
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
148 const dsp_preset & m_initData; // modal dialog so we can reference this caller-owned object.
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
149 dsp_preset_edit_callback & m_callback;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
150
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
151 CTrackBarCtrl m_slider;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
152 fb2k::CDarkModeHooks m_dark;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
153 };
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
154
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
155 static void RunDSPConfigPopup(const dsp_preset & p_data,HWND p_parent,dsp_preset_edit_callback & p_callback) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
156 CMyDSPPopup popup(p_data, p_callback);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
157 if (popup.DoModal(p_parent) != IDOK) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
158 // If the dialog exited with something else than IDOK,k
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
159 // tell host that the editing has been cancelled by sending it old preset data that we got initialized with
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
160 p_callback.on_preset_changed(p_data);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
161 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
162 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
163 #endif