2020
2121#include "xsmc.h"
2222#include "mc.xs.h" // for xsID_ values
23+ #include "mc.defines.h"
2324
2425#ifndef MODDEF_AUDIOOUT_STREAMS
2526 #define MODDEF_AUDIOOUT_STREAMS (4)
6162#endif
6263
6364#if MODDEF_AUDIOOUT_BITSPERSAMPLE == 8
64- #define OUTPUTSAMPLETYPE uint8_t
65+ #define OUTPUTSAMPLETYPE int8_t
6566#elif MODDEF_AUDIOOUT_BITSPERSAMPLE == 16
6667 #define OUTPUTSAMPLETYPE int16_t
6768#endif
@@ -130,7 +131,7 @@ typedef struct {
130131 uint32_t buffer [128 ];
131132#elif defined(__ets__ )
132133 uint8_t i2sActive ;
133- int16_t buffer [64 ]; // size assumes DMA Buffer size of I2S
134+ OUTPUTSAMPLETYPE buffer [64 ]; // size assumes DMA Buffer size of I2S
134135#endif
135136
136137#if MODDEF_AUDIOOUT_I2S_PDM
@@ -201,36 +202,53 @@ void xs_audioout(xsMachine *the)
201202{
202203 int i ;
203204 modAudioOut out ;
204- uint16_t sampleRate ;
205- uint8_t numChannels ;
206- uint8_t bitsPerSample ;
207- int streamCount ;
205+ uint16_t sampleRate = 0 ;
206+ uint8_t numChannels = 0 ;
207+ uint8_t bitsPerSample = 0 ;
208+ int streamCount = 0 ;
208209
209210 xsmcVars (1 );
210211
211- xsmcGet (xsVar (0 ), xsArg (0 ), xsID_sampleRate );
212- sampleRate = xsmcToInteger (xsVar (0 ));
212+ if (xsmcHas (xsArg (0 ), xsID_sampleRate )) {
213+ xsmcGet (xsVar (0 ), xsArg (0 ), xsID_sampleRate );
214+ sampleRate = xsmcToInteger (xsVar (0 ));
215+ }
216+ #ifdef MODDEF_AUDIOOUT_SAMPLERATE
217+ else
218+ sampleRate = MODDEF_AUDIOOUT_SAMPLERATE ;
219+ #endif
213220 if ((sampleRate < 8000 ) || (sampleRate > 48000 ))
214221 xsRangeError ("invalid sample rate" );
215222
216- xsmcGet (xsVar (0 ), xsArg (0 ), xsID_numChannels );
217- numChannels = xsmcToInteger (xsVar (0 ));
223+ if (xsmcHas (xsArg (0 ), xsID_numChannels )) {
224+ xsmcGet (xsVar (0 ), xsArg (0 ), xsID_numChannels );
225+ numChannels = xsmcToInteger (xsVar (0 ));
226+ }
227+ #ifdef MODDEF_AUDIOOUT_NUMCHANNELS
228+ else
229+ numChannels = MODDEF_AUDIOOUT_NUMCHANNELS ;
230+ #endif
218231 if ((1 != numChannels ) && (2 != numChannels ))
219232 xsRangeError ("bad numChannels" );
220233
221- xsmcGet (xsVar (0 ), xsArg (0 ), xsID_bitsPerSample );
222- bitsPerSample = xsmcToInteger (xsVar (0 ));
223- if (MODDEF_AUDIOOUT_BITSPERSAMPLE != bitsPerSample )
234+ if (xsmcHas (xsArg (0 ), xsID_bitsPerSample )) {
235+ xsmcGet (xsVar (0 ), xsArg (0 ), xsID_bitsPerSample );
236+ bitsPerSample = xsmcToInteger (xsVar (0 ));
237+ }
238+ #ifdef MODDEF_AUDIOOUT_BITSPERSAMPLE
239+ else
240+ bitsPerSample = MODDEF_AUDIOOUT_BITSPERSAMPLE ;
241+ #endif
242+ if ((8 != bitsPerSample ) && (16 != bitsPerSample ))
224243 xsRangeError ("bad bitsPerSample" );
225244
226- if (!xsmcHas (xsArg (0 ), xsID_streams ))
227- streamCount = 1 ;
228- else {
245+ streamCount = MODDEF_AUDIOOUT_STREAMS ;
246+ if (xsmcHas (xsArg (0 ), xsID_streams )) {
229247 xsmcGet (xsVar (0 ), xsArg (0 ), xsID_streams );
230248 streamCount = xsmcToInteger (xsVar (0 ));
231- if ((streamCount < 1 ) || (streamCount > MODDEF_AUDIOOUT_STREAMS ))
232- xsRangeError ("bad streamCount" );
233249 }
250+ if ((streamCount < 1 ) || (streamCount > MODDEF_AUDIOOUT_STREAMS ))
251+ xsRangeError ("bad streamCount" );
234252
235253 out = (modAudioOut )c_calloc (sizeof (modAudioOutRecord ) + (sizeof (modAudioOutStreamRecord ) * (streamCount - 1 )), 1 );
236254 if (!out )
@@ -628,7 +646,7 @@ void audioOutLoop(void *pvParameter)
628646void doRenderSamples (void * refcon , int16_t * lr , int count )
629647{
630648 modAudioOut out = refcon ;
631- int16_t * s = (int16_t * )out -> buffer ;
649+ OUTPUTSAMPLETYPE * s = (OUTPUTSAMPLETYPE * )out -> buffer ;
632650
633651#if MODDEF_AUDIOOUT_I2S_PDM
634652 count /= (MODDEF_AUDIOOUT_I2S_PDM >> 5 );
@@ -640,6 +658,9 @@ void doRenderSamples(void *refcon, int16_t *lr, int count)
640658 // expand mono to stereo
641659 while (count -- ) {
642660 int16_t sample = * s ++ ;
661+ #if 8 == MODDEF_AUDIOOUT_BITSPERSAMPLE
662+ sample |= sample << 8 ;
663+ #endif
643664 lr [0 ] = sample ;
644665 lr [1 ] = sample ;
645666 lr += 2 ;
@@ -655,8 +676,13 @@ void doRenderSamples(void *refcon, int16_t *lr, int count)
655676
656677 while (count -- ) {
657678 int16_t i , j ;
658- int32_t sample = * s ++ << FRACTIONAL_BITS ; // smear high bits to shifted in low bits?
659- int32_t step = (sample - prevSample ) >> (4 + (MODDEF_AUDIOOUT_I2S_PDM >> 5 ));
679+ int32_t sample = * s ++ , step ;
680+
681+ #if 8 == MODDEF_AUDIOOUT_BITSPERSAMPLE
682+ sample |= sample << 8 ;
683+ #endif
684+ sample <<= FRACTIONAL_BITS ; // smear high bits to shifted in low bits?
685+ step = (sample - prevSample ) >> (4 + (MODDEF_AUDIOOUT_I2S_PDM >> 5 ));
660686 prevSample = sample ;
661687
662688 for (j = MODDEF_AUDIOOUT_I2S_PDM >> 5 ; j ; j -- ) {
0 commit comments