You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

150 lines
6.9KB

  1. /*
  2. * Copyright (C) 2011 Michael Niedermayer (michaelni@gmx.at)
  3. *
  4. * This file is part of libswresample
  5. *
  6. * libswresample is free software; you can redistribute it and/or modify
  7. * it under the terms of the GNU General Public License as published by
  8. * the Free Software Foundation; either version 2 of the License, or
  9. * (at your option) any later version.
  10. *
  11. * libswresample is distributed in the hope that it will be useful,
  12. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  14. * GNU General Public License for more details.
  15. *
  16. * You should have received a copy of the GNU General Public License
  17. * along with libswresample; if not, write to the Free Software
  18. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  19. */
  20. #include "libavutil/avassert.h"
  21. #include "libavutil/common.h"
  22. #include "libavutil/audioconvert.h"
  23. #include "swresample.h"
  24. #undef fprintf
  25. #define SAMPLES 1000
  26. #define ASSERT_LEVEL 2
  27. static double get(const void *p, int index, enum AVSampleFormat f){
  28. switch(f){
  29. case AV_SAMPLE_FMT_U8 : return ((const uint8_t*)p)[index]/255.0*2-1.0;
  30. case AV_SAMPLE_FMT_S16: return ((const int16_t*)p)[index]/32767.0;
  31. case AV_SAMPLE_FMT_S32: return ((const int32_t*)p)[index]/2147483647.0;
  32. case AV_SAMPLE_FMT_FLT: return ((const float *)p)[index];
  33. case AV_SAMPLE_FMT_DBL: return ((const double *)p)[index];
  34. default: av_assert2(0);
  35. }
  36. }
  37. static void set(void *p, int index, enum AVSampleFormat f, double v){
  38. switch(f){
  39. case AV_SAMPLE_FMT_U8 : ((uint8_t*)p)[index]= (v+1.0)*255.0/2; break;
  40. case AV_SAMPLE_FMT_S16: ((int16_t*)p)[index]= v*32767; break;
  41. case AV_SAMPLE_FMT_S32: ((int32_t*)p)[index]= v*2147483647; break;
  42. case AV_SAMPLE_FMT_FLT: ((float *)p)[index]= v; break;
  43. case AV_SAMPLE_FMT_DBL: ((double *)p)[index]= v; break;
  44. default: av_assert2(0);
  45. }
  46. }
  47. uint64_t layouts[]={
  48. AV_CH_LAYOUT_MONO ,
  49. AV_CH_LAYOUT_STEREO ,
  50. AV_CH_LAYOUT_2_1 ,
  51. AV_CH_LAYOUT_SURROUND ,
  52. AV_CH_LAYOUT_4POINT0 ,
  53. AV_CH_LAYOUT_2_2 ,
  54. AV_CH_LAYOUT_QUAD ,
  55. AV_CH_LAYOUT_5POINT0 ,
  56. AV_CH_LAYOUT_5POINT1 ,
  57. AV_CH_LAYOUT_5POINT0_BACK ,
  58. AV_CH_LAYOUT_5POINT1_BACK ,
  59. AV_CH_LAYOUT_7POINT0 ,
  60. AV_CH_LAYOUT_7POINT1 ,
  61. AV_CH_LAYOUT_7POINT1_WIDE ,
  62. 0
  63. };
  64. int main(int argc, char **argv){
  65. int in_sample_rate, out_sample_rate, ch ,i, in_ch_layout_index, out_ch_layout_index, osr;
  66. uint64_t in_ch_layout, out_ch_layout;
  67. enum AVSampleFormat in_sample_fmt, out_sample_fmt;
  68. int sample_rates[]={8000,11025,16000,22050,32000};
  69. uint8_t array_in[SAMPLES*8*8];
  70. uint8_t array_mid[SAMPLES*8*8*3];
  71. uint8_t array_out[SAMPLES*8*8+100];
  72. struct SwrContext * forw_ctx= NULL;
  73. struct SwrContext *backw_ctx= NULL;
  74. in_sample_rate=16000;
  75. for(osr=0; osr<5; osr++){
  76. out_sample_rate= sample_rates[osr];
  77. for(in_sample_fmt= AV_SAMPLE_FMT_U8; in_sample_fmt<=AV_SAMPLE_FMT_DBL; in_sample_fmt++){
  78. for(out_sample_fmt= AV_SAMPLE_FMT_U8; out_sample_fmt<=AV_SAMPLE_FMT_DBL; out_sample_fmt++){
  79. for(in_ch_layout_index=0; layouts[in_ch_layout_index]; in_ch_layout_index++){
  80. in_ch_layout= layouts[in_ch_layout_index];
  81. int in_ch_count= av_get_channel_layout_nb_channels(in_ch_layout);
  82. for(out_ch_layout_index=0; layouts[out_ch_layout_index]; out_ch_layout_index++){
  83. int out_count, mid_count;
  84. out_ch_layout= layouts[out_ch_layout_index];
  85. int out_ch_count= av_get_channel_layout_nb_channels(out_ch_layout);
  86. fprintf(stderr, "ch %d->%d, rate:%5d->%5d, fmt:%s->%s",
  87. in_ch_count, out_ch_count,
  88. in_sample_rate, out_sample_rate,
  89. av_get_sample_fmt_name(in_sample_fmt), av_get_sample_fmt_name(out_sample_fmt));
  90. forw_ctx = swr_alloc2(forw_ctx, out_ch_layout, out_sample_fmt, out_sample_rate,
  91. in_ch_layout, in_sample_fmt, in_sample_rate, 0, 0);
  92. backw_ctx = swr_alloc2(backw_ctx,in_ch_layout, in_sample_fmt, in_sample_rate,
  93. out_ch_layout, out_sample_fmt, out_sample_rate, 0, 0);
  94. if(swr_init( forw_ctx) < 0)
  95. fprintf(stderr, "swr_init(->) failed\n");
  96. if(swr_init(backw_ctx) < 0)
  97. fprintf(stderr, "swr_init(<-) failed\n");
  98. if(!forw_ctx)
  99. fprintf(stderr, "Failed to init forw_cts\n");
  100. if(!backw_ctx)
  101. fprintf(stderr, "Failed to init backw_ctx\n");
  102. //FIXME test planar
  103. for(ch=0; ch<in_ch_count; ch++){
  104. for(i=0; i<SAMPLES; i++)
  105. set(array_in, ch + i*in_ch_count, in_sample_fmt, sin(i*i*3/SAMPLES));
  106. }
  107. mid_count= swr_convert(forw_ctx, ( uint8_t*[]){array_mid}, 3*SAMPLES,
  108. (const uint8_t*[]){array_in }, SAMPLES);
  109. out_count= swr_convert(backw_ctx,( uint8_t*[]){array_out}, 3*SAMPLES,
  110. (const uint8_t*[]){array_mid}, mid_count);
  111. for(ch=0; ch<in_ch_count; ch++){
  112. double sse, x, maxdiff=0;
  113. double sum_a= 0;
  114. double sum_b= 0;
  115. double sum_aa= 0;
  116. double sum_bb= 0;
  117. double sum_ab= 0;
  118. for(i=0; i<SAMPLES; i++){
  119. double a= get(array_in , ch + i*in_ch_count, in_sample_fmt);
  120. double b= get(array_out, ch + i*in_ch_count, in_sample_fmt);
  121. sum_a += a;
  122. sum_b += b;
  123. sum_aa+= a*a;
  124. sum_bb+= b*b;
  125. sum_ab+= a*b;
  126. maxdiff= FFMAX(maxdiff, FFABS(a-b));
  127. }
  128. x = sum_ab/sum_bb;
  129. sse= sum_aa + sum_bb*x*x - 2*x*sum_ab;
  130. fprintf(stderr, "[%f %f %f] len:%5d\n", sqrt(sse/SAMPLES), x, maxdiff, out_count);
  131. }
  132. fprintf(stderr, "\n");
  133. }
  134. }
  135. }
  136. }
  137. }
  138. return 0;
  139. }