static gint64 xmms_mpc_seek (xmms_xform_t *xform, gint64 offset, xmms_xform_seek_mode_t whence, xmms_error_t *err) { xmms_mpc_data_t *data; data = xmms_xform_private_data_get (xform); g_return_val_if_fail (whence == XMMS_XFORM_SEEK_SET, -1); #ifdef HAVE_MPCDEC_OLD mpc_decoder_seek_sample (&data->decoder, offset); #else mpc_demux_seek_sample (data->demux, offset); #endif g_string_erase (data->buffer, 0, data->buffer->len); return offset; }
bool Seek_(int64 frame_offset) { mpc_decoder_seek_sample(&MPCDecoder, frame_offset); return(true); }
static gboolean gst_musepackdec_handle_seek_event (GstMusepackDec * dec, GstEvent * event) { GstSeekType start_type, stop_type; GstSeekFlags flags; GstSegment segment; GstFormat format; gboolean flush; gdouble rate; gint64 start, stop; gint samplerate; gst_event_parse_seek (event, &rate, &format, &flags, &start_type, &start, &stop_type, &stop); if (format != GST_FORMAT_TIME && format != GST_FORMAT_DEFAULT) { GST_DEBUG_OBJECT (dec, "seek failed: only TIME or DEFAULT format allowed"); return FALSE; } samplerate = g_atomic_int_get (&dec->rate); if (format == GST_FORMAT_TIME) { if (start_type != GST_SEEK_TYPE_NONE) start = gst_util_uint64_scale_int (start, samplerate, GST_SECOND); if (stop_type != GST_SEEK_TYPE_NONE) stop = gst_util_uint64_scale_int (stop, samplerate, GST_SECOND); } flush = ((flags & GST_SEEK_FLAG_FLUSH) == GST_SEEK_FLAG_FLUSH); if (flush) gst_pad_push_event (dec->srcpad, gst_event_new_flush_start ()); else gst_pad_pause_task (dec->sinkpad); /* not _stop_task()? */ GST_PAD_STREAM_LOCK (dec->sinkpad); /* operate on segment copy until we know the seek worked */ segment = dec->segment; gst_segment_set_seek (&segment, rate, GST_FORMAT_DEFAULT, flags, start_type, start, stop_type, stop, NULL); gst_pad_push_event (dec->sinkpad, gst_event_new_flush_stop ()); GST_DEBUG_OBJECT (dec, "segment: [%" G_GINT64_FORMAT "-%" G_GINT64_FORMAT "] = [%" GST_TIME_FORMAT "-%" GST_TIME_FORMAT "]", segment.start, segment.stop, GST_TIME_ARGS (segment.start * GST_SECOND / dec->rate), GST_TIME_ARGS (segment.stop * GST_SECOND / dec->rate)); GST_DEBUG_OBJECT (dec, "performing seek to sample %" G_GINT64_FORMAT, segment.start); if (segment.start < 0 || segment.start >= segment.duration) { GST_WARNING_OBJECT (dec, "seek out of bounds"); goto failed; } #ifdef MPC_IS_OLD_API if (!mpc_decoder_seek_sample (dec->d, segment.start)) goto failed; #else if (mpc_demux_seek_sample (dec->d, segment.start) != MPC_STATUS_OK) goto failed; #endif if ((flags & GST_SEEK_FLAG_SEGMENT) == GST_SEEK_FLAG_SEGMENT) { GST_DEBUG_OBJECT (dec, "posting SEGMENT_START message"); gst_element_post_message (GST_ELEMENT (dec), gst_message_new_segment_start (GST_OBJECT (dec), GST_FORMAT_TIME, gst_util_uint64_scale_int (segment.start, GST_SECOND, dec->rate))); } if (flush) { gst_pad_push_event (dec->srcpad, gst_event_new_flush_stop ()); } gst_segment_set_last_stop (&segment, GST_FORMAT_DEFAULT, segment.start); dec->segment = segment; gst_musepackdec_send_newsegment (dec); GST_DEBUG_OBJECT (dec, "seek successful"); gst_pad_start_task (dec->sinkpad, (GstTaskFunction) gst_musepackdec_loop, dec->sinkpad); GST_PAD_STREAM_UNLOCK (dec->sinkpad); return TRUE; failed: { GST_WARNING_OBJECT (dec, "seek failed"); GST_PAD_STREAM_UNLOCK (dec->sinkpad); return FALSE; } }
int decoder_seek(unsigned long id, double pos) { mpc_decoder_seek_sample(&pstreams[id].decoder, (mpc_uint32_t)(pos * pstreams[id].info.pcm_samples) ); return 0; }
int cdrfile_read_audio_sector(CDRFile *p_cdrfile, void *buf, uint8 *SubPWBuf, lsn_t lsn) { if(SubPWBuf) { memset(SubPWBuf, 0, 96); MakeSubQ(p_cdrfile, lsn, SubPWBuf); } if(p_cdrfile->p_cdio) { if(cdio_read_audio_sector(p_cdrfile->p_cdio, buf, lsn) < 0) { memset(buf, 0, 2352); return(0); } Endian_A16_LE_to_NE(buf, 588 * 2); return(1); } else { track_t track; for(track = p_cdrfile->FirstTrack; track < (p_cdrfile->FirstTrack + p_cdrfile->NumTracks); track++) { if(lsn >= (p_cdrfile->Tracks[track].LSN - p_cdrfile->Tracks[track].pregap) && lsn < (p_cdrfile->Tracks[track].LSN + p_cdrfile->Tracks[track].sectors)) { if(lsn < p_cdrfile->Tracks[track].LSN) { //puts("Pregap read"); memset(buf, 0, 2352); } else { if(p_cdrfile->Tracks[track].sf) { long SeekPos = (p_cdrfile->Tracks[track].FileOffset / 4) + (lsn - p_cdrfile->Tracks[track].LSN) * 588; //printf("%d, %d\n", lsn, p_cdrfile->Tracks[track].LSN); if(p_cdrfile->Tracks[track].LastSamplePos != SeekPos) { //printf("Seek: %d %d\n", SeekPos, p_cdrfile->Tracks[track].LastSamplePos); sf_seek(p_cdrfile->Tracks[track].sf, SeekPos, SEEK_SET); p_cdrfile->Tracks[track].LastSamplePos = SeekPos; } sf_count_t readcount = sf_read_short(p_cdrfile->Tracks[track].sf, (short*)buf, 588 * 2); p_cdrfile->Tracks[track].LastSamplePos += readcount / 2; } else if(p_cdrfile->Tracks[track].ovfile)// vorbis { int cursection = 0; if(p_cdrfile->Tracks[track].LastSamplePos != 588 * (lsn - p_cdrfile->Tracks[track].LSN)) { ov_pcm_seek((OggVorbis_File *)p_cdrfile->Tracks[track].ovfile, (lsn - p_cdrfile->Tracks[track].LSN) * 588); p_cdrfile->Tracks[track].LastSamplePos = 588 * (lsn - p_cdrfile->Tracks[track].LSN); } long toread = 2352; while(toread > 0) { long didread = ov_read((OggVorbis_File *)p_cdrfile->Tracks[track].ovfile, (char*)buf, toread, &cursection); if(didread == 0) { memset(buf, 0, toread); toread = 0; break; } buf = (uint8 *)buf + didread; toread -= didread; p_cdrfile->Tracks[track].LastSamplePos += didread / 4; } } // end if vorbis else if(p_cdrfile->Tracks[track].MPCReaderFile) // MPC { //printf("%d %d\n", (lsn - p_cdrfile->Tracks[track].LSN), p_cdrfile->Tracks[track].LastSamplePos); if(p_cdrfile->Tracks[track].LastSamplePos != 1176 * (lsn - p_cdrfile->Tracks[track].LSN)) { mpc_decoder_seek_sample(p_cdrfile->Tracks[track].MPCDecoder, 588 * (lsn - p_cdrfile->Tracks[track].LSN)); p_cdrfile->Tracks[track].LastSamplePos = 1176 * (lsn - p_cdrfile->Tracks[track].LSN); } //MPC_SAMPLE_FORMAT sample_buffer[MPC_DECODER_BUFFER_LENGTH]; // MPC_SAMPLE_FORMAT MPCBuffer[MPC_DECODER_BUFFER_LENGTH]; // uint32 MPCBufferIn; int16 *cowbuf = (int16 *)buf; int32 toread = 1176; while(toread) { int32 tmplen; if(!p_cdrfile->Tracks[track].MPCBufferIn) { int status = mpc_decoder_decode(p_cdrfile->Tracks[track].MPCDecoder, p_cdrfile->Tracks[track].MPCBuffer, 0, 0); if(status < 0) { printf("Bah\n"); break; } p_cdrfile->Tracks[track].MPCBufferIn = status * 2; p_cdrfile->Tracks[track].MPCBufferOffs = 0; } tmplen = p_cdrfile->Tracks[track].MPCBufferIn; if(tmplen >= toread) tmplen = toread; for(int x = 0; x < tmplen; x++) { int32 samp = p_cdrfile->Tracks[track].MPCBuffer[p_cdrfile->Tracks[track].MPCBufferOffs + x] >> 14; //if(samp < - 32768 || samp > 32767) // This happens with some MPCs of ripped games I've tested, and it's not just 1 or 2 over, and I don't know why! // printf("MPC Sample out of range: %d\n", samp); *cowbuf = (int16)samp; cowbuf++; } p_cdrfile->Tracks[track].MPCBufferOffs += tmplen; toread -= tmplen; p_cdrfile->Tracks[track].LastSamplePos += tmplen; p_cdrfile->Tracks[track].MPCBufferIn -= tmplen; } } else // Binary, woo. { long SeekPos = p_cdrfile->Tracks[track].FileOffset + 2352 * (lsn - p_cdrfile->Tracks[track].LSN); //(lsn - p_cdrfile->Tracks[track].index - p_cdrfile->Tracks[track].pregap); if(p_cdrfile->Tracks[track].SubchannelMode) SeekPos += 96 * (lsn - p_cdrfile->Tracks[track].LSN); if(!fseek(p_cdrfile->Tracks[track].fp, SeekPos, SEEK_SET)) { size_t didread = fread(buf, 1, 2352, p_cdrfile->Tracks[track].fp); if(didread != 2352) { if(didread < 0) didread = 0; memset((uint8*)buf + didread, 0, 2352 - didread); } if(SubPWBuf && p_cdrfile->Tracks[track].SubchannelMode) { fread(SubPWBuf, 1, 96, p_cdrfile->Tracks[track].fp); } if(p_cdrfile->Tracks[track].RawAudioMSBFirst) Endian_A16_BE_to_NE(buf, 588 * 2); else Endian_A16_LE_to_NE(buf, 588 * 2); } else memset(buf, 0, 2352); } } // end if audible part of audio track read. break; } // End if LSN is in range } // end track search loop if(track == (p_cdrfile->FirstTrack + p_cdrfile->NumTracks)) { memset(buf, 0, 2352); return(0); } return(1); }