예제 #1
0
static gint
xmms_mpc_read (xmms_xform_t *xform, xmms_sample_t *buffer,
               gint len, xmms_error_t *err)
{
    MPC_SAMPLE_FORMAT internal[MPC_DECODER_BUFFER_LENGTH];
    xmms_mpc_data_t *data;
    mpc_uint32_t ret;
    guint size;

    data = xmms_xform_private_data_get (xform);

    size = MIN (data->buffer->len, len);

#ifdef HAVE_MPCDEC_OLD
    if (size <= 0) {
        ret = mpc_decoder_decode (&data->decoder, internal, NULL, NULL);
        if (ret == -1) {
            xmms_error_set (err, XMMS_ERROR_GENERIC, "Musepack decoder failed");
            return -1;
        }

        ret *= xmms_sample_size_get (XMMS_SAMPLE_FORMAT_FLOAT);
        ret *= data->info.channels;

        g_string_append_len (data->buffer, (gchar *) internal, ret);
    }
#else
    if (size <= 0) {
        mpc_frame_info frame;

        frame.buffer = internal;
        do {
            ret = mpc_demux_decode (data->demux, &frame);
        } while (frame.bits != -1 && frame.samples == 0);

        if (frame.bits == -1 && ret != MPC_STATUS_OK) {
            xmms_error_set (err, XMMS_ERROR_GENERIC, "Musepack decoder failed");
            return -1;
        }
        ret = frame.samples;

        ret *= xmms_sample_size_get (XMMS_SAMPLE_FORMAT_FLOAT);
        ret *= data->info.channels;

        g_string_append_len (data->buffer, (gchar *) internal, ret);
    }
#endif

    /* Update the current size of available data */
    size = MIN (data->buffer->len, len);

    memcpy (buffer, data->buffer->str, size);
    g_string_erase (data->buffer, 0, size);

    return size;
}
예제 #2
0
unsigned long decoder_read(unsigned long id, char* adata, unsigned long dsize)
{
	int  cur = 0;

	if(pstreams[id].sample_start)
	{
		int z = min(dsize, (pstreams[id].sample_end - pstreams[id].sample_start));

		memcpy(adata + cur, ((char*)pstreams[id].sample_buffer) + pstreams[id].sample_start, z);
		pstreams[id].sample_start += z;
		cur += z;

		if(pstreams[id].sample_start >= pstreams[id].sample_end)
		{
			pstreams[id].sample_start = 0;
		}
		
		if(cur >= dsize)
			return cur;
	}
	
	for(;;)
	{
		int z;
		int i = mpc_decoder_decode(&pstreams[id].decoder, pstreams[id].sample_buffer, 0, 0);

		i *= sizeof(MPC_SAMPLE_FORMAT);
		i *= pstreams[id].info.channels;

		if(i == 0) break;
		
		z = min(i, dsize - cur);

		memcpy(adata + cur, pstreams[id].sample_buffer, z);

		cur += z;


		if(cur >= dsize)
		{
			if(i > z)
				pstreams[id].sample_start = z;
			pstreams[id].sample_end   = i;
			return cur;
		}
		
		pstreams[id].sample_start = 0;

		
	}

    return cur;
}
예제 #3
0
 int64 Read_(int16 *buffer, int64 frames)
 {
      //  MPC_SAMPLE_FORMAT MPCBuffer[MPC_DECODER_BUFFER_LENGTH];
      //MPC_SAMPLE_FORMAT sample_buffer[MPC_DECODER_BUFFER_LENGTH];
      //  uint32 MPCBufferIn;
      int16 *cowbuf = (int16 *)buffer;
      int32 toread = frames * 2;

      while(toread > 0)
      {
       int32 tmplen;

       if(!MPCBufferIn)
       {
        int status = mpc_decoder_decode(&MPCDecoder, MPCBuffer, 0, 0);
	if(status < 0)
	 break;

        MPCBufferIn = status * 2;
	MPCBufferOffs = 0;
       }

       tmplen = MPCBufferIn;

       if(tmplen >= toread)
        tmplen = toread;

       for(int x = 0; x < tmplen; x++)
       {
	int32 samp = MPCBuffer[MPCBufferOffs + x];
        samp >> 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++;
       }
      
       MPCBufferOffs += tmplen;
       toread -= tmplen;
       MPCBufferIn -= tmplen;
      }

  return(frames - toread / 2);
 }
