right_word_saved[saved_ptr] = w;
return;
}
- PUT_SOUND_WORD_RIGHT (w);
+ PUT_SOUND_WORD (w);
}
STATIC_INLINE void put_sound_word_left (uae_u32 w)
rold = right_word_saved[saved_ptr] - SOUND16_BASE_VAL;
w = (lnew * mixed_mul2 + rold * mixed_mul1) / MIXED_STEREO_SCALE;
- PUT_SOUND_WORD_LEFT (w);
- PUT_SOUND_WORD_RIGHT (tmp);
+ PUT_SOUND_WORD (w);
+ PUT_SOUND_WORD (tmp);
} else {
- PUT_SOUND_WORD_LEFT (w);
+ PUT_SOUND_WORD (w);
}
}
right2_word_saved[saved_ptr2] = w;
return;
}
- PUT_SOUND_WORD_RIGHT2 (w);
+ PUT_SOUND_WORD (w);
}
STATIC_INLINE void put_sound_word_left2 (uae_u32 w)
rold = right2_word_saved[saved_ptr2] - SOUND16_BASE_VAL;
w = (lnew * mixed_mul2 + rold * mixed_mul1) / MIXED_STEREO_SCALE;
- PUT_SOUND_WORD_LEFT2 (w);
- PUT_SOUND_WORD_RIGHT2 (tmp);
+ PUT_SOUND_WORD (w);
+ PUT_SOUND_WORD (tmp);
} else {
- PUT_SOUND_WORD_LEFT2 (w);
+ PUT_SOUND_WORD (w);
}
}
{
int d1 = *data1 + sample1;
int d2 = *data2 + sample2;
+ if (d1 < -32768)
+ d1 = -32768;
+ if (d1 > 32767)
+ d1 = 32767;
+ if (d2 < -32768)
+ d2 = -32768;
+ if (d2 > 32767)
+ d2 = 32767;
int needswap = currprefs.sound_stereo_swap_paula ^ currprefs.sound_stereo_swap_ahi;
if (needswap) {
*data1 = d2;
{
if (audio_extra_channels[0]) {
int d1 = *data1 + audio_channel[AUDIO_CHANNEL_SNDBOARD_LEFT].current_sample;
+ if (d1 < -32768)
+ d1 = -32768;
+ if (d1 > 32767)
+ d1 = 32767;
*data1 = d1;
}
if (audio_extra_channels[1]) {
int d1 = *data1 + audio_channel[AUDIO_CHANNEL_CDA_LEFT].current_sample;
+ if (d1 < -32768)
+ d1 = -32768;
+ if (d1 > 32767)
+ d1 = 32767;
*data1 = d1;
}
}
+static void do_filter(int *data, int num)
+{
+ if (currprefs.sound_filter)
+ *data = filter (*data, &sound_filter_state[num]);
+}
+
static void sample16i_sinc_handler (void)
{
int datas[4], data1;
samplexx_sinc_handler (datas);
data1 = datas[0] + datas[3] + datas[1] + datas[2];
data1 = FINISH_DATA (data1, 18);
+
+ do_filter(&data1, 0);
+
+ get_extra_channels_sample_mono(&data1);
+
set_sound_buffers ();
PUT_SOUND_WORD_MONO (data1);
check_sound_buffers ();
data = SBASEVAL16(2) + data0;
data = FINISH_DATA (data, 16);
+ do_filter(&data, 0);
+
get_extra_channels_sample_mono(&data);
set_sound_buffers ();
data1 = datas[0] + datas[3] + datas[1] + datas[2];
data1 = FINISH_DATA (data1, 16);
+ do_filter(&data1, 0);
+
get_extra_channels_sample_mono(&data1);
set_sound_buffers ();
data = SBASEVAL16(2) + data0;
data = FINISH_DATA (data, 16);
+ do_filter(&data, 0);
+
get_extra_channels_sample_mono(&data);
set_sound_buffers ();
data = SBASEVAL16(2) + data0;
data = FINISH_DATA (data, 16);
+ do_filter(&data, 0);
+
get_extra_channels_sample_mono(&data);
set_sound_buffers ();
data2 = FINISH_DATA (data2, 14);
data3 = FINISH_DATA (data3, 14);
+ do_filter(&data0, 0);
+ do_filter(&data1, 1);
+ do_filter(&data2, 3);
+ do_filter(&data3, 2);
+
get_extra_channels_sample(&data0, &data1);
get_extra_channels_sample(&data2, &data3);
data2 = FINISH_DATA (datas[2], 14);
data3 = FINISH_DATA (datas[3], 14);
+ do_filter(&data0, 0);
+ do_filter(&data1, 1);
+ do_filter(&data2, 3);
+ do_filter(&data3, 2);
+
get_extra_channels_sample(&data0, &data1);
get_extra_channels_sample(&data3, &data2);
data1 = FINISH_DATA (data1, 15);
data2 = FINISH_DATA (data2, 15);
+ do_filter(&data1, 0);
+ do_filter(&data2, 1);
+
get_extra_channels_sample(&data1, &data2);
set_sound_buffers ();
data2 = FINISH_DATA (datas[2], 16);
data3 = FINISH_DATA (datas[3], 16);
+ do_filter(&data0, 0);
+ do_filter(&data1, 1);
+ do_filter(&data2, 3);
+ do_filter(&data3, 2);
+
get_extra_channels_sample(&data0, &data1);
get_extra_channels_sample(&data3, &data2);
data1 = FINISH_DATA (data1, 17);
data2 = FINISH_DATA (data2, 17);
+ do_filter(&data1, 0);
+ do_filter(&data2, 1);
+
get_extra_channels_sample(&data1, &data2);
set_sound_buffers ();
data3 = SBASEVAL16(1) + data1;
data3 = FINISH_DATA (data3, 15);
+ do_filter(&data2, 0);
+ do_filter(&data3, 1);
+
get_extra_channels_sample(&data2, &data3);
set_sound_buffers ();
data3 = SBASEVAL16(1) + data1;
data3 = FINISH_DATA (data3, 15);
+ do_filter(&data2, 0);
+ do_filter(&data3, 1);
+
get_extra_channels_sample(&data2, &data3);
set_sound_buffers ();
data3 = SBASEVAL16(1) + data1;
data3 = FINISH_DATA (data3, 15);
+ do_filter(&data2, 0);
+ do_filter(&data3, 1);
+
get_extra_channels_sample(&data2, &data3);
set_sound_buffers ();
}
}
+void audio_state_cda(void);
+
static void audio_state_channel (int nr, bool perfin)
{
struct audio_channel_data *cdp = audio_channel + nr;
cdp->dat_written = false;
} else if (nr == AUDIO_CHANNEL_SNDBOARD_LEFT || nr == AUDIO_CHANNEL_SNDBOARD_RIGHT) {
audio_state_sndboard(nr - AUDIO_CHANNEL_SNDBOARD_LEFT);
- } else {
- audio_state_cda(nr - AUDIO_CHANNEL_CDA_LEFT);
+ } else if (nr == AUDIO_CHANNEL_CDA_LEFT) {
+ audio_state_cda();
}
}
|| changed_prefs.sound_volume != currprefs.sound_volume
|| changed_prefs.sound_stereo_swap_paula != currprefs.sound_stereo_swap_paula
|| changed_prefs.sound_stereo_swap_ahi != currprefs.sound_stereo_swap_ahi
+ || changed_prefs.sound_cdaudio != currprefs.sound_cdaudio
|| changed_prefs.sound_filter != currprefs.sound_filter
|| changed_prefs.sound_filter_type != currprefs.sound_filter_type)
return -1;
currprefs.sound_filter = changed_prefs.sound_filter;
currprefs.sound_filter_type = changed_prefs.sound_filter_type;
currprefs.sound_volume = changed_prefs.sound_volume;
+ currprefs.sound_cdaudio = changed_prefs.sound_cdaudio;
currprefs.sound_stereo_swap_paula = changed_prefs.sound_stereo_swap_paula;
currprefs.sound_stereo_swap_ahi = changed_prefs.sound_stereo_swap_ahi;
{
if (!isaudio ())
return;
- if (audio_work_to_do > 0 && currprefs.sound_auto
+ if (audio_work_to_do > 0 && currprefs.sound_auto && !audio_extra_channels[0] && !audio_extra_channels[1]
#ifdef AVIOUTPUT
&& !avioutput_enabled
#endif
return dstbak;
}
+static void audio_set_extra_channels(void)
+{
+ audio_channel_count = audio_extra_channels[1] ? AUDIO_CHANNELS_PAULA + 4 : (audio_extra_channels[0] ? AUDIO_CHANNELS_PAULA + 2 : AUDIO_CHANNELS_PAULA);
+}
+
void audio_enable_sndboard(bool enable)
{
struct audio_channel_data *acd = audio_channel + AUDIO_CHANNEL_SNDBOARD_LEFT;
if (!enable) {
- audio_channel_count = AUDIO_CHANNELS_PAULA;
audio_extra_channels[0] = false;
acd[1].evtime = acd->evtime = MAX_EV;
} else {
- audio_channel_count = AUDIO_CHANNELS_PAULA + 2;
audio_extra_channels[0] = true;
acd[1].evtime = acd->evtime = CYCLE_UNIT;
}
+ audio_set_extra_channels();
}
void audio_enable_cda(bool enable)
{
struct audio_channel_data *acd = audio_channel + AUDIO_CHANNEL_CDA_LEFT;
if (!enable) {
- audio_channel_count = AUDIO_CHANNELS_PAULA;
audio_extra_channels[1] = false;
acd[1].evtime = acd->evtime = MAX_EV;
} else {
- audio_channel_count = AUDIO_CHANNELS_PAULA + 4;
audio_extra_channels[1] = true;
acd[1].evtime = acd->evtime = CYCLE_UNIT;
}
-
+ audio_set_extra_channels();
}
void audio_state_sndboard_state(int ch, int sample, unsigned int evt)
acd->evtime = evt;
}
-void audio_state_cda_state(int ch, int sample, unsigned int evt)
+static uae_s16 *cda_bufptr;
+static int cda_length, cda_userdata;
+static unsigned int cda_evt;
+static uae_s16 dummy_buffer[4] = { 0 };
+static CDA_CALLBACK cda_next_cd_audio_buffer_callback;
+static int cda_volume[2];
+
+void update_cda_sound(double clk)
{
- struct audio_channel_data *acd = audio_channel + AUDIO_CHANNEL_CDA_LEFT + ch;
- acd->last_sample = acd->current_sample;
- acd->current_sample = sample;
- acd->evtime = evt;
+ cda_evt = clk * CYCLE_UNIT / 44100;
+}
+
+void audio_cda_volume(int master, int left, int right)
+{
+ for (int j = 0; j < 2; j++) {
+ cda_volume[j] = j == 0 ? left : right;
+ cda_volume[j] = (100 - master) * cda_volume[j] / 100;
+ if (cda_volume[j])
+ cda_volume[j]++;
+ if (cda_volume[j] >= 32768)
+ cda_volume[j] = 32768;
+ }
+}
+
+void audio_cda_new_buffer(uae_s16 *buffer, int length, int userdata, CDA_CALLBACK next_cd_audio_buffer_callback)
+{
+ if (!buffer) {
+ cda_bufptr = dummy_buffer;
+ cda_length = 0;
+ } else {
+ cda_bufptr = buffer;
+ cda_length = length;
+ cda_userdata = userdata;
+ if (!audio_extra_channels[1])
+ audio_enable_cda(true);
+ }
+ 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_cda(false);
+ return;
+ }
+ struct audio_channel_data *acd = audio_channel + AUDIO_CHANNEL_CDA_LEFT;
+ acd->last_sample = acd->current_sample;
+ acd->current_sample = cda_bufptr[0] * cda_volume[0] / 32768;
+ acd->evtime = cda_evt;
+ acd++;
+ acd->last_sample = acd->current_sample;
+ acd->current_sample = cda_bufptr[1] * cda_volume[1] / 32768;
+ acd->evtime = 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);
+ }
+}
#include "cda_play.h"
#include "memory.h"
#include "audio.h"
+#include "uae.h"
#ifdef RETROPLATFORM
#include "rp.h"
#endif
static volatile int cdimage_unpack_thread, cdimage_unpack_active;
static smp_comm_pipe unpack_pipe;
+static uae_sem_t play_sem;
static struct cdunit *unitisopen (int unitnum)
{
// do this even if audio is not compressed, t->handle also could be
// compressed and we want to unpack it in background too
while (cdimage_unpack_active == 1)
- Sleep (10);
+ sleep_millis(10);
cdimage_unpack_active = 0;
write_comm_pipe_u32 (&unpack_pipe, cdu - &cdunits[0], 0);
write_comm_pipe_u32 (&unpack_pipe, t - &cdu->toc[0], 1);
while (cdimage_unpack_active == 0)
- Sleep (10);
+ sleep_millis(10);
}
-void audio_state_cda(int ch)
+static volatile int cda_bufon[2];
+static cda_audio *cda;
+
+void next_cd_audio_buffer_callback(int bufnum)
{
- audio_state_cda_state(ch, 0, 0);
+ uae_sem_wait(&play_sem);
+ if (bufnum >= 0) {
+ cda_bufon[bufnum] = 0;
+ bufnum = 1 - bufnum;
+ if (cda_bufon[bufnum])
+ audio_cda_new_buffer((uae_s16*)cda->buffers[bufnum], CDDA_BUFFERS * 2352 / 4, bufnum, next_cd_audio_buffer_callback);
+ else
+ bufnum = -1;
+ }
+ if (bufnum < 0) {
+ audio_cda_new_buffer(NULL, 0, -1, NULL);
+ }
+ uae_sem_post(&play_sem);
}
static void *cdda_play_func (void *v)
{
int cdda_pos;
- int num_sectors = CDDA_BUFFERS;
int bufnum;
- int bufon[2];
int oldplay;
int idleframes = 0;
int silentframes = 0;
bool foundsub;
struct cdunit *cdu = (struct cdunit*)v;
int oldtrack = -1;
+ int mode = currprefs.sound_cdaudio;
cdu->thread_active = true;
while (cdu->cdda_play == 0)
- Sleep (10);
+ sleep_millis(10);
oldplay = -1;
- bufon[0] = bufon[1] = 0;
+ cda_bufon[0] = cda_bufon[1] = 0;
bufnum = 0;
- cda_audio *cda = new cda_audio (num_sectors, 2352, 44100);
+ cda = new cda_audio (CDDA_BUFFERS, 2352, 44100);
while (cdu->cdda_play > 0) {
}
idleframes = cdu->cdda_delay_frames;
while (cdu->cdda_paused && cdu->cdda_play > 0) {
- Sleep (10);
+ sleep_millis(10);
idleframes = -1;
}
diff = (tb2.time * (uae_s64)1000 + tb2.millitm) - (tb1.time * (uae_s64)1000 + tb1.millitm);
diff -= cdu->cdda_delay;
if (idleframes >= 0 && diff < 0 && cdu->cdda_play > 0)
- Sleep (-diff);
+ sleep_millis(-diff);
setstate (cdu, AUDIO_STATUS_IN_PROGRESS);
sector = cdda_pos;
}
}
- cda->wait(bufnum);
- bufon[bufnum] = 0;
- if (!cdu->cdda_play)
+ if (mode) {
+ while (cda_bufon[bufnum] && cdu->cdda_play > 0)
+ sleep_millis(10);
+ } else {
+ cda->wait(bufnum);
+ }
+
+ cda_bufon[bufnum] = 0;
+ if (cdu->cdda_play <= 0)
goto end;
if (idleframes <= 0 && cdda_pos >= cdu->cdda_start && !isaudiotrack (&cdu->di.toc, cdda_pos)) {
gui_flicker_led (LED_CD, cdu->di.unitnum - 1, LED_CD_AUDIO);
- memset (cda->buffers[bufnum], 0, num_sectors * 2352);
+ memset (cda->buffers[bufnum], 0, CDDA_BUFFERS * 2352);
- for (cnt = 0; cnt < num_sectors && cdu->cdda_play > 0; cnt++) {
+ for (cnt = 0; cnt < CDDA_BUFFERS && cdu->cdda_play > 0; cnt++) {
uae_u8 *dst = cda->buffers[bufnum] + cnt * 2352;
uae_u8 subbuf[SUB_CHANNEL_SIZE];
sector = cdda_pos;
cdda_pos++;
}
- if (cdda_pos - num_sectors < cdu->cdda_end && cdda_pos >= cdu->cdda_end)
+ if (cdda_pos - CDDA_BUFFERS < cdu->cdda_end && cdda_pos >= cdu->cdda_end)
dofinish = 1;
}
if (idleframes <= 0)
cdu->cd_last_pos = cdda_pos;
- bufon[bufnum] = 1;
- cda->setvolume (currprefs.sound_volume_cd >= 0 ? currprefs.sound_volume_cd : currprefs.sound_volume, cdu->cdda_volume[0], cdu->cdda_volume[1]);
- if (!cda->play (bufnum)) {
- if (cdu->cdda_play > 0)
- setstate (cdu, AUDIO_STATUS_PLAY_ERROR);
- goto end;
+ if (mode) {
+ if (cda_bufon[0] == 0 && cda_bufon[1] == 0) {
+ cda_bufon[bufnum] = 1;
+ next_cd_audio_buffer_callback(1 - bufnum);
+ }
+ audio_cda_volume(currprefs.sound_volume_cd >= 0 ? currprefs.sound_volume_cd : currprefs.sound_volume, cdu->cdda_volume[0], cdu->cdda_volume[1]);
+ cda_bufon[bufnum] = 1;
+ } else {
+ cda_bufon[bufnum] = 1;
+ cda->setvolume (currprefs.sound_volume_cd >= 0 ? currprefs.sound_volume_cd : currprefs.sound_volume, cdu->cdda_volume[0], cdu->cdda_volume[1]);
+ if (!cda->play (bufnum)) {
+ if (cdu->cdda_play > 0)
+ setstate (cdu, AUDIO_STATUS_PLAY_ERROR);
+ goto end;
+ }
}
if (dofinish) {
}
- if (bufon[0] == 0 && bufon[1] == 0) {
+ if (cda_bufon[0] == 0 && cda_bufon[1] == 0) {
while (cdu->cdda_paused && cdu->cdda_play == oldplay)
- Sleep (10);
+ sleep_millis(10);
}
bufnum = 1 - bufnum;
}
end:
- cda->wait (0);
- cda->wait (1);
+ if (mode) {
+ next_cd_audio_buffer_callback(-1);
+ } else {
+ cda->wait (0);
+ cda->wait (1);
+ }
while (cdimage_unpack_active == 1)
- Sleep (10);
+ sleep_millis(10);
delete cda;
if (cdu->cdda_play != 0) {
cdu->cdda_play = -1;
while (cdu->cdda_play && cdu->thread_active) {
- Sleep (10);
+ sleep_millis(10);
}
cdu->cdda_play = 0;
}
cdu->enabled = false;
}
bus_open = 0;
+ uae_sem_destroy(&play_sem);
write_log (_T("IMAGE driver closed.\n"));
}
return 1;
}
bus_open = 1;
+ uae_sem_init(&play_sem, 0, 1);
write_log (_T("Image driver open.\n"));
return 1;
}
#include "uae.h"
#include "debug.h"
#include "custom.h"
+#include "audio.h"
+#include "threaddep/thread.h"
#include "cda_play.h"
#include "archivers/mp2/kjmp2.h"
static int cl450_buffer_offset;
static int cl450_buffer_empty_cnt;
static int libmpeg_offset;
+static bool audio_mode;
+static uae_sem_t play_sem;
+static volatile bool fmv_bufon[2];
+static double fmv_syncadjust;
struct cl450_videoram
{
if (!pcmaudio)
return;
write_log(_T("L64111 mute %d\n"), volume ? 0 : 1);
- if (cda)
- cda->setvolume(currprefs.sound_volume_cd >= 0 ? currprefs.sound_volume_cd : currprefs.sound_volume, volume, volume);
+ if (cda) {
+ if (audio_mode) {
+ audio_cda_volume(currprefs.sound_volume_cd >= 0 ? currprefs.sound_volume_cd : currprefs.sound_volume, volume, volume);
+ } else {
+ cda->setvolume(currprefs.sound_volume_cd >= 0 ? currprefs.sound_volume_cd : currprefs.sound_volume, volume, volume);
+ }
+ }
}
static int l64111_get_frame(uae_u8 *data, int remaining)
{
case CL_Play:
cl450_play = 1;
+ audio_mode = currprefs.sound_cdaudio;
write_log(_T("CL450 PLAY\n"));
break;
case CL_Pause:
case CL_Reset:
write_log(_T("CL450 Reset\n"));
cl450_reset_cmd();
+ audio_mode = currprefs.sound_cdaudio;
break;
case CL_FlushBitStream:
write_log(_T("CL450 CL_FlushBitStream\n"));
static double max_sync_vpos;
static double remaining_sync_vpos;
-void cd32_fmv_set_sync(double svpos)
+void cd32_fmv_set_sync(double svpos, double adjust)
{
- max_sync_vpos = svpos;
+ max_sync_vpos = svpos / adjust;
+ fmv_syncadjust = adjust;
}
-void cd32_fmv_hsync_handler(void)
+void fmv_next_cd_audio_buffer_callback(int bufnum)
{
- if (!fmv_ram_bank.baseaddr)
- return;
-
- if (cl450_play > 0)
- cl450_scr += 90000.0 / hblank_hz;
-
- if (cl450_video_hsync_wait > 0)
- cl450_video_hsync_wait--;
- if (cl450_video_hsync_wait == 0) {
- cl450_set_status(CL_INT_PIC_D);
- if (cl450_videoram_cnt > 0) {
- cd32_fmv_new_image(videoram[cl450_videoram_read].width, videoram[cl450_videoram_read].height,
- videoram[cl450_videoram_read].depth, cl450_blank ? NULL : videoram[cl450_videoram_read].data);
- cl450_videoram_read++;
- cl450_videoram_read &= CL450_VIDEO_BUFFERS - 1;
- cl450_videoram_cnt--;
- }
- cl450_video_hsync_wait = max_sync_vpos;
- while (remaining_sync_vpos >= 1.0) {
- cl450_video_hsync_wait++;
- remaining_sync_vpos -= 1.0;
- }
- remaining_sync_vpos += max_sync_vpos - cl450_video_hsync_wait;
- if (cl450_frame_rate < 40)
- cl450_video_hsync_wait *= 2;
+ uae_sem_wait(&play_sem);
+ if (bufnum >= 0) {
+ fmv_bufon[bufnum] = 0;
+ bufnum = 1 - bufnum;
+ if (fmv_bufon[bufnum])
+ audio_cda_new_buffer((uae_s16*)cda->buffers[bufnum], PCM_SECTORS * KJMP2_SAMPLES_PER_FRAME, bufnum, fmv_next_cd_audio_buffer_callback);
+ else
+ bufnum = -1;
}
-
- if (vpos & 7)
- return;
-
- if (cl450_play > 0) {
- if (cl450_newpacket_mode && cl450_buffer_offset < cl450_threshold) {
- int newpacket_len = 0;
- for (int i = 0; i < CL450_NEWPACKET_BUFFER_SIZE; i++)
- newpacket_len += cl450_newpacket_buffer[i].length;
- if (cl450_buffer_offset >= newpacket_len - 6)
- cl450_set_status(CL_INT_RDY);
- }
-
- if (cl450_buffer_offset >= 512 && cl450_videoram_cnt < CL450_VIDEO_BUFFERS - 1) {
- cl450_parse_frame();
- }
+ if (bufnum < 0) {
+ audio_cda_new_buffer(NULL, 0, -1, NULL);
}
+ uae_sem_post(&play_sem);
}
void cd32_fmv_vsync_handler(void)
+{
+}
+
+static void cd32_fmv_audio_handler(void)
{
int bufnum;
int offset, needsectors;
cl450_buffer_empty_cnt = 0;
}
-
if (!cda || !(l64111_regs[A_CONTROL1] & 1))
return;
- play0 = cda->isplaying(0);
- play1 = cda->isplaying(1);
+ if (audio_mode) {
+ play0 = fmv_bufon[0];
+ play1 = fmv_bufon[1];
+ } else {
+ play0 = cda->isplaying(0);
+ play1 = cda->isplaying(1);
+ }
needsectors = PCM_SECTORS;
if (!play0 && !play1) {
needsectors *= 2;
memcpy(cda->buffers[bufnum] + i * KJMP2_SAMPLES_PER_FRAME * 4, pcmaudio[offset2].pcm, KJMP2_SAMPLES_PER_FRAME * 4);
pcmaudio[offset2].ready = false;
}
- cda->play(bufnum);
+ if (audio_mode) {
+ if (!play0 && !play1) {
+ fmv_bufon[bufnum] = 1;
+ fmv_next_cd_audio_buffer_callback(1 - bufnum);
+ }
+ fmv_bufon[bufnum] = 1;
+ } else {
+ cda->play(bufnum);
+ }
offset += PCM_SECTORS;
offset &= l64111_cb_mask;
l64111_regs[A_CB_READ] = offset;
l64111_regs[A_CB_STATUS] -= PCM_SECTORS;
}
+void cd32_fmv_hsync_handler(void)
+{
+ if (!fmv_ram_bank.baseaddr)
+ return;
+
+ if (cl450_play > 0)
+ cl450_scr += 90000.0 / (hblank_hz / fmv_syncadjust);
+
+ if (cl450_video_hsync_wait > 0)
+ cl450_video_hsync_wait--;
+ if (cl450_video_hsync_wait == 0) {
+ cl450_set_status(CL_INT_PIC_D);
+ if (cl450_videoram_cnt > 0) {
+ cd32_fmv_new_image(videoram[cl450_videoram_read].width, videoram[cl450_videoram_read].height,
+ videoram[cl450_videoram_read].depth, cl450_blank ? NULL : videoram[cl450_videoram_read].data);
+ cl450_videoram_read++;
+ cl450_videoram_read &= CL450_VIDEO_BUFFERS - 1;
+ cl450_videoram_cnt--;
+ }
+ cl450_video_hsync_wait = max_sync_vpos;
+ while (remaining_sync_vpos >= 1.0) {
+ cl450_video_hsync_wait++;
+ remaining_sync_vpos -= 1.0;
+ }
+ remaining_sync_vpos += max_sync_vpos - cl450_video_hsync_wait;
+ if (cl450_frame_rate < 40)
+ cl450_video_hsync_wait *= 2;
+ }
+
+ if ((vpos & 63) == 0)
+ cd32_fmv_audio_handler();
+
+ if (vpos & 7)
+ return;
+
+ if (cl450_play > 0) {
+ if (cl450_newpacket_mode && cl450_buffer_offset < cl450_threshold) {
+ int newpacket_len = 0;
+ for (int i = 0; i < CL450_NEWPACKET_BUFFER_SIZE; i++)
+ newpacket_len += cl450_newpacket_buffer[i].length;
+ if (cl450_buffer_offset >= newpacket_len - 6)
+ cl450_set_status(CL_INT_RDY);
+ }
+
+ if (cl450_buffer_offset >= 512 && cl450_videoram_cnt < CL450_VIDEO_BUFFERS - 1) {
+ cl450_parse_frame();
+ }
+ }
+}
+
+
void cd32_fmv_reset(void)
{
if (fmv_ram_bank.baseaddr)
xfree(videoram);
videoram = NULL;
if (cda) {
- cda->wait(0);
- cda->wait(1);
+ if (audio_mode) {
+ fmv_next_cd_audio_buffer_callback(-1);
+ } else {
+ cda->wait(0);
+ cda->wait(1);
+ }
delete cda;
}
cda = NULL;
+ uae_sem_destroy(&play_sem);
xfree(pcmaudio);
pcmaudio = NULL;
if (mpeg_decoder)
map_banks(&fmv_rom_bank, (fmv_start + ROM_BASE) >> 16, fmv_rom_size >> 16, 0);
map_banks(&fmv_ram_bank, (fmv_start + RAM_BASE) >> 16, fmv_ram_size >> 16, 0);
map_banks(&fmv_bank, (fmv_start + IO_BASE) >> 16, (RAM_BASE - IO_BASE) >> 16, 0);
+ uae_sem_init(&play_sem, 0, 1);
cd32_fmv_reset();
return &fmv_rom_bank;
}
{
double svpos = maxvpos_nom;
double shpos = maxhpos_short;
+ double syncadjust = 1.0;
fake_vblank_hz = 0;
vblank_hz_mult = 0;
vblank_hz_state = 1;
if (fabs (currprefs.chipset_refreshrate) > 0.1) {
+ syncadjust = currprefs.chipset_refreshrate / vblank_hz_nom;
vblank_hz = currprefs.chipset_refreshrate;
if (isvsync_chipset ()) {
int mult = 0;
double clk = svpos * shpos * fake_vblank_hz;
//write_log (_T("SNDRATE %.1f*%.1f*%.6f=%.6f\n"), svpos, shpos, fake_vblank_hz, clk);
update_sound (clk);
- update_sndboard_sound (clk);
+ update_sndboard_sound (clk / syncadjust);
+ update_cda_sound(clk / syncadjust);
}
- cd32_fmv_set_sync(svpos);
+ cd32_fmv_set_sync(svpos, syncadjust);
}
extern void audio_hsync (void);
extern void audio_update_adkmasks (void);
extern void update_sound (double clk);
+extern void update_cda_sound (double clk);
extern void led_filter_audio (void);
extern void set_audio (void);
extern int audio_activate (void);
extern void audio_state_sndboard(int);
extern void audio_state_sndboard_state(int, int, unsigned int);
-extern void audio_update_cda(unsigned int);
-extern void audio_enable_cda(bool);
-extern void audio_state_cda(int);
-extern void audio_state_cda_state(int, int, unsigned int);
+typedef void (*CDA_CALLBACK)(int);
+extern void audio_cda_new_buffer(uae_s16 *buffer, int length, int userdata, CDA_CALLBACK next_cd_audio_buffer_callback);
+extern void audio_cda_volume(int master, int left, int right);
#define AUDIO_CHANNELS_PAULA 4
#define AUDIO_CHANNELS_MAX 8
extern void cd32_fmv_new_image(int, int, int, uae_u8*);
extern void cd32_fmv_genlock(struct vidbuffer*, struct vidbuffer*);
extern void cd32_fmv_new_border_color(uae_u32);
-extern void cd32_fmv_set_sync(double svpos);
+extern void cd32_fmv_set_sync(double svpos, double adjust);
extern int cd32_fmv_active;
/* sample_evtime is in normal Amiga cycles; scaled_sample_evtime is in our
event cycles. */
extern float scaled_sample_evtime;
+extern float scaled_sample_evtime_orig;
/* Determine if we can produce any sound at all. This can be only a guess;
* if unsure, say yes. Any call to init_sound may change the value. */
#include "scsidev.h"
#include "gui.h"
#include "win32.h"
+#include "audio.h"
#include <devioctl.h>
#include <ntddcdrm.h>
static struct dev_info_ioctl ciw32[MAX_TOTAL_SCSI_DEVICES];
static int unittable[MAX_TOTAL_SCSI_DEVICES];
static int bus_open;
+static uae_sem_t play_sem;
static void seterrormode (struct dev_info_ioctl *ciw)
{
return 0;
}
+static cda_audio *cda;
+static volatile int cda_bufon[2];
+
+void ioctl_next_cd_audio_buffer_callback(int bufnum)
+{
+ uae_sem_wait(&play_sem);
+ if (bufnum >= 0) {
+ cda_bufon[bufnum] = 0;
+ bufnum = 1 - bufnum;
+ if (cda_bufon[bufnum])
+ audio_cda_new_buffer((uae_s16*)cda->buffers[bufnum], CDDA_BUFFERS * 2352 / 4, bufnum, ioctl_next_cd_audio_buffer_callback);
+ else
+ bufnum = -1;
+ }
+ if (bufnum < 0) {
+ audio_cda_new_buffer(NULL, 0, -1, NULL);
+ }
+ uae_sem_post(&play_sem);
+}
+
static void *cdda_play (void *v)
{
struct dev_info_ioctl *ciw = (struct dev_info_ioctl*)v;
int cdda_pos;
- int num_sectors = CDDA_BUFFERS;
int bufnum;
int buffered;
- int bufon[2];
int i;
int oldplay;
int idleframes;
int muteframes;
int readblocksize = 2352 + 96;
+ int mode = currprefs.sound_cdaudio;
while (ciw->cdda_play == 0)
- Sleep (10);
+ sleep_millis(10);
oldplay = -1;
- bufon[0] = bufon[1] = 0;
+ cda_bufon[0] = cda_bufon[1] = 0;
bufnum = 0;
buffered = 0;
- cda_audio *cda = new cda_audio (num_sectors, 2352, 44100);
+ cda = new cda_audio (CDDA_BUFFERS, 2352, 44100);
while (ciw->cdda_play > 0) {
- cda->wait(bufnum);
+ if (mode) {
+ while (cda_bufon[bufnum] && ciw->cdda_play > 0)
+ sleep_millis(10);
+ } else {
+ cda->wait(bufnum);
+ }
if (ciw->cdda_play <= 0)
goto end;
- bufon[bufnum] = 0;
+ cda_bufon[bufnum] = 0;
if (oldplay != ciw->cdda_play) {
idleframes = 0;
ciw->subcodevalid = false;
idleframes = ciw->cdda_delay_frames;
while (ciw->cdda_paused && ciw->cdda_play > 0) {
- Sleep (10);
+ sleep_millis(10);
idleframes = -1;
}
// force spin up
if (isaudiotrack (&ciw->di.toc, cdda_pos))
- read_block (ciw, -1, cda->buffers[bufnum], cdda_pos, num_sectors, readblocksize);
+ read_block (ciw, -1, cda->buffers[bufnum], cdda_pos, CDDA_BUFFERS, readblocksize);
if (!isaudiotrack (&ciw->di.toc, cdda_pos - 150))
muteframes = 75;
int diff = (tb2.time * (uae_s64)1000 + tb2.millitm) - (tb1.time * (uae_s64)1000 + tb1.millitm);
diff -= ciw->cdda_delay;
if (idleframes >= 0 && diff < 0 && ciw->cdda_play > 0)
- Sleep (-diff);
+ sleep_millis(-diff);
if (diff > 0 && !seensub) {
int ch = diff / 7 + 25;
if (ch > idleframes)
ciw->subcodevalid = false;
memset (ciw->subcode, 0, sizeof ciw->subcode);
- memset (cda->buffers[bufnum], 0, num_sectors * readblocksize);
+ memset (cda->buffers[bufnum], 0, CDDA_BUFFERS * readblocksize);
if (cdda_pos >= 0) {
- if (read_block (ciw, -1, cda->buffers[bufnum], cdda_pos, num_sectors, readblocksize)) {
- for (i = 0; i < num_sectors; i++) {
+ if (read_block (ciw, -1, cda->buffers[bufnum], cdda_pos, CDDA_BUFFERS, readblocksize)) {
+ for (i = 0; i < CDDA_BUFFERS; i++) {
memcpy (ciw->subcode + i * SUB_CHANNEL_SIZE, cda->buffers[bufnum] + readblocksize * i + 2352, SUB_CHANNEL_SIZE);
}
- for (i = 1; i < num_sectors; i++) {
+ for (i = 1; i < CDDA_BUFFERS; i++) {
memmove (cda->buffers[bufnum] + 2352 * i, cda->buffers[bufnum] + readblocksize * i, 2352);
}
ciw->subcodevalid = true;
}
}
- for (i = 0; i < num_sectors; i++) {
+ for (i = 0; i < CDDA_BUFFERS; i++) {
if (muteframes > 0) {
memset (cda->buffers[bufnum] + 2352 * i, 0, 2352);
muteframes--;
ciw->subcodevalid = false;
if (ciw->cdda_subfunc)
- ciw->cdda_subfunc (ciw->subcode, num_sectors);
+ ciw->cdda_subfunc (ciw->subcode, CDDA_BUFFERS);
uae_sem_post (&ciw->sub_sem);
if (ciw->subcodevalid) {
uae_sem_wait (&ciw->sub_sem2);
- memcpy (ciw->subcodebuf, ciw->subcode + (num_sectors - 1) * SUB_CHANNEL_SIZE, SUB_CHANNEL_SIZE);
+ memcpy (ciw->subcodebuf, ciw->subcode + (CDDA_BUFFERS - 1) * SUB_CHANNEL_SIZE, SUB_CHANNEL_SIZE);
uae_sem_post (&ciw->sub_sem2);
}
- bufon[bufnum] = 1;
- cda->setvolume (currprefs.sound_volume_cd >= 0 ? currprefs.sound_volume_cd : currprefs.sound_volume, ciw->cdda_volume[0], ciw->cdda_volume[1]);
- if (!cda->play (bufnum)) {
- setstate (ciw, AUDIO_STATUS_PLAY_ERROR);
- goto end; // data track?
+ if (mode) {
+ if (cda_bufon[0] == 0 && cda_bufon[1] == 0) {
+ cda_bufon[bufnum] = 1;
+ ioctl_next_cd_audio_buffer_callback(1 - bufnum);
+ }
+ audio_cda_volume(currprefs.sound_volume_cd >= 0 ? currprefs.sound_volume_cd : currprefs.sound_volume, ciw->cdda_volume[0], ciw->cdda_volume[1]);
+ cda_bufon[bufnum] = 1;
+ } else {
+ cda_bufon[bufnum] = 1;
+ cda->setvolume (currprefs.sound_volume_cd >= 0 ? currprefs.sound_volume_cd : currprefs.sound_volume, ciw->cdda_volume[0], ciw->cdda_volume[1]);
+ if (!cda->play (bufnum)) {
+ setstate (ciw, AUDIO_STATUS_PLAY_ERROR);
+ goto end; // data track?
+ }
}
if (ciw->cdda_scan) {
- cdda_pos += ciw->cdda_scan * num_sectors;
+ cdda_pos += ciw->cdda_scan * CDDA_BUFFERS;
if (cdda_pos < 0)
cdda_pos = 0;
} else {
- if (cdda_pos < 0 && cdda_pos + num_sectors >= 0)
+ if (cdda_pos < 0 && cdda_pos + CDDA_BUFFERS >= 0)
cdda_pos = 0;
else
- cdda_pos += num_sectors;
+ cdda_pos += CDDA_BUFFERS;
}
if (idleframes <= 0) {
- if (cdda_pos - num_sectors < ciw->cdda_end && cdda_pos >= ciw->cdda_end) {
+ if (cdda_pos - CDDA_BUFFERS < ciw->cdda_end && cdda_pos >= ciw->cdda_end) {
setstate (ciw, AUDIO_STATUS_PLAY_COMPLETE);
ciw->cdda_play_finished = 1;
ciw->cdda_play = -1;
}
while (ciw->cdda_paused && ciw->cdda_play == oldplay)
- Sleep (10);
+ sleep_millis(10);
bufnum = 1 - bufnum;
}
end:
+
+ if (mode) {
+ ioctl_next_cd_audio_buffer_callback(-1);
+ } else {
+ cda->wait (0);
+ cda->wait (1);
+ }
+
ciw->subcodevalid = false;
delete cda;
if (ciw->cdda_play != 0) {
ciw->cdda_play = -1;
while (ciw->cdda_play) {
- Sleep (10);
+ sleep_millis(10);
}
}
ciw->cdda_play_finished = 0;
unittable[i] = 0;
}
bus_open = 0;
+ uae_sem_destroy(&play_sem);
write_log (_T("IOCTL driver closed.\n"));
}
dwDriveMask >>= 1;
}
bus_open = 1;
+ uae_sem_init(&play_sem, 0, 1);
write_log (_T("IOCTL driver open, %d devices.\n"), total_devices);
return total_devices;
}
}
#define PUT_SOUND_WORD(b) do { *(uae_u16 *)paula_sndbufpt = b; paula_sndbufpt = (uae_u16 *)(((uae_u8 *)paula_sndbufpt) + 2); } while (0)
-#define PUT_SOUND_WORD_LEFT(b) do { if (currprefs.sound_filter) b = filter (b, &sound_filter_state[0]); PUT_SOUND_WORD(b); } while (0)
-#define PUT_SOUND_WORD_RIGHT(b) do { if (currprefs.sound_filter) b = filter (b, &sound_filter_state[1]); PUT_SOUND_WORD(b); } while (0)
-#define PUT_SOUND_WORD_LEFT2(b) do { if (currprefs.sound_filter) b = filter (b, &sound_filter_state[2]); PUT_SOUND_WORD(b); } while (0)
-#define PUT_SOUND_WORD_RIGHT2(b) do { if (currprefs.sound_filter) b = filter (b, &sound_filter_state[3]); PUT_SOUND_WORD(b); } while (0)
-
-#define PUT_SOUND_WORD_MONO(b) PUT_SOUND_WORD_LEFT(b)
+#define PUT_SOUND_WORD_MONO(b) PUT_SOUND_WORD(b)
#define SOUND16_BASE_VAL 0
#define SOUND8_BASE_VAL 128