[Flac-dev] Reg. FLAC decoding

Joe Steeve joesteeve at zodiactorp.com
Fri Sep 30 01:00:21 PDT 2005


I'm using seekable_stream_decoder, And., this is my write_callback. I'm
not getting the required output. The PCM i get is not the proper music.
Am I doing something wrong here?

FLAC__StreamDecoderWriteStatus
AFLACStreamPlayer::StreamWriteCb (
	const FLAC__SeekableStreamDecoder *decoder,
	const FLAC__Frame *frame, 
	const FLAC__int32 * const buffer[],
	void *client_data)
{
  int Channels, BitsPerSample, BytesPerSample;
  RMstatus ret;

  AFLACStreamPlayer *pThis = (AFLACStreamPlayer *)client_data;
  pThis = (AFLACStreamPlayer *)client_data;

  /* Query the m_AppPlayerPipe and check for commands from it. Act
   * accordingly */
  pThis->QueryCommand ();

  Channels = FLAC__seekable_stream_decoder_get_channels
					(pThis->m_Decoder);
  BitsPerSample = 
	FLAC__seekable_stream_decoder_get_bits_per_sample 
					(pThis->m_Decoder);
  pThis->m_AudioSettings.PcmCdaParams.BitsPerSample = BitsPerSample;
  pThis->m_AudioSettings.PcmCdaParams.SamplingFrequency = 
		FLAC__seekable_stream_decoder_get_sample_rate 					(pThis->m_Decoder);
  pThis->ApplyAudioDecoderSettingsOnTheFly ();

  unsigned char *LChannel, *RChannel;
  unsigned int RPos, LPos;
	
  LChannel = RChannel = (unsigned char *)buffer[0];
  if (Channels > 1)
 	RChannel = (unsigned char *)buffer[1];
  
  BytesPerSample = BitsPerSample >> 3;
  LPos = RPos = 0;

 /* Copy the decoded audio data to the DMA buffer. We have to
  * interleave the channels. When the DMA buffer is full, we've to
  * send it to the chip. And once the data is sent, we'll clear the
  * buffer up */

  while (1)
	{
		
	 /* If the 1MB buffer becomes., full we'll have to send it out
	  * to the chip and create a new buffer */
	  if ((pThis->m_Position + (BytesPerSample * 2)) < 0x100000)
	  {
		short * TempDest =
			(short*)(&pThis->m_TempBuffer[pThis->m_Position]);

			short * TempSource = (short *)&LChannel[LPos];

			*TempDest = *TempSource;
			TempSource = (short *)&RChannel[RPos];

			TempDest ++;
			*TempDest = *TempSource;

			LPos = LPos + BytesPerSample;
			RPos = RPos + BytesPerSample;
			pThis->m_Position = pThis->m_Position + (BytesPerSample<<1);

			if ((LPos >frame->header.blocksize) || 
				(RPos >frame->header.blocksize))
			{
				SystemText ("Huge buffer : %d", pThis->m_Position);
				break;
			}
			continue;
		}

		SystemText ("The huge buffer is full. Now playing it.");
		unsigned int val = pThis->m_Position;
		unsigned int pos = 0;
		while (1)
		{
			unsigned int size;
			while ( RUAGetBuffer ((RMuint8 *)&pThis->m_DMABuff) != RM_OK );
			pThis->m_DMAPos = 0;

			
			if ((val - pos) < (1<<DMA_BUFFER_SIZE_LOG2))
				size = (val - pos);
			else
				size = (1<<DMA_BUFFER_SIZE_LOG2);

			memcpy ((void *)pThis->m_DMABuff, 
					(void*)&pThis->m_TempBuffer[pos],
					size);
			pos = pos + size;			
			
			/* Now send the decoded buffer to the chip */
			ret = RUASendData (pThis->m_DMABuff, size);

			/* Finally release the DMA buffer. */
			RUAReleaseBuffer(pThis->m_DMABuff);

			if (pos == val)
				break;
			else
				SystemText ("Playing %d", pos);
		}

		pThis->m_Position = 0;
	}

	return FLAC__STREAM_DECODER_WRITE_STATUS_CONTINUE;
}


-- 
Joe Steeve (http://www.joesteeve.org/)
Z500 Development team (http://www.z500series.com/)

Terminus Graphics Studios
http://www.terminus.in/



More information about the Flac-dev mailing list