videoeditorengine/audioeditorengine/resampler/src/resampler_sinc_conv_44_to_48_int16.cpp
changeset 0 951a5db380a0
equal deleted inserted replaced
-1:000000000000 0:951a5db380a0
       
     1 /*
       
     2 * Copyright (c) 2010 Ixonos Plc.
       
     3 * All rights reserved.
       
     4 * This component and the accompanying materials are made available
       
     5 * under the terms of the "Eclipse Public License v1.0"
       
     6 * which accompanies this distribution, and is available
       
     7 * at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     8 *
       
     9 * Initial Contributors:
       
    10 * Nokia Corporation - Initial contribution
       
    11 *
       
    12 * Contributors:
       
    13 * Ixonos Plc
       
    14 *
       
    15 * Description:
       
    16 *
       
    17 */
       
    18 
       
    19 
       
    20 #include "resampler_sinc_conv_44_to_48_int16.h"
       
    21 #include "resampler_clip.h"
       
    22 #include "resampler_sinc_conv_44_to_48_tables_economy.h"
       
    23 #include "resampler_sinc_conv_44_to_48_tables_standard.h"
       
    24 #include "resampler_sinc_conv_44_to_48_tables_premium.h"
       
    25 
       
    26 #include <string.h>
       
    27 
       
    28 #include "resampler_sinc_conv_filter_int16.h"
       
    29 
       
    30 /*
       
    31  * The amount of zero crossings in positive or negative
       
    32  * side of the sinc function. Because of filter symmetry
       
    33  * the amount of filter taps used in convolution is
       
    34  * zero crossings * 2.
       
    35  */
       
    36 static const int LC_MAX_ZERO_CROSSINGS = RESAMPLER_44_TO_48_ZERO_CROSSINGS_PREMIUM;
       
    37 
       
    38 static const int LC_BUFFER_ACCESS_OUTPUT = LC_MAX_ZERO_CROSSINGS;
       
    39 
       
    40 /*
       
    41  * The number of filters needed in 44.1 to 48 kHz sinc interpolation
       
    42  * sampling rate conversion. Filter symmetry is utilized.
       
    43  */
       
    44 static const int LC_FILTER_COUNT = 160;
       
    45 
       
    46 /*
       
    47  * Calculated as 160-147.
       
    48  * 147/160 is the smallest ratio of 44100/48000.
       
    49  * Used as a hop increment in the filter table defined below.
       
    50  */
       
    51 static const int LC_MATRIX_HOP_SIZE = 13;       
       
    52 
       
    53 /*
       
    54  * This constant is calculated as ceil(2^23/160).
       
    55  * and used in InSamplesNeeded() method to 
       
    56  * avoid the division by 160. The result of the multiplication
       
    57  * has to be shifted afterwards by 23 bits right.
       
    58  */
       
    59 static const int LC_SAMPLE_COUNT_MULT = 52429;   
       
    60 
       
    61 /** Do not remove! LC_MAX_BLOCK_SIZE used in assert!
       
    62  */
       
    63 #if 0
       
    64 /* 
       
    65  * M_INPUT_COUNT_MULT * (6289*13+160) = 4294826393 (0xfffdd999).
       
    66  * 6289 is the largest number that fits 32 bits in the
       
    67  * input sample count multiplication method.
       
    68  */
       
    69 static const int LC_MAX_BLOCK_SIZE = 6289;      
       
    70 #endif // 0
       
    71 
       
    72 
       
    73 RESAMPLER_SincConv44To48Int16::RESAMPLER_SincConv44To48Int16(int channelCount) :
       
    74 m_memBuffers(0),
       
    75 m_scratchBuffer(0),
       
    76 m_channelCount(channelCount),
       
    77 m_blockSize(0),
       
    78 m_channelEnabled(0),
       
    79 m_inputSamples(0),
       
    80 m_index1(LC_FILTER_COUNT),
       
    81 m_index2(0),
       
    82 m_zeroCrossings(RESAMPLER_44_TO_48_ZERO_CROSSINGS_STANDARD),
       
    83 m_filterMatrix(RESAMPLER_44_TO_48_FILTERS_STANDARD)
       
    84 {
       
    85 }
       
    86 
       
    87 
       
    88 RESAMPLER_SincConv44To48Int16::~RESAMPLER_SincConv44To48Int16()
       
    89 {
       
    90     DeInit();
       
    91 }
       
    92 
       
    93 bool RESAMPLER_SincConv44To48Int16::InitInputDriven()
       
    94 {
       
    95     return Init();
       
    96 }
       
    97 
       
    98 
       
    99 bool RESAMPLER_SincConv44To48Int16::InitOutputDriven()
       
   100 {
       
   101     return Init();
       
   102 }
       
   103 
       
   104 bool RESAMPLER_SincConv44To48Int16::Init()
       
   105 {
       
   106     int i(0);
       
   107 
       
   108     m_memBuffers = new int16 *[m_channelCount];
       
   109     if (!m_memBuffers)
       
   110     {
       
   111         return false;
       
   112     }
       
   113 
       
   114     for (i = 0; i < m_channelCount; i++) 
       
   115     {
       
   116         m_memBuffers[i] = 0;
       
   117     }
       
   118 
       
   119     m_channelEnabled = new bool[m_channelCount];
       
   120     if (!m_channelEnabled)
       
   121     {
       
   122         DeInit();
       
   123         return false;
       
   124     }
       
   125     for (i = 0; i < m_channelCount; i++) 
       
   126     {
       
   127         m_channelEnabled[i] = true;
       
   128     }
       
   129 
       
   130     for (i = 0; i < m_channelCount; i++) 
       
   131     {
       
   132         m_memBuffers[i] = new int16[LC_MAX_ZERO_CROSSINGS * 2];
       
   133         if (!m_memBuffers[i])
       
   134         {
       
   135             DeInit();
       
   136             return false;
       
   137         }
       
   138         memset(m_memBuffers[i], 0, sizeof(int16) * (LC_MAX_ZERO_CROSSINGS * 2));
       
   139     }
       
   140 
       
   141     return true;
       
   142 }
       
   143 
       
   144 void 
       
   145 RESAMPLER_SincConv44To48Int16::DeInit()
       
   146 {
       
   147     if (m_channelCount)
       
   148     {
       
   149         for (int i = 0; i < m_channelCount; i++)
       
   150         {
       
   151             delete [] m_memBuffers[i];
       
   152         }
       
   153         delete [] m_memBuffers;
       
   154         delete [] m_channelEnabled;
       
   155     }
       
   156 }
       
   157 
       
   158 bool 
       
   159 RESAMPLER_SincConv44To48Int16::SetQualityInputDriven(int mode)
       
   160 {
       
   161     return SetQualityOutputDriven(mode);
       
   162 }
       
   163 
       
   164 bool 
       
   165 RESAMPLER_SincConv44To48Int16::SetQualityOutputDriven(int mode)
       
   166 {
       
   167     switch (mode)
       
   168     {
       
   169     case RESAMPLER_RATE_CONVERSION_QUALITY_ECONOMY:
       
   170         m_zeroCrossings = RESAMPLER_44_TO_48_ZERO_CROSSINGS_ECONOMY;
       
   171         m_filterMatrix  = RESAMPLER_44_TO_48_FILTERS_ECONOMY;
       
   172         break;
       
   173     case RESAMPLER_RATE_CONVERSION_QUALITY_STANDARD:
       
   174         m_zeroCrossings = RESAMPLER_44_TO_48_ZERO_CROSSINGS_STANDARD;
       
   175         m_filterMatrix  = RESAMPLER_44_TO_48_FILTERS_STANDARD;
       
   176         break;
       
   177     case RESAMPLER_RATE_CONVERSION_QUALITY_PREMIUM:
       
   178         m_zeroCrossings = RESAMPLER_44_TO_48_ZERO_CROSSINGS_PREMIUM;
       
   179         m_filterMatrix  = RESAMPLER_44_TO_48_FILTERS_PREMIUM;
       
   180         break;
       
   181     default:
       
   182         return false;
       
   183     }
       
   184     return true;
       
   185 }
       
   186 
       
   187 void 
       
   188 RESAMPLER_SincConv44To48Int16::EnableChannelInputDriven(int channel)
       
   189 {
       
   190     EnableChannelOutputDriven(channel);
       
   191 }
       
   192 
       
   193 
       
   194 void 
       
   195 RESAMPLER_SincConv44To48Int16::DisableChannelInputDriven(int channel)
       
   196 {
       
   197     DisableChannelOutputDriven(channel);
       
   198 }
       
   199 
       
   200 
       
   201 void 
       
   202 RESAMPLER_SincConv44To48Int16::EnableChannelOutputDriven(int channel)
       
   203 {
       
   204     m_channelEnabled[channel] = true;
       
   205 }
       
   206 
       
   207 
       
   208 void 
       
   209 RESAMPLER_SincConv44To48Int16::DisableChannelOutputDriven(int channel)
       
   210 {
       
   211     m_channelEnabled[channel] = false;
       
   212 }
       
   213 
       
   214 size_t 
       
   215 RESAMPLER_SincConv44To48Int16::ScratchMemoryNeedInputDriven(int maxInputBlockSize) const
       
   216 {
       
   217     /** 6289 == LC_MAX_BLOCK_SIZE
       
   218      */
       
   219     if (maxInputBlockSize > 6289 * 44100.0/48000.0)
       
   220         {
       
   221         return 0;
       
   222         }
       
   223 
       
   224     return sizeof(int16) * (LC_MAX_ZERO_CROSSINGS * 2 + maxInputBlockSize);
       
   225 }
       
   226 
       
   227 void 
       
   228 RESAMPLER_SincConv44To48Int16::SetScratchBufferInputDriven(char *buffer)
       
   229 {
       
   230     m_scratchBuffer = (int16 *)buffer;
       
   231 }
       
   232 
       
   233 size_t 
       
   234 RESAMPLER_SincConv44To48Int16::ScratchMemoryNeedOutputDriven(int maxOutputBlockSize) const
       
   235 {
       
   236     int blockSize =  (int)((maxOutputBlockSize * 44100.0/48000.0) + 1); 
       
   237     
       
   238     return ScratchMemoryNeedInputDriven(blockSize);
       
   239 }
       
   240 
       
   241 void 
       
   242 RESAMPLER_SincConv44To48Int16::SetScratchBufferOutputDriven(char *buffer)
       
   243 {
       
   244     m_scratchBuffer = (int16 *)buffer;
       
   245 }
       
   246 
       
   247 
       
   248 
       
   249 int 
       
   250 RESAMPLER_SincConv44To48Int16::MaxInputSampleCount(int outSamples) const
       
   251 { 
       
   252     return (int)((outSamples * (44100.0 / 48000.0)) + 1); 
       
   253 }
       
   254 
       
   255 
       
   256 int 
       
   257 RESAMPLER_SincConv44To48Int16::InSamplesNeeded(int outSamples)
       
   258 {
       
   259     m_inputSamples = outSamples - ((LC_SAMPLE_COUNT_MULT * (outSamples*13+m_index2)) >> 23);
       
   260  
       
   261     return m_inputSamples;
       
   262 }
       
   263 
       
   264 int 
       
   265 RESAMPLER_SincConv44To48Int16::MaxOutputSampleCount(int inSamples) const
       
   266 { 
       
   267     return (int)(inSamples * 160.0 / 147.0 + 1.0); 
       
   268 }
       
   269 
       
   270 
       
   271 int RESAMPLER_SincConv44To48Int16::ProcessFromInput(int16 *outputBuffers[], 
       
   272                                               int16 *inputBuffers[], 
       
   273                                               int inSamples)
       
   274 {
       
   275     int outSamples = (int)((inSamples * 160.0 + m_index2) / 147.0);
       
   276     m_inputSamples = inSamples;
       
   277     return ProcessToOutput(outputBuffers, inputBuffers, outSamples);
       
   278 }
       
   279 
       
   280 int 
       
   281 RESAMPLER_SincConv44To48Int16::ProcessToOutput(int16 *outputBuffers[], 
       
   282                                          int16 *inputBuffers[], 
       
   283                                          int outSamples)
       
   284 {
       
   285     static const int FILTER_LENGTH = 2 * LC_MAX_ZERO_CROSSINGS;
       
   286 	int i, j;
       
   287     int index1 = m_index1;
       
   288     int index2 = m_index2;
       
   289 
       
   290     for (i = 0; i < m_channelCount; i++) 
       
   291     {
       
   292         if (!m_channelEnabled[i])
       
   293         {
       
   294             break;
       
   295         }
       
   296 
       
   297         int16 *tempBuf = m_scratchBuffer;
       
   298         int16 *outBuf  = outputBuffers[i];
       
   299         index1 = m_index1; /* 160 SRC filter number */
       
   300         index2 = m_index2; /* 0 */
       
   301         
       
   302         int state = 0;
       
   303 
       
   304         memcpy(m_scratchBuffer, 
       
   305                m_memBuffers[i], 
       
   306                FILTER_LENGTH * sizeof(int16));
       
   307 
       
   308         // Read samples into memory
       
   309         memcpy(tempBuf + FILTER_LENGTH, 
       
   310                inputBuffers[i], 
       
   311                m_inputSamples * sizeof(int16));
       
   312 
       
   313         // Do band limited interpolation and set the result into 
       
   314         // every index in the output buffer. 
       
   315         for (j = 0; j < outSamples; j++) 
       
   316         {
       
   317             index1 -= LC_MATRIX_HOP_SIZE; /* -13 */ 
       
   318             index2 += LC_MATRIX_HOP_SIZE;  /* +13 */ 
       
   319 
       
   320             if (index1 <= 0)
       
   321             {
       
   322                 index1 += LC_FILTER_COUNT; /* +160 */
       
   323                 index2 -= LC_FILTER_COUNT;  /* -160 */
       
   324                 state++;
       
   325             }
       
   326 
       
   327             /*lint -e{662} */
       
   328             const int16 *filterPtr1 = m_filterMatrix + index1 * m_zeroCrossings;
       
   329             const int16 *filterPtr2 = m_filterMatrix + index2 * m_zeroCrossings;
       
   330               
       
   331             int32 newSample = 
       
   332                 RESAMPLER_SincConvFilterInt16(tempBuf + LC_BUFFER_ACCESS_OUTPUT - state + j,
       
   333                                         filterPtr1,
       
   334                                         filterPtr2,
       
   335                                         m_zeroCrossings);
       
   336              
       
   337             // round and shift down
       
   338             outBuf[j] = (int16)RESAMPLER_Clip16((newSample + 16384) >> 15);
       
   339         }
       
   340         
       
   341         // Copy the newest samples to the beginning of the buffer
       
   342         memcpy(m_memBuffers[i], 
       
   343                m_scratchBuffer + m_inputSamples, 
       
   344                FILTER_LENGTH * sizeof(int16));       
       
   345     }
       
   346 
       
   347     m_index1 = index1;
       
   348     m_index2 = index2;
       
   349 
       
   350 	return outSamples;
       
   351 }
       
   352