static int vtx_read (DB_fileinfo_t *_info, char *bytes, int size) { // try decode `size' bytes // return number of decoded bytes // return 0 on EOF vtx_info_t *info = (vtx_info_t *)_info; int initsize = size; int donow = 0; while (size > 0) { if (info->left > 0) { donow = (size > info->left) ? info->left : size; info->left -= donow; bytes = ayemu_gen_sound (&info->ay, (char *)bytes, donow); size -= donow; } else { if ((ayemu_vtx_get_next_frame (info) == 0)) { break; // eof } else { // number of samples it current frame info->left = _info->fmt.samplerate / info->decoder->playerFreq; // mul by rate to get number of bytes; info->left *= info->rate; ayemu_set_regs (&info->ay, info->regs); donow = 0; } } } info->currentsample += (initsize - size) / 4; _info->readpos = (float)info->currentsample / _info->fmt.samplerate; return initsize - size; }
void play (const char *filename) { ayemu_vtx_t *vtx; int len; vtx = ayemu_vtx_load_from_file(filename); if (!vtx) return; if (!qflag) printf(" Title: %s\n Author: %s\n From: %s\n Comment: %s\n Year: %d\n", vtx->title, vtx->author, vtx->from, vtx->comment, vtx->year); int audio_bufsize = freq * chans * (bits >> 3) / vtx->playerFreq; if ((audio_buf = malloc (audio_bufsize)) == NULL) { fprintf (stderr, "Can't allocate sound buffer\n"); goto free_vtx; } ayemu_reset(&ay); ayemu_set_chip_type(&ay, vtx->chiptype, NULL); ayemu_set_chip_freq(&ay, vtx->chipFreq); ayemu_set_stereo(&ay, vtx->stereo, NULL); size_t pos = 0; while (pos++ < vtx->frames) { ayemu_vtx_getframe (vtx, pos, regs); ayemu_set_regs (&ay, regs); ayemu_gen_sound (&ay, audio_buf, audio_bufsize); if ((len = write(audio_fd, audio_buf, audio_bufsize)) == -1) { fprintf (stderr, "Error writting to sound device, break.\n"); break; } } free_vtx: ayemu_vtx_free(vtx); }
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; }