bool active;
unsigned int evtime;
struct audio_channel_data2 data[AUDIO_CHANNEL_MAX_STREAM_CH];
+ SOUND_STREAM_CALLBACK cb;
};
struct audio_channel_data
audio_state_channel2 (nr, perfin);
cdp->dat_written = false;
} else {
- audio_state_stream(nr - AUDIO_CHANNELS_PAULA + 1);
+ bool ok = false;
+ int streamid = nr - AUDIO_CHANNELS_PAULA + 1;
+ struct audio_stream_data *asd = &audio_stream[nr - AUDIO_CHANNELS_PAULA];
+ if (asd->cb) {
+ ok = asd->cb(streamid);
+ }
+ if (!ok) {
+ audio_state_stream_state(streamid, NULL, 0, MAX_EV);
+ }
}
}
set_extra_prehandler();
}
-int audio_enable_stream(bool enable, int streamid, int ch)
+int audio_enable_stream(bool enable, int streamid, int ch, SOUND_STREAM_CALLBACK cb)
{
if (streamid == 0)
return 0;
}
audio_extra_streams[streamid] = ch;
struct audio_stream_data *asd = audio_stream + streamid;
+ asd->cb = cb;
asd->evtime = CYCLE_UNIT;
for (int i = 0; i < ch; i++) {
struct audio_channel_data2 *acd = &asd->data[i];
for (int i = 0; i < audio_extra_streams[streamid]; i++) {
struct audio_channel_data2 *acd = &asd->data[i];
acd->last_sample = acd->current_sample;
- acd->current_sample = samplep[i];
+ acd->current_sample = samplep ? samplep[i] : 0;
}
asd->evtime = evt;
}
}
}
+static bool audio_state_cda(int streamid)
+{
+ if (cda_bufptr >= dummy_buffer && cda_bufptr <= dummy_buffer + 4) {
+ audio_enable_stream(false, cda_streamid, 0, NULL);
+ cda_streamid = 0;
+ return false;
+ }
+ if (cda_streamid <= 0)
+ return false;
+ int samples[2];
+ samples[0] = cda_bufptr[0] * cda_volume[0] / 32768;
+ samples[1] = cda_bufptr[1] * cda_volume[1] / 32768;
+ audio_state_stream_state(streamid, samples, 2, cda_evt);
+ cda_bufptr += 2;
+ cda_length--;
+ if (cda_length <= 0 && cda_next_cd_audio_buffer_callback) {
+ cda_next_cd_audio_buffer_callback(cda_userdata);
+ }
+ return true;
+}
+
void audio_cda_new_buffer(uae_s16 *buffer, int length, int userdata, CDA_CALLBACK next_cd_audio_buffer_callback)
{
if (!buffer) {
cda_length = length;
cda_userdata = userdata;
if (cda_streamid <= 0)
- cda_streamid = audio_enable_stream(true, -1, 2);
+ cda_streamid = audio_enable_stream(true, -1, 2, audio_state_cda);
}
cda_next_cd_audio_buffer_callback = next_cd_audio_buffer_callback;
audio_activate();
}
-
-static void audio_state_cda(void)
-{
- if (cda_bufptr >= dummy_buffer && cda_bufptr <= dummy_buffer + 4) {
- audio_enable_stream(false, cda_streamid, 0);
- cda_streamid = 0;
- return;
- }
- if (cda_streamid <= 0)
- return;
- struct audio_stream_data *asd = audio_stream + cda_streamid;
- asd->evtime = cda_evt;
- struct audio_channel_data2 *acd;
- acd = &asd->data[0];
- acd->last_sample = acd->current_sample;
- acd->current_sample = cda_bufptr[0] * cda_volume[0] / 32768;
- acd = &asd->data[1];
- acd->last_sample = acd->current_sample;
- acd->current_sample = cda_bufptr[1] * cda_volume[1] / 32768;
- cda_bufptr += 2;
- cda_length--;
- if (cda_length <= 0 && cda_next_cd_audio_buffer_callback) {
- cda_next_cd_audio_buffer_callback(cda_userdata);
- }
-}
*/
+static bool audio_state_sndboard_uae(int streamid);
+
static bool uaesnd_rethink(void)
{
bool irq = false;
return;
s->play = 0;
data->streammask &= ~(1 << (s - data->stream));
- audio_enable_stream(false, s->streamid, 0);
+ audio_enable_stream(false, s->streamid, 0, NULL);
s->streamid = 0;
data->streamcnt--;
}
s->sample[i] = 0;
}
uaesnd_setfreq(s);
- s->streamid = audio_enable_stream(true, -1, MAX_UAE_CHANNELS);
+ s->streamid = audio_enable_stream(true, -1, MAX_UAE_CHANNELS, audio_state_sndboard_uae);
if (!s->streamid) {
uaesndboard_stop(s);
}
}
}
-static void audio_state_sndboard_uae(int streamid)
+static bool audio_state_sndboard_uae(int streamid)
{
struct uaesndboard_data *data = &uaesndboard[0];
struct uaesndboard_stream *s = NULL;
int highestch = s->ch;
+ if (!uaesnd_active)
+ return false;
+
for (int i = 0; i < MAX_UAE_STREAMS; i++) {
if (data->stream[i].streamid == streamid) {
s = &data->stream[i];
}
int streamnum = s - data->stream;
if (!s)
- return;
+ return false;
if (s->play && (data->streammask & (1 << streamnum))) {
int len = s->repeating ? s->replen : s->len;
uaecptr addr = s->repeating ? s->repeat : s->address;
s->sample[7] = lfe;
}
audio_state_stream_state(s->streamid, s->sample, highestch, s->event_time);
+ return true;
}
static void uaesnd_latch(struct uaesndboard_stream *s)
if (data->enabled) {
for (int i = 0; i < MAX_UAE_STREAMS; i++) {
if (data->stream[i].streamid) {
- audio_enable_stream(false, data->stream[i].streamid, 0);
+ audio_enable_stream(false, data->stream[i].streamid, 0, NULL);
memset(&data->stream[i], 0, sizeof(struct uaesndboard_stream));
}
}
data->fifo_half |= STATUS_FIFO_PLAY;
}
-static void audio_state_sndboard_toccata(int streamid)
+static bool audio_state_sndboard_toccata(int streamid)
{
struct toccata_data *data = &toccata[0];
+ if (!toccata[0].toccata_active)
+ return false;
if (data->streamid != streamid)
- return;
+ return false;
if ((data->toccata_active & STATUS_FIFO_PLAY)) {
// get all bytes at once to prevent fifo going out of sync
// if fifo has for example 3 bytes remaining but we need 4.
}
}
audio_state_stream_state(data->streamid, data->ch_sample, 2, data->event_time);
+ return true;
}
static int get_volume(uae_u8 v)
data->record_event_counter = 0;
if (data->toccata_active & STATUS_FIFO_PLAY) {
- data->streamid = audio_enable_stream(true, -1, 2);
+ data->streamid = audio_enable_stream(true, -1, 2, audio_state_sndboard_toccata);
}
if (data->toccata_active & STATUS_FIFO_RECORD) {
capture_buffer = xcalloc(uae_u8, capture_buffer_size);
write_log(_T("TOCCATA stop\n"));
data->toccata_active = 0;
sndboard_free_capture();
- audio_enable_stream(false, data->streamid, 0);
+ audio_enable_stream(false, data->streamid, 0, NULL);
data->streamid = 0;
xfree(capture_buffer);
capture_buffer = NULL;
struct toccata_data *data = &toccata[0];
data->ch_sample[0] = 0;
data->ch_sample[1] = 0;
- audio_enable_stream(false, data->streamid, 0);
+ audio_enable_stream(false, data->streamid, 0, NULL);
data->streamid = 0;
}
{
write_log(_T("FM801 STOP\n"));
data->play_on = false;
- audio_enable_stream(false, data->streamid, 0);
+ audio_enable_stream(false, data->streamid, 0, NULL);
data->streamid = 0;
}
}
}
-static void audio_state_sndboard_fm801(int streamid)
+static bool audio_state_sndboard_fm801(int streamid)
{
struct fm801_data *data = &fm801;
+ if (!fm801_active)
+ return false;
if (data->streamid != streamid)
- return;
+ return false;
if (data->play_on) {
uae_u8 sample[2 * 6] = { 0 };
pci_read_dma(data->pcibs, data->play_dma2[data->dmach], sample, data->bytesperframe);
}
}
audio_state_stream_state(data->streamid, data->ch_sample, data->ch, data->event_time);
+ return true;
}
static void fm801_hsync_handler(struct pci_board_state *pcibs)
write_log(_T("FM801 PLAY: freq=%d ch=%d bits=%d\n"), data->freq, data->ch, data->bits);
- data->streamid = audio_enable_stream(true, -1, data->ch);
+ data->streamid = audio_enable_stream(true, -1, data->ch, audio_state_sndboard_fm801);
}
static void fm801_pause(struct fm801_data *data, bool pause)
static SWVoiceOut *qemu_voice_out;
+static bool audio_state_sndboard_qemu(int streamid)
+{
+ SWVoiceOut *out = qemu_voice_out;
+
+ if (!out || !out->active)
+ return false;
+ if (streamid != out->streamid)
+ return false;
+ if (out->active) {
+ uae_s16 l, r;
+ if (out->samplebuf_index >= out->samplebuf_total) {
+ int maxsize = sizeof(out->samplebuf);
+ int size = 128 * out->bytesperframe;
+ if (size > maxsize)
+ size = maxsize;
+ out->callback(out->opaque, size);
+ out->samplebuf_index = 0;
+ }
+ uae_u8 *p = out->samplebuf + out->samplebuf_index;
+ if (out->bits == 8) {
+ if (out->ch == 1) {
+ p[1] = p[0];
+ p[2] = p[0];
+ p[3] = p[0];
+ } else {
+ p[2] = p[1];
+ p[3] = p[1];
+ p[1] = p[0];
+ }
+ } else {
+ if (out->ch == 1) {
+ p[2] = p[0];
+ p[3] = p[1];
+ }
+ }
+ l = (p[1] << 8) | p[0];
+ r = (p[3] << 8) | p[2];
+ out->ch_sample[0] = l;
+ out->ch_sample[1] = r;
+ out->ch_sample[0] = out->ch_sample[0] * out->left_volume / 32768;
+ out->ch_sample[1] = out->ch_sample[1] * out->right_volume / 32768;
+ out->samplebuf_index += out->bytesperframe;
+ }
+ audio_state_stream_state(out->streamid, out->ch_sample, out->ch, out->event_time);
+ return true;
+}
+
static void calculate_volume_qemu(void)
{
SWVoiceOut *out = qemu_voice_out;
sw->samplebuf_index = 0;
sw->samplebuf_total = 0;
calculate_volume_qemu();
- audio_enable_stream(false, sw->streamid, 2);
+ audio_enable_stream(false, sw->streamid, 2, NULL);
sw->streamid = 0;
if (on) {
- sw->streamid = audio_enable_stream(true, -1, 2);
+ sw->streamid = audio_enable_stream(true, -1, 2, audio_state_sndboard_qemu);
}
}
void AUD_set_active_in(SWVoiceIn *sw, int on)
{
qemu_voice_out = NULL;
if (sw) {
- audio_enable_stream(false, sw->streamid, 0);
+ audio_enable_stream(false, sw->streamid, 0, NULL);
sw->streamid = 0;
xfree(sw);
}
return out;
}
-static void audio_state_sndboard_qemu(int streamid)
-{
- SWVoiceOut *out = qemu_voice_out;
-
- if (!out)
- return;
- if (streamid != out->streamid)
- return;
- if (out->active) {
- uae_s16 l, r;
- if (out->samplebuf_index >= out->samplebuf_total) {
- int maxsize = sizeof(out->samplebuf);
- int size = 128 * out->bytesperframe;
- if (size > maxsize)
- size = maxsize;
- out->callback(out->opaque, size);
- out->samplebuf_index = 0;
- }
- uae_u8 *p = out->samplebuf + out->samplebuf_index;
- if (out->bits == 8) {
- if (out->ch == 1) {
- p[1] = p[0];
- p[2] = p[0];
- p[3] = p[0];
- } else {
- p[2] = p[1];
- p[3] = p[1];
- p[1] = p[0];
- }
- } else {
- if (out->ch == 1) {
- p[2] = p[0];
- p[3] = p[1];
- }
- }
- l = (p[1] << 8) | p[0];
- r = (p[3] << 8) | p[2];
- out->ch_sample[0] = l;
- out->ch_sample[1] = r;
- out->ch_sample[0] = out->ch_sample[0] * out->left_volume / 32768;
- out->ch_sample[1] = out->ch_sample[1] * out->right_volume / 32768;
- out->samplebuf_index += out->bytesperframe;
- }
- audio_state_stream_state(out->streamid, out->ch_sample, out->ch, out->event_time);
-}
-
static void sndboard_vsync_qemu(void)
{
audio_activate();
}
-void audio_state_stream(int streamid)
-{
- if (toccata[0].toccata_active)
- audio_state_sndboard_toccata(streamid);
- if (fm801_active)
- audio_state_sndboard_fm801(streamid);
- if (qemu_voice_out && qemu_voice_out->active)
- audio_state_sndboard_qemu(streamid);
- if (uaesnd_active)
- audio_state_sndboard_uae(streamid);
-}
-
void sndboard_vsync(void)
{
if (toccata[0].toccata_active)