[Flac-dev] Re: Reg. FLAC decoding

Josh Coalson xflac at yahoo.com
Fri Sep 30 10:44:09 PDT 2005


I can't be totally sure what 'short' is on your platform, but if
it's (probably) 16-bits, it looks like you're treating the samples
in buffer[] as packed 16 bit numbers.

but all samples in buffer[] are 32-bit signed integers in host
order, regardless of the bits-per-sample of the frame.  so to get
them down to shorts (assuming they'll fit), do like:

  FLAC__int32 * LChannel = buffer[0];
  short TempSource = (short)LChannel[LPos];

instead of

  LChannel = (unsigned char *)buffer[0];
  short * TempSource = (short *)&LChannel[LPos];

etc.

also, it's probably faster and safer to get the #channels,
bits-per-sample, and sample rate from the the frame header
itself, e.g.

  channels = frame->header.channels
  sample_rate = frame->header.sample_rate
  bits_per_sample = frame->header.bits_per_sample

c.f. http://flac.sourceforge.net/api/structFLAC____FrameHeader.html

let me know if this works or if you have other questions.

Josh


--- Joe Steeve <joesteeve at zodiactorp.com> wrote:

> 
> 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/


		
__________________________________ 
Yahoo! Mail - PC Magazine Editors' Choice 2005 
http://mail.yahoo.com


More information about the Flac-dev mailing list