/* Jump (seek) to a given position (time is in seconds) */ void GME_jump_to_time(struct MUSIC_GME *music, double time) { if(music) { gme_seek(music->game_emu, (int)round(time*1000)); } }
static int read_seek_gme(AVFormatContext *s, int stream_idx, int64_t ts, int flags) { GMEContext *gme = s->priv_data; if (!gme_seek(gme->music_emu, (int)ts)) return AVERROR_EXTERNAL; return 0; }
static void gst_gme_play (GstPad * pad) { GstGmeDec *gme = GST_GME_DEC (gst_pad_get_parent (pad)); GstFlowReturn flow_return; GstBuffer *out; gboolean seeking = gme->seeking; gme_err_t gme_err = NULL; const int NUM_SAMPLES = 1600; /* 4 bytes (stereo 16-bit) per sample */ if (!seeking) { GstMapInfo map; out = gst_buffer_new_and_alloc (NUM_SAMPLES * 4); GST_BUFFER_TIMESTAMP (out) = gme_tell (gme->player) * GST_MSECOND; gst_buffer_map (out, &map, GST_MAP_WRITE); gme_err = gme_play (gme->player, NUM_SAMPLES * 2, (short *) map.data); gst_buffer_unmap (out, &map); if (gme_err) { GST_ELEMENT_ERROR (gme, STREAM, DEMUX, (NULL), ("%s", gme_err)); gst_pad_pause_task (pad); gst_pad_push_event (pad, gst_event_new_eos ()); gst_object_unref (gme); return; } } else { gme_seek (gme->player, gme->seekpoint); gme->seeking = FALSE; out = gst_buffer_new (); } if ((flow_return = gst_pad_push (gme->srcpad, out)) != GST_FLOW_OK) { GST_DEBUG_OBJECT (gme, "pausing task, reason %s", gst_flow_get_name (flow_return)); gst_pad_pause_task (pad); if (flow_return == GST_FLOW_EOS) { gst_pad_push_event (pad, gst_event_new_eos ()); } else if (flow_return < GST_FLOW_EOS || flow_return == GST_FLOW_NOT_LINKED) { GST_ELEMENT_ERROR (gme, STREAM, FAILED, ("Internal data stream error."), ("stream stopped, reason %s", gst_flow_get_name (flow_return))); gst_pad_push_event (pad, gst_event_new_eos ()); } } if (gme_tell (gme->player) * GST_MSECOND > gme->total_duration) { gst_pad_pause_task (pad); gst_pad_push_event (pad, gst_event_new_eos ()); } gst_object_unref (gme); return; }
jlong Java_de_illogical_modo_SpcDecoder_spcSeekDirect(JNIEnv* env, jclass clazz, int time) { if (emu == NULL) { return -1; } return gme_seek(emu, time) == NULL; }
jlong Java_de_illogical_modo_GmeDecoder_gmeSeek(JNIEnv* env, jclass clazz, jlong milli) { if (emu == NULL) { return -1; } return gme_seek(emu, gme_tell(emu) + milli) == NULL; }
static int cgme_seek (DB_fileinfo_t *_info, float time) { gme_fileinfo_t *info = (gme_fileinfo_t*)_info; if (gme_seek (info->emu, (long)(time * 1000))) { return -1; } _info->readpos = time; return 0; }
static void deltaseek(media_pipe_t *mp, media_buf_t **mbp, Music_Emu *emu, int delta) { int pos = gme_tell(emu) + delta; if(pos < 0) pos = 0; gme_seek(emu, pos); seekflush(mp, mbp); }
bool GmeDecoder::rewind() { // If we're in the first track, rewind. if (cur_track == 0) return gme_seek(emu, 0) == 0; else { // Otherwise, start from the first track again. cur_track = 0; return gme_start_track(emu, cur_track) == 0; } }
static gint64 xmms_gme_seek (xmms_xform_t *xform, gint64 samples, xmms_xform_seek_mode_t whence, xmms_error_t *err) { xmms_gme_data_t *data; gint64 target_time; gint duration; int samplerate; g_return_val_if_fail (whence == XMMS_XFORM_SEEK_SET, -1); 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); samplerate = data->samplerate; if (samples < 0) { xmms_error_set (err, XMMS_ERROR_INVAL, "Trying to seek before start of stream"); return -1; } target_time = (samples / samplerate) * 1000; xmms_xform_metadata_get_int (xform, XMMS_MEDIALIB_ENTRY_PROPERTY_DURATION, &duration); if (target_time > duration) { xmms_error_set (err, XMMS_ERROR_INVAL, "Trying to seek past end of stream"); return -1; } gme_seek (data->emu, target_time); return (gme_tell (data->emu) / 1000) * samplerate; }
bool GmeDecoder::seek(float s) { return gme_seek(emu, static_cast<long>(s * 1000.f)) != 0; }
JNIEXPORT jboolean JNICALL Java_com_ssb_droidsound_plugins_GMEPlugin_N_1seekTo(JNIEnv *env, jobject obj, jlong song, int where) { GMEInfo *info = (GMEInfo*)song; gme_seek(info->emu, where); return true; }
static int Control (demux_t *demux, int query, va_list args) { demux_sys_t *sys = demux->p_sys; switch (query) { case DEMUX_CAN_SEEK: *va_arg (args, bool *) = true; return VLC_SUCCESS; case DEMUX_GET_POSITION: { double *pos = va_arg (args, double *); if (unlikely(sys->track_id >= sys->titlec) || (sys->titlev[sys->track_id]->i_length == 0)) *pos = 0.; else { int offset = gme_tell (sys->emu); *pos = (double)offset / (double)(sys->titlev[sys->track_id]->i_length / 1000); } return VLC_SUCCESS; } case DEMUX_SET_POSITION: { double pos = va_arg (args, double); if (unlikely(sys->track_id >= sys->titlec) || (sys->titlev[sys->track_id]->i_length == 0)) break; int seek = (sys->titlev[sys->track_id]->i_length / 1000) * pos; if (gme_seek (sys->emu, seek)) break; return VLC_SUCCESS; } case DEMUX_GET_LENGTH: { int64_t *v = va_arg (args, int64_t *); if (unlikely(sys->track_id >= sys->titlec) || (sys->titlev[sys->track_id]->i_length == 0)) break; *v = sys->titlev[sys->track_id]->i_length; return VLC_SUCCESS; } case DEMUX_GET_TIME: { int64_t *v = va_arg (args, int64_t *); *v = gme_tell (sys->emu) * INT64_C(1000); return VLC_SUCCESS; } case DEMUX_SET_TIME: { int64_t v = va_arg (args, int64_t) / 1000; if (v > INT_MAX || gme_seek (sys->emu, v)) break; return VLC_SUCCESS; } case DEMUX_GET_TITLE_INFO: { input_title_t ***titlev = va_arg (args, input_title_t ***); int *titlec = va_arg (args, int *); *(va_arg (args, int *)) = 0; /* Title offset */ *(va_arg (args, int *)) = 0; /* Chapter offset */ unsigned n = sys->titlec; *titlev = malloc (sizeof (**titlev) * n); if (unlikely(*titlev == NULL)) n = 0; *titlec = n; for (unsigned i = 0; i < n; i++) (*titlev)[i] = vlc_input_title_Duplicate (sys->titlev[i]); return VLC_SUCCESS; } case DEMUX_SET_TITLE: { int track_id = va_arg (args, int); if (track_id >= gme_track_count (sys->emu)) break; gme_start_track (sys->emu, track_id); demux->info.i_update |= INPUT_UPDATE_TITLE; demux->info.i_title = track_id; sys->track_id = track_id; return VLC_SUCCESS; } } return VLC_EGENERIC; }
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; }
BBString * bmx_gme_seek(MaxMusicEmu * emu, long msec) { return bbStringFromCString(gme_seek(emu->emu, msec)); }
bool GME::seek(int s, bool) { return !gme_seek(m_gme, s * 1000); }
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; }
void Java_com_example_subtle_SoundMachine_fillBuffer( JNIEnv* env, jobject callingObject, jstring filePath, jshortArray bufferArray, jint myID ) { /* Grab File Path */ const char *file_path = (*env)->GetStringUTFChars(env, filePath, 0); /* Get Class Information */ jclass thisClass = (*env)->GetObjectClass(env, callingObject); /* Open music file in new emulator */ Music_Emu* emu; handle_error( gme_open_file( file_path, &emu, SAMPLE_RATE ) ); /* Get Track Info */ gme_info_t* track_info = NULL; handle_error( gme_track_info( emu, &track_info, TRACK ) ); /* Start track */ handle_error( gme_start_track( emu, TRACK ) ); /* Start Filling Buffer */ jshort current_state = 0; jfieldID fid_playback_command = (*env)->GetFieldID(env, thisClass, "JNIPlaybackCommand", "I"); jfieldID fid_active_thread = (*env)->GetFieldID(env, thisClass, "activeThreadID", "I"); jfieldID fid_seek_to = (*env)->GetFieldID(env, thisClass, "seekTo", "I"); jmethodID mid_write = (*env)->GetMethodID(env, thisClass, "fillBufferCallback", "(I)V"); jsize buffer_size = (*env)->GetArrayLength( env, bufferArray ); jshort *buffer_pointer; jint command; jint currentPosition; jint activeID; jint seekTo; while ( 1 ) { /** * Read Control Commands */ /* Get Control Command */ command = (*env)->GetIntField(env, callingObject, fid_playback_command); /* Get Active Thread ID */ activeID = (*env)->GetIntField(env, callingObject, fid_active_thread); /* Get Seek To */ seekTo = (*env)->GetIntField(env, callingObject, fid_seek_to); /** * Respond to Control Commands */ if ( activeID != myID || command == SIG_STOP ) { // stop or new track is now playing /* Exit */ break; } else if (seekTo != SEEK_STATUS_NOT_SEEKING) { /* Seek */ handle_error( gme_seek ( emu, seekTo ) ); /* Report Seek */ (*env)->CallVoidMethod(env, callingObject, mid_write, SEEK_STATUS_FINISHED_SEEKING); } else if ( command == SIG_PLAY ) { /* If We Finish, Kill Thread */ if (gme_tell( emu ) >= track_info->play_length) { /* Write Buffer */ (*env)->CallVoidMethod(env, callingObject, mid_write, track_info->play_length); // Finished Track /* Exit */ break; } /* Get Java Buffer */ buffer_pointer = (*env)->GetShortArrayElements( env, bufferArray, NULL ); /* Fill sample buffer */ handle_error( gme_play( emu, buffer_size, buffer_pointer ) ); /* Release Java Buffer */ (*env)->ReleaseShortArrayElements( env, bufferArray, buffer_pointer, 0 ); /* Get Current Position */ currentPosition = gme_tell( emu ); /* Write Buffer */ (*env)->CallVoidMethod(env, callingObject, mid_write, currentPosition); } else if ( command == SIG_PAUSE ) { /* Get Current Position */ currentPosition = gme_tell( emu ); /* Write Buffer */ (*env)->CallVoidMethod(env, callingObject, mid_write, currentPosition); /* Sleep */ sleep(.1); } } /* Cleanup */ (*env)->ReleaseStringUTFChars(env, filePath, file_path); gme_free_info( track_info ); gme_delete( emu ); }