Ejemplo n.º 1
0
static void
vtx_free (DB_fileinfo_t *_info) {
    // free everything allocated in _init
    vtx_info_t *info = (vtx_info_t *)_info;
    if (_info) {
        if (info->decoder) {
            ayemu_vtx_free (info->decoder);
            info->decoder = NULL;
        }
        ayemu_reset (&info->ay);
        free (_info);
    }
}
Ejemplo n.º 2
0
Tuple *vtx_probe_for_tuple(const gchar *filename, VFSFile *fd)
{
    ayemu_vtx_t tmp;

    if (ayemu_vtx_open(&tmp, filename))
    {
        Tuple *ti = vtx_get_song_tuple_from_vtx(filename, &tmp);
        ayemu_vtx_free(&tmp);
        return ti;
    }

    return NULL;
}
Ejemplo n.º 3
0
static DB_playItem_t *
vtx_insert (ddb_playlist_t *plt, DB_playItem_t *after, const char *fname) {
    // read information from the track
    // load/process cuesheet if exists
    // insert track into playlist
    // return track pointer on success
    // return NULL on failure

    trace ("vtx_insert %s\n");
    // load header
    DB_FILE *fp = deadbeef->fopen (fname);
    if (!fp) {
        trace ("vtx: failed to open file\n");
        return NULL;
    }
    char buf[0x4000];
    size_t sz;
    sz = deadbeef->fread (buf, 1, sizeof (buf), fp);
    deadbeef->fclose (fp);
    if (sz <= 0) {
        trace ("vtx: failed to read header data from file\n");
        return NULL;
    }
    ayemu_vtx_t *hdr = ayemu_vtx_header (buf, sz);
    if (!hdr) {
        trace ("vtx: failed to read header\n");
        return NULL;
    }
    trace ("vtx: datasize: %d\n", hdr->regdata_size);

    DB_playItem_t *it = deadbeef->pl_item_alloc_init (fname, plugin.plugin.id);
    deadbeef->pl_add_meta (it, ":FILETYPE", "VTX");

    int numframes = hdr->regdata_size / AY_FRAME_SIZE;
//    int totalsamples = numframes * hdr->playerFreq;
    trace ("vtx: numframes=%d, playerFreq=%d\n", numframes, hdr->playerFreq);
    deadbeef->plt_set_item_duration (plt, it, (float)numframes / hdr->playerFreq);

    // add metadata
    deadbeef->pl_add_meta (it, "title", hdr->title);
    deadbeef->pl_add_meta (it, "artist", hdr->author);
    deadbeef->pl_add_meta (it, "album", hdr->from);

    ayemu_vtx_free (hdr);
    after = deadbeef->plt_insert_item (plt, after, it);
    deadbeef->pl_item_unref (it);
    return after;
}
Ejemplo n.º 4
0
static data_ptr_t read_header(data_ptr_t buf, ayemu_vtx_t **target, size_t size)
{
  char hdr[3];
  ayemu_vtx_t *vtx;

  hdr[0] = tolower(*buf++);
  hdr[1] = tolower(*buf++);
  hdr[2] = '\0';

  if (size < 20) {
    fprintf(stderr, "ayemu_vtx_open: file size < 20 bytes - it is impossible\n");
    return NULL;
  }

  vtx = (ayemu_vtx_t*) calloc(1, sizeof(ayemu_vtx_t));

  if (strncmp(hdr, "ay", 2) == 0)
    vtx->chiptype = AYEMU_AY;
  else if (strncmp (hdr, "ym", 2) == 0)
    vtx->chiptype = AYEMU_YM;
  else {
    trace ("File is _not_ VORTEX format!\n"
	     "It not begins with 'ay' or 'ym' string.\n");
    goto clean_and_ret_null;
  }

  buf = read_byte(buf,   &vtx->stereo);
  buf = read_word16(buf, &vtx->loop);
  buf = read_word32(buf, &vtx->chipFreq);
  buf = read_byte(buf,   &vtx->playerFreq);
  buf = read_word16(buf, &vtx->year);
  buf = read_word32(buf, &vtx->regdata_size);

  buf = read_string(buf, &vtx->title);
  buf = read_string(buf, &vtx->author);
  buf = read_string(buf, &vtx->from);
  buf = read_string(buf, &vtx->tracker);
  buf = read_string(buf, &vtx->comment);

  *target = vtx;
  return buf;

 clean_and_ret_null:

  ayemu_vtx_free(vtx);
  return NULL;
}
Ejemplo n.º 5
0
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);
}
Ejemplo n.º 6
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;
}
Ejemplo n.º 7
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;
}