예제 #1
0
파일: sid.cpp 프로젝트: chouquette/vlc
static int Open (vlc_object_t *obj)
{
    demux_t *demux = (demux_t *)obj;
    demux_sys_t *sys = NULL;
    es_format_t fmt;
    bool result = false;
    SidTune *tune = NULL;
    sidplay2 *player = NULL;
    ReSIDBuilder *builder = NULL;

    int64_t size = stream_Size (demux->s);
    if (size < 4 || size > LONG_MAX) /* We need to load the whole file for sidplay */
        return VLC_EGENERIC;

    const uint8_t *peek;
    if (vlc_stream_Peek (demux->s, &peek, 4) < 4)
        return VLC_EGENERIC;

    /* sidplay2 can read PSID and the newer RSID formats */
    if(memcmp(peek,"PSID",4)!=0 && memcmp(peek,"RSID",4)!=0)
        return VLC_EGENERIC;

    uint8_t *data = (uint8_t*) malloc(size);
    if (unlikely (data==NULL))
        goto error;

    if (vlc_stream_Read (demux->s,data,size) < size) {
        free (data);
        goto error;
    }

    tune = new (std::nothrow) SidTune(0);
    if (unlikely (tune==NULL)) {
        free (data);
        goto error;
    }

    result = tune->read (data, size);
    free (data);
    if (!result)
        goto error;

    player = new (std::nothrow) sidplay2();
    if (unlikely(player==NULL))
        goto error;

    sys = (demux_sys_t*) calloc (1, sizeof(demux_sys_t));
    if (unlikely(sys==NULL))
        goto error;

    sys->player = player;
    sys->tune = tune;

    tune->getInfo (sys->tuneInfo);

    sys->info = player->info();
    sys->config = player->config();

    builder = new (std::nothrow) ReSIDBuilder ("ReSID");
    if (unlikely(builder==NULL))
        goto error;

    builder->create (sys->info.maxsids);
    builder->sampling (sys->config.frequency);

    sys->config.sidEmulation = builder;
    sys->config.precision    = 16;
    sys->config.playback     = (sys->info.channels == 2 ? sid2_stereo : sid2_mono);

    player->config (sys->config);

    sys->bytes_per_frame = sys->info.channels * sys->config.precision / 8;
    sys->block_size = sys->config.frequency / 10 * sys->bytes_per_frame;

    es_format_Init (&fmt, AUDIO_ES, VLC_CODEC_S16N);

    fmt.audio.i_channels        = sys->info.channels;
    fmt.audio.i_bitspersample   = sys->config.precision;
    fmt.audio.i_rate            = sys->config.frequency;
    fmt.audio.i_bytes_per_frame = sys->bytes_per_frame;
    fmt.audio.i_frame_length    = fmt.audio.i_bytes_per_frame;
    fmt.audio.i_blockalign      = fmt.audio.i_bytes_per_frame;

    fmt.i_bitrate = fmt.audio.i_rate * fmt.audio.i_bytes_per_frame;

    sys->es = es_out_Add (demux->out, &fmt);

    date_Init (&sys->pts, fmt.audio.i_rate, 1);
    date_Set (&sys->pts, 0);

    sys->tune->selectSong (0);
    result = (sys->player->load (sys->tune) >=0 );
    sys->player->fastForward (100);
    if (!result)
        goto error;

    /* Callbacks */
    demux->pf_demux = Demux;
    demux->pf_control = Control;
    demux->p_sys = sys;

    return VLC_SUCCESS;

error:
    msg_Err (demux, "An error occurred during sid demuxing" );
    delete player;
    delete builder;
    delete tune;
    free (sys);
    return VLC_EGENERIC;
}
예제 #2
0
파일: csid.cpp 프로젝트: amitkr/deadbeef
extern "C" DB_playItem_t *
csid_insert (ddb_playlist_t *plt, DB_playItem_t *after, const char *fname) {
    trace ("inserting %s\n", fname);
    sldb_load ();
    SidTune *tune;
    trace ("new SidTune\n");
    tune = new SidTune (fname);
    int tunes = tune->getInfo ().songs;
    trace ("subtunes: %d\n", tunes);
    uint8_t sig[16];
    unsigned char tmp[2];
#if 1
    trace ("calculating md5\n");
    DB_md5_t md5;
    deadbeef->md5_init (&md5);
    deadbeef->md5_append (&md5, (const uint8_t *)tune->cache.get () + tune->fileOffset, tune->getInfo ().c64dataLen);
    le_int16 (tune->getInfo ().initAddr, tmp);
    deadbeef->md5_append (&md5, tmp, 2);
    le_int16 (tune->getInfo ().playAddr, tmp);
    deadbeef->md5_append (&md5, tmp, 2);
    le_int16 (tune->getInfo ().songs, tmp);
    deadbeef->md5_append (&md5, tmp, 2);
    for (int s = 1; s <= tunes; s++)
    {
        tune->selectSong (s);
        // songspeed is uint8_t, so no need for byteswap
        deadbeef->md5_append (&md5, &tune->getInfo ().songSpeed, 1);
    }
    if (tune->getInfo ().clockSpeed == SIDTUNE_CLOCK_NTSC) {
        deadbeef->md5_append (&md5, &tune->getInfo ().clockSpeed, sizeof (tune->getInfo ().clockSpeed));
    }
    deadbeef->md5_finish (&md5, sig);
#else
    // md5 calc from libsidplay2
    MD5 myMD5;
    myMD5.append ((const char *)tune->cache.get() + tune->fileOffset, tune->getInfo ().c64dataLen);
    // Include INIT and PLAY address.
    endian_little16 (tmp,tune->getInfo ().initAddr);
    myMD5.append    (tmp,sizeof(tmp));
    endian_little16 (tmp,tune->getInfo ().playAddr);
    myMD5.append    (tmp,sizeof(tmp));
    // Include number of songs.
    endian_little16 (tmp,tune->getInfo ().songs);
    myMD5.append    (tmp,sizeof(tmp));
    {
        // Include song speed for each song.
        for (uint_least16_t s = 1; s <= tune->getInfo ().songs; s++)
        {
            tune->selectSong (s);
            myMD5.append (&tune->getInfo ().songSpeed,1);
        }
    }
    // Deal with PSID v2NG clock speed flags: Let only NTSC
    // clock speed change the MD5 fingerprint. That way the
    // fingerprint of a PAL-speed sidtune in PSID v1, v2, and
    // PSID v2NG format is the same.
    if (tune->getInfo ().clockSpeed == SIDTUNE_CLOCK_NTSC) {
        myMD5.append (&tune->getInfo ().clockSpeed,sizeof(tune->getInfo ().clockSpeed));
    }
    myMD5.finish ();
    memcpy (sig, myMD5.getDigest (), 16);
#endif

    int song = -1;
    if (sldb_loaded) {
        song = sldb_find (sig);
    }

    trace ("inserting tunes...\n");
    for (int s = 0; s < tunes; s++) {
        trace ("select %d...\n", s);
        if (tune->selectSong (s+1)) {
            DB_playItem_t *it = deadbeef->pl_item_alloc_init (fname, sid_plugin.plugin.id);
            deadbeef->pl_set_meta_int (it, ":TRACKNUM", s);
            SidTuneInfo sidinfo;
            tune->getInfo (sidinfo);
            int i = sidinfo.numberOfInfoStrings;
            int title_added = 0;
            trace ("set %d metainfo...\n", s);
            char temp[2048];
            if (i >= 1 && sidinfo.infoString[0] && sidinfo.infoString[0][0]) {
                const char *meta;
                if (sidinfo.songs > 1) {
                    meta = "album";
                }
                else {
                    meta = "title";
                    title_added = 1;
                }
                deadbeef->pl_add_meta (it, meta, convstr (sidinfo.infoString[0], strlen (sidinfo.infoString[0]), temp, sizeof (temp)));
            }
            if (i >= 2 && sidinfo.infoString[1] && sidinfo.infoString[1][0]) {
                deadbeef->pl_add_meta (it, "artist", convstr (sidinfo.infoString[1], strlen (sidinfo.infoString[1]), temp, sizeof (temp)));
            }
            if (i >= 3 && sidinfo.infoString[2] && sidinfo.infoString[2][0]) {
                deadbeef->pl_add_meta (it, "copyright", convstr (sidinfo.infoString[2], strlen (sidinfo.infoString[2]), temp, sizeof (temp)));
            }

            for (int j = 3; j < i; j++)
            {
                if (sidinfo.infoString[j] && sidinfo.infoString[j][0]) {
                    deadbeef->pl_add_meta (it, "info", convstr (sidinfo.infoString[j], strlen (sidinfo.infoString[j]), temp, sizeof (temp)));
                }
            }
            char trk[10];
            snprintf (trk, 10, "%d", s+1);
            deadbeef->pl_add_meta (it, "track", trk);
            if (!title_added) {
                deadbeef->pl_add_meta (it, "title", NULL);
            }

            float length = deadbeef->conf_get_float ("sid.defaultlength", 180);
            if (sldb_loaded) {
                if (song >= 0 && sldb->sldb_lengths[song][s] >= 0) {
                    length = sldb->sldb_lengths[song][s];
                }
                //        if (song < 0) {
                //            trace ("song %s not found in db, md5: ", fname);
                //            for (int j = 0; j < 16; j++) {
                //                trace ("%02x", (int)sig[j]);
                //            }
                //            trace ("\n");
                //        }
            }
            deadbeef->plt_set_item_duration (plt, it, length);
            deadbeef->pl_add_meta (it, ":FILETYPE", "SID");

            after = deadbeef->plt_insert_item (plt, after, it);
            deadbeef->pl_item_unref (it);
        }
    }
    trace ("delete sidtune\n");
    delete tune;
    return after;
}
예제 #3
0
파일: XBMCSID.cpp 프로젝트: Kr0nZ/boxee
 int __declspec(dllexport) DLL_GetNumberOfSongs(const char* szFileName)
 {
   SidTune tune;
   tune.load(szFileName,true);
   return tune.getInfo().songs;
 }
