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