tor' content='cgit v1.2.3-13-gbd6f'/>
aboutsummaryrefslogblamecommitdiff
path: root/src/plugins/Input/flac/decoder_flac.cpp
blob: da6ac3b86564613dd07f7ab5366eb09b1b74d965 (plain) (tree)
1
2
3
                                                                            
                                                                            
                                                                            













                                                                            
                                                                            


                                                                             



                                                               




                               
                               

                                     
                  
                
                    
                             
                     
                   
                           

                         

                                 
                                                  
                                                                 
                                                

                                                               
                         
 


                                           
 
























                                                                      
 



                                               

 
                                                                           
 
                                                            
                     
 
                                  

     
                                                         





                                                      
                                   


                     

     





                                                                



                   
                                                                                    


                            
 
                                                            
                                                           



                     
                                








                                                              

 
                                                                                        


                                          
 
                                                            

                                                          
                    

                                                       

                                     
                                                                     
     
                                                        
         
                                                                                                            

                                                   
 
                                                     


        

                                                                                         
         


                                                                                                          

         
 

                                                                
                                                                 

                                                                   



                                                      
                                                                                     

                             
 
                                                            
                                   

                                                            
                                  


                                               
                                                                                     

                            
 
                                                            
                                   
                                                            
 
                                    



                                                    
                                                                                         

                                    
 
                                                            
                                   

                                                              
                                         


                                                 


                                                                         
 
                                                            




                                                         
                             

                                                               
                               
                                                       


                                                                      
 
                                                                            
         
                                                                    


            
                              
         


     
                                                                         
 
                 

 





                                                                       


                

                                                                         
 
                           
                      

 


                           
               
     


                                                         
                         
     

                       
                    

 

                              
                       
     

                                                             

                                
                                                   

                                                                                         
                                          

                                                                     
 
                                                                      
             
                                                                    


                                                                                                      
                                                          
                                                              

                                                                           
                                 
                 

                                                         
                                                                                               
                 
                                                                               

                                                               
                                                                                                     
                     
                 
                                                                                 



                                                                          
                             



             
                                                                  
                         
         

     
                                 
     
                                                           
                     

     


                                   
                                     



                              




                                                            

                  
                                          



                                                                          
                                        
     

                                         
                                             




                                                        
                         










                                                 
                                                               
         
                         
         
                                                     
                                                   



                                             








                                       
                                                               
         
                         
         
                                                        
                                               

        
     
                                                    
                     


                                                            
                                 
     
                     
     
 
                                                        
                       
     
                                                                                      


                     
                                   

           
                                                            

              
                                                               


              
                                                               

              
                     
     


                
                                               

                                                          
                                                                        
                                                                     


                     
                                         
 
                                             
                

 
                                     
 

                        
                          

 
                                
 
                           
 
 
                                   
 

                                                   
                                                              

                         

                                                                                             
 

 
                                                         
 









                                                                    
                                     


                                  
                                





                                                        
                                                  

















                                                                                           
                                               

                    
                                           
 


                          

                                                      
 
                                                               
     

                               
                                
      

                        
                       

 
                                          

                                                   
                                          

                         

 
                        
 
                                                   
     
                  

                                               

                                                          
                                                                         
                                                         
                                                                     
                         
     
 












                                                                           
 
                                                





























































                                                    
/***************************************************************************
 *   Copyright (C) 2006-2021 by Ilya Kotov                                 *
 *   forkotov02@ya.ru                                                      *
 *                                                                         *
 *   This program is free software; you can redistribute it and/or modify  *
 *   it under the terms of the GNU General Public License as published by  *
 *   the Free Software Foundation; either version 2 of the License, or     *
 *   (at your option) any later version.                                   *
 *                                                                         *
 *   This program is distributed in the hope that it will be useful,       *
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
 *   GNU General Public License for more details.                          *
 *                                                                         *
 *   You should have received a copy of the GNU General Public License     *
 *   along with this program; if not, write to the                         *
 *   Free Software Foundation, Inc.,                                       *
 *   51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.         *
 ***************************************************************************/


/* The code is based on MOC by Damian Pietras <daper@daper.net>
   and libxmms-flac written by Josh Coalson. */


#include <taglib/tag.h>
#include <taglib/fileref.h>
#include <taglib/flacfile.h>
#include <taglib/xiphcomment.h>
#include <taglib/tmap.h>
#include <taglib/id3v2header.h>
#include <taglib/tfilestream.h>
#include <taglib/id3v2framefactory.h>
#include <QObject>
#include <QFile>
#include <QIODevice>
#include <QRegularExpression>
#include <FLAC/all.h>
#include <stdint.h>
#include <qmmp/cueparser.h>
#include "decoder_flac.h"

#define BITRATE_CALC_TIME_MS 2000

static size_t pack_pcm_signed (FLAC__byte *output,
                               const FLAC__int32 * const input[],
                               unsigned samples,
                               unsigned channels, unsigned bps)
{
    unsigned channel = 0;

    uint8_t *data8 = (uint8_t *) output;
    uint16_t *data16 = (uint16_t *) output;
    uint32_t *data32 = (uint32_t *) output;

     for(unsigned sample = 0; sample < samples; sample++)
     {
         for (channel = 0; channel < channels; channel++)
         {
             switch (bps)
             {
             case 8:
                 *data8 = input[channel][sample] & 0xff;
                 data8++;
                 break;
             case 16:
                 *data16 = input[channel][sample] & 0xffffff;
                 data16++;
                 break;
             case 24:
                 *data32 = (input[channel][sample] << 8) & 0xffffff00;
                 data32++;
                 break;
             case 32:
                 *data32 = input[channel][sample];
                 data32++;
                 break;
             }
         }
     }

     if(bps == 24) // we encode to 32-bit words
         bps = 32;

     return samples * channels * bps / 8;
}

static int flac_decode (void *client_data, unsigned char *buf, int buf_len)
{
    flac_data *data = static_cast<flac_data *>(client_data);
    unsigned to_copy;

    if (!data->sample_buffer_fill)
    {

        if (FLAC__stream_decoder_get_state(data->decoder)
                == FLAC__STREAM_DECODER_END_OF_STREAM)
        {
            return 0;
        }

        if (!FLAC__stream_decoder_process_single(
                    data->decoder))
        {
            return 0;
        }
    }

    to_copy = qMin((unsigned)buf_len, data->sample_buffer_fill);
    memcpy (buf, data->sample_buffer, to_copy);
    memmove (data->sample_buffer,
             data->sample_buffer + to_copy,
             data->sample_buffer_fill - to_copy);
    data->sample_buffer_fill -= to_copy;
    return to_copy;
}


static FLAC__StreamDecoderReadStatus flac_callback_read (const FLAC__StreamDecoder*,
        FLAC__byte buffer[],
        size_t *bytes,
        void *client_data)
{
    flac_data *data = static_cast<flac_data *>(client_data);
    qint64 res = data->input->read((char *)buffer, *bytes);

    if (res > 0)
    {
        *bytes = res;
        data->read_bytes += res;
        return FLAC__STREAM_DECODER_READ_STATUS_CONTINUE;
    }
    if (res == 0)
    {
        *bytes = res;
        return FLAC__STREAM_DECODER_READ_STATUS_END_OF_STREAM;
    }

    return FLAC__STREAM_DECODER_READ_STATUS_ABORT;
}

static FLAC__StreamDecoderWriteStatus flac_callback_write (const FLAC__StreamDecoder *d,
        const FLAC__Frame *frame,
        const FLAC__int32* const buffer[],
        void *client_data)
{
    flac_data *data = static_cast<flac_data *>(client_data);