#define PERIOD_MIN_NONCE 60
int audio_channel_mask = 15;
+volatile bool cd_audio_mode_changed;
STATIC_INLINE bool isaudio (void)
{
events_schedule ();
}
set_config_changed ();
+ cd_audio_mode_changed = true;
}
void update_audio (void)
void audio_cda_new_buffer(uae_s16 *buffer, int length, int userdata, CDA_CALLBACK next_cd_audio_buffer_callback)
{
+ if (length < 0 && cda_streamid > 0) {
+ audio_enable_stream(false, cda_streamid, 0, NULL);
+ cda_streamid = 0;
+ return;
+ }
if (!buffer) {
cda_bufptr = dummy_buffer;
cda_length = 0;
uae_sem_post(&play_sem);
}
-static void *cdda_play_func (void *v)
+static bool cdda_play_func2 (struct cdunit *cdu, int *outpos)
{
int cdda_pos;
int bufnum;
int idleframes = 0;
int silentframes = 0;
bool foundsub;
- struct cdunit *cdu = (struct cdunit*)v;
int oldtrack = -1;
int mode = currprefs.sound_cdaudio;
+ bool restart = false;
cdu->thread_active = true;
}
cdda_pos -= idleframes;
- _ftime (&tb2);
- 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_millis(-diff);
- setstate (cdu, AUDIO_STATUS_IN_PROGRESS, cdda_pos);
+ if (*outpos < 0) {
+ _ftime (&tb2);
+ 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_millis(-diff);
+ setstate (cdu, AUDIO_STATUS_IN_PROGRESS, cdda_pos);
+ }
sector = cdda_pos;
struct cdtoc *t1 = findtoc (cdu, §or, false);
}
if (mode) {
- while (cda_bufon[bufnum] && cdu->cdda_play > 0)
+ while (cda_bufon[bufnum] && cdu->cdda_play > 0) {
+ if (cd_audio_mode_changed) {
+ restart = true;
+ goto end;
+ }
sleep_millis(10);
+ }
} else {
cda->wait(bufnum);
}
sleep_millis(10);
}
+ if (cd_audio_mode_changed) {
+ restart = true;
+ goto end;
+ }
+
bufnum = 1 - bufnum;
}
end:
+ *outpos = cdda_pos;
if (mode) {
next_cd_audio_buffer_callback(-1);
+ if (restart)
+ audio_cda_new_buffer(NULL, -1, -1, NULL);
} else {
cda->wait (0);
cda->wait (1);
delete cda;
- cdu->cdda_play = 0;
- write_log (_T("IMAGE CDDA: thread killed\n"));
+ write_log (_T("IMAGE CDDA: thread killed (%s)\n"), restart ? _T("restart") : _T("play end"));
+ cd_audio_mode_changed = false;
+ return restart;
+}
+
+static void *cdda_play_func (void *v)
+{
+ int outpos = -1;
+ struct cdunit *cdu = (struct cdunit*)v;
+ cd_audio_mode_changed = false;
+ for (;;) {
+ if (!cdda_play_func2(cdu, &outpos)) {
+ cdu->cdda_play = 0;
+ break;
+ }
+ cdu->cdda_start = outpos;
+ if (cdu->cdda_start + 150 >= cdu->cdda_end) {
+ if (cdu->cdda_play >= 0)
+ setstate (cdu, AUDIO_STATUS_PLAY_COMPLETE, cdu->cdda_end + 1);
+ cdu->cdda_play = -1;
+ break;
+ }
+ cdu->cdda_play = 1;
+ }
cdu->thread_active = false;
return NULL;
}
-
static void cdda_stop (struct cdunit *cdu)
{
if (cdu->cdda_play != 0) {
if (!fmv_ram_bank.baseaddr)
return;
+ if (cd_audio_mode_changed) {
+ cd_audio_mode_changed = false;
+ if (cl450_play) {
+ if (audio_mode) {
+ audio_cda_new_buffer(NULL, -1, -1, NULL);
+ }
+ audio_mode = currprefs.sound_cdaudio;
+ fmv_bufon[0] = fmv_bufon[1] = 0;
+ }
+ }
+
if (cl450_buffer_offset == 0) {
if (cl450_buffer_empty_cnt >= 2)
cl450_set_status(CL_INT_UND);
uae_sem_post(&play_sem);
}
-static void *cdda_play (void *v)
+static bool cdda_play2 (struct dev_info_ioctl *ciw, int *outpos)
{
- struct dev_info_ioctl *ciw = (struct dev_info_ioctl*)v;
int cdda_pos;
int bufnum;
int buffered;
int muteframes;
int readblocksize = 2352 + 96;
int mode = currprefs.sound_cdaudio;
+ bool restart = false;
while (ciw->cdda_play == 0)
sleep_millis(10);
}
cdda_pos -= idleframes;
- _ftime (&tb2);
- 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_millis(-diff);
- if (diff > 0 && !seensub) {
- int ch = diff / 7 + 25;
- if (ch > idleframes)
- ch = idleframes;
- idleframes -= ch;
- cdda_pos += ch;
+ if (*outpos < 0) {
+ _ftime (&tb2);
+ 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_millis(-diff);
+ if (diff > 0 && !seensub) {
+ int ch = diff / 7 + 25;
+ if (ch > idleframes)
+ ch = idleframes;
+ idleframes -= ch;
+ cdda_pos += ch;
+ }
+ setstate (ciw, AUDIO_STATUS_IN_PROGRESS, cdda_pos);
}
-
- setstate (ciw, AUDIO_STATUS_IN_PROGRESS, cdda_pos);
}
if ((cdda_pos < ciw->cdda_end || ciw->cdda_end == 0xffffffff) && !ciw->cdda_paused && ciw->cdda_play) {
while (ciw->cdda_paused && ciw->cdda_play == oldplay)
sleep_millis(10);
+ if (cd_audio_mode_changed) {
+ restart = true;
+ goto end;
+ }
+
bufnum = 1 - bufnum;
}
if (mode) {
ioctl_next_cd_audio_buffer_callback(-1);
+ if (restart)
+ audio_cda_new_buffer(NULL, -1, -1, NULL);
} else {
cda->wait (0);
cda->wait (1);
}
ciw->subcodevalid = false;
+ cd_audio_mode_changed = false;
delete cda;
- ciw->cdda_play = 0;
write_log (_T("IOCTL CDDA: thread killed\n"));
+ return restart;
+}
+
+static void *cdda_play (void *v)
+{
+ int outpos = -1;
+ struct dev_info_ioctl *ciw = (struct dev_info_ioctl*)v;
+ cd_audio_mode_changed = false;
+ for (;;) {
+ if (!cdda_play2(ciw, &outpos)) {
+ break;
+ }
+ ciw->cdda_start = outpos;
+ if (ciw->cdda_start + 150 >= ciw->cdda_end) {
+ if (ciw->cdda_play >= 0)
+ setstate (ciw, AUDIO_STATUS_PLAY_COMPLETE, ciw->cdda_end + 1);
+ ciw->cdda_play = -1;
+ break;
+ }
+ ciw->cdda_play = 1;
+ }
+ ciw->cdda_play = 0;
return NULL;
}
#include <dsound.h>
#endif
+extern volatile bool cd_audio_mode_changed;
+
class cda_audio
{
private: