uxn

Varvara Ordinator, written in ANSI C(SDL2)
git clone https://git.eamoncaddigan.net/uxn.git
Log | Files | Refs | README | LICENSE

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:
Msrc/devices/audio.c | 38++++++++++++++++++++++++++++++++++----
Msrc/devices/audio.h | 19+++++--------------
Msrc/uxnemu.c | 30++++++++++--------------------
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); }