Make the UxnAudio struct private to audio.c.

This commit is contained in:
Andrew Alderwick 2022-03-17 16:59:36 +00:00
parent 084a0f5ab4
commit 5dcf0a2b35
3 changed files with 49 additions and 38 deletions

View File

@ -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;
}

View File

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

View File

@ -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);
}