static void *timidity_open (const char *file) { struct timidity_data *data = make_timidity_data(file); if(data->midisong) { data->length = mid_song_get_total_time(data->midisong); } if(data->midisong) { debug ("Opened file %s", file); mid_song_set_volume(data->midisong, options_get_int("TiMidity_Volume")); mid_song_start(data->midisong); } return data; }
void MidiDecoder::start() { if (!d->initialized) { QIODevice::open(QIODevice::ReadWrite | QIODevice::Unbuffered); d->options.rate = d->outputInfo.frequency; d->options.format = MID_AUDIO_S16LSB; // 16 d->options.channels = d->outputInfo.channels; d->options.buffer_size = MIDI_BUFFER_SIZE / (16 * 2 / 8); d->midiStream = mid_istream_open_callbacks(midiReadCallback, midiCloseCallback, this); d->song = mid_song_load(d->midiStream, &d->options); if (d->song != 0) { d->state = QtopiaMedia::Playing; d->length = mid_song_get_total_time(d->song); emit lengthChanged(d->length); mid_song_set_volume(d->song, d->muted ? 0 : d->volume * 2); mid_song_start(d->song); d->initialized = true; } else { qLog(Media) << "MidiDecoder::start(); Failed to load MIDI file"; d->state = QtopiaMedia::Error; } } else d->state = QtopiaMedia::Playing; if (d->initialized) { emit readyRead(); emit playerStateChanged(d->state); } }
void MusicDriver_LibTimidity::PlaySong(const char *filename) { this->StopSong(); _midi.stream = mid_istream_open_file(filename); if (_midi.stream == NULL) { DEBUG(driver, 0, "Could not open music file"); return; } _midi.song = mid_song_load(_midi.stream, &_midi.options); mid_istream_close(_midi.stream); _midi.song_length = mid_song_get_total_time(_midi.song); if (_midi.song == NULL) { DEBUG(driver, 1, "Invalid MIDI file"); return; } mid_song_start(_midi.song); _midi.status = MIDI_PLAYING; }
//private: qint64 MidiDecoder::readData(char *data, qint64 maxlen) { if (d->state != QtopiaMedia::Playing) return 0; qint64 rc = 0; if (maxlen > 0) { quint32 position = (mid_song_get_time(d->song) / 1000) * 1000; if (d->position != position) { d->position = position; emit positionChanged(d->position); } if ((rc = (qint64) mid_song_read_wave(d->song, data, maxlen)) == 0) { seek(0); mid_song_start(d->song); emit playerStateChanged(d->state = QtopiaMedia::Stopped); } } return rc; }
static void gst_timidity_loop (GstPad * sinkpad) { GstTimidity *timidity = GST_TIMIDITY (GST_PAD_PARENT (sinkpad)); GstBuffer *out; GstFlowReturn ret; if (timidity->mididata_size == 0) { if (!gst_timidity_get_upstream_size (timidity, &timidity->mididata_size)) { GST_ELEMENT_ERROR (timidity, STREAM, DECODE, (NULL), ("Unable to get song length")); goto paused; } if (timidity->mididata) g_free (timidity->mididata); timidity->mididata = g_malloc (timidity->mididata_size); timidity->mididata_offset = 0; return; } if (timidity->mididata_offset < timidity->mididata_size) { GstBuffer *buffer; gint64 size; GST_DEBUG_OBJECT (timidity, "loading song"); ret = gst_pad_pull_range (timidity->sinkpad, timidity->mididata_offset, -1, &buffer); if (ret != GST_FLOW_OK) { GST_ELEMENT_ERROR (timidity, STREAM, DECODE, (NULL), ("Unable to load song")); goto paused; } size = timidity->mididata_size - timidity->mididata_offset; if (GST_BUFFER_SIZE (buffer) < size) size = GST_BUFFER_SIZE (buffer); memmove (timidity->mididata + timidity->mididata_offset, GST_BUFFER_DATA (buffer), size); gst_buffer_unref (buffer); timidity->mididata_offset += size; GST_DEBUG_OBJECT (timidity, "Song loaded"); return; } if (!timidity->song) { MidIStream *stream; GstTagList *tags = NULL; gchar *text; GST_DEBUG_OBJECT (timidity, "Parsing song"); stream = mid_istream_open_mem (timidity->mididata, timidity->mididata_size, 0); timidity->song = mid_song_load (stream, timidity->song_options); mid_istream_close (stream); if (!timidity->song) { GST_ELEMENT_ERROR (timidity, STREAM, DECODE, (NULL), ("Unable to parse midi")); goto paused; } mid_song_start (timidity->song); timidity->o_len = (GST_MSECOND * (GstClockTime) mid_song_get_total_time (timidity->song)) / timidity->time_per_frame; gst_segment_set_newsegment (timidity->o_segment, FALSE, 1.0, GST_FORMAT_DEFAULT, 0, GST_CLOCK_TIME_NONE, 0); gst_pad_push_event (timidity->srcpad, gst_timidity_get_new_segment_event (timidity, GST_FORMAT_TIME, FALSE)); /* extract tags */ text = mid_song_get_meta (timidity->song, MID_SONG_TEXT); if (text) { tags = gst_tag_list_new (); gst_tag_list_add (tags, GST_TAG_MERGE_APPEND, GST_TAG_TITLE, text, NULL); //g_free (text); } text = mid_song_get_meta (timidity->song, MID_SONG_COPYRIGHT); if (text) { if (tags == NULL) tags = gst_tag_list_new (); gst_tag_list_add (tags, GST_TAG_MERGE_APPEND, GST_TAG_COPYRIGHT, text, NULL); //g_free (text); } if (tags) { gst_element_found_tags (GST_ELEMENT (timidity), tags); } GST_DEBUG_OBJECT (timidity, "Parsing song done"); return; } if (timidity->o_segment_changed) { GstSegment *segment = gst_timidity_get_segment (timidity, GST_FORMAT_TIME, !timidity->o_new_segment); GST_LOG_OBJECT (timidity, "sending newsegment from %" GST_TIME_FORMAT "-%" GST_TIME_FORMAT ", pos=%" GST_TIME_FORMAT, GST_TIME_ARGS ((guint64) segment->start), GST_TIME_ARGS ((guint64) segment->stop), GST_TIME_ARGS ((guint64) segment->time)); if (timidity->o_segment->flags & GST_SEEK_FLAG_SEGMENT) { gst_element_post_message (GST_ELEMENT (timidity), gst_message_new_segment_start (GST_OBJECT (timidity), segment->format, segment->start)); } gst_segment_free (segment); timidity->o_segment_changed = FALSE; return; } if (timidity->o_seek) { /* perform a seek internally */ timidity->o_segment->last_stop = timidity->o_segment->time; mid_song_seek (timidity->song, (timidity->o_segment->last_stop * timidity->time_per_frame) / GST_MSECOND); } out = gst_timidity_get_buffer (timidity); if (!out) { GST_LOG_OBJECT (timidity, "Song ended, generating eos"); gst_pad_push_event (timidity->srcpad, gst_event_new_eos ()); timidity->o_seek = FALSE; goto paused; } if (timidity->o_seek) { GST_BUFFER_FLAG_SET (out, GST_BUFFER_FLAG_DISCONT); timidity->o_seek = FALSE; } gst_buffer_set_caps (out, timidity->out_caps); ret = gst_pad_push (timidity->srcpad, out); if (GST_FLOW_IS_FATAL (ret) || ret == GST_FLOW_NOT_LINKED) goto error; return; paused: { GST_DEBUG_OBJECT (timidity, "pausing task"); gst_pad_pause_task (timidity->sinkpad); return; } error: { GST_ELEMENT_ERROR (timidity, STREAM, FAILED, ("Internal data stream error"), ("Streaming stopped, reason %s", gst_flow_get_name (ret))); gst_pad_push_event (timidity->srcpad, gst_event_new_eos ()); goto paused; } }