static gboolean vtx_play(InputPlayback * playback, const gchar * filename, VFSFile * file, gint start_time, gint stop_time, gboolean pause) { gboolean error = FALSE; gboolean eof = FALSE; void *stream; /* pointer to current position in sound buffer */ guchar regs[14]; gint need; gint left; /* how many sound frames can play with current AY register frame */ gint donow; gint rate; left = 0; rate = chans * (bits / 8); memset(&ay, 0, sizeof(ay)); if (!ayemu_vtx_open(&vtx, filename)) { g_print("libvtx: Error read vtx header from %s\n", filename); error = TRUE; goto ERR_NO_CLOSE; } else if (!ayemu_vtx_load_data(&vtx)) { g_print("libvtx: Error read vtx data from %s\n", filename); error = TRUE; goto ERR_NO_CLOSE; } ayemu_init(&ay); ayemu_set_chip_type(&ay, vtx.hdr.chiptype, NULL); ayemu_set_chip_freq(&ay, vtx.hdr.chipFreq); ayemu_set_stereo(&ay, vtx.hdr.stereo, NULL); if (playback->output->open_audio(FMT_S16_NE, freq, chans) == 0) { g_print("libvtx: output audio error!\n"); error = TRUE; goto ERR_NO_CLOSE; } if (pause) playback->output->pause (TRUE); stop_flag = FALSE; playback->set_params(playback, 14 * 50 * 8, freq, bits / 8); playback->set_pb_ready(playback); while (!stop_flag) { g_mutex_lock(seek_mutex); if (seek_value >= 0) { vtx.pos = seek_value * 50 / 1000; /* (time in sec) * 50 = offset in AY register data frames */ playback->output->flush(seek_value); seek_value = -1; g_cond_signal(seek_cond); } g_mutex_unlock(seek_mutex); /* fill sound buffer */ stream = sndbuf; for (need = SNDBUFSIZE / rate; need > 0; need -= donow) if (left > 0) { /* use current AY register frame */ donow = (need > left) ? left : need; left -= donow; stream = ayemu_gen_sound(&ay, (char *)stream, donow * rate); } else { /* get next AY register frame */ if (ayemu_vtx_get_next_frame(&vtx, (char *)regs) == 0) { donow = need; memset(stream, 0, donow * rate); eof = TRUE; } else { left = freq / vtx.hdr.playerFreq; ayemu_set_regs(&ay, regs); donow = 0; } } if (!stop_flag) playback->output->write_audio(sndbuf, SNDBUFSIZE); if (eof) { AUDDBG("EOF.\n"); while (!stop_flag && playback->output->buffer_playing()) g_usleep(10000); goto CLEANUP; } } CLEANUP: ayemu_vtx_free(&vtx); g_mutex_lock(seek_mutex); stop_flag = TRUE; g_cond_signal(seek_cond); /* wake up any waiting request */ g_mutex_unlock(seek_mutex); playback->output->close_audio(); ERR_NO_CLOSE: return !error; }
static gboolean vtx_play(const gchar * filename, VFSFile * file) { gboolean eof = FALSE; void *stream; /* pointer to current position in sound buffer */ guchar regs[14]; gint need; gint left; /* how many sound frames can play with current AY register frame */ gint donow; gint rate; left = 0; rate = chans * (bits / 8); memset(&ay, 0, sizeof(ay)); if (!ayemu_vtx_open(&vtx, filename)) { g_print("libvtx: Error read vtx header from %s\n", filename); return FALSE; } else if (!ayemu_vtx_load_data(&vtx)) { g_print("libvtx: Error read vtx data from %s\n", filename); return FALSE; } ayemu_init(&ay); ayemu_set_chip_type(&ay, vtx.hdr.chiptype, NULL); ayemu_set_chip_freq(&ay, vtx.hdr.chipFreq); ayemu_set_stereo(&ay, vtx.hdr.stereo, NULL); if (aud_input_open_audio(FMT_S16_NE, freq, chans) == 0) { g_print("libvtx: output audio error!\n"); return FALSE; } aud_input_set_bitrate(14 * 50 * 8); while (!aud_input_check_stop() && !eof) { /* (time in sec) * 50 = offset in AY register data frames */ int seek_value = aud_input_check_seek(); if (seek_value >= 0) vtx.pos = seek_value / 20; /* fill sound buffer */ stream = sndbuf; for (need = SNDBUFSIZE / rate; need > 0; need -= donow) { if (left > 0) { /* use current AY register frame */ donow = (need > left) ? left : need; left -= donow; stream = ayemu_gen_sound(&ay, (char *)stream, donow * rate); } else { /* get next AY register frame */ if (ayemu_vtx_get_next_frame(&vtx, (char *)regs) == 0) { donow = need; memset(stream, 0, donow * rate); eof = TRUE; } else { left = freq / vtx.hdr.playerFreq; ayemu_set_regs(&ay, regs); donow = 0; } } } aud_input_write_audio(sndbuf, SNDBUFSIZE); } ayemu_vtx_free(&vtx); return TRUE; }