示例#1
0
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;
}
示例#2
0
 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;
    }
}
示例#4
0
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;
}
示例#5
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);
 }