Added audio.ha
This commit is contained in:
+169
@@ -0,0 +1,169 @@
|
|||||||
|
use fmt;
|
||||||
|
use sdl3;
|
||||||
|
|
||||||
|
def SAMPLE_FREQUENCY = 44100;
|
||||||
|
def POLYPHONY = 4;
|
||||||
|
def NOTE_PERIOD = (SAMPLE_FREQUENCY * 0x4000 / 11025);
|
||||||
|
def ADSR_STEP = (SAMPLE_FREQUENCY / 0xf);
|
||||||
|
|
||||||
|
export fn init_audio() void = {
|
||||||
|
let aspec = sdl3::AudioSpec {
|
||||||
|
format = sdl3::AudioFormat::S16,
|
||||||
|
channels = 2,
|
||||||
|
freq = SAMPLE_FREQUENCY,
|
||||||
|
};
|
||||||
|
// sdl3::zero(as);
|
||||||
|
// as.freq = SAMPLE_FREQUENCY;
|
||||||
|
// as.format = AUDIO_S16SYS;
|
||||||
|
// as.channels = 2;
|
||||||
|
// as.callback = audio_callback;
|
||||||
|
// as.samples = 512;
|
||||||
|
// as.userdata = NULL;
|
||||||
|
// sdl3::OpenAudioDeviceStream(null,0,&as,null,0);
|
||||||
|
const device = *(sdl3::GetAudioPlaybackDevices(&1)!);
|
||||||
|
const audio_id = sdl3::OpenAudioDeviceStream(device,&aspec,&audio_callback,null);
|
||||||
|
};
|
||||||
|
|
||||||
|
fn audio_callback(userdata: nullable *opaque,stream: nullable *sdl3::AudioStream, additional_amount: int, total_amount: int) void = {
|
||||||
|
|
||||||
|
// int instance, running = 0;
|
||||||
|
let instance = 0;
|
||||||
|
let running = 0;
|
||||||
|
// Sint16 *samples = (Sint16 *)stream;
|
||||||
|
match(stream) {
|
||||||
|
case let s: *sdl3::AudioStream =>
|
||||||
|
const samples = (s: *[*]i16)[0..additional_amount];//TODO verify this makes sense
|
||||||
|
for(let instance = 0; instance < POLYPHONY; instance+=1){
|
||||||
|
running += audio_render(instance,samples);
|
||||||
|
};
|
||||||
|
|
||||||
|
case null =>
|
||||||
|
return;
|
||||||
|
};
|
||||||
|
// USED(u);
|
||||||
|
// SDL_memset(stream, 0, len);
|
||||||
|
// for(instance = 0; instance < POLYPHONY; instance++)
|
||||||
|
// running += audio_render(instance, samples, samples + len / 2);
|
||||||
|
// if(!running)
|
||||||
|
// SDL_PauseAudioDevice(audio_id, 1);
|
||||||
|
};
|
||||||
|
|
||||||
|
// static void
|
||||||
|
// audio_finished_handler(int instance)
|
||||||
|
// {
|
||||||
|
// SDL_Event event;
|
||||||
|
// event.type = audio0_event + instance;
|
||||||
|
// SDL_PushEvent(&event);
|
||||||
|
// }
|
||||||
|
|
||||||
|
// static Sint32
|
||||||
|
// envelope(UxnAudio *c, Uint32 age)
|
||||||
|
// {
|
||||||
|
// if(!c->r) return 0x0888;
|
||||||
|
// if(age < c->a) return 0x0888 * age / c->a;
|
||||||
|
// if(age < c->d) return 0x0444 * (2 * c->d - c->a - age) / (c->d - c->a);
|
||||||
|
// if(age < c->s) return 0x0444;
|
||||||
|
// if(age < c->r) return 0x0444 * (c->r - age) / (c->r - c->s);
|
||||||
|
// c->advance = 0;
|
||||||
|
// return 0x0000;
|
||||||
|
// }
|
||||||
|
|
||||||
|
|
||||||
|
// int
|
||||||
|
// 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) {
|
||||||
|
// c->count += c->advance;
|
||||||
|
// c->i += c->count / c->period;
|
||||||
|
// c->count %= c->period;
|
||||||
|
// if(c->i >= c->len) {
|
||||||
|
// if(!c->repeat) {
|
||||||
|
// c->advance = 0;
|
||||||
|
// break;
|
||||||
|
// }
|
||||||
|
// c->i %= c->len;
|
||||||
|
// }
|
||||||
|
// s = (Sint8)(c->addr[c->i] + 0x80) * envelope(c, c->age++);
|
||||||
|
// *sample++ += s * c->volume[0] / 0x180;
|
||||||
|
// *sample++ += s * c->volume[1] / 0x180;
|
||||||
|
// }
|
||||||
|
// if(!c->advance) audio_finished_handler(instance);
|
||||||
|
// return 1;
|
||||||
|
// }
|
||||||
|
fn audio_render(instance: int, samples: []i16) int = {
|
||||||
|
return 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
// static void
|
||||||
|
// audio_start(int instance, Uint8 *d)
|
||||||
|
// {
|
||||||
|
// UxnAudio *c = &uxn_audio[instance];
|
||||||
|
// Uint8 pitch = d[0xf] & 0x7f;
|
||||||
|
// Uint16 addr = peek2(d + 0xc);
|
||||||
|
// Uint16 adsr = peek2(d + 0x8);
|
||||||
|
// c->len = peek2(d + 0xa);
|
||||||
|
// if(c->len > 0x10000 - addr)
|
||||||
|
// c->len = 0x10000 - addr;
|
||||||
|
// c->addr = &ram[addr];
|
||||||
|
// c->volume[0] = d[0xe] >> 4;
|
||||||
|
// c->volume[1] = d[0xe] & 0xf;
|
||||||
|
// c->repeat = !(d[0xf] & 0x80);
|
||||||
|
// if(pitch < 108 && c->len)
|
||||||
|
// c->advance = advances[pitch % 12] >> (8 - pitch / 12);
|
||||||
|
// else {
|
||||||
|
// c->advance = 0;
|
||||||
|
// return;
|
||||||
|
// }
|
||||||
|
// c->a = ADSR_STEP * (adsr >> 12);
|
||||||
|
// c->d = ADSR_STEP * (adsr >> 8 & 0xf) + c->a;
|
||||||
|
// c->s = ADSR_STEP * (adsr >> 4 & 0xf) + c->d;
|
||||||
|
// c->r = ADSR_STEP * (adsr >> 0 & 0xf) + c->s;
|
||||||
|
// c->age = 0;
|
||||||
|
// c->i = 0;
|
||||||
|
// if(c->len <= 0x100) /* single cycle mode */
|
||||||
|
// c->period = NOTE_PERIOD * 337 / 2 / c->len;
|
||||||
|
// else /* sample repeat mode */
|
||||||
|
// c->period = NOTE_PERIOD;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// static void
|
||||||
|
// audio_play(int instance, Uint8 *d)
|
||||||
|
// {
|
||||||
|
// SDL_LockAudioDevice(audio_id);
|
||||||
|
// audio_start(instance, d);
|
||||||
|
// SDL_UnlockAudioDevice(audio_id);
|
||||||
|
// SDL_PauseAudioDevice(audio_id, 0);
|
||||||
|
// }
|
||||||
|
|
||||||
|
// Uint8
|
||||||
|
// audio_get_vu(int instance)
|
||||||
|
// {
|
||||||
|
// int i;
|
||||||
|
// UxnAudio *c = &uxn_audio[instance];
|
||||||
|
// Sint32 sum[2] = {0, 0};
|
||||||
|
// if(!c->advance || !c->period) return 0;
|
||||||
|
// for(i = 0; i < 2; i++) {
|
||||||
|
// if(!c->volume[i]) continue;
|
||||||
|
// sum[i] = 1 + envelope(c, c->age) * c->volume[i] / 0x800;
|
||||||
|
// if(sum[i] > 0xf) sum[i] = 0xf;
|
||||||
|
// }
|
||||||
|
// return (sum[0] << 4) | sum[1];
|
||||||
|
// }
|
||||||
|
|
||||||
|
// Uint16
|
||||||
|
// audio_get_position(int instance)
|
||||||
|
// {
|
||||||
|
// return uxn_audio[instance].i;
|
||||||
|
// }
|
||||||
|
|
||||||
|
fn audio_pitch(device: u8, state: *uxn) void = {
|
||||||
|
if(device > 3){
|
||||||
|
fmt::fatal("Trying to use non-existant audio device!");
|
||||||
|
};
|
||||||
|
|
||||||
|
return;
|
||||||
|
};
|
||||||
Reference in New Issue
Block a user