audio fixes and normalization between hardware types

This commit is contained in:
Jorj Bauer 2020-08-02 10:02:35 -04:00
parent 2bef4b7eb0
commit 1edae0f56a
3 changed files with 20 additions and 24 deletions

View File

@ -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) {

View File

@ -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<AUDIO_BLOCK_SAMPLES-bufIdx; i++) {
stream[i+bufIdx] = lastKnownSample;
}
bufIdx = 0;
} else {
// No big deal - buffer underrun might just mean nothing is
// trying to play audio right now.

View File

@ -27,8 +27,8 @@ class TeensySpeaker : public PhysicalSpeaker {
private:
uint32_t mixerValue;
uint8_t numMixed;
uint8_t mixerValue;
bool toggleState;
};
#endif