@@ -202,7 +202,6 @@ uint32_t SRLAUtility_ComputeOffsetLeftShift(
202202 return offset_shift ;
203203}
204204
205-
206205/* プリエンファシスフィルタ初期化 */
207206void SRLAPreemphasisFilter_Initialize (struct SRLAPreemphasisFilter * preem )
208207{
@@ -211,6 +210,52 @@ void SRLAPreemphasisFilter_Initialize(struct SRLAPreemphasisFilter *preem)
211210 preem -> coef = 0 ;
212211}
213212
213+ /* プリエンファシスの係数計算 */
214+ void SRLAPreemphasisFilter_CalculateCoefficient (
215+ struct SRLAPreemphasisFilter * preem , const int32_t * data , uint32_t num_samples )
216+ {
217+ uint32_t i ;
218+ double r0 , r1 ;
219+ double curr , succ ;
220+ double double_coef ;
221+
222+ SRLA_ASSERT (preem != NULL );
223+ SRLA_ASSERT (data != NULL );
224+
225+ /* 相関の計算 */
226+ curr = data [0 ];
227+ succ = data [1 ];
228+ r0 = r1 = 0.0 ;
229+ for (i = 0 ; i < num_samples - 2 ; i ++ ) {
230+ const double succsucc = data [i + 2 ];
231+ r0 += curr * curr ;
232+ r1 += curr * succ ;
233+ curr = succ ;
234+ succ = succsucc ;
235+ }
236+ /* i = num_samples - 1 */
237+ r0 += curr * curr ;
238+ r1 += curr * succ ;
239+ curr = succ ;
240+ r0 += curr * curr ;
241+ SRLA_ASSERT (r0 >= r1 );
242+
243+ /* 分散が小さい場合は0を設定 */
244+ if (r0 < 1e-6 ) {
245+ preem -> coef = 0 ;
246+ return ;
247+ }
248+
249+ /* 係数計算・固定小数化 */
250+ {
251+ const double double_coef = r1 / r0 ;
252+ int32_t coef = (int32_t )SRLAUtility_Round (double_coef * pow (2.0f , SRLA_PREEMPHASIS_COEF_SHIFT ));
253+ /* 丸め込み */
254+ coef = SRLAUTILITY_INNER_VALUE (coef , - (1 << SRLA_PREEMPHASIS_COEF_SHIFT ), (1 << SRLA_PREEMPHASIS_COEF_SHIFT ) - 1 );
255+ preem -> coef = coef ;
256+ }
257+ }
258+
214259/* 多段プリエンファシスの係数計算 */
215260void SRLAPreemphasisFilter_CalculateMultiStageCoefficients (
216261 struct SRLAPreemphasisFilter * preem , uint32_t num_preem , const int32_t * buffer , uint32_t num_samples )
@@ -221,7 +266,6 @@ void SRLAPreemphasisFilter_CalculateMultiStageCoefficients(
221266 double double_coef [SRLA_NUM_PREEMPHASIS_FILTERS ];
222267
223268 /* 注意)現段階では2回を前提 */
224- SRLA_STATIC_ASSERT (SRLA_NUM_PREEMPHASIS_FILTERS == 2 );
225269 SRLA_ASSERT (num_preem == 2 );
226270
227271 SRLA_ASSERT (preem != NULL );
@@ -313,6 +357,26 @@ void SRLAPreemphasisFilter_Preemphasis(
313357 preem -> prev = prev ;
314358}
315359
360+ /* デエンファシスを適用 */
361+ void SRLAPreemphasisFilter_Deemphasis (
362+ struct SRLAPreemphasisFilter * preem , int32_t * buffer , uint32_t num_samples )
363+ {
364+ uint32_t smpl ;
365+ const int32_t c0 = preem [0 ].coef ;
366+
367+ SRLA_ASSERT (buffer != NULL );
368+ SRLA_ASSERT (preem != NULL );
369+
370+ buffer [0 ] += (preem [0 ].prev * c0 ) >> SRLA_PREEMPHASIS_COEF_SHIFT ;
371+
372+ for (smpl = 2 ; smpl < num_samples ; smpl ++ ) {
373+ buffer [smpl - 1 ] += (buffer [smpl - 2 ] * c0 ) >> SRLA_PREEMPHASIS_COEF_SHIFT ;
374+ }
375+
376+ preem [0 ].prev = buffer [num_samples - 1 ];
377+ buffer [num_samples - 1 ] += (buffer [num_samples - 2 ] * c0 ) >> SRLA_PREEMPHASIS_COEF_SHIFT ;
378+ }
379+
316380/* デエンファシスを複数回適用 */
317381void SRLAPreemphasisFilter_MultiStageDeemphasis (
318382 struct SRLAPreemphasisFilter * preem , uint32_t num_preem , int32_t * buffer , uint32_t num_samples )
@@ -322,7 +386,6 @@ void SRLAPreemphasisFilter_MultiStageDeemphasis(
322386 const int32_t c1 = preem [1 ].coef ;
323387
324388 /* 注意)現段階では2回を前提 */
325- SRLA_STATIC_ASSERT (SRLA_NUM_PREEMPHASIS_FILTERS == 2 );
326389 SRLA_ASSERT (num_preem == 2 );
327390
328391 SRLA_ASSERT (buffer != NULL );
0 commit comments