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 int vtx_init (DB_fileinfo_t *_info, DB_playItem_t *it) { // prepare to decode the track // return -1 on failure vtx_info_t *info = (vtx_info_t *)_info; size_t sz = 0; char *buf = NULL; deadbeef->pl_lock (); DB_FILE *fp = deadbeef->fopen (deadbeef->pl_find_meta (it, ":URI")); deadbeef->pl_unlock (); if (!fp) { trace ("vtx: failed to open file %s\n", deadbeef->pl_find_meta (it, ":URI")); return -1; } sz = deadbeef->fgetlength (fp); if (sz <= 0) { trace ("vtx: bad file size\n"); return -1; } buf = malloc (sz); if (!buf) { trace ("vtx: out of memory\n"); return -1; } if (deadbeef->fread (buf, 1, sz, fp) != sz) { trace ("vtx: read failed\n"); free (buf); return -1; } info->decoder = ayemu_vtx_load (buf, sz); if (!info->decoder) { trace ("vtx: ayemu_vtx_load failed\n"); free (buf); return -1; } trace ("vtx: data=%p, size=%d\n", info->decoder->regdata, info->decoder->regdata_size); free (buf); ayemu_init (&info->ay); ayemu_set_chip_type (&info->ay, info->decoder->chiptype, NULL); ayemu_set_chip_freq (&info->ay, info->decoder->chipFreq); ayemu_set_stereo (&info->ay, info->decoder->stereo, NULL); int samplerate = deadbeef->conf_get_int ("synth.samplerate", 44100); info->left = 0; info->vtx_pos = 0; _info->plugin = &plugin; _info->fmt.bps = deadbeef->conf_get_int ("vtx.bps", 16);; if (_info->fmt.bps != 16 && _info->fmt.bps != 8) { _info->fmt.bps = 16; } _info->fmt.channels = 2; _info->fmt.samplerate = samplerate; _info->fmt.channelmask = _info->fmt.channels == 1 ? DDB_SPEAKER_FRONT_LEFT : (DDB_SPEAKER_FRONT_LEFT | DDB_SPEAKER_FRONT_RIGHT); _info->readpos = 0; ayemu_set_sound_format (&info->ay, samplerate, _info->fmt.channels, _info->fmt.bps); info->rate = _info->fmt.channels * _info->fmt.bps / 8; return 0; }
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; }