117 lines
No EOL
2.7 KiB
HolyC
117 lines
No EOL
2.7 KiB
HolyC
extern U0 (*fp_snd_fill_buf)(U32* buf, I64 buf_num);
|
|
|
|
#define AUDIO_MAX_STREAMS 16
|
|
|
|
#define AUDIO_OUTPUT_BUFFER_SIZE 1024
|
|
|
|
#define AUDIO_STREAM_FIFO_SIZE 1048576
|
|
#define AUDIO_STREAM_TYPE_INPUT 0
|
|
#define AUDIO_STREAM_TYPE_OUTPUT 1
|
|
|
|
class Sound {
|
|
// For simplicity, all samples will be converted to 44100 Hz, 2 channels, 16
|
|
// bit when they are loaded.
|
|
I64 rate;
|
|
I64 channels;
|
|
I64 bits;
|
|
U32* data;
|
|
I64 length; // in samples
|
|
};
|
|
|
|
class @audio_device
|
|
{
|
|
Bool enabled;
|
|
};
|
|
|
|
class @audio_mixer
|
|
{
|
|
I64 left;
|
|
I64 right;
|
|
};
|
|
|
|
class @audio_stream
|
|
{
|
|
I64 type;
|
|
I64 rate;
|
|
I64 channels;
|
|
I64 bits;
|
|
CFifoI64* data;
|
|
};
|
|
|
|
class @audio_wave_generator
|
|
{
|
|
F64 duration;
|
|
I64 frequency;
|
|
};
|
|
|
|
class @audio
|
|
{
|
|
I64 driver;
|
|
@audio_device device;
|
|
@audio_mixer mixer;
|
|
@audio_stream output[AUDIO_MAX_STREAMS + 1];
|
|
@audio_wave_generator wavegen;
|
|
U0 (*Beep)();
|
|
U0 (*Init)();
|
|
U0 (*MixOutput)(U64 buf, I64);
|
|
Sound (*SoundFromFile)(U8* filename);
|
|
U0 (*FreeSound)(Sound* snd);
|
|
I64 (*PlaySound)(Sound* snd);
|
|
};
|
|
|
|
@audio Audio;
|
|
|
|
U0 @audio_mix_output(U32* buf, I64 length = NULL)
|
|
{
|
|
I64 i;
|
|
I64 j;
|
|
I64 acc_sample_L = 0;
|
|
I64 acc_sample_R = 0;
|
|
I64 acc_streams = 0;
|
|
U32 sample;
|
|
if (!length)
|
|
length = AUDIO_OUTPUT_BUFFER_SIZE;
|
|
for (i = 0; i < length / 4; i++) {
|
|
acc_sample_L = 0;
|
|
acc_sample_R = 0;
|
|
acc_streams = 0;
|
|
if (Audio.wavegen.frequency) {
|
|
sample.i16[0] = T(Sin(Audio.wavegen.frequency * Audio.wavegen.duration) >= 0.0,
|
|
I16_MAX / 8, I16_MIN / 8);
|
|
sample.i16[1] = sample.i16[0];
|
|
FifoI64Ins(Audio.output[AUDIO_MAX_STREAMS].data, sample);
|
|
Audio.wavegen.duration += 6.4 / 48000.0;
|
|
}
|
|
for (j = 0; j < AUDIO_MAX_STREAMS + 1; j++) {
|
|
if (FifoI64Cnt(Audio.output[j].data)) {
|
|
FifoI64Rem(Audio.output[j].data, &sample);
|
|
acc_streams++;
|
|
acc_sample_L += sample.i16[0];
|
|
acc_sample_R += sample.i16[1];
|
|
}
|
|
}
|
|
buf[i].i16[0] = ToI64(acc_sample_L / Sqrt(acc_streams) * Audio.mixer.left / 100);
|
|
buf[i].i16[1] = ToI64(acc_sample_R / Sqrt(acc_streams) * Audio.mixer.right / 100);
|
|
}
|
|
}
|
|
|
|
U0 @audio_init()
|
|
{
|
|
I64 i = 0;
|
|
for (i = 0; i < AUDIO_MAX_STREAMS + 1; i++)
|
|
Audio.output[i].data = FifoI64New(AUDIO_STREAM_FIFO_SIZE);
|
|
Audio.mixer.left = 100;
|
|
Audio.mixer.right = 100;
|
|
Audio.wavegen.duration = 0.0;
|
|
Audio.wavegen.frequency = 0;
|
|
Audio.device.enabled = TRUE;
|
|
}
|
|
|
|
Audio.driver = NULL;
|
|
Audio.Init = &@audio_init;
|
|
Audio.MixOutput = &@audio_mix_output;
|
|
|
|
// Initialize Audio
|
|
Audio.Init();
|
|
|
|
"audio "; |