2222namespace juce
2323{
2424
25+ namespace
26+ {
27+
28+ template <class T >
29+ using hasAudioSampleFrameSamplesPerChannel = decltype (T::samplesPerChannel);
30+
31+ template <class T >
32+ int getNumSamplesPerChannel (const T& frame)
33+ {
34+ if constexpr (isDetected<hasAudioSampleFrameSamplesPerChannel, T>)
35+ return frame.samplesPerChannel ;
36+ else
37+ return 128 ;
38+ }
39+
40+ } // namespace
41+
2542// ==============================================================================
2643class AudioWorkletAudioIODevice final : public AudioIODevice
2744{
@@ -94,11 +111,9 @@ class AudioWorkletAudioIODevice final : public AudioIODevice
94111 double sampleRate,
95112 int bufferSizeSamples) override
96113 {
97- yup::Logger::outputDebugString (" open" );
98-
99- if (sampleRate != getDefaultSampleRate ())
114+ if (sampleRate != getDefaultSampleRate () || bufferSizeSamples != getDefaultBufferSize ())
100115 {
101- lastError = " Browser audio outputs only support 44.1 kHz sample rate" ;
116+ lastError = " Browser audio outputs only support 44.1 kHz sample rate and 128 samples buffer size. " ;
102117 return lastError;
103118 }
104119
@@ -125,8 +140,6 @@ class AudioWorkletAudioIODevice final : public AudioIODevice
125140
126141 void close () override
127142 {
128- yup::Logger::outputDebugString (" close" );
129-
130143 stop ();
131144
132145 if (isDeviceOpen)
@@ -155,17 +168,11 @@ class AudioWorkletAudioIODevice final : public AudioIODevice
155168
156169 void start (AudioIODeviceCallback* newCallback) override
157170 {
158- yup::Logger::outputDebugString (" start 1" );
159-
160171 if (! isDeviceOpen)
161172 return ;
162173
163- yup::Logger::outputDebugString (" start 2" );
164-
165174 if (isRunning)
166175 {
167- yup::Logger::outputDebugString (" start 3" );
168-
169176 if (newCallback != callback)
170177 {
171178 if (newCallback != nullptr )
@@ -182,40 +189,27 @@ class AudioWorkletAudioIODevice final : public AudioIODevice
182189 }
183190 else
184191 {
185- yup::Logger::outputDebugString (" start 4" );
186-
187192 callback = newCallback;
188193 isRunning = emscripten_audio_context_state (context) == AUDIO_CONTEXT_STATE_RUNNING;
189194
190195 if (! isRunning && hasBeenActivatedAlreadyByUser)
191196 {
192- yup::Logger::outputDebugString (" start 5" );
193-
194197 emscripten_resume_audio_context_sync (context);
195198 isRunning = emscripten_audio_context_state (context) == AUDIO_CONTEXT_STATE_RUNNING;
196199 }
197200
198201 firstCallback = true ;
199202
200- yup::Logger::outputDebugString (" start 6" );
201-
202203 if (callback != nullptr )
203204 {
204205 if (isRunning)
205- {
206- yup::Logger::outputDebugString (" start 7" );
207206 callback->audioDeviceAboutToStart (this );
208- }
209207 }
210-
211- yup::Logger::outputDebugString (" start 8" );
212208 }
213209 }
214210
215211 void stop () override
216212 {
217- yup::Logger::outputDebugString (" stop" );
218-
219213 AudioIODeviceCallback* oldCallback = nullptr ;
220214
221215 if (callback != nullptr )
@@ -260,12 +254,12 @@ class AudioWorkletAudioIODevice final : public AudioIODevice
260254 }
261255
262256 int getOutputLatencyInSamples () override
263- { /* TODO */
257+ {
264258 return 0 ;
265259 }
266260
267261 int getInputLatencyInSamples () override
268- { /* TODO */
262+ {
269263 return 0 ;
270264 }
271265
@@ -279,8 +273,6 @@ class AudioWorkletAudioIODevice final : public AudioIODevice
279273
280274 void audioThreadInitialized ()
281275 {
282- yup::Logger::outputDebugString (" audioThreadInitialized" );
283-
284276 WebAudioWorkletProcessorCreateOptions opts =
285277 {
286278 .name = audioWorkletTypeName
@@ -292,8 +284,6 @@ class AudioWorkletAudioIODevice final : public AudioIODevice
292284
293285 void audioWorkletProcessorCreated ()
294286 {
295- yup::Logger::outputDebugString (" audioWorkletProcessorCreated" );
296-
297287 int outputChannelCounts[1 ] = { actualNumberOfOutputs };
298288 EmscriptenAudioWorkletNodeCreateOptions options =
299289 {
@@ -307,7 +297,7 @@ class AudioWorkletAudioIODevice final : public AudioIODevice
307297 context, audioWorkletTypeName, &options, renderAudioCallback, this );
308298
309299 // Connect it to audio context destination
310- // emscripten_audio_node_connect (audioWorkletNode, context, 0, 0);
300+ // emscripten_audio_node_connect (audioWorkletNode, context, 0, 0);
311301 EM_ASM ({
312302 emscriptenGetAudioObject ($0 ).connect (emscriptenGetAudioObject ($1 ).destination );
313303 }, audioWorkletNode, context);
@@ -319,10 +309,19 @@ class AudioWorkletAudioIODevice final : public AudioIODevice
319309 int numOutputs, AudioSampleFrame* outputs,
320310 int numParams, const AudioParamFrame* params)
321311 {
322- const int audioFrames = 128 ;
312+ const int samplesPerChannel = [&]
313+ {
314+ if (numOutputs > 0 )
315+ return getNumSamplesPerChannel (outputs[0 ]);
316+
317+ else if (numInputs > 0 )
318+ return getNumSamplesPerChannel (inputs[0 ]);
319+
320+ return 128 ;
321+ }();
323322
324323 // check for xruns
325- calculateXruns (audioFrames );
324+ calculateXruns (samplesPerChannel );
326325
327326 ScopedLock lock (callbackLock);
328327
@@ -334,17 +333,17 @@ class AudioWorkletAudioIODevice final : public AudioIODevice
334333
335334 // Setup channelOutBuffers (assume a single worklet output)
336335 for (int ch = 0 ; ch < actualNumberOfOutputs; ++ch)
337- channelOutBuffer[ch] = &(outputs[0 ].data [ch * 128 ]); // outputs[0].samplesPerChannel / outputs[0].quantumSize
336+ channelOutBuffer[ch] = &(outputs[0 ].data [ch * samplesPerChannel ]);
338337
339338 callback->audioDeviceIOCallbackWithContext (channelInBuffer.getData (),
340339 actualNumberOfInputs,
341340 channelOutBuffer.getData (),
342341 actualNumberOfOutputs,
343- audioFrames ,
342+ samplesPerChannel ,
344343 {});
345- }
346344
347- audioFramesElapsed += audioFrames;
345+ audioFramesElapsed += samplesPerChannel;
346+ }
348347
349348 return EM_TRUE; // keep going !
350349 }
@@ -353,8 +352,6 @@ class AudioWorkletAudioIODevice final : public AudioIODevice
353352 {
354353 if (emscripten_audio_context_state (context) != AUDIO_CONTEXT_STATE_RUNNING)
355354 {
356- yup::Logger::outputDebugString (" canvasClick" );
357-
358355 emscripten_resume_audio_context_sync (context);
359356
360357 isRunning = true ;
0 commit comments