예제 #4
0
extern "C" DB_playItem_t *
csid_insert (ddb_playlist_t *plt, DB_playItem_t *after, const char *fname) {
    trace ("inserting %s\n", fname);

    find_hvsc_path_from_fname (fname);

    sldb_load ();
    SidTune *tune;
    trace ("new SidTune\n");
    tune = new SidTune (fname);
    int tunes = tune->getInfo ().songs;
    trace ("subtunes: %d\n", tunes);
    uint8_t sig[16];
    unsigned char tmp[2];
    trace ("calculating md5\n");
    DB_md5_t md5;
    deadbeef->md5_init (&md5);
    if (sldb_legacy) {
        deadbeef->md5_append (&md5, (const uint8_t *)tune->cache.get () + tune->fileOffset, tune->getInfo ().c64dataLen);
        le_int16 (tune->getInfo ().initAddr, tmp);
        deadbeef->md5_append (&md5, tmp, 2);
        le_int16 (tune->getInfo ().playAddr, tmp);
        deadbeef->md5_append (&md5, tmp, 2);
        le_int16 (tune->getInfo ().songs, tmp);
        deadbeef->md5_append (&md5, tmp, 2);
        for (int s = 1; s <= tunes; s++)
        {
            tune->selectSong (s);
            // songspeed is uint8_t, so no need for byteswap
            deadbeef->md5_append (&md5, &tune->getInfo ().songSpeed, 1);
        }
        if (tune->getInfo ().clockSpeed == SIDTUNE_CLOCK_NTSC) {
            deadbeef->md5_append (&md5, &tune->getInfo ().clockSpeed, sizeof (tune->getInfo ().clockSpeed));
        }
    }
    else {
        deadbeef->md5_append (&md5, (const uint8_t *)tune->cache.get (), tune->getInfo ().dataFileLen);
    }
    deadbeef->md5_finish (&md5, sig);

    int song = -1;
    if (sldb_loaded) {
        song = sldb_find (sig);
    }

    trace ("inserting tunes...\n");
    for (int s = 0; s < tunes; s++) {
        trace ("select %d...\n", s);
        if (tune->selectSong (s+1)) {
            DB_playItem_t *it = deadbeef->pl_item_alloc_init (fname, sid_plugin.plugin.id);
            deadbeef->pl_set_meta_int (it, ":TRACKNUM", s);
            SidTuneInfo sidinfo;
            tune->getInfo (sidinfo);
            int i = sidinfo.numberOfInfoStrings;
            int title_added = 0;
            trace ("set %d metainfo...\n", s);
            char temp[2048];
            if (i >= 1 && sidinfo.infoString[0] && sidinfo.infoString[0][0]) {
                const char *meta;
                if (sidinfo.songs > 1) {
                    meta = "album";
                }
                else {
                    meta = "title";
                    title_added = 1;
                }
                deadbeef->pl_add_meta (it, meta, convstr (sidinfo.infoString[0], strlen (sidinfo.infoString[0]), temp, sizeof (temp)));
            }
            if (i >= 2 && sidinfo.infoString[1] && sidinfo.infoString[1][0]) {
                deadbeef->pl_add_meta (it, "artist", convstr (sidinfo.infoString[1], strlen (sidinfo.infoString[1]), temp, sizeof (temp)));
            }
            if (i >= 3 && sidinfo.infoString[2] && sidinfo.infoString[2][0]) {
                deadbeef->pl_add_meta (it, "copyright", convstr (sidinfo.infoString[2], strlen (sidinfo.infoString[2]), temp, sizeof (temp)));
            }

            for (int j = 3; j < i; j++)
            {
                if (sidinfo.infoString[j] && sidinfo.infoString[j][0]) {
                    deadbeef->pl_add_meta (it, "info", convstr (sidinfo.infoString[j], strlen (sidinfo.infoString[j]), temp, sizeof (temp)));
                }
            }
            char trk[10];
            snprintf (trk, 10, "%d", s+1);
            deadbeef->pl_add_meta (it, "track", trk);
            if (!title_added) {
                deadbeef->pl_add_meta (it, "title", NULL);
            }

            float length = deadbeef->conf_get_float ("sid.defaultlength", 180);
            if (sldb_loaded && song >= 0 && s < sldb[song].subsongs) {
                uint16_t l = sldb_lengths[sldb[song].lengths_offset+s];
                if (l >= 0) {
                    length = l;
                }
            }
            deadbeef->plt_set_item_duration (plt, it, length);
            deadbeef->pl_add_meta (it, ":FILETYPE", "SID");

            after = deadbeef->plt_insert_item (plt, after, it);
            deadbeef->pl_item_unref (it);
        }
    }
    trace ("delete sidtune\n");
    delete tune;
    return after;
}