static int midi_stream_seek (sfxstream_t *stream, int pos) { unsigned long int new_pos; pos *= stream->wavinfo.width * stream->wavinfo.channels; pos += stream->wavinfo.dataofs; new_pos = pos; return WildMidi_FastSeek(stream->file, &new_pos); }
void MidiPlayerThread::seek( int secs ) { if ( !m_midiPtr ) { qDebug( "MidiPlayerThread::seek: WildMidi library is not initialized" ); return; } _WM_Info *wm_info = WildMidi_GetInfo( m_midiPtr ); qDebug() << "MidiPlayerThread::seek: current sample = " << wm_info->current_sample << ", total samples = " << wm_info->approx_total_samples; ulong sample = ( ulong )m_sample_rate * secs + wm_info->current_sample; qDebug() << "MidiPlayerThread::seek: secs = " << secs << ", sample = " << sample; WildMidi_FastSeek( m_midiPtr, &sample ); }
void midiStreamCallback(void* userData, u32 requestedChunkSize, u8* chunkData) { LOCK(); s32 soundSize = 0; s32 totalSize = 0; while (totalSize < (s32)requestedChunkSize) { if (s_midiFormat == MFMT_GUS_PATCH) { soundSize = WildMidi_GetOutput(s_song, (char*)&chunkData[totalSize], requestedChunkSize-totalSize); } else if (s_midiFormat == MFMT_SOUND_FONT) { if (!s_fluidPlaying) { fluid_player_play( s_fluidPlayer ); fluid_player_set_loop(s_fluidPlayer, -1); s_fluidPlaying = true; } soundSize = fillFluidBuffer(requestedChunkSize, chunkData, s_sampleRate, s_fluidSynth, s_fluidPlayer); } //we've finished the loop, start the song all over again. if (soundSize == 0) { if (s_midiFormat == MFMT_GUS_PATCH) { unsigned long beginning = 0; WildMidi_FastSeek(s_song, &beginning); soundSize = WildMidi_GetOutput(s_song, (char*)&chunkData[totalSize], requestedChunkSize-totalSize); } else if (s_midiFormat == MFMT_SOUND_FONT) { LOG( LOG_ERROR, "midi synthesizer should handle looping." ); } } totalSize += soundSize; }; UNLOCK(); }
static gboolean gst_wildmidi_do_seek (GstWildmidi * wildmidi, GstEvent * event) { gdouble rate; GstFormat src_format, dst_format; GstSeekFlags flags; GstSeekType start_type, stop_type; gint64 start, stop; gboolean flush, update; #ifdef HAVE_WILDMIDI_0_2_2 gboolean accurate; #endif gboolean res; unsigned long int sample; GstSegment *segment; if (!wildmidi->song) return FALSE; gst_event_parse_seek (event, &rate, &src_format, &flags, &start_type, &start, &stop_type, &stop); /* convert the input format to samples */ dst_format = GST_FORMAT_DEFAULT; res = TRUE; if (start_type != GST_SEEK_TYPE_NONE) { res = gst_wildmidi_src_convert (wildmidi, src_format, start, &dst_format, &start); } if (res && stop_type != GST_SEEK_TYPE_NONE) { res = gst_wildmidi_src_convert (wildmidi, src_format, stop, &dst_format, &stop); } /* unsupported format */ if (!res) return res; flush = ((flags & GST_SEEK_FLAG_FLUSH) == GST_SEEK_FLAG_FLUSH); #ifdef HAVE_WILDMIDI_0_2_2 accurate = ((flags & GST_SEEK_FLAG_ACCURATE) == GST_SEEK_FLAG_ACCURATE); #endif if (flush) { GST_DEBUG ("performing flush"); gst_pad_push_event (wildmidi->srcpad, gst_event_new_flush_start ()); } else { gst_pad_stop_task (wildmidi->sinkpad); } segment = wildmidi->o_segment; GST_PAD_STREAM_LOCK (wildmidi->sinkpad); if (flush) { gst_pad_push_event (wildmidi->srcpad, gst_event_new_flush_stop (TRUE)); } /* update the segment now */ gst_segment_do_seek (segment, rate, dst_format, flags, start_type, start, stop_type, stop, &update); /* we need to seek to position in the segment now, sample will be updated */ sample = segment->position; GST_OBJECT_LOCK (wildmidi); #ifdef HAVE_WILDMIDI_0_2_2 if (accurate) { WildMidi_SampledSeek (wildmidi->song, &sample); } else { WildMidi_FastSeek (wildmidi->song, &sample); } #else WildMidi_FastSeek (wildmidi->song, &sample); #endif GST_OBJECT_UNLOCK (wildmidi); segment->start = segment->time = segment->position = sample; gst_pad_push_event (wildmidi->srcpad, gst_wildmidi_get_new_segment_event (wildmidi, GST_FORMAT_TIME)); gst_pad_start_task (wildmidi->sinkpad, (GstTaskFunction) gst_wildmidi_loop, wildmidi->sinkpad, NULL); wildmidi->discont = TRUE; GST_PAD_STREAM_UNLOCK (wildmidi->sinkpad); GST_DEBUG ("seek done"); return TRUE; }