mirror of https://github.com/JorjBauer/aiie.git
audio fixes and normalization between hardware types
This commit is contained in:
parent
2bef4b7eb0
commit
1edae0f56a
|
@ -10,8 +10,8 @@ extern "C"
|
||||||
};
|
};
|
||||||
|
|
||||||
// What values do we use for logical speaker-high and speaker-low?
|
// What values do we use for logical speaker-high and speaker-low?
|
||||||
#define HIGHVAL (0x1FFF)
|
#define HIGHVAL (0x4FFF)
|
||||||
#define LOWVAL (-(0x1FFF))
|
#define LOWVAL (-(0x4FFF))
|
||||||
|
|
||||||
#include "globals.h"
|
#include "globals.h"
|
||||||
|
|
||||||
|
@ -21,11 +21,13 @@ extern "C"
|
||||||
|
|
||||||
#define WATERLEVEL SDLSIZE
|
#define WATERLEVEL SDLSIZE
|
||||||
|
|
||||||
|
#define AUDIO_SAMPLE_RATE_EXACT 44100
|
||||||
|
|
||||||
// FIXME: Globals; ick.
|
// FIXME: Globals; ick.
|
||||||
static volatile uint32_t bufIdx = 0;
|
static volatile uint32_t bufIdx = 0;
|
||||||
static volatile short soundBuf[CACHEMULTIPLIER*SDLSIZE];
|
static volatile short soundBuf[CACHEMULTIPLIER*SDLSIZE];
|
||||||
static pthread_mutex_t togmutex = PTHREAD_MUTEX_INITIALIZER;
|
static pthread_mutex_t togmutex = PTHREAD_MUTEX_INITIALIZER;
|
||||||
static volatile uint32_t skippedSamples = 0;
|
static volatile uint64_t skippedSamples = 0;
|
||||||
#define SAMPLEBYTES sizeof(short)
|
#define SAMPLEBYTES sizeof(short)
|
||||||
|
|
||||||
volatile uint8_t audioRunning = 0;
|
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
|
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);
|
memcpy(stream, (void *)soundBuf, SDLSIZE*SAMPLEBYTES);
|
||||||
lastKnownSample = stream[SDLSIZE-1];
|
lastKnownSample = stream[SDLSIZE-1];
|
||||||
|
|
||||||
|
@ -138,7 +140,7 @@ void SDLSpeaker::begin()
|
||||||
SDL_AudioSpec audioDevice;
|
SDL_AudioSpec audioDevice;
|
||||||
SDL_AudioSpec audioActual;
|
SDL_AudioSpec audioActual;
|
||||||
SDL_memset(&audioDevice, 0, sizeof(audioDevice));
|
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.format = AUDIO_S16;
|
||||||
audioDevice.channels = 1;
|
audioDevice.channels = 1;
|
||||||
audioDevice.samples = SDLSIZE; // SDLSIZE 16-bit samples @ 44100Hz: 4096 is about 1/10th second out of sync
|
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);
|
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) {
|
if (lastFilledTime == 0) {
|
||||||
lastFilledTime = expectedCycleNumber;
|
lastFilledTime = expectedCycleNumber;
|
||||||
}
|
}
|
||||||
// This subtracts skippedSamples because those were filled automatically
|
// This subtracts skippedSamples because those were filled automatically
|
||||||
// by the audioCallback when we had no data.
|
// 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
|
// If audioBufferSamples < 0, then we need to keep some
|
||||||
// skippedSamples for later; otherwise we can keep moving forward.
|
// skippedSamples for later; otherwise we can keep moving forward.
|
||||||
if (audioBufferSamples < 0) {
|
if (audioBufferSamples < 0) {
|
||||||
|
|
|
@ -24,13 +24,8 @@ AudioConnection patchCord4(mixer1, 0, i2s, 0);
|
||||||
#define BUFSIZE (4096)
|
#define BUFSIZE (4096)
|
||||||
#define CACHEMULTIPLIER 2
|
#define CACHEMULTIPLIER 2
|
||||||
static volatile uint32_t bufIdx; // 0 .. BUFSIZE-1
|
static volatile uint32_t bufIdx; // 0 .. BUFSIZE-1
|
||||||
static volatile uint32_t skippedSamples; // Who knows where this will
|
static volatile uint64_t skippedSamples; // Who knows where this will
|
||||||
// wind up (FIXME: eventual
|
// wind up
|
||||||
// rollover means we need a
|
|
||||||
// way to purge the queue
|
|
||||||
// when it's quiescent for
|
|
||||||
// too long & restart all the
|
|
||||||
// constants)
|
|
||||||
static volatile uint8_t audioRunning = 0; // FIXME: needs constants abstracted
|
static volatile uint8_t audioRunning = 0; // FIXME: needs constants abstracted
|
||||||
static volatile int64_t lastFilledTime = 0;
|
static volatile int64_t lastFilledTime = 0;
|
||||||
|
|
||||||
|
@ -45,7 +40,8 @@ static bool toggleState = false;
|
||||||
TeensySpeaker::TeensySpeaker(uint8_t sda, uint8_t scl) : PhysicalSpeaker()
|
TeensySpeaker::TeensySpeaker(uint8_t sda, uint8_t scl) : PhysicalSpeaker()
|
||||||
{
|
{
|
||||||
toggleState = false;
|
toggleState = false;
|
||||||
mixerValue = numMixed = 0;
|
mixerValue = 0x80;
|
||||||
|
|
||||||
AudioMemory(8);
|
AudioMemory(8);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -55,8 +51,8 @@ TeensySpeaker::~TeensySpeaker()
|
||||||
|
|
||||||
void TeensySpeaker::begin()
|
void TeensySpeaker::begin()
|
||||||
{
|
{
|
||||||
mixer1.gain(0, 0.1f); // left channel
|
mixer1.gain(0, 0.1f); // left channel (off for now)
|
||||||
mixer1.gain(1, 0.1f); // right channel
|
mixer1.gain(1, 0.1f); // right channel (full volume for now)
|
||||||
|
|
||||||
memset(soundBuf, 0, sizeof(soundBuf));
|
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
|
// and we have filled to cycle number lastFilledTime. So how many do
|
||||||
// we need? This subtracts skippedSamples because those were filled
|
// we need? This subtracts skippedSamples because those were filled
|
||||||
// automatically by the audioCallback when we had no data.
|
// 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
|
// If audioBufferSamples < 0, then we need to keep some
|
||||||
// skippedSamples for later; otherwise we can keep moving forward.
|
// skippedSamples for later; otherwise we can keep moving forward.
|
||||||
if (audioBufferSamples < 0) {
|
if (audioBufferSamples < 0) {
|
||||||
|
@ -184,10 +180,7 @@ void TeensyAudio::update(void)
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
|
|
||||||
// FROM THE SOUND OF IT, something below this line isn't filling buffers
|
static short lastKnownSample = 0; // saved for when the apple is quiescent
|
||||||
// completely; or something isn't filling soundBuf completely in toggle().
|
|
||||||
|
|
||||||
static short lastKnownSample = 0;
|
|
||||||
|
|
||||||
if (bufIdx >= AUDIO_BLOCK_SAMPLES) {
|
if (bufIdx >= AUDIO_BLOCK_SAMPLES) {
|
||||||
memcpy(stream, (void *)soundBuf, AUDIO_BLOCK_SAMPLES * SAMPLEBYTES);
|
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++) {
|
for (int32_t i=0; i<AUDIO_BLOCK_SAMPLES-bufIdx; i++) {
|
||||||
stream[i+bufIdx] = lastKnownSample;
|
stream[i+bufIdx] = lastKnownSample;
|
||||||
}
|
}
|
||||||
|
bufIdx = 0;
|
||||||
} else {
|
} else {
|
||||||
// No big deal - buffer underrun might just mean nothing is
|
// No big deal - buffer underrun might just mean nothing is
|
||||||
// trying to play audio right now.
|
// trying to play audio right now.
|
||||||
|
|
|
@ -27,8 +27,8 @@ class TeensySpeaker : public PhysicalSpeaker {
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
uint32_t mixerValue;
|
uint8_t mixerValue;
|
||||||
uint8_t numMixed;
|
bool toggleState;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
Loading…
Reference in New Issue