Du kan inte välja fler än 25 ämnen Ämnen måste starta med en bokstav eller siffra, kan innehålla bindestreck ('-') och vara max 35 tecken långa.

Quantizer.cpp 8.2KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247
  1. /* Audio Library for Teensy 3.X
  2. * Copyright (c) 2019, Paul Stoffregen, paul@pjrc.com
  3. *
  4. * Development of this audio library was funded by PJRC.COM, LLC by sales of
  5. * Teensy and Audio Adaptor boards. Please support PJRC's efforts to develop
  6. * open source software by purchasing Teensy or other PJRC products.
  7. *
  8. * Permission is hereby granted, free of charge, to any person obtaining a copy
  9. * of this software and associated documentation files (the "Software"), to deal
  10. * in the Software without restriction, including without limitation the rights
  11. * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  12. * copies of the Software, and to permit persons to whom the Software is
  13. * furnished to do so, subject to the following conditions:
  14. *
  15. * The above copyright notice, development funding notice, and this permission
  16. * notice shall be included in all copies or substantial portions of the Software.
  17. *
  18. * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  19. * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  20. * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  21. * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  22. * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  23. * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  24. * THE SOFTWARE.
  25. */
  26. /*
  27. by Alexander Walch
  28. */
  29. #include "Quantizer.h"
  30. #define SAMPLEINVALID(sample) (!isfinite(sample) || abs(sample) >= 1.2) //use only for floating point samples (\in [-1.,1.])
  31. Quantizer::Quantizer(float audio_sample_rate){
  32. #ifdef DEBUG_QUANTIZER
  33. while(!Serial);
  34. #endif
  35. randomSeed(1);
  36. if(audio_sample_rate==44100.f){
  37. _noiseSFilter[0]=-0.06935825f;
  38. _noiseSFilter[1]=0.52540845f;
  39. _noiseSFilter[2]= -1.20537028f;
  40. _noiseSFilter[3]= 2.09422811f;
  41. _noiseSFilter[4]= -3.2177438f;
  42. _noiseSFilter[5]= 4.04852027f;
  43. _noiseSFilter[6]= -3.83872701f;
  44. _noiseSFilter[7]= 3.30584589f;
  45. _noiseSFilter[8]= -2.38682527f;
  46. // all coefficients in correct order:
  47. // {1. , -2.38682527, 3.30584589, -3.83872701, 4.04852027,
  48. // -3.2177438 , 2.09422811, -1.20537028, 0.52540845, -0.06935825};
  49. } else if(audio_sample_rate==48000.f){
  50. _noiseSFilter[0]=0.1967454f;
  51. _noiseSFilter[1]=-0.30086406f;
  52. _noiseSFilter[2]= 0.09575588f;
  53. _noiseSFilter[3]= 0.58209648f;
  54. _noiseSFilter[4]= -1.88579617f;
  55. _noiseSFilter[5]= 3.37325788f;
  56. _noiseSFilter[6]= -3.88076402f;
  57. _noiseSFilter[7]= 3.58558504f;
  58. _noiseSFilter[8]= -2.54334066f;
  59. // all coefficients in correct order:
  60. // {1. , -2.54334066, 3.58558504, -3.88076402, 3.37325788,
  61. // -1.88579617, 0.58209648, 0.09575588, -0.30086406, 0.1967454};
  62. // }
  63. }
  64. else {
  65. _noiseSFilter[0]=0.f;
  66. _noiseSFilter[1]=0.f;
  67. _noiseSFilter[2]=0.f;
  68. _noiseSFilter[3]=0.f;
  69. _noiseSFilter[4]=0.f;
  70. _noiseSFilter[5]=0.f;
  71. _noiseSFilter[6]=0.f;
  72. _noiseSFilter[7]=0.f;
  73. _noiseSFilter[8]=0.f;
  74. }
  75. _bufferEnd0=&_buffer0[NOISE_SHAPE_F_LENGTH];
  76. reset();
  77. }
  78. void Quantizer::configure(bool noiseShaping, bool dither, float factor){
  79. _noiseShaping=noiseShaping;
  80. _dither=dither;
  81. _factor=factor;
  82. if (_dither){
  83. _factor-=1.f;
  84. }
  85. if (_noiseShaping){
  86. // the maximum rounding error is 0.5
  87. // Assuming the rounding errors of the last NOISE_SHAPE_F_LENGTH samples was 0.5 at the positive noise-shaping-coefficients and -0.5 at the negative coefficients,
  88. // the maximum added value can be computed as follows:
  89. float* f=_noiseSFilter;
  90. float maxAddedVal=0.f;
  91. for (uint16_t j =0; j< NOISE_SHAPE_F_LENGTH; j++){
  92. maxAddedVal+=abs(*f++);
  93. }
  94. maxAddedVal/=2.f;
  95. _factor-=maxAddedVal;
  96. }
  97. reset();
  98. }
  99. void Quantizer::reset(){
  100. _bPtr0=_buffer0;
  101. _bPtr1=_buffer1;
  102. _fOutputLastIt0=0.;
  103. _fOutputLastIt1=0.;
  104. memset(_buffer0, 0, NOISE_SHAPE_F_LENGTH*sizeof(float));
  105. memset(_buffer1, 0, NOISE_SHAPE_F_LENGTH*sizeof(float));
  106. }
  107. void Quantizer::quantize(float* input, int16_t* output, uint16_t length){
  108. float xn, xnD, error;
  109. const float f2 = 1.f/1000000.f;
  110. #ifdef DEBUG_QUANTIZER
  111. float debugFF=1024.f;
  112. const float factor=(powf(2.f, 15.f)-1.f)/debugFF;
  113. #endif
  114. for (uint16_t i =0; i< length; i++){
  115. xn= SAMPLEINVALID(*input) ? 0. : *input*_factor; //-_fOutputLastIt0 according to paper
  116. ++input;
  117. if (_noiseShaping){
  118. xn+=_fOutputLastIt0;
  119. }
  120. if(_dither){
  121. const uint32_t r0=random(1000000);
  122. const uint32_t r1=random(1000000);
  123. xnD=xn + (r0 + r1)*f2-1.f;
  124. }
  125. else {
  126. xnD=xn;
  127. }
  128. float xnDR=round(xnD);
  129. if (_noiseShaping){
  130. //compute quatization error:
  131. error=xnDR- xn;
  132. *_bPtr0++=error;
  133. if (_bPtr0==_bufferEnd0){
  134. _bPtr0=_buffer0;
  135. }
  136. float* f=_noiseSFilter;
  137. _fOutputLastIt0=(*_bPtr0++ * *f++);
  138. if (_bPtr0==_bufferEnd0){
  139. _bPtr0=_buffer0;
  140. }
  141. for (uint16_t j =1; j< NOISE_SHAPE_F_LENGTH; j++){
  142. _fOutputLastIt0+=(*_bPtr0++ * *f++);
  143. if (_bPtr0==_bufferEnd0){
  144. _bPtr0=_buffer0;
  145. }
  146. }
  147. }
  148. #ifdef DEBUG_QUANTIZER
  149. xnDR*=debugFF;
  150. #endif
  151. if (xnDR > _factor){
  152. *output=(int16_t)_factor;
  153. }
  154. else if (xnDR < -_factor){
  155. *output=-(int16_t)_factor;
  156. }
  157. else {
  158. *output=(int16_t)xnDR;
  159. }
  160. ++output;
  161. }
  162. }
  163. void Quantizer::quantize(float* input0, float* input1, int32_t* outputInterleaved, uint16_t length){
  164. float xn0, xnD0, error0,xnDR0, xn1, xnD1, error1,xnDR1;
  165. const float f2 = 1.f/1000000.f;
  166. #ifdef DEBUG_QUANTIZER
  167. float debugFF=1024.f;
  168. const float factor=(powf(2.f, 15.f)-1.f)/debugFF;
  169. #endif
  170. for (uint16_t i =0; i< length; i++){
  171. xn0= SAMPLEINVALID(*input0) ? 0. : *input0*_factor; //-_fOutputLastIt0 according to paper
  172. ++input0;
  173. xn1= SAMPLEINVALID(*input1) ? 0. : *input1*_factor; //-_fOutputLastIt0 according to paper
  174. ++input1;
  175. if (_noiseShaping){
  176. xn0+=_fOutputLastIt0;
  177. xn1+=_fOutputLastIt1;
  178. }
  179. if(_dither){
  180. uint32_t r0=random(1000000);
  181. uint32_t r1=random(1000000);
  182. xnD0=xn0 + (r0 + r1)*f2-1.f;
  183. r0=random(1000000);
  184. r1=random(1000000);
  185. xnD1=xn1 + (r0 + r1)*f2-1.f;
  186. }
  187. else {
  188. xnD0=xn0;
  189. xnD1=xn1;
  190. }
  191. xnDR0=round(xnD0);
  192. xnDR1=round(xnD1);
  193. if (_noiseShaping){
  194. //compute quatization error0:
  195. error0=xnDR0- xn0;
  196. error1=xnDR1- xn1;
  197. *_bPtr0++=error0;
  198. *_bPtr1++=error1;
  199. if (_bPtr0==_bufferEnd0){
  200. _bPtr0=_buffer0;
  201. _bPtr1=_buffer1;
  202. }
  203. float* f=_noiseSFilter;
  204. _fOutputLastIt0=(*_bPtr0++ * *f);
  205. _fOutputLastIt1=(*_bPtr1++ * *f++);
  206. if (_bPtr0==_bufferEnd0){
  207. _bPtr0=_buffer0;
  208. _bPtr1=_buffer1;
  209. }
  210. for (uint16_t j =1 ; j< NOISE_SHAPE_F_LENGTH; j++){
  211. _fOutputLastIt0+=(*_bPtr0++ * *f);
  212. _fOutputLastIt1+=(*_bPtr1++ * *f++);
  213. if (_bPtr0==_bufferEnd0){
  214. _bPtr0=_buffer0;
  215. _bPtr1=_buffer1;
  216. }
  217. }
  218. }
  219. #ifdef DEBUG_QUANTIZER
  220. xnDR0*=debugFF;
  221. #endif
  222. if (xnDR0 > _factor){
  223. *outputInterleaved++=(int32_t)_factor;
  224. }
  225. else if (xnDR0 < -_factor){
  226. *outputInterleaved++=-(int32_t)_factor;
  227. }
  228. else {
  229. *outputInterleaved++=(int32_t)xnDR0;
  230. }
  231. if (xnDR1 > _factor){
  232. *outputInterleaved++=(int32_t)_factor;
  233. }
  234. else if (xnDR1 < -_factor){
  235. *outputInterleaved++=-(int32_t)_factor;
  236. }
  237. else {
  238. *outputInterleaved++=(int32_t)xnDR1;
  239. }
  240. }
  241. }