예제 #4
0
static void
gst_musepackdec_loop (GstPad * sinkpad)
{
    GstMusepackDec *musepackdec;
    GstFlowReturn flow;
    GstBuffer *out;

#ifdef MPC_IS_OLD_API
    guint32 update_acc, update_bits;
#else
    mpc_frame_info frame;
    mpc_status err;
#endif
    gint num_samples, samplerate, bitspersample;

    musepackdec = GST_MUSEPACK_DEC (GST_PAD_PARENT (sinkpad));

    samplerate = g_atomic_int_get (&musepackdec->rate);

    if (samplerate == 0) {
        if (!gst_musepack_stream_init (musepackdec))
            goto pause_task;

        gst_musepackdec_send_newsegment (musepackdec);
        samplerate = g_atomic_int_get (&musepackdec->rate);
    }

    bitspersample = g_atomic_int_get (&musepackdec->bps);

    flow = gst_pad_alloc_buffer_and_set_caps (musepackdec->srcpad, -1,
            MPC_DECODER_BUFFER_LENGTH * 4, GST_PAD_CAPS (musepackdec->srcpad), &out);

    if (flow != GST_FLOW_OK) {
        GST_DEBUG_OBJECT (musepackdec, "Flow: %s", gst_flow_get_name (flow));
        goto pause_task;
    }
#ifdef MPC_IS_OLD_API
    num_samples = mpc_decoder_decode (musepackdec->d,
                                      (MPC_SAMPLE_FORMAT *) GST_BUFFER_DATA (out), &update_acc, &update_bits);

    if (num_samples < 0) {
        GST_ERROR_OBJECT (musepackdec, "Failed to decode sample");
        GST_ELEMENT_ERROR (musepackdec, STREAM, DECODE, (NULL), (NULL));
        goto pause_task;
    } else if (num_samples == 0) {
        goto eos_and_pause;
    }
#else
    frame.buffer = (MPC_SAMPLE_FORMAT *) GST_BUFFER_DATA (out);
    err = mpc_demux_decode (musepackdec->d, &frame);

    if (err != MPC_STATUS_OK) {
        GST_ERROR_OBJECT (musepackdec, "Failed to decode sample");
        GST_ELEMENT_ERROR (musepackdec, STREAM, DECODE, (NULL), (NULL));
        goto pause_task;
    } else if (frame.bits == -1) {
        goto eos_and_pause;
    }

    num_samples = frame.samples;
#endif

    GST_BUFFER_SIZE (out) = num_samples * bitspersample;

    GST_BUFFER_OFFSET (out) = musepackdec->segment.last_stop;
    GST_BUFFER_TIMESTAMP (out) =
        gst_util_uint64_scale_int (musepackdec->segment.last_stop,
                                   GST_SECOND, samplerate);
    GST_BUFFER_DURATION (out) =
        gst_util_uint64_scale_int (num_samples, GST_SECOND, samplerate);

    musepackdec->segment.last_stop += num_samples;

    GST_LOG_OBJECT (musepackdec, "Pushing buffer, timestamp %" GST_TIME_FORMAT,
                    GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (out)));

    flow = gst_pad_push (musepackdec->srcpad, out);
    if (flow != GST_FLOW_OK) {
        GST_DEBUG_OBJECT (musepackdec, "Flow: %s", gst_flow_get_name (flow));
        goto pause_task;
    }

    /* check if we're at the end of a configured segment */
    if (musepackdec->segment.stop != -1 &&
            musepackdec->segment.last_stop >= musepackdec->segment.stop) {
        gint64 stop_time;

        GST_DEBUG_OBJECT (musepackdec, "Reached end of configured segment");

        if ((musepackdec->segment.flags & GST_SEEK_FLAG_SEGMENT) == 0)
            goto eos_and_pause;

        GST_DEBUG_OBJECT (musepackdec, "Posting SEGMENT_DONE message");

        stop_time = gst_util_uint64_scale_int (musepackdec->segment.stop,
                                               GST_SECOND, samplerate);

        gst_element_post_message (GST_ELEMENT (musepackdec),
                                  gst_message_new_segment_done (GST_OBJECT (musepackdec),
                                          GST_FORMAT_TIME, stop_time));

        goto pause_task;
    }

    return;

eos_and_pause:
    {
        GST_DEBUG_OBJECT (musepackdec, "sending EOS event");
        gst_pad_push_event (musepackdec->srcpad, gst_event_new_eos ());
        /* fall through to pause */
    }

pause_task:
    {
        GST_DEBUG_OBJECT (musepackdec, "Pausing task");
        gst_pad_pause_task (sinkpad);
        return;
    }
}
예제 #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);
 }