// Callback hook to read streaming GME data. static FMOD_RESULT F_CALLBACK GMEReadCallback(FMOD_SOUND *sound, void *data, unsigned int datalen) { Music_Emu *emu; void *emuvoid = NULL; // get our emu FMR(FMOD_Sound_GetUserData(sound, &emuvoid)); emu = emuvoid; // no emu? no play. if (!emu) return FMOD_ERR_FILE_EOF; if (gme_track_ended(emu)) { // don't delete the primary music stream if (emu == gme) return FMOD_ERR_FILE_EOF; // do delete sfx streams FMR(FMOD_Sound_SetUserData(sound, NULL)); gme_delete(emu); return FMOD_ERR_FILE_EOF; } // play beautiful musics theme of ancient land. if (gme_play(emu, datalen/2, data)) return FMOD_ERR_FILE_BAD; // O.K return FMOD_OK; }
bool GME::read(Packet &decoded, int &idx) { if (m_aborted || gme_track_ended(m_gme)) return false; gme_set_fade(m_gme, (m_length - 8) * 1000); //Set every time to avoid problems const int chunkSize = 1024 * 2; //Always stereo decoded.resize(chunkSize * sizeof(float)); qint16 *srcData = (qint16 *)decoded.data(); float *dstData = (float *)decoded.data(); if (gme_play(m_gme, chunkSize, srcData) != NULL) return false; for (int i = chunkSize - 1; i >= 0; --i) dstData[i] = srcData[i] / 32768.0; decoded.ts = gme_tell(m_gme) / 1000.0; decoded.duration = chunkSize / 2 / (double)m_srate; idx = 0; return true; }
static int Demux (demux_t *demux) { demux_sys_t *sys = demux->p_sys; /* Next track */ if (gme_track_ended (sys->emu)) { msg_Dbg (demux, "track %u ended", sys->track_id); if (++sys->track_id >= (unsigned)gme_track_count (sys->emu)) return 0; demux->info.i_update |= INPUT_UPDATE_TITLE; demux->info.i_title = sys->track_id; gme_start_track (sys->emu, sys->track_id); } block_t *block = block_Alloc (2 * 2 * SAMPLES); if (unlikely(block == NULL)) return 0; gme_err_t ret = gme_play (sys->emu, 2 * SAMPLES, (void *)block->p_buffer); if (ret != NULL) { block_Release (block); msg_Err (demux, "%s", ret); return 0; } block->i_pts = block->i_dts = VLC_TS_0 + date_Get (&sys->pts); es_out_Control (demux->out, ES_OUT_SET_PCR, block->i_pts); es_out_Send (demux->out, sys->es, block); date_Increment (&sys->pts, SAMPLES); return 1; }
static int cgme_read (DB_fileinfo_t *_info, char *bytes, int size) { gme_fileinfo_t *info = (gme_fileinfo_t*)_info; float t = (size/4) / (float)_info->fmt.samplerate; if (_info->readpos + t >= info->duration) { t = info->duration - _info->readpos; if (t <= 0) { return 0; } // DON'T ajust size, buffer must always be po2 //size = t * (float)info->samplerate * 4; } if (chip_voices_changed) { chip_voices = deadbeef->conf_get_int ("chip.voices", 0xff); chip_voices_changed = 0; gme_mute_voices (info->emu, chip_voices^0xff); } if (gme_play (info->emu, size/2, (short*)bytes)) { return 0; } if (conf_fadeout > 0 && info->duration >= conf_fadeout && info->reallength <= 0 && _info->readpos >= info->duration - conf_fadeout) { float fade_amnt = (info->duration - _info->readpos) / (float)conf_fadeout; int nsamples = size/2; float fade_incr = 1.f / (_info->fmt.samplerate * conf_fadeout) * 256; const float ln10=2.3025850929940002f; float fade = exp(ln10*(-(1.f-fade_amnt) * 3)); for (int i = 0; i < nsamples; i++) { ((short*)bytes)[i] *= fade; if (!(i & 0xff)) { fade_amnt += fade_incr; fade = exp(ln10*(-(1.f-fade_amnt) * 3)); } } } _info->readpos += t; if (info->reallength == -1) { if (gme_track_ended (info->emu)) { return 0; } } return size; }
static int read_packet_gme(AVFormatContext *s, AVPacket *pkt) { GMEContext *gme = s->priv_data; int n_samples = AUDIO_PKT_SIZE / 2; int ret; if (gme_track_ended(gme->music_emu)) return AVERROR_EOF; if ((ret = av_new_packet(pkt, AUDIO_PKT_SIZE)) < 0) return ret; if (gme_play(gme->music_emu, n_samples, (short *)pkt->data)) return AVERROR_EXTERNAL; pkt->size = AUDIO_PKT_SIZE; return 0; }
int GmeDecoder::decode() { short *sbuf = static_cast<short*>(buffer); int size = bufferSize / sizeof(short); if (gme_play(emu, size, sbuf) != 0) throw love::Exception("Error while decoding game music"); if (!eof && gme_track_ended(emu)) { // Start the next track if this one ended. if (cur_track < num_tracks - 1) gme_start_track(emu, ++cur_track); else eof = true; } return bufferSize; }
JNIEXPORT jint JNICALL Java_com_ssb_droidsound_plugins_GMEPlugin_N_1getSoundData(JNIEnv *env, jobject obj, jlong song, jshortArray bArray, int size) { GMEInfo *info = (GMEInfo*)song; if(!info->started) { gme_err_t err = gme_start_track(info->emu, 0); info->started = true; } if(gme_track_ended(info->emu)) { return 0; } jshort *ptr = env->GetShortArrayElements(bArray, NULL); //__android_log_print(ANDROID_LOG_VERBOSE, "GMEPlugin", "Getting %d shorts from %p", size, emu); gme_err_t err = gme_play(info->emu, size, ptr); //__android_log_print(ANDROID_LOG_VERBOSE, "GMEPlugin", "Result %d", err); env->ReleaseShortArrayElements(bArray, ptr, 0); return size; }
JNIEXPORT jint JNICALL Java_com_ssb_droidsound_plugins_GMEPlugin_N_1getSoundData(JNIEnv *env, jobject obj, jlong song, jshortArray sArray, int size) { GMEInfo *info = (GMEInfo*)song; if(!info->started) { gme_err_t err = gme_start_track(info->emu, 0); info->started = true; } if(gme_track_ended(info->emu)) { return -1; } jshort *ptr = env->GetShortArrayElements(sArray, NULL); gme_err_t err = gme_play(info->emu, size, ptr); env->ReleaseShortArrayElements(sArray, ptr, 0); return size; }
static int cgme_read (DB_fileinfo_t *_info, char *bytes, int size) { gme_fileinfo_t *info = (gme_fileinfo_t*)_info; int playForever = conf_play_forever && info->can_loop; float t = (size/4) / (float)_info->fmt.samplerate; if (info->eof) { return 0; } if (!playForever && _info->readpos + t >= info->duration) { t = info->duration - _info->readpos; if (t <= 0) { return 0; } // DON'T ajust size, buffer must always be po2 //size = t * (float)info->samplerate * 4; } if (chip_voices_changed) { chip_voices = deadbeef->conf_get_int ("chip.voices", 0xff); chip_voices_changed = 0; gme_mute_voices (info->emu, chip_voices^0xff); } if (playForever) gme_set_fade(info->emu, -1, 0); else gme_set_fade(info->emu, (int)(info->duration * 1000), conf_fadeout * 1000); if (gme_play (info->emu, size/2, (short*)bytes)) { return 0; } _info->readpos += t; if (gme_track_ended (info->emu)) { info->eof = 1; } return size; }
/* Read some data */ static gint xmms_gme_read (xmms_xform_t *xform, xmms_sample_t *buf, gint len, xmms_error_t *err) { xmms_gme_data_t *data; gme_err_t play_error; g_return_val_if_fail (xform, -1); data = (xmms_gme_data_t *)xmms_xform_private_data_get (xform); g_return_val_if_fail (data, -1); if (gme_track_ended (data->emu)) return 0; play_error = gme_play (data->emu, len/2, (short int *)buf); if (play_error) { XMMS_DBG ("gme_play returned an error: %s", play_error); xmms_error_set (err, XMMS_ERROR_GENERIC, play_error); return -1; } return len; }
bool GMESong::Read(SoundStream *stream, void *buff, int len, void *userdata) { gme_err_t err; GMESong *song = (GMESong *)userdata; song->CritSec.Enter(); if (gme_track_ended(song->Emu)) { if (song->m_Looping) { song->StartTrack(song->CurrTrack, false); } else { memset(buff, 0, len); song->CritSec.Leave(); return false; } } err = gme_play(song->Emu, len >> 1, (short *)buff); song->CritSec.Leave(); return (err == NULL); }
static event_t * fa_gme_playfile_internal(media_pipe_t *mp, const void *buf, size_t size, char *errbuf, size_t errlen, int hold, int track, const char *url) { media_queue_t *mq = &mp->mp_audio; Music_Emu *emu; gme_err_t err; int sample_rate = 48000; media_buf_t *mb = NULL; event_t *e; int registered_play = 0; err = gme_open_data(buf, size, &emu, sample_rate); if(err != NULL) { snprintf(errbuf, errlen, "Unable to load file -- %s", err); return NULL; } gme_start_track(emu, track); mp->mp_audio.mq_stream = 0; mp_configure(mp, MP_PLAY_CAPS_PAUSE | MP_PLAY_CAPS_SEEK, MP_BUFFER_SHALLOW, 0); mp_become_primary(mp); while(1) { if(gme_track_ended(emu)) { e = event_create_type(EVENT_EOF); break; } if(mb == NULL) { mb = media_buf_alloc_unlocked(mp, sizeof(int16_t) * CHUNK_SIZE * 2); mb->mb_data_type = MB_AUDIO; mb->mb_channels = 2; mb->mb_rate = sample_rate; mb->mb_pts = gme_tell(emu) * 1000; mb->mb_drive_clock = 1; if(!registered_play && mb->mb_pts > METADB_AUDIO_PLAY_THRESHOLD) { registered_play = 1; metadb_register_play(url, 1, CONTENT_AUDIO); } gme_play(emu, CHUNK_SIZE * mb->mb_channels, mb->mb_data); } if((e = mb_enqueue_with_events(mp, mq, mb)) == NULL) { mb = NULL; /* Enqueue succeeded */ continue; } if(event_is_type(e, EVENT_PLAYQUEUE_JUMP)) { mp_flush(mp, 0); break; } else if(event_is_type(e, EVENT_SEEK)) { event_ts_t *ets = (event_ts_t *)e; gme_seek(emu, ets->ts / 1000); seekflush(mp, &mb); } else if(event_is_action(e, ACTION_SKIP_BACKWARD) || event_is_action(e, ACTION_SKIP_FORWARD) || event_is_action(e, ACTION_STOP)) { mp_flush(mp, 0); break; } event_release(e); } gme_delete(emu); if(mb != NULL) media_buf_free_unlocked(mp, mb); return e; }
static event_t * fa_gme_playfile_internal(media_pipe_t *mp, void *fh, char *errbuf, size_t errlen, int hold, int track) { media_queue_t *mq = &mp->mp_audio; Music_Emu *emu; gme_err_t err; char *buf; int lost_focus = 0; size_t size, r; int sample_rate = 48000; media_buf_t *mb = NULL; event_t *e; size = fa_fsize(fh); buf = malloc(size); r = fa_read(fh, buf, size); if(r != size) { snprintf(errbuf, errlen, "Unable to read file"); free(buf); return NULL; } err = gme_open_data(buf, size, &emu, sample_rate); free(buf); if(err != NULL) { snprintf(errbuf, errlen, "Unable to load file -- %s", err); return NULL; } gme_start_track(emu, track); mp_set_playstatus_by_hold(mp, hold, NULL); mp->mp_audio.mq_stream = 0; mp_set_play_caps(mp, MP_PLAY_CAPS_PAUSE | MP_PLAY_CAPS_SEEK); mp_become_primary(mp); while(1) { if(gme_track_ended(emu)) { e = event_create_type(EVENT_EOF); break; } if(mb == NULL) { mb = media_buf_alloc(); mb->mb_data_type = MB_AUDIO; mb->mb_channels = 2; mb->mb_size = sizeof(int16_t) * CHUNK_SIZE * mb->mb_channels; mb->mb_data = malloc(mb->mb_size); mb->mb_rate = sample_rate; mb->mb_time = gme_tell(emu) * 1000; gme_play(emu, CHUNK_SIZE * mb->mb_channels, mb->mb_data); } if((e = mb_enqueue_with_events(mp, mq, mb)) == NULL) { mb = NULL; /* Enqueue succeeded */ continue; } if(event_is_type(e, EVENT_PLAYQUEUE_JUMP)) { mp_flush(mp, 0); break; } else if(event_is_type(e, EVENT_SEEK)) { event_ts_t *ets = (event_ts_t *)e; gme_seek(emu, ets->pts / 1000); seekflush(mp, &mb); } else if(event_is_action(e, ACTION_SEEK_FAST_BACKWARD)) { deltaseek(mp, &mb, emu, -60000); } else if(event_is_action(e, ACTION_SEEK_BACKWARD)) { deltaseek(mp, &mb, emu, -15000); } else if(event_is_action(e, ACTION_SEEK_FAST_FORWARD)) { deltaseek(mp, &mb, emu, 60000); } else if(event_is_action(e, ACTION_SEEK_FORWARD)) { deltaseek(mp, &mb, emu, 15000); } else if(event_is_action(e, ACTION_PLAYPAUSE) || event_is_action(e, ACTION_PLAY) || event_is_action(e, ACTION_PAUSE)) { hold = action_update_hold_by_event(hold, e); mp_send_cmd_head(mp, mq, hold ? MB_CTRL_PAUSE : MB_CTRL_PLAY); lost_focus = 0; mp_set_playstatus_by_hold(mp, hold, NULL); } else if(event_is_type(e, EVENT_MP_NO_LONGER_PRIMARY)) { hold = 1; lost_focus = 1; mp_send_cmd_head(mp, mq, MB_CTRL_PAUSE); mp_set_playstatus_by_hold(mp, hold, e->e_payload); } else if(event_is_type(e, EVENT_MP_IS_PRIMARY)) { if(lost_focus) { hold = 0; lost_focus = 0; mp_send_cmd_head(mp, mq, MB_CTRL_PLAY); mp_set_playstatus_by_hold(mp, hold, NULL); } } else if(event_is_type(e, EVENT_INTERNAL_PAUSE)) { hold = 1; lost_focus = 0; mp_send_cmd_head(mp, mq, MB_CTRL_PAUSE); mp_set_playstatus_by_hold(mp, hold, e->e_payload); } else if(event_is_action(e, ACTION_PREV_TRACK) || event_is_action(e, ACTION_NEXT_TRACK) || event_is_action(e, ACTION_STOP)) { mp_flush(mp, 0); break; } event_release(e); } gme_delete(emu); if(mb != NULL) media_buf_free(mb); if(hold) { // If we were paused, release playback again. mp_send_cmd(mp, mq, MB_CTRL_PLAY); mp_set_playstatus_by_hold(mp, 0, NULL); } return e; }
int bmx_gme_track_ended(MaxMusicEmu * emu) { return gme_track_ended(emu->emu); }
bool Music_Player::track_ended() const { return emu_ ? gme_track_ended( emu_ ) : false; }