1 /*****************************************************************************
2 * adpcm.c : adpcm variant audio decoder
3 *****************************************************************************
4 * Copyright (C) 2001, 2002 VLC authors and VideoLAN
7 * Authors: Laurent Aimar <fenrir@via.ecp.fr>
8 * RĂ©mi Denis-Courmont <rem # videolan.org>
10 * This program is free software; you can redistribute it and/or modify it
11 * under the terms of the GNU Lesser General Public License as published by
12 * the Free Software Foundation; either version 2.1 of the License, or
13 * (at your option) any later version.
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU Lesser General Public License for more details.
20 * You should have received a copy of the GNU Lesser General Public License
21 * along with this program; if not, write to the Free Software Foundation,
22 * Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
23 *****************************************************************************/
25 /*****************************************************************************
28 * Documentation: http://www.pcisys.net/~melanson/codecs/adpcm.txt
29 *****************************************************************************/
34 #include <vlc_common.h>
35 #include <vlc_plugin.h>
36 #include <vlc_codec.h>
38 /*****************************************************************************
40 *****************************************************************************/
41 static int OpenDecoder( vlc_object_t
* );
42 static void CloseDecoder( vlc_object_t
* );
44 static int DecodeAudio( decoder_t
*, block_t
* );
45 static void Flush( decoder_t
* );
48 set_description( N_("ADPCM audio decoder") )
49 set_capability( "audio decoder", 50 )
50 set_category( CAT_INPUT
)
51 set_subcategory( SUBCAT_INPUT_ACODEC
)
52 set_callbacks( OpenDecoder
, CloseDecoder
)
55 /*****************************************************************************
57 *****************************************************************************/
70 enum adpcm_codec_e codec
;
73 size_t i_samplesperblock
;
79 static void DecodeAdpcmMs ( decoder_t
*, int16_t *, uint8_t * );
80 static void DecodeAdpcmImaWav( decoder_t
*, int16_t *, uint8_t * );
81 static void DecodeAdpcmImaQT ( decoder_t
*, int16_t *, uint8_t * );
82 static void DecodeAdpcmDk4 ( decoder_t
*, int16_t *, uint8_t * );
83 static void DecodeAdpcmDk3 ( decoder_t
*, int16_t *, uint8_t * );
84 static void DecodeAdpcmEA ( decoder_t
*, int16_t *, uint8_t * );
86 /* Various table from http://www.pcisys.net/~melanson/codecs/adpcm.txt */
87 static const int i_index_table
[16] =
89 -1, -1, -1, -1, 2, 4, 6, 8,
90 -1, -1, -1, -1, 2, 4, 6, 8
93 static const int i_step_table
[89] =
95 7, 8, 9, 10, 11, 12, 13, 14, 16, 17,
96 19, 21, 23, 25, 28, 31, 34, 37, 41, 45,
97 50, 55, 60, 66, 73, 80, 88, 97, 107, 118,
98 130, 143, 157, 173, 190, 209, 230, 253, 279, 307,
99 337, 371, 408, 449, 494, 544, 598, 658, 724, 796,
100 876, 963, 1060, 1166, 1282, 1411, 1552, 1707, 1878, 2066,
101 2272, 2499, 2749, 3024, 3327, 3660, 4026, 4428, 4871, 5358,
102 5894, 6484, 7132, 7845, 8630, 9493, 10442, 11487, 12635, 13899,
103 15289, 16818, 18500, 20350, 22385, 24623, 27086, 29794, 32767
106 static const int i_adaptation_table
[16] =
108 230, 230, 230, 230, 307, 409, 512, 614,
109 768, 614, 512, 409, 307, 230, 230, 230
112 static const int i_adaptation_coeff1
[7] =
114 256, 512, 0, 192, 240, 460, 392
117 static const int i_adaptation_coeff2
[7] =
119 0, -256, 0, 64, 0, -208, -232
122 /*****************************************************************************
123 * OpenDecoder: probe the decoder and return score
124 *****************************************************************************/
125 static int OpenDecoder( vlc_object_t
*p_this
)
127 decoder_t
*p_dec
= (decoder_t
*)p_this
;
128 decoder_sys_t
*p_sys
;
130 switch( p_dec
->fmt_in
.i_codec
)
132 case VLC_CODEC_ADPCM_IMA_QT
:
133 case VLC_CODEC_ADPCM_IMA_WAV
:
134 case VLC_CODEC_ADPCM_MS
:
135 case VLC_CODEC_ADPCM_DK4
:
136 case VLC_CODEC_ADPCM_DK3
:
137 case VLC_CODEC_ADPCM_XA_EA
:
143 if( p_dec
->fmt_in
.audio
.i_rate
<= 0 )
145 msg_Err( p_dec
, "bad samplerate" );
149 /* Allocate the memory needed to store the decoder's structure */
150 p_sys
= malloc(sizeof(*p_sys
));
151 if( unlikely(p_sys
== NULL
) )
155 p_sys
->i_samplesperblock
= 0;
157 unsigned i_channels
= p_dec
->fmt_in
.audio
.i_channels
;
158 uint8_t i_max_channels
= 5;
159 switch( p_dec
->fmt_in
.i_codec
)
161 case VLC_CODEC_ADPCM_IMA_QT
: /* IMA ADPCM */
162 p_sys
->codec
= ADPCM_IMA_QT
;
165 case VLC_CODEC_ADPCM_IMA_WAV
: /* IMA ADPCM */
166 p_sys
->codec
= ADPCM_IMA_WAV
;
169 case VLC_CODEC_ADPCM_MS
: /* MS ADPCM */
170 p_sys
->codec
= ADPCM_MS
;
173 case VLC_CODEC_ADPCM_DK4
: /* Duck DK4 ADPCM */
174 p_sys
->codec
= ADPCM_DK4
;
177 case VLC_CODEC_ADPCM_DK3
: /* Duck DK3 ADPCM */
178 p_sys
->codec
= ADPCM_DK3
;
181 case VLC_CODEC_ADPCM_XA_EA
: /* EA ADPCM */
182 p_sys
->codec
= ADPCM_EA
;
183 p_sys
->prev
= calloc( 2 * p_dec
->fmt_in
.audio
.i_channels
,
185 if( unlikely(p_sys
->prev
== NULL
) )
193 if (i_channels
> i_max_channels
|| i_channels
== 0)
197 msg_Err( p_dec
, "Invalid number of channels %i", p_dec
->fmt_in
.audio
.i_channels
);
201 if( p_dec
->fmt_in
.audio
.i_blockalign
<= 0 )
203 p_sys
->i_block
= (p_sys
->codec
== ADPCM_IMA_QT
) ?
204 34 * p_dec
->fmt_in
.audio
.i_channels
: 1024;
205 msg_Warn( p_dec
, "block size undefined, using %zu", p_sys
->i_block
);
209 p_sys
->i_block
= p_dec
->fmt_in
.audio
.i_blockalign
;
212 /* calculate samples per block */
213 switch( p_sys
->codec
)
216 p_sys
->i_samplesperblock
= 64;
219 if( p_sys
->i_block
>= 4 * i_channels
)
221 p_sys
->i_samplesperblock
= 2 * ( p_sys
->i_block
- 4 * i_channels
)
226 if( p_sys
->i_block
>= 7 * i_channels
)
228 p_sys
->i_samplesperblock
=
229 2 * (p_sys
->i_block
- 7 * i_channels
) / i_channels
+ 2;
233 if( p_sys
->i_block
>= 4 * i_channels
)
235 p_sys
->i_samplesperblock
=
236 2 * (p_sys
->i_block
- 4 * i_channels
) / i_channels
+ 1;
241 if( p_sys
->i_block
>= 16 )
242 p_sys
->i_samplesperblock
= ( 4 * ( p_sys
->i_block
- 16 ) + 2 )/ 3;
245 if( p_sys
->i_block
>= i_channels
)
247 p_sys
->i_samplesperblock
=
248 2 * (p_sys
->i_block
- i_channels
) / i_channels
;
252 msg_Dbg( p_dec
, "format: samplerate:%d Hz channels:%d bits/sample:%d "
253 "blockalign:%zu samplesperblock:%zu",
254 p_dec
->fmt_in
.audio
.i_rate
, i_channels
,
255 p_dec
->fmt_in
.audio
.i_bitspersample
, p_sys
->i_block
,
256 p_sys
->i_samplesperblock
);
258 if (p_sys
->i_samplesperblock
== 0)
262 msg_Err( p_dec
, "Error computing number of samples per block");
266 p_dec
->p_sys
= p_sys
;
267 p_dec
->fmt_out
.i_codec
= VLC_CODEC_S16N
;
268 p_dec
->fmt_out
.audio
.i_rate
= p_dec
->fmt_in
.audio
.i_rate
;
269 p_dec
->fmt_out
.audio
.i_channels
= i_channels
;
270 p_dec
->fmt_out
.audio
.i_physical_channels
= vlc_chan_maps
[i_channels
];
272 date_Init( &p_sys
->end_date
, p_dec
->fmt_out
.audio
.i_rate
, 1 );
274 p_dec
->pf_decode
= DecodeAudio
;
275 p_dec
->pf_flush
= Flush
;
280 /*****************************************************************************
282 *****************************************************************************/
283 static void Flush( decoder_t
*p_dec
)
285 decoder_sys_t
*p_sys
= p_dec
->p_sys
;
287 date_Set( &p_sys
->end_date
, VLC_TICK_INVALID
);
290 /*****************************************************************************
292 *****************************************************************************/
293 static block_t
*DecodeBlock( decoder_t
*p_dec
, block_t
**pp_block
)
295 decoder_sys_t
*p_sys
= p_dec
->p_sys
;
298 if( !*pp_block
) return NULL
;
302 if( p_block
->i_flags
& (BLOCK_FLAG_DISCONTINUITY
|BLOCK_FLAG_CORRUPTED
) )
305 if( p_block
->i_flags
& BLOCK_FLAG_CORRUPTED
)
309 if( p_block
->i_pts
!= VLC_TICK_INVALID
&&
310 p_block
->i_pts
!= date_Get( &p_sys
->end_date
) )
312 date_Set( &p_sys
->end_date
, p_block
->i_pts
);
314 else if( date_Get( &p_sys
->end_date
) == VLC_TICK_INVALID
)
315 /* We've just started the stream, wait for the first PTS. */
318 /* Don't re-use the same pts twice */
319 p_block
->i_pts
= VLC_TICK_INVALID
;
321 if( p_block
->i_buffer
>= p_sys
->i_block
)
325 if( decoder_UpdateAudioFormat( p_dec
) )
327 p_out
= decoder_NewAudioBuffer( p_dec
, p_sys
->i_samplesperblock
);
331 p_out
->i_pts
= date_Get( &p_sys
->end_date
);
332 p_out
->i_length
= date_Increment( &p_sys
->end_date
,
333 p_sys
->i_samplesperblock
) - p_out
->i_pts
;
335 switch( p_sys
->codec
)
338 DecodeAdpcmImaQT( p_dec
, (int16_t*)p_out
->p_buffer
,
342 DecodeAdpcmImaWav( p_dec
, (int16_t*)p_out
->p_buffer
,
346 DecodeAdpcmMs( p_dec
, (int16_t*)p_out
->p_buffer
,
350 DecodeAdpcmDk4( p_dec
, (int16_t*)p_out
->p_buffer
,
354 DecodeAdpcmDk3( p_dec
, (int16_t*)p_out
->p_buffer
,
358 DecodeAdpcmEA( p_dec
, (int16_t*)p_out
->p_buffer
,
364 p_block
->p_buffer
+= p_sys
->i_block
;
365 p_block
->i_buffer
-= p_sys
->i_block
;
370 block_Release( p_block
);
375 static int DecodeAudio( decoder_t
*p_dec
, block_t
*p_block
)
377 if( p_block
== NULL
) /* No Drain */
378 return VLCDEC_SUCCESS
;
380 block_t
**pp_block
= &p_block
, *p_out
;
381 while( ( p_out
= DecodeBlock( p_dec
, pp_block
) ) != NULL
)
382 decoder_QueueAudio( p_dec
, p_out
);
383 return VLCDEC_SUCCESS
;
386 /*****************************************************************************
388 *****************************************************************************/
389 static void CloseDecoder( vlc_object_t
*p_this
)
391 decoder_t
*p_dec
= (decoder_t
*)p_this
;
392 decoder_sys_t
*p_sys
= p_dec
->p_sys
;
398 /*****************************************************************************
400 *****************************************************************************/
401 #define CLAMP( v, min, max ) \
402 if( (v) < (min) ) (v) = (min); \
403 if( (v) > (max) ) (v) = (max)
405 #define GetByte( v ) \
406 (v) = *p_buffer; p_buffer++;
408 #define GetWord( v ) \
409 (v) = *p_buffer; p_buffer++; \
410 (v) |= ( *p_buffer ) << 8; p_buffer++; \
411 if( (v)&0x8000 ) (v) -= 0x010000;
416 typedef struct adpcm_ms_channel_s
419 int i_sample1
, i_sample2
;
420 int i_coeff1
, i_coeff2
;
422 } adpcm_ms_channel_t
;
425 static int AdpcmMsExpandNibble(adpcm_ms_channel_t
*p_channel
,
432 i_snibble
= i_nibble
- ( i_nibble
&0x08 ? 0x10 : 0 );
434 i_predictor
= ( p_channel
->i_sample1
* p_channel
->i_coeff1
+
435 p_channel
->i_sample2
* p_channel
->i_coeff2
) / 256 +
436 i_snibble
* p_channel
->i_idelta
;
438 CLAMP( i_predictor
, -32768, 32767 );
440 p_channel
->i_sample2
= p_channel
->i_sample1
;
441 p_channel
->i_sample1
= i_predictor
;
443 p_channel
->i_idelta
= ( i_adaptation_table
[i_nibble
] *
444 p_channel
->i_idelta
) / 256;
445 if( p_channel
->i_idelta
< 16 )
447 p_channel
->i_idelta
= 16;
449 return( i_predictor
);
452 static void DecodeAdpcmMs( decoder_t
*p_dec
, int16_t *p_sample
,
455 decoder_sys_t
*p_sys
= p_dec
->p_sys
;
456 adpcm_ms_channel_t channel
[2];
458 int i_block_predictor
;
460 size_t i_total_samples
= p_sys
->i_samplesperblock
;
461 if(i_total_samples
< 2)
464 b_stereo
= p_dec
->fmt_out
.audio
.i_channels
== 2 ? 1 : 0;
466 GetByte( i_block_predictor
);
467 CLAMP( i_block_predictor
, 0, 6 );
468 channel
[0].i_coeff1
= i_adaptation_coeff1
[i_block_predictor
];
469 channel
[0].i_coeff2
= i_adaptation_coeff2
[i_block_predictor
];
473 GetByte( i_block_predictor
);
474 CLAMP( i_block_predictor
, 0, 6 );
475 channel
[1].i_coeff1
= i_adaptation_coeff1
[i_block_predictor
];
476 channel
[1].i_coeff2
= i_adaptation_coeff2
[i_block_predictor
];
478 GetWord( channel
[0].i_idelta
);
481 GetWord( channel
[1].i_idelta
);
484 GetWord( channel
[0].i_sample1
);
487 GetWord( channel
[1].i_sample1
);
490 GetWord( channel
[0].i_sample2
);
493 GetWord( channel
[1].i_sample2
);
498 *p_sample
++ = channel
[0].i_sample2
;
499 *p_sample
++ = channel
[1].i_sample2
;
500 *p_sample
++ = channel
[0].i_sample1
;
501 *p_sample
++ = channel
[1].i_sample1
;
505 *p_sample
++ = channel
[0].i_sample2
;
506 *p_sample
++ = channel
[0].i_sample1
;
509 for( i_total_samples
-= 2; i_total_samples
>= 2; i_total_samples
-= 2, p_buffer
++ )
511 *p_sample
++ = AdpcmMsExpandNibble( &channel
[0], (*p_buffer
) >> 4);
512 *p_sample
++ = AdpcmMsExpandNibble( &channel
[b_stereo
? 1 : 0],
520 typedef struct adpcm_ima_wav_channel_s
525 } adpcm_ima_wav_channel_t
;
527 static int AdpcmImaWavExpandNibble(adpcm_ima_wav_channel_t
*p_channel
,
532 i_diff
= i_step_table
[p_channel
->i_step_index
] >> 3;
533 if( i_nibble
&0x04 ) i_diff
+= i_step_table
[p_channel
->i_step_index
];
534 if( i_nibble
&0x02 ) i_diff
+= i_step_table
[p_channel
->i_step_index
]>>1;
535 if( i_nibble
&0x01 ) i_diff
+= i_step_table
[p_channel
->i_step_index
]>>2;
537 p_channel
->i_predictor
-= i_diff
;
539 p_channel
->i_predictor
+= i_diff
;
541 CLAMP( p_channel
->i_predictor
, -32768, 32767 );
543 p_channel
->i_step_index
+= i_index_table
[i_nibble
];
545 CLAMP( p_channel
->i_step_index
, 0, 88 );
547 return( p_channel
->i_predictor
);
550 static void DecodeAdpcmImaWav( decoder_t
*p_dec
, int16_t *p_sample
,
553 decoder_sys_t
*p_sys
= p_dec
->p_sys
;
554 adpcm_ima_wav_channel_t channel
[2];
558 b_stereo
= p_dec
->fmt_out
.audio
.i_channels
== 2 ? 1 : 0;
560 GetWord( channel
[0].i_predictor
);
561 GetByte( channel
[0].i_step_index
);
562 CLAMP( channel
[0].i_step_index
, 0, 88 );
567 GetWord( channel
[1].i_predictor
);
568 GetByte( channel
[1].i_step_index
);
569 CLAMP( channel
[1].i_step_index
, 0, 88 );
575 for( i_nibbles
= 2 * (p_sys
->i_block
- 8);
581 for( i
= 0; i
< 4; i
++ )
584 AdpcmImaWavExpandNibble(&channel
[0],p_buffer
[i
]&0x0f);
585 p_sample
[i
* 4 + 2] =
586 AdpcmImaWavExpandNibble(&channel
[0],p_buffer
[i
] >> 4);
590 for( i
= 0; i
< 4; i
++ )
592 p_sample
[i
* 4 + 1] =
593 AdpcmImaWavExpandNibble(&channel
[1],p_buffer
[i
]&0x0f);
594 p_sample
[i
* 4 + 3] =
595 AdpcmImaWavExpandNibble(&channel
[1],p_buffer
[i
] >> 4);
606 for( i_nibbles
= 2 * (p_sys
->i_block
- 4);
608 i_nibbles
-= 2, p_buffer
++ )
610 *p_sample
++ =AdpcmImaWavExpandNibble( &channel
[0], (*p_buffer
)&0x0f );
611 *p_sample
++ =AdpcmImaWavExpandNibble( &channel
[0], (*p_buffer
) >> 4 );
619 static void DecodeAdpcmImaQT( decoder_t
*p_dec
, int16_t *p_sample
,
622 adpcm_ima_wav_channel_t channel
[2];
627 i_step
= p_dec
->fmt_out
.audio
.i_channels
;
629 for( i_ch
= 0; i_ch
< p_dec
->fmt_out
.audio
.i_channels
; i_ch
++ )
632 channel
[i_ch
].i_predictor
= (int16_t)((( ( p_buffer
[0] << 1 )|( p_buffer
[1] >> 7 ) ))<<7);
633 channel
[i_ch
].i_step_index
= p_buffer
[1]&0x7f;
635 CLAMP( channel
[i_ch
].i_step_index
, 0, 88 );
638 for( i_nibbles
= 0; i_nibbles
< 64; i_nibbles
+=2 )
640 *p_sample
= AdpcmImaWavExpandNibble( &channel
[i_ch
], (*p_buffer
)&0x0f);
643 *p_sample
= AdpcmImaWavExpandNibble( &channel
[i_ch
], (*p_buffer
>> 4)&0x0f);
650 p_sample
+= 1 - 64 * i_step
;
657 static void DecodeAdpcmDk4( decoder_t
*p_dec
, int16_t *p_sample
,
660 decoder_sys_t
*p_sys
= p_dec
->p_sys
;
661 adpcm_ima_wav_channel_t channel
[2];
665 b_stereo
= p_dec
->fmt_out
.audio
.i_channels
== 2 ? 1 : 0;
667 GetWord( channel
[0].i_predictor
);
668 GetByte( channel
[0].i_step_index
);
669 CLAMP( channel
[0].i_step_index
, 0, 88 );
674 GetWord( channel
[1].i_predictor
);
675 GetByte( channel
[1].i_step_index
);
676 CLAMP( channel
[1].i_step_index
, 0, 88 );
680 /* first output predictor */
681 *p_sample
++ = channel
[0].i_predictor
;
684 *p_sample
++ = channel
[1].i_predictor
;
688 i_nibbles
< p_sys
->i_block
- 4 * (b_stereo
? 2:1 );
691 *p_sample
++ = AdpcmImaWavExpandNibble( &channel
[0],
693 *p_sample
++ = AdpcmImaWavExpandNibble( &channel
[b_stereo
? 1 : 0],
703 static void DecodeAdpcmDk3( decoder_t
*p_dec
, int16_t *p_sample
,
706 decoder_sys_t
*p_sys
= p_dec
->p_sys
;
707 uint8_t *p_end
= &p_buffer
[p_sys
->i_block
];
708 adpcm_ima_wav_channel_t sum
;
709 adpcm_ima_wav_channel_t diff
;
714 GetWord( sum
.i_predictor
);
715 GetWord( diff
.i_predictor
);
716 GetByte( sum
.i_step_index
);
717 GetByte( diff
.i_step_index
);
719 i_diff_value
= diff
.i_predictor
;
720 /* we process 6 nibbles at once */
721 while( p_buffer
+ 1 <= p_end
)
723 /* first 3 nibbles */
724 AdpcmImaWavExpandNibble( &sum
,
727 AdpcmImaWavExpandNibble( &diff
,
730 i_diff_value
= ( i_diff_value
+ diff
.i_predictor
) / 2;
732 *p_sample
++ = sum
.i_predictor
+ i_diff_value
;
733 *p_sample
++ = sum
.i_predictor
- i_diff_value
;
737 AdpcmImaWavExpandNibble( &sum
,
740 *p_sample
++ = sum
.i_predictor
+ i_diff_value
;
741 *p_sample
++ = sum
.i_predictor
- i_diff_value
;
743 /* now last 3 nibbles */
744 AdpcmImaWavExpandNibble( &sum
,
747 if( p_buffer
< p_end
)
749 AdpcmImaWavExpandNibble( &diff
,
752 i_diff_value
= ( i_diff_value
+ diff
.i_predictor
) / 2;
754 *p_sample
++ = sum
.i_predictor
+ i_diff_value
;
755 *p_sample
++ = sum
.i_predictor
- i_diff_value
;
757 AdpcmImaWavExpandNibble( &sum
,
761 *p_sample
++ = sum
.i_predictor
+ i_diff_value
;
762 *p_sample
++ = sum
.i_predictor
- i_diff_value
;
772 static void DecodeAdpcmEA( decoder_t
*p_dec
, int16_t *p_sample
,
775 static const int16_t EATable
[]=
777 0x0000, 0x00F0, 0x01CC, 0x0188, 0x0000, 0x0000, 0xFF30, 0xFF24,
778 0x0000, 0x0001, 0x0003, 0x0004, 0x0007, 0x0008, 0x000A, 0x000B,
779 0x0000, 0xFFFF, 0xFFFD, 0xFFFC,
781 decoder_sys_t
*p_sys
= p_dec
->p_sys
;
782 int_fast32_t c1
[MAX_CHAN
], c2
[MAX_CHAN
];
783 int_fast8_t d
[MAX_CHAN
];
785 unsigned chans
= p_dec
->fmt_out
.audio
.i_channels
;
786 const uint8_t *p_end
= &p_buffer
[p_sys
->i_block
];
787 int16_t *prev
= p_sys
->prev
;
788 int16_t *cur
= prev
+ chans
;
790 for (unsigned c
= 0; c
< chans
; c
++)
792 uint8_t input
= p_buffer
[c
];
794 c1
[c
] = EATable
[input
>> 4];
795 c2
[c
] = EATable
[(input
>> 4) + 4];
796 d
[c
] = (input
& 0xf) + 8;
799 for (p_buffer
+= chans
; p_buffer
< p_end
; p_buffer
+= chans
)
801 union { uint32_t u
; int32_t i
; } spl
;
803 for (unsigned c
= 0; c
< chans
; c
++)
805 spl
.u
= (p_buffer
[c
] & 0xf0u
) << 24u;
807 spl
.i
= (spl
.i
+ cur
[c
] * c1
[c
] + prev
[c
] * c2
[c
] + 0x80) >> 8;
808 CLAMP(spl
.i
, -32768, 32767);
812 *(p_sample
++) = spl
.i
;
815 for (unsigned c
= 0; c
< chans
; c
++)
817 spl
.u
= (p_buffer
[c
] & 0x0fu
) << 28u;
819 spl
.i
= (spl
.i
+ cur
[c
] * c1
[c
] + prev
[c
] * c2
[c
] + 0x80) >> 8;
820 CLAMP(spl
.i
, -32768, 32767);
824 *(p_sample
++) = spl
.i
;