MusInfo *GME_OpenSong(FILE *file, BYTE *musiccache, int len, const char *fmt) { gme_type_t type; gme_err_t err; BYTE *song; Music_Emu *emu; int sample_rate; type = gme_identify_extension(fmt); if (type == NULL) { return NULL; } sample_rate = (int)GSnd->GetOutputRate(); emu = gme_new_emu(type, sample_rate); if (emu == NULL) { return NULL; } if (musiccache != NULL) { song = musiccache; } else { song = new BYTE[len]; if (fread(song, 1, len, file) != (size_t)len) { delete[] song; gme_delete(emu); return NULL; } } err = gme_load_data(emu, song, len); if (song != musiccache) { delete[] song; } if (err != NULL) { Printf("Failed loading song: %s\n", err); gme_delete(emu); return NULL; } return new GMESong(emu, sample_rate); }
gme_err_t gme_open_data( void const* data, long size, Music_Emu** out, int sample_rate ) { require( (data || !size) && out ); *out = NULL; gme_type_t file_type = 0; if ( size >= 4 ) file_type = gme_identify_extension( gme_identify_header( data ) ); if ( !file_type ) return blargg_err_file_type; Music_Emu* emu = gme_new_emu( file_type, sample_rate ); CHECK_ALLOC( emu ); gme_err_t err = gme_load_data( emu, data, size ); if ( err ) delete emu; else *out = emu; return err; }
gme_err_t gme_open_file( const char path [], Music_Emu** out, int sample_rate ) { require( path && out ); *out = NULL; GME_FILE_READER in; RETURN_ERR( in.open( path ) ); char header [4]; int header_size = 0; gme_type_t file_type = gme_identify_extension( path ); if ( !file_type ) { header_size = sizeof header; RETURN_ERR( in.read( header, sizeof header ) ); file_type = gme_identify_extension( gme_identify_header( header ) ); } if ( !file_type ) return blargg_err_file_type; Music_Emu* emu = gme_new_emu( file_type, sample_rate ); CHECK_ALLOC( emu ); // optimization: avoids seeking/re-reading header Remaining_Reader rem( header, header_size, &in ); gme_err_t err = emu->load( rem ); in.close(); if ( err ) delete emu; else *out = emu; return err; }
static int Open (vlc_object_t *obj) { demux_t *demux = (demux_t *)obj; int64_t size = stream_Size (demux->s); if (size > LONG_MAX /* too big for GME */) return VLC_EGENERIC; /* Auto detection */ const uint8_t *peek; if (stream_Peek (demux->s, &peek, 4) < 4) return VLC_EGENERIC; const char *type = gme_identify_header (peek); if (!*type) return VLC_EGENERIC; msg_Dbg (obj, "detected file type %s", type); block_t *data = NULL; if (size <= 0) { data = stream_Block (demux->s, 1 << 24); if (data == NULL) return VLC_EGENERIC; } /* Initialization */ demux_sys_t *sys = malloc (sizeof (*sys)); if (unlikely(sys == NULL)) return VLC_ENOMEM; sys->emu = gme_new_emu (gme_identify_extension (type), RATE); if (sys->emu == NULL) { free (sys); return VLC_ENOMEM; } if (data) { gme_load_custom (sys->emu, ReaderBlock, data->i_buffer, data); block_Release(data); } else { gme_load_custom (sys->emu, ReaderStream, size, demux->s); } gme_start_track (sys->emu, sys->track_id = 0); es_format_t fmt; es_format_Init (&fmt, AUDIO_ES, VLC_CODEC_S16N); fmt.audio.i_rate = RATE; fmt.audio.i_bytes_per_frame = 4; fmt.audio.i_frame_length = 4; fmt.audio.i_channels = 2; fmt.audio.i_blockalign = 4; fmt.audio.i_bitspersample = 16; fmt.i_bitrate = RATE * 4; sys->es = es_out_Add (demux->out, &fmt); date_Init (&sys->pts, RATE, 1); date_Set (&sys->pts, 0); /* Titles */ unsigned n = gme_track_count (sys->emu); sys->titlev = malloc (n * sizeof (*sys->titlev)); if (unlikely(sys->titlev == NULL)) n = 0; sys->titlec = n; for (unsigned i = 0; i < n; i++) { input_title_t *title = vlc_input_title_New (); sys->titlev[i] = title; if (unlikely(title == NULL)) continue; gme_info_t *infos; if (gme_track_info (sys->emu, &infos, i)) continue; msg_Dbg (obj, "track %u: %s %d ms", i, infos->song, infos->length); if (infos->length != -1) title->i_length = infos->length * INT64_C(1000); if (infos->song[0]) title->psz_name = strdup (infos->song); gme_free_info (infos); } /* Callbacks */ demux->pf_demux = Demux; demux->pf_control = Control; demux->p_sys = sys; return VLC_SUCCESS; }