resample.c
上传用户:wstnjxml
上传日期:2014-04-03
资源大小:7248k
文件大小:7k
源码类别:

Windows CE

开发平台:

C/C++

  1. /*
  2.  * Sample rate convertion for both audio and video
  3.  * Copyright (c) 2000 Fabrice Bellard.
  4.  *
  5.  * This library is free software; you can redistribute it and/or
  6.  * modify it under the terms of the GNU Lesser General Public
  7.  * License as published by the Free Software Foundation; either
  8.  * version 2 of the License, or (at your option) any later version.
  9.  *
  10.  * This library 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 GNU
  13.  * Lesser General Public License for more details.
  14.  *
  15.  * You should have received a copy of the GNU Lesser General Public
  16.  * License along with this library; if not, write to the Free Software
  17.  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  18.  */
  19. /**
  20.  * @file resample.c
  21.  * Sample rate convertion for both audio and video.
  22.  */
  23. #include "avcodec.h"
  24. struct AVResampleContext;
  25. struct ReSampleContext {
  26.     struct AVResampleContext *resample_context;
  27.     short *temp[2];
  28.     int temp_len;
  29.     float ratio;
  30.     /* channel convert */
  31.     int input_channels, output_channels, filter_channels;
  32. };
  33. /* n1: number of samples */
  34. static void stereo_to_mono(short *output, short *input, int n1)
  35. {
  36.     short *p, *q;
  37.     int n = n1;
  38.     p = input;
  39.     q = output;
  40.     while (n >= 4) {
  41.         q[0] = (p[0] + p[1]) >> 1;
  42.         q[1] = (p[2] + p[3]) >> 1;
  43.         q[2] = (p[4] + p[5]) >> 1;
  44.         q[3] = (p[6] + p[7]) >> 1;
  45.         q += 4;
  46.         p += 8;
  47.         n -= 4;
  48.     }
  49.     while (n > 0) {
  50.         q[0] = (p[0] + p[1]) >> 1;
  51.         q++;
  52.         p += 2;
  53.         n--;
  54.     }
  55. }
  56. /* n1: number of samples */
  57. static void mono_to_stereo(short *output, short *input, int n1)
  58. {
  59.     short *p, *q;
  60.     int n = n1;
  61.     int v;
  62.     p = input;
  63.     q = output;
  64.     while (n >= 4) {
  65.         v = p[0]; q[0] = v; q[1] = v;
  66.         v = p[1]; q[2] = v; q[3] = v;
  67.         v = p[2]; q[4] = v; q[5] = v;
  68.         v = p[3]; q[6] = v; q[7] = v;
  69.         q += 8;
  70.         p += 4;
  71.         n -= 4;
  72.     }
  73.     while (n > 0) {
  74.         v = p[0]; q[0] = v; q[1] = v;
  75.         q += 2;
  76.         p += 1;
  77.         n--;
  78.     }
  79. }
  80. /* XXX: should use more abstract 'N' channels system */
  81. static void stereo_split(short *output1, short *output2, short *input, int n)
  82. {
  83.     int i;
  84.     for(i=0;i<n;i++) {
  85.         *output1++ = *input++;
  86.         *output2++ = *input++;
  87.     }
  88. }
  89. static void stereo_mux(short *output, short *input1, short *input2, int n)
  90. {
  91.     int i;
  92.     for(i=0;i<n;i++) {
  93.         *output++ = *input1++;
  94.         *output++ = *input2++;
  95.     }
  96. }
  97. static void ac3_5p1_mux(short *output, short *input1, short *input2, int n)
  98. {
  99.     int i;
  100.     short l,r;
  101.     for(i=0;i<n;i++) {
  102.       l=*input1++;
  103.       r=*input2++;
  104.       *output++ = l;           /* left */
  105.       *output++ = (l/2)+(r/2); /* center */
  106.       *output++ = r;           /* right */
  107.       *output++ = 0;           /* left surround */
  108.       *output++ = 0;           /* right surroud */
  109.       *output++ = 0;           /* low freq */
  110.     }
  111. }
  112. ReSampleContext *audio_resample_init(int output_channels, int input_channels, 
  113.                                       int output_rate, int input_rate)
  114. {
  115.     ReSampleContext *s;
  116.     
  117.     if ( input_channels > 2)
  118.       {
  119. av_log(NULL, AV_LOG_ERROR, "Resampling with input channels greater than 2 unsupported.");
  120. return NULL;
  121.       }
  122.     s = av_mallocz(sizeof(ReSampleContext));
  123.     if (!s)
  124.       {
  125. av_log(NULL, AV_LOG_ERROR, "Can't allocate memory for resample context.");
  126. return NULL;
  127.       }
  128.     s->ratio = (float)output_rate / (float)input_rate;
  129.     
  130.     s->input_channels = input_channels;
  131.     s->output_channels = output_channels;
  132.     
  133.     s->filter_channels = s->input_channels;
  134.     if (s->output_channels < s->filter_channels)
  135.         s->filter_channels = s->output_channels;
  136. /*
  137.  * ac3 output is the only case where filter_channels could be greater than 2.
  138.  * input channels can't be greater than 2, so resample the 2 channels and then
  139.  * expand to 6 channels after the resampling.
  140.  */
  141.     if(s->filter_channels>2)
  142.       s->filter_channels = 2;
  143.     s->resample_context= av_resample_init(output_rate, input_rate, 16, 10, 0, 1.0);
  144.     
  145.     return s;
  146. }
  147. /* resample audio. 'nb_samples' is the number of input samples */
  148. /* XXX: optimize it ! */
  149. int audio_resample(ReSampleContext *s, short *output, short *input, int nb_samples)
  150. {
  151.     int i, nb_samples1;
  152.     short *bufin[2];
  153.     short *bufout[2];
  154.     short *buftmp2[2], *buftmp3[2];
  155.     int lenout;
  156.     if (s->input_channels == s->output_channels && s->ratio == 1.0 && 0) {
  157.         /* nothing to do */
  158.         memcpy(output, input, nb_samples * s->input_channels * sizeof(short));
  159.         return nb_samples;
  160.     }
  161.     /* XXX: move those malloc to resample init code */
  162.     for(i=0; i<s->filter_channels; i++){
  163.         bufin[i]= (short*) av_malloc( (nb_samples + s->temp_len) * sizeof(short) );
  164.         memcpy(bufin[i], s->temp[i], s->temp_len * sizeof(short));
  165.         buftmp2[i] = bufin[i] + s->temp_len;
  166.     }
  167.     
  168.     /* make some zoom to avoid round pb */
  169.     lenout= (int)(nb_samples * s->ratio) + 16;
  170.     bufout[0]= (short*) av_malloc( lenout * sizeof(short) );
  171.     bufout[1]= (short*) av_malloc( lenout * sizeof(short) );
  172.     if (s->input_channels == 2 &&
  173.         s->output_channels == 1) {
  174.         buftmp3[0] = output;
  175.         stereo_to_mono(buftmp2[0], input, nb_samples);
  176.     } else if (s->output_channels >= 2 && s->input_channels == 1) {
  177.         buftmp3[0] = bufout[0];
  178.         memcpy(buftmp2[0], input, nb_samples*sizeof(short));
  179.     } else if (s->output_channels >= 2) {
  180.         buftmp3[0] = bufout[0];
  181.         buftmp3[1] = bufout[1];
  182.         stereo_split(buftmp2[0], buftmp2[1], input, nb_samples);
  183.     } else {
  184.         buftmp3[0] = output;
  185.         memcpy(buftmp2[0], input, nb_samples*sizeof(short));
  186.     }
  187.     nb_samples += s->temp_len;
  188.     /* resample each channel */
  189.     nb_samples1 = 0; /* avoid warning */
  190.     for(i=0;i<s->filter_channels;i++) {
  191.         int consumed;
  192.         int is_last= i+1 == s->filter_channels;
  193.         nb_samples1 = av_resample(s->resample_context, buftmp3[i], bufin[i], &consumed, nb_samples, lenout, is_last);
  194.         s->temp_len= nb_samples - consumed;
  195.         s->temp[i]= av_realloc(s->temp[i], s->temp_len*sizeof(short));
  196.         memcpy(s->temp[i], bufin[i] + consumed, s->temp_len*sizeof(short));
  197.     }
  198.     if (s->output_channels == 2 && s->input_channels == 1) {
  199.         mono_to_stereo(output, buftmp3[0], nb_samples1);
  200.     } else if (s->output_channels == 2) {
  201.         stereo_mux(output, buftmp3[0], buftmp3[1], nb_samples1);
  202.     } else if (s->output_channels == 6) {
  203.         ac3_5p1_mux(output, buftmp3[0], buftmp3[1], nb_samples1);
  204.     }
  205.     for(i=0; i<s->filter_channels; i++)
  206.         av_free(bufin[i]);
  207.     av_free(bufout[0]);
  208.     av_free(bufout[1]);
  209.     return nb_samples1;
  210. }
  211. void audio_resample_close(ReSampleContext *s)
  212. {
  213.     av_resample_close(s->resample_context);
  214.     av_freep(&s->temp[0]);
  215.     av_freep(&s->temp[1]);
  216.     av_free(s);
  217. }