compression_size_test.c 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205
  1. /*
  2. ** Copyright (C) 2007-2012 Erik de Castro Lopo <erikd@mega-nerd.com>
  3. **
  4. ** This program is free software; you can redistribute it and/or modify
  5. ** it under the terms of the GNU General Public License as published by
  6. ** the Free Software Foundation; either version 2 of the License, or
  7. ** (at your option) any later version.
  8. **
  9. ** This program is distributed in the hope that it will be useful,
  10. ** but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. ** GNU General Public License for more details.
  13. **
  14. ** You should have received a copy of the GNU General Public License
  15. ** along with this program; if not, write to the Free Software
  16. ** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
  17. */
  18. #include "sfconfig.h"
  19. #include <stdio.h>
  20. #include <stdlib.h>
  21. #include <string.h>
  22. #include <unistd.h>
  23. #include <math.h>
  24. #include <sndfile.h>
  25. #include "utils.h"
  26. #include "dft_cmp.h"
  27. #define SAMPLE_RATE 16000
  28. #define DATA_LENGTH (SAMPLE_RATE)
  29. static float data_out [DATA_LENGTH] ;
  30. static inline float
  31. max_float (float a, float b)
  32. { return a > b ? a : b ;
  33. } /* max_float */
  34. static void
  35. vorbis_test (void)
  36. { static float float_data [DFT_DATA_LENGTH] ;
  37. const char * filename = "vorbis_test.oga" ;
  38. SNDFILE * file ;
  39. SF_INFO sfinfo ;
  40. float max_abs = 0.0 ;
  41. unsigned k ;
  42. print_test_name ("vorbis_test", filename) ;
  43. /* Generate float data. */
  44. gen_windowed_sine_float (float_data, ARRAY_LEN (float_data), 1.0) ;
  45. /* Set up output file type. */
  46. memset (&sfinfo, 0, sizeof (sfinfo)) ;
  47. sfinfo.format = SF_FORMAT_OGG | SF_FORMAT_VORBIS ;
  48. sfinfo.channels = 1 ;
  49. sfinfo.samplerate = SAMPLE_RATE ;
  50. /* Write the output file. */
  51. /* The Vorbis encoder has a bug on PowerPC and X86-64 with sample rates
  52. ** <= 22050. Increasing the sample rate to 32000 avoids triggering it.
  53. ** See https://trac.xiph.org/ticket/1229
  54. */
  55. if ((file = sf_open (filename, SFM_WRITE, &sfinfo)) == NULL)
  56. { const char * errstr ;
  57. errstr = sf_strerror (NULL) ;
  58. if (strstr (errstr, "Sample rate chosen is known to trigger a Vorbis") == NULL)
  59. { printf ("Line %d: sf_open (SFM_WRITE) failed : %s\n", __LINE__, errstr) ;
  60. dump_log_buffer (NULL) ;
  61. exit (1) ;
  62. } ;
  63. printf ("\n Sample rate -> 32kHz ") ;
  64. sfinfo.samplerate = 32000 ;
  65. file = test_open_file_or_die (filename, SFM_WRITE, &sfinfo, SF_TRUE, __LINE__) ;
  66. } ;
  67. test_write_float_or_die (file, 0, float_data, ARRAY_LEN (float_data), __LINE__) ;
  68. sf_close (file) ;
  69. memset (float_data, 0, sizeof (float_data)) ;
  70. /* Read the file back in again. */
  71. memset (&sfinfo, 0, sizeof (sfinfo)) ;
  72. file = test_open_file_or_die (filename, SFM_READ, &sfinfo, SF_FALSE, __LINE__) ;
  73. test_read_float_or_die (file, 0, float_data, ARRAY_LEN (float_data), __LINE__) ;
  74. sf_close (file) ;
  75. for (k = 0 ; k < ARRAY_LEN (float_data) ; k ++)
  76. max_abs = max_float (max_abs, fabs (float_data [k])) ;
  77. if (max_abs > 1.021)
  78. { printf ("\n\n Error : max_abs %f should be < 1.021.\n\n", max_abs) ;
  79. exit (1) ;
  80. } ;
  81. puts ("ok") ;
  82. unlink (filename) ;
  83. } /* vorbis_test */
  84. static void
  85. compression_size_test (int format, const char * filename)
  86. { /*
  87. ** Encode two files, one at quality 0.3 and one at quality 0.5 and then
  88. ** make sure that the quality 0.3 files is the smaller of the two.
  89. */
  90. char q3_fname [64] ;
  91. char q6_fname [64] ;
  92. char test_name [64] ;
  93. SNDFILE *q3_file, *q6_file ;
  94. SF_INFO sfinfo ;
  95. int q3_size, q6_size ;
  96. double quality ;
  97. int k ;
  98. snprintf (q3_fname, sizeof (q3_fname), "q3_%s", filename) ;
  99. snprintf (q6_fname, sizeof (q6_fname), "q6_%s", filename) ;
  100. snprintf (test_name, sizeof (test_name), "q[36]_%s", filename) ;
  101. print_test_name (__func__, test_name) ;
  102. memset (&sfinfo, 0, sizeof (sfinfo)) ;
  103. /* Set up output file type. */
  104. sfinfo.format = format ;
  105. sfinfo.channels = 1 ;
  106. sfinfo.samplerate = SAMPLE_RATE ;
  107. /* Write the output file. */
  108. q3_file = test_open_file_or_die (q3_fname, SFM_WRITE, &sfinfo, SF_FALSE, __LINE__) ;
  109. q6_file = test_open_file_or_die (q6_fname, SFM_WRITE, &sfinfo, SF_FALSE, __LINE__) ;
  110. quality = 0.3 ;
  111. sf_command (q3_file, SFC_SET_VBR_ENCODING_QUALITY, &quality, sizeof (quality)) ;
  112. quality = 0.6 ;
  113. sf_command (q6_file, SFC_SET_VBR_ENCODING_QUALITY, &quality, sizeof (quality)) ;
  114. for (k = 0 ; k < 5 ; k++)
  115. { gen_lowpass_signal_float (data_out, ARRAY_LEN (data_out)) ;
  116. test_write_float_or_die (q3_file, 0, data_out, ARRAY_LEN (data_out), __LINE__) ;
  117. test_write_float_or_die (q6_file, 0, data_out, ARRAY_LEN (data_out), __LINE__) ;
  118. } ;
  119. sf_close (q3_file) ;
  120. sf_close (q6_file) ;
  121. q3_size = file_length (q3_fname) ;
  122. q6_size = file_length (q6_fname) ;
  123. if (q3_size >= q6_size)
  124. { printf ("\n\nLine %d : q3 size (%d) >= q5 size (%d)\n\n", __LINE__, q3_size, q6_size) ;
  125. exit (1) ;
  126. } ;
  127. puts ("ok") ;
  128. unlink (q3_fname) ;
  129. unlink (q6_fname) ;
  130. } /* compression_size_test */
  131. int
  132. main (int argc, char *argv [])
  133. { int all_tests = 0, tests = 0 ;
  134. if (argc != 2)
  135. { printf (
  136. "Usage : %s <test>\n"
  137. " Where <test> is one of:\n"
  138. " vorbis - test Ogg/Vorbis\n"
  139. " flac - test FLAC\n"
  140. " all - perform all tests\n",
  141. argv [0]) ;
  142. exit (0) ;
  143. } ;
  144. if (! HAVE_EXTERNAL_LIBS)
  145. { puts (" No Ogg/Vorbis tests because Ogg/Vorbis support was not compiled in.") ;
  146. return 0 ;
  147. } ;
  148. if (strcmp (argv [1], "all") == 0)
  149. all_tests = 1 ;
  150. if (all_tests || strcmp (argv [1], "vorbis") == 0)
  151. { vorbis_test () ;
  152. compression_size_test (SF_FORMAT_OGG | SF_FORMAT_VORBIS, "vorbis.oga") ;
  153. tests ++ ;
  154. } ;
  155. if (all_tests || strcmp (argv [1], "flac") == 0)
  156. { compression_size_test (SF_FORMAT_FLAC | SF_FORMAT_PCM_16, "pcm16.flac") ;
  157. tests ++ ;
  158. } ;
  159. return 0 ;
  160. } /* main */