commit 5dcf0a2b35d98ccba1a6782a1e7ac194e4b74544
parent 084a0f5ab43d932c4abb0d577c2ac56de27a6e74
Author: Andrew Alderwick <andrew@alderwick.co.uk>
Date: Thu, 17 Mar 2022 16:59:36 +0000
Make the UxnAudio struct private to audio.c.
Diffstat:
3 files changed, 49 insertions(+), 38 deletions(-)
diff --git a/src/devices/audio.c b/src/devices/audio.c
@@ -16,6 +16,14 @@ WITH REGARD TO THIS SOFTWARE.
#define NOTE_PERIOD (SAMPLE_FREQUENCY * 0x4000 / 11025)
#define ADSR_STEP (SAMPLE_FREQUENCY / 0xf)
+typedef struct {
+ Uint8 *addr;
+ Uint32 count, advance, period, age, a, d, s, r;
+ Uint16 i, len;
+ Sint8 volume[2];
+ Uint8 pitch, repeat;
+} UxnAudio;
+
/* clang-format off */
static Uint32 advances[12] = {
@@ -40,8 +48,9 @@ envelope(UxnAudio *c, Uint32 age)
}
int
-audio_render(UxnAudio *c, Sint16 *sample, Sint16 *end)
+audio_render(int instance, Sint16 *sample, Sint16 *end)
{
+ UxnAudio *c = &uxn_audio[instance];
Sint32 s;
if(!c->advance || !c->period) return 0;
while(sample < end) {
@@ -59,13 +68,26 @@ audio_render(UxnAudio *c, Sint16 *sample, Sint16 *end)
*sample++ += s * c->volume[0] / 0x180;
*sample++ += s * c->volume[1] / 0x180;
}
- if(!c->advance) audio_finished_handler(c);
+ if(!c->advance) audio_finished_handler(instance);
return 1;
}
void
-audio_start(UxnAudio *c, Uint16 adsr, Uint8 pitch)
+audio_start(int instance, Device *d)
{
+ UxnAudio *c = &uxn_audio[instance];
+ Uint16 addr, adsr;
+ Uint8 pitch;
+ DEVPEEK16(adsr, 0x8);
+ DEVPEEK16(c->len, 0xa);
+ DEVPEEK16(addr, 0xc);
+ if(c->len > 0x10000 - addr)
+ c->len = 0x10000 - addr;
+ c->addr = &d->u->ram[addr];
+ c->volume[0] = d->dat[0xe] >> 4;
+ c->volume[1] = d->dat[0xe] & 0xf;
+ c->repeat = !(d->dat[0xf] & 0x80);
+ pitch = d->dat[0xf] & 0x7f;
if(pitch < 108 && c->len)
c->advance = advances[pitch % 12] >> (8 - pitch / 12);
else {
@@ -85,8 +107,9 @@ audio_start(UxnAudio *c, Uint16 adsr, Uint8 pitch)
}
Uint8
-audio_get_vu(UxnAudio *c)
+audio_get_vu(int instance)
{
+ UxnAudio *c = &uxn_audio[instance];
int i;
Sint32 sum[2] = {0, 0};
if(!c->advance || !c->period) return 0;
@@ -97,3 +120,10 @@ audio_get_vu(UxnAudio *c)
}
return (sum[0] << 4) | sum[1];
}
+
+Uint16
+audio_get_position(int instance)
+{
+ UxnAudio *c = &uxn_audio[instance];
+ return c->i;
+}
diff --git a/src/devices/audio.h b/src/devices/audio.h
@@ -15,17 +15,8 @@ typedef signed int Sint32;
#define SAMPLE_FREQUENCY 44100
#define POLYPHONY 4
-typedef struct {
- Uint8 *addr;
- Uint32 count, advance, period, age, a, d, s, r;
- Uint16 i, len;
- Sint8 volume[2];
- Uint8 pitch, repeat;
-} UxnAudio;
-
-extern UxnAudio uxn_audio[POLYPHONY];
-
-Uint8 audio_get_vu(UxnAudio *c);
-int audio_render(UxnAudio *c, Sint16 *sample, Sint16 *end);
-void audio_start(UxnAudio *c, Uint16 adsr, Uint8 pitch);
-void audio_finished_handler(UxnAudio *c);
+Uint8 audio_get_vu(int instance);
+Uint16 audio_get_position(int instance);
+int audio_render(int instance, Sint16 *sample, Sint16 *end);
+void audio_start(int instance, Device *d);
+void audio_finished_handler(int instance);
diff --git a/src/uxnemu.c b/src/uxnemu.c
@@ -58,21 +58,21 @@ error(char *msg, const char *err)
static void
audio_callback(void *u, Uint8 *stream, int len)
{
- int i, running = 0;
+ int instance, running = 0;
Sint16 *samples = (Sint16 *)stream;
SDL_memset(stream, 0, len);
- for(i = 0; i < POLYPHONY; i++)
- running += audio_render(&uxn_audio[i], samples, samples + len / 2);
+ for(instance = 0; instance < POLYPHONY; instance++)
+ running += audio_render(instance, samples, samples + len / 2);
if(!running)
SDL_PauseAudioDevice(audio_id, 1);
(void)u;
}
void
-audio_finished_handler(UxnAudio *c)
+audio_finished_handler(int instance)
{
SDL_Event event;
- event.type = audio0_event + (c - uxn_audio);
+ event.type = audio0_event + instance;
SDL_PushEvent(&event);
}
@@ -185,11 +185,11 @@ console_deo(Device *d, Uint8 port)
static Uint8
audio_dei(Device *d, Uint8 port)
{
- UxnAudio *c = &uxn_audio[d - devaudio0];
+ int instance = d - devaudio0;
if(!audio_id) return d->dat[port];
switch(port) {
- case 0x4: return audio_get_vu(c);
- case 0x2: DEVPOKE16(0x2, c->i); /* fall through */
+ case 0x4: return audio_get_vu(instance);
+ case 0x2: DEVPOKE16(0x2, audio_get_position(instance)); /* fall through */
default: return d->dat[port];
}
}
@@ -197,21 +197,11 @@ audio_dei(Device *d, Uint8 port)
static void
audio_deo(Device *d, Uint8 port)
{
- UxnAudio *c = &uxn_audio[d - devaudio0];
+ int instance = d - devaudio0;
if(!audio_id) return;
if(port == 0xf) {
- Uint16 addr, adsr;
SDL_LockAudioDevice(audio_id);
- DEVPEEK16(adsr, 0x8);
- DEVPEEK16(c->len, 0xa);
- DEVPEEK16(addr, 0xc);
- if(c->len > 0x10000 - addr)
- c->len = 0x10000 - addr;
- c->addr = &d->u->ram[addr];
- c->volume[0] = d->dat[0xe] >> 4;
- c->volume[1] = d->dat[0xe] & 0xf;
- c->repeat = !(d->dat[0xf] & 0x80);
- audio_start(c, adsr, d->dat[0xf] & 0x7f);
+ audio_start(instance, d);
SDL_UnlockAudioDevice(audio_id);
SDL_PauseAudioDevice(audio_id, 0);
}