2c4d93f1037fb55aa9857a41c22077e3663570d6
[vuplus_xbmc] / xbmc / cores / paplayer / FLACcodec.cpp
1 /*
2  *      Copyright (C) 2005-2013 Team XBMC
3  *      http://xbmc.org
4  *
5  *  This Program is free software; you can redistribute it and/or modify
6  *  it under the terms of the GNU General Public License as published by
7  *  the Free Software Foundation; either version 2, or (at your option)
8  *  any later version.
9  *
10  *  This Program is distributed in the hope that it will be useful,
11  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
12  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13  *  GNU General Public License for more details.
14  *
15  *  You should have received a copy of the GNU General Public License
16  *  along with XBMC; see the file COPYING.  If not, see
17  *  <http://www.gnu.org/licenses/>.
18  *
19  */
20
21 #include "FLACcodec.h"
22 #include "utils/log.h"
23 #include "cores/AudioEngine/Utils/AEUtil.h"
24 #include "music/tags/TagLoaderTagLib.h"
25
26 FLACCodec::FLACCodec()
27 {
28   m_SampleRate = 0;
29   m_Channels = 0;
30   m_BitsPerSample = 0;
31   m_DataFormat = AE_FMT_INVALID;
32   m_TotalTime=0;
33   m_Bitrate = 0;
34   m_CodecName = "flac";
35
36   m_pFlacDecoder=NULL;
37
38   m_pBuffer=NULL;
39   m_BufferSize=0;
40   m_MaxFrameSize=0;
41
42 }
43
44 FLACCodec::~FLACCodec()
45 {
46   DeInit();
47 }
48
49 bool FLACCodec::Init(const CStdString &strFile, unsigned int filecache)
50 {
51   if (!m_dll.Load())
52     return false;
53
54   if (!m_file.Open(strFile, READ_CACHED))
55     return false;
56
57   //  Extract ReplayGain info
58   CTagLoaderTagLib tagLoaderTagLib;
59   tagLoaderTagLib.Load(strFile, m_tag, "flac");
60
61   m_pFlacDecoder=m_dll.FLAC__stream_decoder_new();
62
63   if (!m_pFlacDecoder)
64   {
65     CLog::Log(LOGERROR, "FLACCodec: Error creating decoder");
66     return false;
67   }
68
69   if (m_dll.FLAC__stream_decoder_init_stream(m_pFlacDecoder, DecoderReadCallback,
70                                                              DecoderSeekCallback,
71                                                              DecoderTellCallback,
72                                                              DecoderLengthCallback,
73                                                              DecoderEofCallback,
74                                                              DecoderWriteCallback,
75                                                              DecoderMetadataCallback,
76                                                              DecoderErrorCallback,
77                                                              this) != FLAC__STREAM_DECODER_INIT_STATUS_OK)
78   {
79     CLog::Log(LOGERROR, "FLACCodec: Error initializing decoder");
80     FreeDecoder();
81     return false;
82   }
83
84   //  Process metadata like number of channels...
85   if (!m_dll.FLAC__stream_decoder_process_until_end_of_metadata(m_pFlacDecoder))
86   {
87     CLog::Log(LOGERROR, "FLACCodec: Error while processing metadata");
88     FreeDecoder();
89     return false;
90   }
91
92   //  These are filled by the metadata callback
93   if (m_SampleRate==0 || m_Channels==0 || m_BitsPerSample==0 || m_TotalTime==0 || m_MaxFrameSize==0 || m_DataFormat == AE_FMT_INVALID)
94   {
95     CLog::Log(LOGERROR, "FLACCodec: Can't get stream info, SampleRate=%i, Channels=%i, BitsPerSample=%i, TotalTime=%"PRIu64", MaxFrameSize=%i", m_SampleRate, m_Channels, m_BitsPerSample, m_TotalTime, m_MaxFrameSize);
96     FreeDecoder();
97     return false;
98   }
99
100   m_Bitrate = (int)(((float)m_file.GetLength() * 8) / ((float)m_TotalTime / 1000));
101
102   if (m_pBuffer)
103   {
104     delete[] m_pBuffer;
105     m_pBuffer=NULL;
106   }
107   //  allocate the buffer to hold the audio data,
108   //  it is 5 times bigger then a single decoded frame
109   m_pBuffer=new BYTE[m_MaxFrameSize*5];
110
111   return true;
112 }
113
114 void FLACCodec::DeInit()
115 {
116   FreeDecoder();
117   m_file.Close();
118
119   if (m_pBuffer)
120   {
121     delete[] m_pBuffer;
122     m_pBuffer=NULL;
123   }
124 }
125
126 int64_t FLACCodec::Seek(int64_t iSeekTime)
127 {
128   //  Seek to the nearest sample
129   // set the buffer size to 0 first, as this invokes a WriteCallback which
130   // may be called when the buffer is almost full (resulting in a buffer
131   // overrun unless we reset m_BufferSize first).
132   m_BufferSize=0;
133   if(!m_dll.FLAC__stream_decoder_seek_absolute(m_pFlacDecoder, (int64_t)(iSeekTime*m_SampleRate)/1000))
134     CLog::Log(LOGERROR, "FLACCodec::Seek - failed to seek");
135
136   if(m_dll.FLAC__stream_decoder_get_state(m_pFlacDecoder)==FLAC__STREAM_DECODER_SEEK_ERROR)
137   {
138     CLog::Log(LOGINFO, "FLACCodec::Seek - must reset decoder after seek");
139     if(!m_dll.FLAC__stream_decoder_flush(m_pFlacDecoder))
140       CLog::Log(LOGERROR, "FLACCodec::Seek - flush failed");
141   }
142
143   return iSeekTime;
144 }
145
146 int FLACCodec::ReadPCM(BYTE *pBuffer, int size, int *actualsize)
147 {
148   *actualsize=0;
149
150   bool eof=false;
151   if (m_dll.FLAC__stream_decoder_get_state(m_pFlacDecoder)==FLAC__STREAM_DECODER_END_OF_STREAM)
152     eof=true;
153
154   if (!eof)
155   {
156     //  fill our buffer 4 decoded frame (the buffer could hold 5)
157     while(m_BufferSize < m_MaxFrameSize*4 &&
158           m_dll.FLAC__stream_decoder_get_state(m_pFlacDecoder)!=FLAC__STREAM_DECODER_END_OF_STREAM)
159     {
160       if (!m_dll.FLAC__stream_decoder_process_single(m_pFlacDecoder))
161       {
162         CLog::Log(LOGERROR, "FLACCodec: Error decoding single block");
163         return READ_ERROR;
164       }
165     }
166   }
167
168   if (size<m_BufferSize)
169   { //  do we need less audio data then in our buffer
170     memcpy(pBuffer, m_pBuffer, size);
171     memmove(m_pBuffer, m_pBuffer+size, m_BufferSize-size);
172     m_BufferSize-=size;
173     *actualsize=size;
174   }
175   else
176   {
177     memcpy(pBuffer, m_pBuffer, m_BufferSize);
178     *actualsize=m_BufferSize;
179     m_BufferSize=0;
180   }
181
182   if (eof && m_BufferSize==0)
183     return READ_EOF;
184
185   return READ_SUCCESS;
186 }
187
188 bool FLACCodec::CanInit()
189 {
190   return m_dll.CanLoad();
191 }
192
193 void FLACCodec::FreeDecoder()
194 {
195   if (m_pFlacDecoder)
196   {
197     m_dll.FLAC__stream_decoder_finish(m_pFlacDecoder);
198     m_dll.FLAC__stream_decoder_delete(m_pFlacDecoder);
199     m_pFlacDecoder=NULL;
200   }
201 }
202
203 FLAC__StreamDecoderReadStatus FLACCodec::DecoderReadCallback(const FLAC__StreamDecoder *decoder, FLAC__byte buffer[], size_t *bytes, void *client_data)
204 {
205   FLACCodec* pThis=(FLACCodec*)client_data;
206   if (!pThis)
207     return FLAC__STREAM_DECODER_READ_STATUS_ABORT;
208
209   *bytes=pThis->m_file.Read(buffer, *bytes);
210
211   if (*bytes==0)
212     return FLAC__STREAM_DECODER_READ_STATUS_END_OF_STREAM;
213   else
214     return FLAC__STREAM_DECODER_READ_STATUS_CONTINUE;
215 }
216
217 FLAC__StreamDecoderSeekStatus FLACCodec::DecoderSeekCallback(const FLAC__StreamDecoder *decoder, FLAC__uint64 absolute_byte_offset, void *client_data)
218 {
219   FLACCodec* pThis=(FLACCodec*)client_data;
220   if (!pThis)
221     return FLAC__STREAM_DECODER_SEEK_STATUS_ERROR;
222
223   if (pThis->m_file.Seek(absolute_byte_offset, SEEK_SET)<0)
224     return FLAC__STREAM_DECODER_SEEK_STATUS_ERROR;
225
226
227   return FLAC__STREAM_DECODER_SEEK_STATUS_OK;
228 }
229
230 FLAC__StreamDecoderTellStatus FLACCodec::DecoderTellCallback(const FLAC__StreamDecoder *decoder, FLAC__uint64 *absolute_byte_offset, void *client_data)
231 {
232   FLACCodec* pThis=(FLACCodec*)client_data;
233   if (!pThis)
234     return FLAC__STREAM_DECODER_TELL_STATUS_ERROR;
235
236   *absolute_byte_offset=pThis->m_file.GetPosition();
237
238   return FLAC__STREAM_DECODER_TELL_STATUS_OK;
239 }
240
241 FLAC__StreamDecoderLengthStatus FLACCodec::DecoderLengthCallback(const FLAC__StreamDecoder *decoder, FLAC__uint64 *stream_length, void *client_data)
242 {
243   FLACCodec* pThis=(FLACCodec*)client_data;
244   if (!pThis)
245     return FLAC__STREAM_DECODER_LENGTH_STATUS_ERROR;
246
247   *stream_length=pThis->m_file.GetLength();
248
249   return FLAC__STREAM_DECODER_LENGTH_STATUS_OK;
250 }
251
252 FLAC__bool FLACCodec::DecoderEofCallback(const FLAC__StreamDecoder *decoder, void *client_data)
253 {
254   FLACCodec* pThis=(FLACCodec*)client_data;
255   if (!pThis)
256     return true;
257
258   return (pThis->m_file.GetLength()==pThis->m_file.GetPosition());
259 }
260
261 FLAC__StreamDecoderWriteStatus FLACCodec::DecoderWriteCallback(const FLAC__StreamDecoder *decoder, const FLAC__Frame *frame, const FLAC__int32 * const buffer[], void *client_data)
262 {
263   FLACCodec* pThis=(FLACCodec*)client_data;
264   if (!pThis)
265     return FLAC__STREAM_DECODER_WRITE_STATUS_ABORT;
266
267   const int bytes_per_sample = frame->header.bits_per_sample/8;
268   BYTE* outptr = pThis->m_pBuffer+pThis->m_BufferSize;
269   FLAC__int16* outptr16 = (FLAC__int16 *) outptr;
270   FLAC__int32* outptr32 = (FLAC__int32 *) outptr;
271
272   unsigned int current_sample = 0;
273   for(current_sample = 0; current_sample < frame->header.blocksize; current_sample++)
274   {
275     for(unsigned int channel = 0; channel < frame->header.channels; channel++)
276     {
277       switch(bytes_per_sample)
278       {
279         case 2:
280           outptr16[current_sample*frame->header.channels + channel] = (FLAC__int16) buffer[channel][current_sample];
281           break;
282         case 3:
283           outptr[2] = (buffer[channel][current_sample] >> 16) & 0xff;
284           outptr[1] = (buffer[channel][current_sample] >> 8 ) & 0xff;
285           outptr[0] = (buffer[channel][current_sample] >> 0 ) & 0xff;
286           outptr += bytes_per_sample;
287           break;
288         default:
289           outptr32[current_sample*frame->header.channels + channel] = buffer[channel][current_sample];
290           break;
291       }
292     }
293   }
294
295   if (bytes_per_sample == 1)
296   {
297     for(unsigned int i=0;i<current_sample;i++)
298     {
299       BYTE* outptr=pThis->m_pBuffer+pThis->m_BufferSize;
300       outptr[i]^=0x80;
301     }
302   }
303
304   pThis->m_BufferSize += current_sample*bytes_per_sample*frame->header.channels;
305
306   return FLAC__STREAM_DECODER_WRITE_STATUS_CONTINUE;
307 }
308
309 void FLACCodec::DecoderMetadataCallback(const FLAC__StreamDecoder *decoder, const FLAC__StreamMetadata *metadata, void *client_data)
310 {
311   FLACCodec* pThis=(FLACCodec*)client_data;
312   if (!pThis)
313     return;
314
315   if (metadata->type==FLAC__METADATA_TYPE_STREAMINFO)
316   {
317     static enum AEChannel map[8][9] = {
318       {AE_CH_FC, AE_CH_NULL},
319       {AE_CH_FL, AE_CH_FR, AE_CH_NULL},
320       {AE_CH_FL, AE_CH_FR, AE_CH_FC, AE_CH_NULL},
321       {AE_CH_FL, AE_CH_FR, AE_CH_BL, AE_CH_BR, AE_CH_NULL},
322       {AE_CH_FL, AE_CH_FR, AE_CH_FC, AE_CH_BL, AE_CH_BR, AE_CH_NULL},
323       {AE_CH_FL, AE_CH_FR, AE_CH_FC, AE_CH_LFE, AE_CH_BL, AE_CH_BR, AE_CH_NULL}, // 6 channels
324       {AE_CH_FL, AE_CH_FR, AE_CH_FC, AE_CH_LFE, AE_CH_BC, AE_CH_BL, AE_CH_BR, AE_CH_NULL}, // 7 channels
325       {AE_CH_FL, AE_CH_FR, AE_CH_FC, AE_CH_LFE, AE_CH_BL, AE_CH_BR, AE_CH_SL, AE_CH_SR, AE_CH_NULL} // 8 channels
326     };
327
328     /* channel counts greater then 6 are undefined */
329     if (metadata->data.stream_info.channels > 8)
330       pThis->m_ChannelInfo = CAEUtil::GuessChLayout(metadata->data.stream_info.channels);
331     else
332       pThis->m_ChannelInfo = CAEChannelInfo(map[metadata->data.stream_info.channels - 1]);
333
334     pThis->m_SampleRate    = metadata->data.stream_info.sample_rate;
335     pThis->m_Channels      = metadata->data.stream_info.channels;
336     pThis->m_BitsPerSample = metadata->data.stream_info.bits_per_sample;
337     switch(pThis->m_BitsPerSample)
338     {
339       case  8: pThis->m_DataFormat = AE_FMT_U8;     break;
340       case 16: pThis->m_DataFormat = AE_FMT_S16NE;  break;
341       case 24: pThis->m_DataFormat = AE_FMT_S24NE3; break;
342       case 32: pThis->m_DataFormat = AE_FMT_FLOAT;  break;
343     }
344     pThis->m_TotalTime     = (int64_t)metadata->data.stream_info.total_samples * 1000 / metadata->data.stream_info.sample_rate;
345     pThis->m_MaxFrameSize  = metadata->data.stream_info.max_blocksize*(pThis->m_BitsPerSample/8)*pThis->m_Channels;
346   }
347 }
348
349 void FLACCodec::DecoderErrorCallback(const FLAC__StreamDecoder *decoder, FLAC__StreamDecoderErrorStatus status, void *client_data)
350 {
351   CLog::Log(LOGERROR, "FLACCodec: Read error %i", status);
352 }