Make the UxnAudio struct private to audio.c.
This commit is contained in:
parent
084a0f5ab4
commit
5dcf0a2b35
|
@ -16,6 +16,14 @@ WITH REGARD TO THIS SOFTWARE.
|
||||||
#define NOTE_PERIOD (SAMPLE_FREQUENCY * 0x4000 / 11025)
|
#define NOTE_PERIOD (SAMPLE_FREQUENCY * 0x4000 / 11025)
|
||||||
#define ADSR_STEP (SAMPLE_FREQUENCY / 0xf)
|
#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 */
|
/* clang-format off */
|
||||||
|
|
||||||
static Uint32 advances[12] = {
|
static Uint32 advances[12] = {
|
||||||
|
@ -40,8 +48,9 @@ envelope(UxnAudio *c, Uint32 age)
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
audio_render(UxnAudio *c, Sint16 *sample, Sint16 *end)
|
audio_render(int instance, Sint16 *sample, Sint16 *end)
|
||||||
{
|
{
|
||||||
|
UxnAudio *c = &uxn_audio[instance];
|
||||||
Sint32 s;
|
Sint32 s;
|
||||||
if(!c->advance || !c->period) return 0;
|
if(!c->advance || !c->period) return 0;
|
||||||
while(sample < end) {
|
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[0] / 0x180;
|
||||||
*sample++ += s * c->volume[1] / 0x180;
|
*sample++ += s * c->volume[1] / 0x180;
|
||||||
}
|
}
|
||||||
if(!c->advance) audio_finished_handler(c);
|
if(!c->advance) audio_finished_handler(instance);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
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)
|
if(pitch < 108 && c->len)
|
||||||
c->advance = advances[pitch % 12] >> (8 - pitch / 12);
|
c->advance = advances[pitch % 12] >> (8 - pitch / 12);
|
||||||
else {
|
else {
|
||||||
|
@ -85,8 +107,9 @@ audio_start(UxnAudio *c, Uint16 adsr, Uint8 pitch)
|
||||||
}
|
}
|
||||||
|
|
||||||
Uint8
|
Uint8
|
||||||
audio_get_vu(UxnAudio *c)
|
audio_get_vu(int instance)
|
||||||
{
|
{
|
||||||
|
UxnAudio *c = &uxn_audio[instance];
|
||||||
int i;
|
int i;
|
||||||
Sint32 sum[2] = {0, 0};
|
Sint32 sum[2] = {0, 0};
|
||||||
if(!c->advance || !c->period) return 0;
|
if(!c->advance || !c->period) return 0;
|
||||||
|
@ -97,3 +120,10 @@ audio_get_vu(UxnAudio *c)
|
||||||
}
|
}
|
||||||
return (sum[0] << 4) | sum[1];
|
return (sum[0] << 4) | sum[1];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Uint16
|
||||||
|
audio_get_position(int instance)
|
||||||
|
{
|
||||||
|
UxnAudio *c = &uxn_audio[instance];
|
||||||
|
return c->i;
|
||||||
|
}
|
||||||
|
|
|
@ -15,17 +15,8 @@ typedef signed int Sint32;
|
||||||
#define SAMPLE_FREQUENCY 44100
|
#define SAMPLE_FREQUENCY 44100
|
||||||
#define POLYPHONY 4
|
#define POLYPHONY 4
|
||||||
|
|
||||||
typedef struct {
|
Uint8 audio_get_vu(int instance);
|
||||||
Uint8 *addr;
|
Uint16 audio_get_position(int instance);
|
||||||
Uint32 count, advance, period, age, a, d, s, r;
|
int audio_render(int instance, Sint16 *sample, Sint16 *end);
|
||||||
Uint16 i, len;
|
void audio_start(int instance, Device *d);
|
||||||
Sint8 volume[2];
|
void audio_finished_handler(int instance);
|
||||||
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);
|
|
||||||
|
|
30
src/uxnemu.c
30
src/uxnemu.c
|
@ -58,21 +58,21 @@ error(char *msg, const char *err)
|
||||||
static void
|
static void
|
||||||
audio_callback(void *u, Uint8 *stream, int len)
|
audio_callback(void *u, Uint8 *stream, int len)
|
||||||
{
|
{
|
||||||
int i, running = 0;
|
int instance, running = 0;
|
||||||
Sint16 *samples = (Sint16 *)stream;
|
Sint16 *samples = (Sint16 *)stream;
|
||||||
SDL_memset(stream, 0, len);
|
SDL_memset(stream, 0, len);
|
||||||
for(i = 0; i < POLYPHONY; i++)
|
for(instance = 0; instance < POLYPHONY; instance++)
|
||||||
running += audio_render(&uxn_audio[i], samples, samples + len / 2);
|
running += audio_render(instance, samples, samples + len / 2);
|
||||||
if(!running)
|
if(!running)
|
||||||
SDL_PauseAudioDevice(audio_id, 1);
|
SDL_PauseAudioDevice(audio_id, 1);
|
||||||
(void)u;
|
(void)u;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
audio_finished_handler(UxnAudio *c)
|
audio_finished_handler(int instance)
|
||||||
{
|
{
|
||||||
SDL_Event event;
|
SDL_Event event;
|
||||||
event.type = audio0_event + (c - uxn_audio);
|
event.type = audio0_event + instance;
|
||||||
SDL_PushEvent(&event);
|
SDL_PushEvent(&event);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -185,11 +185,11 @@ console_deo(Device *d, Uint8 port)
|
||||||
static Uint8
|
static Uint8
|
||||||
audio_dei(Device *d, Uint8 port)
|
audio_dei(Device *d, Uint8 port)
|
||||||
{
|
{
|
||||||
UxnAudio *c = &uxn_audio[d - devaudio0];
|
int instance = d - devaudio0;
|
||||||
if(!audio_id) return d->dat[port];
|
if(!audio_id) return d->dat[port];
|
||||||
switch(port) {
|
switch(port) {
|
||||||
case 0x4: return audio_get_vu(c);
|
case 0x4: return audio_get_vu(instance);
|
||||||
case 0x2: DEVPOKE16(0x2, c->i); /* fall through */
|
case 0x2: DEVPOKE16(0x2, audio_get_position(instance)); /* fall through */
|
||||||
default: return d->dat[port];
|
default: return d->dat[port];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -197,21 +197,11 @@ audio_dei(Device *d, Uint8 port)
|
||||||
static void
|
static void
|
||||||
audio_deo(Device *d, Uint8 port)
|
audio_deo(Device *d, Uint8 port)
|
||||||
{
|
{
|
||||||
UxnAudio *c = &uxn_audio[d - devaudio0];
|
int instance = d - devaudio0;
|
||||||
if(!audio_id) return;
|
if(!audio_id) return;
|
||||||
if(port == 0xf) {
|
if(port == 0xf) {
|
||||||
Uint16 addr, adsr;
|
|
||||||
SDL_LockAudioDevice(audio_id);
|
SDL_LockAudioDevice(audio_id);
|
||||||
DEVPEEK16(adsr, 0x8);
|
audio_start(instance, d);
|
||||||
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);
|
|
||||||
SDL_UnlockAudioDevice(audio_id);
|
SDL_UnlockAudioDevice(audio_id);
|
||||||
SDL_PauseAudioDevice(audio_id, 0);
|
SDL_PauseAudioDevice(audio_id, 0);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue