From 1edae0f56a231f05587a646cf5cee7e078d47531 Mon Sep 17 00:00:00 2001 From: Jorj Bauer Date: Sun, 2 Aug 2020 10:02:35 -0400 Subject: [PATCH] audio fixes and normalization between hardware types --- sdl/sdl-speaker.cpp | 16 +++++++++------- teensy/teensy-speaker.cpp | 24 +++++++++--------------- teensy/teensy-speaker.h | 4 ++-- 3 files changed, 20 insertions(+), 24 deletions(-) diff --git a/sdl/sdl-speaker.cpp b/sdl/sdl-speaker.cpp index 2d4f118..9e4ae05 100644 --- a/sdl/sdl-speaker.cpp +++ b/sdl/sdl-speaker.cpp @@ -10,8 +10,8 @@ extern "C" }; // What values do we use for logical speaker-high and speaker-low? -#define HIGHVAL (0x1FFF) -#define LOWVAL (-(0x1FFF)) +#define HIGHVAL (0x4FFF) +#define LOWVAL (-(0x4FFF)) #include "globals.h" @@ -21,11 +21,13 @@ extern "C" #define WATERLEVEL SDLSIZE +#define AUDIO_SAMPLE_RATE_EXACT 44100 + // FIXME: Globals; ick. static volatile uint32_t bufIdx = 0; static volatile short soundBuf[CACHEMULTIPLIER*SDLSIZE]; static pthread_mutex_t togmutex = PTHREAD_MUTEX_INITIALIZER; -static volatile uint32_t skippedSamples = 0; +static volatile uint64_t skippedSamples = 0; #define SAMPLEBYTES sizeof(short) volatile uint8_t audioRunning = 0; @@ -63,7 +65,7 @@ static void audioCallback(void *unused, Uint8 *stream, int len) static short lastKnownSample = 0; // saved for when the apple is quiescent - if (bufIdx >= SDLSIZE) { + if (bufIdx >= SDLSIZE) { // technically 'len/SAMPLEBYTES' but it should always be constant I think? memcpy(stream, (void *)soundBuf, SDLSIZE*SAMPLEBYTES); lastKnownSample = stream[SDLSIZE-1]; @@ -138,7 +140,7 @@ void SDLSpeaker::begin() SDL_AudioSpec audioDevice; SDL_AudioSpec audioActual; SDL_memset(&audioDevice, 0, sizeof(audioDevice)); - audioDevice.freq = 44100; // count of 16-bit samples + audioDevice.freq = AUDIO_SAMPLE_RATE_EXACT; // count of 16-bit samples audioDevice.format = AUDIO_S16; audioDevice.channels = 1; audioDevice.samples = SDLSIZE; // SDLSIZE 16-bit samples @ 44100Hz: 4096 is about 1/10th second out of sync @@ -161,13 +163,13 @@ void SDLSpeaker::toggle(int64_t c) { pthread_mutex_lock(&togmutex); - int64_t expectedCycleNumber = (float)c * (float)44100 / (float)g_speed; + int64_t expectedCycleNumber = (float)c * (float)AUDIO_SAMPLE_RATE_EXACT / (float)g_speed; if (lastFilledTime == 0) { lastFilledTime = expectedCycleNumber; } // This subtracts skippedSamples because those were filled automatically // by the audioCallback when we had no data. - int32_t audioBufferSamples = expectedCycleNumber - lastFilledTime - skippedSamples; + int64_t audioBufferSamples = expectedCycleNumber - lastFilledTime - skippedSamples; // If audioBufferSamples < 0, then we need to keep some // skippedSamples for later; otherwise we can keep moving forward. if (audioBufferSamples < 0) { diff --git a/teensy/teensy-speaker.cpp b/teensy/teensy-speaker.cpp index 822fe3b..d00e595 100644 --- a/teensy/teensy-speaker.cpp +++ b/teensy/teensy-speaker.cpp @@ -24,13 +24,8 @@ AudioConnection patchCord4(mixer1, 0, i2s, 0); #define BUFSIZE (4096) #define CACHEMULTIPLIER 2 static volatile uint32_t bufIdx; // 0 .. BUFSIZE-1 -static volatile uint32_t skippedSamples; // Who knows where this will - // wind up (FIXME: eventual - // rollover means we need a - // way to purge the queue - // when it's quiescent for - // too long & restart all the - // constants) +static volatile uint64_t skippedSamples; // Who knows where this will + // wind up static volatile uint8_t audioRunning = 0; // FIXME: needs constants abstracted static volatile int64_t lastFilledTime = 0; @@ -45,7 +40,8 @@ static bool toggleState = false; TeensySpeaker::TeensySpeaker(uint8_t sda, uint8_t scl) : PhysicalSpeaker() { toggleState = false; - mixerValue = numMixed = 0; + mixerValue = 0x80; + AudioMemory(8); } @@ -55,8 +51,8 @@ TeensySpeaker::~TeensySpeaker() void TeensySpeaker::begin() { - mixer1.gain(0, 0.1f); // left channel - mixer1.gain(1, 0.1f); // right channel + mixer1.gain(0, 0.1f); // left channel (off for now) + mixer1.gain(1, 0.1f); // right channel (full volume for now) memset(soundBuf, 0, sizeof(soundBuf)); @@ -83,7 +79,7 @@ void TeensySpeaker::toggle(int64_t c) // and we have filled to cycle number lastFilledTime. So how many do // we need? This subtracts skippedSamples because those were filled // automatically by the audioCallback when we had no data. - int32_t audioBufferSamples = expectedCycleNumber - lastFilledTime - skippedSamples; + int64_t audioBufferSamples = expectedCycleNumber - lastFilledTime - skippedSamples; // If audioBufferSamples < 0, then we need to keep some // skippedSamples for later; otherwise we can keep moving forward. if (audioBufferSamples < 0) { @@ -184,10 +180,7 @@ void TeensyAudio::update(void) goto done; } - // FROM THE SOUND OF IT, something below this line isn't filling buffers - // completely; or something isn't filling soundBuf completely in toggle(). - - static short lastKnownSample = 0; + static short lastKnownSample = 0; // saved for when the apple is quiescent if (bufIdx >= AUDIO_BLOCK_SAMPLES) { memcpy(stream, (void *)soundBuf, AUDIO_BLOCK_SAMPLES * SAMPLEBYTES); @@ -208,6 +201,7 @@ void TeensyAudio::update(void) for (int32_t i=0; i