Example #1
0
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;
}
Example #2
0
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;
}
Example #3
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;
}
Example #4
0
int main (int argc, char **argv)
{
  int index;
  int c;
  int option_index = 0;
	   
  opterr = 0;
     
  while ((c = getopt_long (argc, argv, short_opts, options, &option_index)) != -1)
    switch (c)
      {
      case 'q':
	qflag = 1;
	break;
      case 'Z':
	Zflag = 1;
	break;
      case 's':
	sflag = 1;
	break;
      case 'v':
	vflag = 1;
	break;
      case 'V':
	printf ("playvtx %s\n", VERSION);
	exit (0);
      case 'h':
      case 'u':
	usage ();
	exit (0);
      case '?':
	if (isprint (optopt))
	  fprintf (stderr, "Unknown option `-%c'.\n", optopt);
	else
	  fprintf (stderr,
		   "Unknown option character `\\x%x'.\n",
		   optopt);
	usage ();
	return 1;
      case -1:
	break;
      default:
	abort ();
      }
     
  if (DEBUG)
    printf ("qflag = %d, Zflag = %d, sflag = %d, vflag = %d\n", 
	    qflag, Zflag, sflag, vflag);
     
  if (Zflag)
    printf ("The -Z flag is not implemented yet, sorry\n");

  if (optind == argc) {
    fprintf (stderr, "No files to play specified, see %s --usage.\n",
	     argv[0]);
    exit (1);
  }

  init_oss();
  if (DEBUG) 
    printf ("OSS sound system initialization success: bits=%d, chans=%d, freq=%d\n",
	    bits, chans, freq);

  ayemu_init(&ay);
  ayemu_set_sound_format(&ay, freq, chans, bits);

  for (index = optind; index < argc; index++) {
    printf ("\nPlaying file %s\n", argv[index]);
    play (argv[index]);
  }

  return 0;
}