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; }
/* Play some of a stream previously started with GME_play() */ int GME_playAudio(struct MUSIC_GME *music, Uint8 *stream, int len) { if(music==NULL) return 1; if(music->game_emu==NULL) return 1; if(music->playing==-1) return 1; if( len<0 ) return 0; int srgArraySize = len/music->cvt.len_ratio; short buf[srgArraySize]; int srcLen = (int)((double)(len/2)/music->cvt.len_ratio); char *err = (char*)gme_play( music->game_emu, srcLen, buf ); if( err != NULL) { Mix_SetError("GAME-EMU: %s", err); return 0; } int dest_len = srcLen*2; if( music->cvt.needed ) { music->cvt.len = dest_len; music->cvt.buf = (Uint8*)buf; SDL_ConvertAudio(&music->cvt); dest_len = music->cvt.len_cvt; } if ( music->volume == MIX_MAX_VOLUME ) { SDL_memcpy(stream, (Uint8*)buf, dest_len); } else { SDL_MixAudioFormat(stream, (Uint8*)buf, mixer.format, dest_len, music->volume); } return len-dest_len; }
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; }
// 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; }
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; }
int crPlayerGenerateStereoFrames(void *context, int16_t *samples, int frameCount) { gmeContext *gme = (gmeContext*)context; gme_err_t status; status = gme_play(gme->emu, frameCount * SAMPLES_PER_FRAME, samples); return (status == NULL); }
void Music_Player::fill_buffer( void* data, sample_t* out, int count ) { Music_Player* self = (Music_Player*) data; if ( self->emu_ ) { if ( gme_play( self->emu_, count, out ) ) { } // ignore error if ( self->scope_buf ) memcpy( self->scope_buf, out, self->scope_buf_size * sizeof *self->scope_buf ); } }
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; }
/** * NOT USED */ void Java_com_example_subtle_SoundMachine_convertToWave( JNIEnv* env, jobject callingObject, jstring fromPath, jstring toPath ) { /* Buffer Size */ int buf_size = 1024; /* can be any multiple of 2 */ /* Grab Paths */ const char *from_path = (*env)->GetStringUTFChars(env, fromPath, 0); const char *to_path = (*env)->GetStringUTFChars(env, toPath, 0); /* Open music file in new emulator */ Music_Emu* emu; handle_error( gme_open_file( from_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 ) ); /* Begin writing to wave file */ wave_open( SAMPLE_RATE, to_path ); wave_enable_stereo(); /* Output to Wave */ while ( gme_tell( emu ) < track_info->play_length ) { /* Sample buffer */ short buf [buf_size]; /* Fill sample buffer */ handle_error( gme_play( emu, buf_size, buf ) ); /* Write samples to wave file */ wave_write( buf, buf_size ); } /* Cleanup */ gme_free_info( track_info ); (*env)->ReleaseStringUTFChars(env, fromPath, from_path); (*env)->ReleaseStringUTFChars(env, toPath, to_path); gme_delete( emu ); wave_close(); }
jint Java_de_illogical_modo_GmeDecoder_gmeGetSamples(JNIEnv* env, jclass clazz, jshortArray samples) { if (emu == NULL) { return -1; } // How many samples are needed int sampleCount = (*env)->GetArrayLength(env, samples); // Fill in local playback, no more than 50k, returns NULL on success gme_err_t err = gme_play(emu, sampleCount, localSamples); // copy local buffer to java array (*env)->SetShortArrayRegion(env, samples, 0, sampleCount, localSamples); return err == NULL; }
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; }
int main(int argc, char *argv[]) { const char *filename = "test.nsf"; /* Default file to open */ if ( argc >= 2 ) filename = argv[1]; long sample_rate = 44100; /* number of samples per second */ /* index of track to play (0 = first) */ int track = argc >= 3 ? atoi(argv[2]) : 0; /* Open music file in new emulator */ Music_Emu* emu; handle_error( gme_open_file( filename, &emu, sample_rate ) ); /* Start track */ handle_error( gme_start_track( emu, track ) ); /* Begin writing to wave file */ wave_open( sample_rate, "out.wav" ); wave_enable_stereo(); /* Record 10 seconds of track */ while ( gme_tell( emu ) < 10 * 1000L ) { /* Sample buffer */ #define buf_size 1024 /* can be any multiple of 2 */ short buf [buf_size]; /* Fill sample buffer */ handle_error( gme_play( emu, buf_size, buf ) ); /* Write samples to wave file */ wave_write( buf, buf_size ); } /* Cleanup */ gme_delete( emu ); wave_close(); return 0; }
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; }
BBString * bmx_gme_play(MaxMusicEmu * emu, long count, short * out) { return bbStringFromCString(gme_play(emu->emu, count, out)); }
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; }
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 ); }