vorbis_test.c 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176
  1. /*
  2. ** Copyright (C) 2007-2011 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 / 8)
  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. vorbis_quality_test (void)
  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. const char * q3_fname = "q3_vorbis.oga" ;
  91. const char * q5_fname = "q5_vorbis.oga" ;
  92. SNDFILE *q3_file, *q5_file ;
  93. SF_INFO sfinfo ;
  94. int q3_size, q5_size ;
  95. double quality ;
  96. int k ;
  97. print_test_name (__func__, "q[35]_vorbis.oga") ;
  98. memset (&sfinfo, 0, sizeof (sfinfo)) ;
  99. /* Set up output file type. */
  100. sfinfo.format = SF_FORMAT_OGG | SF_FORMAT_VORBIS ;
  101. sfinfo.channels = 1 ;
  102. sfinfo.samplerate = SAMPLE_RATE ;
  103. /* Write the output file. */
  104. q3_file = test_open_file_or_die (q3_fname, SFM_WRITE, &sfinfo, SF_FALSE, __LINE__) ;
  105. q5_file = test_open_file_or_die (q5_fname, SFM_WRITE, &sfinfo, SF_FALSE, __LINE__) ;
  106. quality = 0.3 ;
  107. sf_command (q3_file, SFC_SET_VBR_ENCODING_QUALITY, &quality, sizeof (quality)) ;
  108. quality = 0.5 ;
  109. sf_command (q5_file, SFC_SET_VBR_ENCODING_QUALITY, &quality, sizeof (quality)) ;
  110. for (k = 0 ; k < 5 ; k++)
  111. { gen_lowpass_noise_float (data_out, ARRAY_LEN (data_out)) ;
  112. test_write_float_or_die (q3_file, 0, data_out, ARRAY_LEN (data_out), __LINE__) ;
  113. test_write_float_or_die (q5_file, 0, data_out, ARRAY_LEN (data_out), __LINE__) ;
  114. } ;
  115. sf_close (q3_file) ;
  116. sf_close (q5_file) ;
  117. q3_size = file_length (q3_fname) ;
  118. q5_size = file_length (q5_fname) ;
  119. if (q3_size >= q5_size)
  120. { printf ("\n\nLine %d : q3 size (%d) >= q5 size (%d)\n\n", __LINE__, q3_size, q5_size) ;
  121. exit (1) ;
  122. } ;
  123. puts ("ok") ;
  124. unlink (q3_fname) ;
  125. unlink (q5_fname) ;
  126. } /* vorbis_quality_test */
  127. int
  128. main (void)
  129. {
  130. if (HAVE_EXTERNAL_LIBS)
  131. { vorbis_test () ;
  132. vorbis_quality_test () ;
  133. }
  134. else
  135. puts (" No Ogg/Vorbis tests because Ogg/Vorbis support was not compiled in.") ;
  136. return 0 ;
  137. } /* main */