1 /*****************************************************************************
2 * adpcm.c : adpcm variant audio decoder
3 *****************************************************************************
4 * Copyright (C) 2001, 2002 VLC authors and VideoLAN
6 * Authors: Laurent Aimar <fenrir@via.ecp.fr>
9 * This program is free software; you can redistribute it and/or modify it
10 * under the terms of the GNU Lesser General Public License as published by
11 * the Free Software Foundation; either version 2.1 of the License, or
12 * (at your option) any later version.
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU Lesser General Public License for more details.
19 * You should have received a copy of the GNU Lesser General Public License
20 * along with this program; if not, write to the Free Software Foundation,
21 * Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
22 *****************************************************************************/
24 /*****************************************************************************
27 * Documentation: http://www.pcisys.net/~melanson/codecs/adpcm.txt
28 *****************************************************************************/
33 #include <vlc_common.h>
34 #include <vlc_plugin.h>
35 #include <vlc_codec.h>
37 /*****************************************************************************
39 *****************************************************************************/
40 static int OpenDecoder( vlc_object_t
* );
41 static void CloseDecoder( vlc_object_t
* );
43 static int DecodeAudio( decoder_t
*, block_t
* );
44 static void Flush( decoder_t
* );
47 set_description( N_("ADPCM audio decoder") )
48 set_capability( "audio decoder", 50 )
49 set_category( CAT_INPUT
)
50 set_subcategory( SUBCAT_INPUT_ACODEC
)
51 set_callbacks( OpenDecoder
, CloseDecoder
)
54 /*****************************************************************************
56 *****************************************************************************/
69 enum adpcm_codec_e codec
;
72 size_t i_samplesperblock
;
78 static void DecodeAdpcmMs ( decoder_t
*, int16_t *, uint8_t * );
79 static void DecodeAdpcmImaWav( decoder_t
*, int16_t *, uint8_t * );
80 static void DecodeAdpcmImaQT ( decoder_t
*, int16_t *, uint8_t * );
81 static void DecodeAdpcmDk4 ( decoder_t
*, int16_t *, uint8_t * );
82 static void DecodeAdpcmDk3 ( decoder_t
*, int16_t *, uint8_t * );
83 static void DecodeAdpcmEA ( decoder_t
*, int16_t *, uint8_t * );
85 /* Various table from http://www.pcisys.net/~melanson/codecs/adpcm.txt */
86 static const int i_index_table
[16] =
88 -1, -1, -1, -1, 2, 4, 6, 8,
89 -1, -1, -1, -1, 2, 4, 6, 8
92 static const int i_step_table
[89] =
94 7, 8, 9, 10, 11, 12, 13, 14, 16, 17,
95 19, 21, 23, 25, 28, 31, 34, 37, 41, 45,
96 50, 55, 60, 66, 73, 80, 88, 97, 107, 118,
97 130, 143, 157, 173, 190, 209, 230, 253, 279, 307,
98 337, 371, 408, 449, 494, 544, 598, 658, 724, 796,
99 876, 963, 1060, 1166, 1282, 1411, 1552, 1707, 1878, 2066,
100 2272, 2499, 2749, 3024, 3327, 3660, 4026, 4428, 4871, 5358,
101 5894, 6484, 7132, 7845, 8630, 9493, 10442, 11487, 12635, 13899,
102 15289, 16818, 18500, 20350, 22385, 24623, 27086, 29794, 32767
105 static const int i_adaptation_table
[16] =
107 230, 230, 230, 230, 307, 409, 512, 614,
108 768, 614, 512, 409, 307, 230, 230, 230
111 static const int i_adaptation_coeff1
[7] =
113 256, 512, 0, 192, 240, 460, 392
116 static const int i_adaptation_coeff2
[7] =
118 0, -256, 0, 64, 0, -208, -232
121 /*****************************************************************************
122 * OpenDecoder: probe the decoder and return score
123 *****************************************************************************/
124 static int OpenDecoder( vlc_object_t
*p_this
)
126 decoder_t
*p_dec
= (decoder_t
*)p_this
;
127 decoder_sys_t
*p_sys
;
129 switch( p_dec
->fmt_in
.i_codec
)
131 case VLC_CODEC_ADPCM_IMA_QT
:
132 case VLC_CODEC_ADPCM_IMA_WAV
:
133 case VLC_CODEC_ADPCM_MS
:
134 case VLC_CODEC_ADPCM_DK4
:
135 case VLC_CODEC_ADPCM_DK3
:
136 case VLC_CODEC_ADPCM_XA_EA
:
142 if( p_dec
->fmt_in
.audio
.i_rate
<= 0 )
144 msg_Err( p_dec
, "bad samplerate" );
148 /* Allocate the memory needed to store the decoder's structure */
149 p_sys
= malloc(sizeof(*p_sys
));
150 if( unlikely(p_sys
== NULL
) )
154 p_sys
->i_samplesperblock
= 0;
156 unsigned i_channels
= p_dec
->fmt_in
.audio
.i_channels
;
157 uint8_t i_max_channels
= 5;
158 switch( p_dec
->fmt_in
.i_codec
)
160 case VLC_CODEC_ADPCM_IMA_QT
: /* IMA ADPCM */
161 p_sys
->codec
= ADPCM_IMA_QT
;
164 case VLC_CODEC_ADPCM_IMA_WAV
: /* IMA ADPCM */
165 p_sys
->codec
= ADPCM_IMA_WAV
;
168 case VLC_CODEC_ADPCM_MS
: /* MS ADPCM */
169 p_sys
->codec
= ADPCM_MS
;
172 case VLC_CODEC_ADPCM_DK4
: /* Duck DK4 ADPCM */
173 p_sys
->codec
= ADPCM_DK4
;
176 case VLC_CODEC_ADPCM_DK3
: /* Duck DK3 ADPCM */
177 p_sys
->codec
= ADPCM_DK3
;
180 case VLC_CODEC_ADPCM_XA_EA
: /* EA ADPCM */
181 p_sys
->codec
= ADPCM_EA
;
182 p_sys
->prev
= calloc( 2 * p_dec
->fmt_in
.audio
.i_channels
,
184 if( unlikely(p_sys
->prev
== NULL
) )
192 if (i_channels
> i_max_channels
|| i_channels
== 0)
196 msg_Err( p_dec
, "Invalid number of channels %i", p_dec
->fmt_in
.audio
.i_channels
);
200 if( p_dec
->fmt_in
.audio
.i_blockalign
<= 0 )
202 p_sys
->i_block
= (p_sys
->codec
== ADPCM_IMA_QT
) ?
203 34 * p_dec
->fmt_in
.audio
.i_channels
: 1024;
204 msg_Warn( p_dec
, "block size undefined, using %zu", p_sys
->i_block
);
208 p_sys
->i_block
= p_dec
->fmt_in
.audio
.i_blockalign
;
211 /* calculate samples per block */
212 switch( p_sys
->codec
)
215 p_sys
->i_samplesperblock
= 64;
218 if( p_sys
->i_block
>= 4 * i_channels
)
220 p_sys
->i_samplesperblock
= 2 * ( p_sys
->i_block
- 4 * i_channels
)
225 if( p_sys
->i_block
>= 7 * i_channels
)
227 p_sys
->i_samplesperblock
=
228 2 * (p_sys
->i_block
- 7 * i_channels
) / i_channels
+ 2;
232 if( p_sys
->i_block
>= 4 * i_channels
)
234 p_sys
->i_samplesperblock
=
235 2 * (p_sys
->i_block
- 4 * i_channels
) / i_channels
+ 1;
240 if( p_sys
->i_block
>= 16 )
241 p_sys
->i_samplesperblock
= ( 4 * ( p_sys
->i_block
- 16 ) + 2 )/ 3;
244 if( p_sys
->i_block
>= i_channels
)
246 p_sys
->i_samplesperblock
=
247 2 * (p_sys
->i_block
- i_channels
) / i_channels
;
251 msg_Dbg( p_dec
, "format: samplerate:%d Hz channels:%d bits/sample:%d "
252 "blockalign:%zu samplesperblock:%zu",
253 p_dec
->fmt_in
.audio
.i_rate
, i_channels
,
254 p_dec
->fmt_in
.audio
.i_bitspersample
, p_sys
->i_block
,
255 p_sys
->i_samplesperblock
);
257 if (p_sys
->i_samplesperblock
== 0)
261 msg_Err( p_dec
, "Error computing number of samples per block");
265 p_dec
->p_sys
= p_sys
;
266 p_dec
->fmt_out
.i_codec
= VLC_CODEC_S16N
;
267 p_dec
->fmt_out
.audio
.i_rate
= p_dec
->fmt_in
.audio
.i_rate
;
268 p_dec
->fmt_out
.audio
.i_channels
= i_channels
;
269 p_dec
->fmt_out
.audio
.i_physical_channels
= vlc_chan_maps
[i_channels
];
271 date_Init( &p_sys
->end_date
, p_dec
->fmt_out
.audio
.i_rate
, 1 );
273 p_dec
->pf_decode
= DecodeAudio
;
274 p_dec
->pf_flush
= Flush
;
279 /*****************************************************************************
281 *****************************************************************************/
282 static void Flush( decoder_t
*p_dec
)
284 decoder_sys_t
*p_sys
= p_dec
->p_sys
;
286 date_Set( &p_sys
->end_date
, VLC_TICK_INVALID
);
289 /*****************************************************************************
291 *****************************************************************************/
292 static block_t
*DecodeBlock( decoder_t
*p_dec
, block_t
**pp_block
)
294 decoder_sys_t
*p_sys
= p_dec
->p_sys
;
297 if( !*pp_block
) return NULL
;
301 if( p_block
->i_flags
& (BLOCK_FLAG_DISCONTINUITY
|BLOCK_FLAG_CORRUPTED
) )
304 if( p_block
->i_flags
& BLOCK_FLAG_CORRUPTED
)
308 if( p_block
->i_pts
!= VLC_TICK_INVALID
&&
309 p_block
->i_pts
!= date_Get( &p_sys
->end_date
) )
311 date_Set( &p_sys
->end_date
, p_block
->i_pts
);
313 else if( date_Get( &p_sys
->end_date
) == VLC_TICK_INVALID
)
314 /* We've just started the stream, wait for the first PTS. */
317 /* Don't re-use the same pts twice */
318 p_block
->i_pts
= VLC_TICK_INVALID
;
320 if( p_block
->i_buffer
>= p_sys
->i_block
)
324 if( decoder_UpdateAudioFormat( p_dec
) )
326 p_out
= decoder_NewAudioBuffer( p_dec
, p_sys
->i_samplesperblock
);
330 p_out
->i_pts
= date_Get( &p_sys
->end_date
);
331 p_out
->i_length
= date_Increment( &p_sys
->end_date
,
332 p_sys
->i_samplesperblock
) - p_out
->i_pts
;
334 switch( p_sys
->codec
)
337 DecodeAdpcmImaQT( p_dec
, (int16_t*)p_out
->p_buffer
,
341 DecodeAdpcmImaWav( p_dec
, (int16_t*)p_out
->p_buffer
,
345 DecodeAdpcmMs( p_dec
, (int16_t*)p_out
->p_buffer
,
349 DecodeAdpcmDk4( p_dec
, (int16_t*)p_out
->p_buffer
,
353 DecodeAdpcmDk3( p_dec
, (int16_t*)p_out
->p_buffer
,
357 DecodeAdpcmEA( p_dec
, (int16_t*)p_out
->p_buffer
,
363 p_block
->p_buffer
+= p_sys
->i_block
;
364 p_block
->i_buffer
-= p_sys
->i_block
;
369 block_Release( p_block
);
374 static int DecodeAudio( decoder_t
*p_dec
, block_t
*p_block
)
376 if( p_block
== NULL
) /* No Drain */
377 return VLCDEC_SUCCESS
;
379 block_t
**pp_block
= &p_block
, *p_out
;
380 while( ( p_out
= DecodeBlock( p_dec
, pp_block
) ) != NULL
)
381 decoder_QueueAudio( p_dec
, p_out
);
382 return VLCDEC_SUCCESS
;
385 /*****************************************************************************
387 *****************************************************************************/
388 static void CloseDecoder( vlc_object_t
*p_this
)
390 decoder_t
*p_dec
= (decoder_t
*)p_this
;
391 decoder_sys_t
*p_sys
= p_dec
->p_sys
;
397 /*****************************************************************************
399 *****************************************************************************/
400 #define CLAMP( v, min, max ) \
401 if( (v) < (min) ) (v) = (min); \
402 if( (v) > (max) ) (v) = (max)
404 #define GetByte( v ) \
405 (v) = *p_buffer; p_buffer++;
407 #define GetWord( v ) \
408 (v) = *p_buffer; p_buffer++; \
409 (v) |= ( *p_buffer ) << 8; p_buffer++; \
410 if( (v)&0x8000 ) (v) -= 0x010000;
415 typedef struct adpcm_ms_channel_s
418 int i_sample1
, i_sample2
;
419 int i_coeff1
, i_coeff2
;
421 } adpcm_ms_channel_t
;
424 static int AdpcmMsExpandNibble(adpcm_ms_channel_t
*p_channel
,
431 i_snibble
= i_nibble
- ( i_nibble
&0x08 ? 0x10 : 0 );
433 i_predictor
= ( p_channel
->i_sample1
* p_channel
->i_coeff1
+
434 p_channel
->i_sample2
* p_channel
->i_coeff2
) / 256 +
435 i_snibble
* p_channel
->i_idelta
;
437 CLAMP( i_predictor
, -32768, 32767 );
439 p_channel
->i_sample2
= p_channel
->i_sample1
;
440 p_channel
->i_sample1
= i_predictor
;
442 p_channel
->i_idelta
= ( i_adaptation_table
[i_nibble
] *
443 p_channel
->i_idelta
) / 256;
444 if( p_channel
->i_idelta
< 16 )
446 p_channel
->i_idelta
= 16;
448 return( i_predictor
);
451 static void DecodeAdpcmMs( decoder_t
*p_dec
, int16_t *p_sample
,
454 decoder_sys_t
*p_sys
= p_dec
->p_sys
;
455 adpcm_ms_channel_t channel
[2];
457 int i_block_predictor
;
459 size_t i_total_samples
= p_sys
->i_samplesperblock
;
460 if(i_total_samples
< 2)
463 b_stereo
= p_dec
->fmt_out
.audio
.i_channels
== 2 ? 1 : 0;
465 GetByte( i_block_predictor
);
466 CLAMP( i_block_predictor
, 0, 6 );
467 channel
[0].i_coeff1
= i_adaptation_coeff1
[i_block_predictor
];
468 channel
[0].i_coeff2
= i_adaptation_coeff2
[i_block_predictor
];
472 GetByte( i_block_predictor
);
473 CLAMP( i_block_predictor
, 0, 6 );
474 channel
[1].i_coeff1
= i_adaptation_coeff1
[i_block_predictor
];
475 channel
[1].i_coeff2
= i_adaptation_coeff2
[i_block_predictor
];
477 GetWord( channel
[0].i_idelta
);
480 GetWord( channel
[1].i_idelta
);
483 GetWord( channel
[0].i_sample1
);
486 GetWord( channel
[1].i_sample1
);
489 GetWord( channel
[0].i_sample2
);
492 GetWord( channel
[1].i_sample2
);
497 *p_sample
++ = channel
[0].i_sample2
;
498 *p_sample
++ = channel
[1].i_sample2
;
499 *p_sample
++ = channel
[0].i_sample1
;
500 *p_sample
++ = channel
[1].i_sample1
;
504 *p_sample
++ = channel
[0].i_sample2
;
505 *p_sample
++ = channel
[0].i_sample1
;
508 for( i_total_samples
-= 2; i_total_samples
>= 2; i_total_samples
-= 2, p_buffer
++ )
510 *p_sample
++ = AdpcmMsExpandNibble( &channel
[0], (*p_buffer
) >> 4);
511 *p_sample
++ = AdpcmMsExpandNibble( &channel
[b_stereo
? 1 : 0],
519 typedef struct adpcm_ima_wav_channel_s
524 } adpcm_ima_wav_channel_t
;
526 static int AdpcmImaWavExpandNibble(adpcm_ima_wav_channel_t
*p_channel
,
531 i_diff
= i_step_table
[p_channel
->i_step_index
] >> 3;
532 if( i_nibble
&0x04 ) i_diff
+= i_step_table
[p_channel
->i_step_index
];
533 if( i_nibble
&0x02 ) i_diff
+= i_step_table
[p_channel
->i_step_index
]>>1;
534 if( i_nibble
&0x01 ) i_diff
+= i_step_table
[p_channel
->i_step_index
]>>2;
536 p_channel
->i_predictor
-= i_diff
;
538 p_channel
->i_predictor
+= i_diff
;
540 CLAMP( p_channel
->i_predictor
, -32768, 32767 );
542 p_channel
->i_step_index
+= i_index_table
[i_nibble
];
544 CLAMP( p_channel
->i_step_index
, 0, 88 );
546 return( p_channel
->i_predictor
);
549 static void DecodeAdpcmImaWav( decoder_t
*p_dec
, int16_t *p_sample
,
552 decoder_sys_t
*p_sys
= p_dec
->p_sys
;
553 adpcm_ima_wav_channel_t channel
[2];
557 b_stereo
= p_dec
->fmt_out
.audio
.i_channels
== 2 ? 1 : 0;
559 GetWord( channel
[0].i_predictor
);
560 GetByte( channel
[0].i_step_index
);
561 CLAMP( channel
[0].i_step_index
, 0, 88 );
566 GetWord( channel
[1].i_predictor
);
567 GetByte( channel
[1].i_step_index
);
568 CLAMP( channel
[1].i_step_index
, 0, 88 );
574 for( i_nibbles
= 2 * (p_sys
->i_block
- 8);
580 for( i
= 0; i
< 4; i
++ )
583 AdpcmImaWavExpandNibble(&channel
[0],p_buffer
[i
]&0x0f);
584 p_sample
[i
* 4 + 2] =
585 AdpcmImaWavExpandNibble(&channel
[0],p_buffer
[i
] >> 4);
589 for( i
= 0; i
< 4; i
++ )
591 p_sample
[i
* 4 + 1] =
592 AdpcmImaWavExpandNibble(&channel
[1],p_buffer
[i
]&0x0f);
593 p_sample
[i
* 4 + 3] =
594 AdpcmImaWavExpandNibble(&channel
[1],p_buffer
[i
] >> 4);
605 for( i_nibbles
= 2 * (p_sys
->i_block
- 4);
607 i_nibbles
-= 2, p_buffer
++ )
609 *p_sample
++ =AdpcmImaWavExpandNibble( &channel
[0], (*p_buffer
)&0x0f );
610 *p_sample
++ =AdpcmImaWavExpandNibble( &channel
[0], (*p_buffer
) >> 4 );
618 static void DecodeAdpcmImaQT( decoder_t
*p_dec
, int16_t *p_sample
,
621 adpcm_ima_wav_channel_t channel
[2];
626 i_step
= p_dec
->fmt_out
.audio
.i_channels
;
628 for( i_ch
= 0; i_ch
< p_dec
->fmt_out
.audio
.i_channels
; i_ch
++ )
631 channel
[i_ch
].i_predictor
= (int16_t)((( ( p_buffer
[0] << 1 )|( p_buffer
[1] >> 7 ) ))<<7);
632 channel
[i_ch
].i_step_index
= p_buffer
[1]&0x7f;
634 CLAMP( channel
[i_ch
].i_step_index
, 0, 88 );
637 for( i_nibbles
= 0; i_nibbles
< 64; i_nibbles
+=2 )
639 *p_sample
= AdpcmImaWavExpandNibble( &channel
[i_ch
], (*p_buffer
)&0x0f);
642 *p_sample
= AdpcmImaWavExpandNibble( &channel
[i_ch
], (*p_buffer
>> 4)&0x0f);
649 p_sample
+= 1 - 64 * i_step
;
656 static void DecodeAdpcmDk4( decoder_t
*p_dec
, int16_t *p_sample
,
659 decoder_sys_t
*p_sys
= p_dec
->p_sys
;
660 adpcm_ima_wav_channel_t channel
[2];
664 b_stereo
= p_dec
->fmt_out
.audio
.i_channels
== 2 ? 1 : 0;
666 GetWord( channel
[0].i_predictor
);
667 GetByte( channel
[0].i_step_index
);
668 CLAMP( channel
[0].i_step_index
, 0, 88 );
673 GetWord( channel
[1].i_predictor
);
674 GetByte( channel
[1].i_step_index
);
675 CLAMP( channel
[1].i_step_index
, 0, 88 );
679 /* first output predictor */
680 *p_sample
++ = channel
[0].i_predictor
;
683 *p_sample
++ = channel
[1].i_predictor
;
687 i_nibbles
< p_sys
->i_block
- 4 * (b_stereo
? 2:1 );
690 *p_sample
++ = AdpcmImaWavExpandNibble( &channel
[0],
692 *p_sample
++ = AdpcmImaWavExpandNibble( &channel
[b_stereo
? 1 : 0],
702 static void DecodeAdpcmDk3( decoder_t
*p_dec
, int16_t *p_sample
,
705 decoder_sys_t
*p_sys
= p_dec
->p_sys
;
706 uint8_t *p_end
= &p_buffer
[p_sys
->i_block
];
707 adpcm_ima_wav_channel_t sum
;
708 adpcm_ima_wav_channel_t diff
;
713 GetWord( sum
.i_predictor
);
714 GetWord( diff
.i_predictor
);
715 GetByte( sum
.i_step_index
);
716 GetByte( diff
.i_step_index
);
718 i_diff_value
= diff
.i_predictor
;
719 /* we process 6 nibbles at once */
720 while( p_buffer
+ 1 <= p_end
)
722 /* first 3 nibbles */
723 AdpcmImaWavExpandNibble( &sum
,
726 AdpcmImaWavExpandNibble( &diff
,
729 i_diff_value
= ( i_diff_value
+ diff
.i_predictor
) / 2;
731 *p_sample
++ = sum
.i_predictor
+ i_diff_value
;
732 *p_sample
++ = sum
.i_predictor
- i_diff_value
;
736 AdpcmImaWavExpandNibble( &sum
,
739 *p_sample
++ = sum
.i_predictor
+ i_diff_value
;
740 *p_sample
++ = sum
.i_predictor
- i_diff_value
;
742 /* now last 3 nibbles */
743 AdpcmImaWavExpandNibble( &sum
,
746 if( p_buffer
< p_end
)
748 AdpcmImaWavExpandNibble( &diff
,
751 i_diff_value
= ( i_diff_value
+ diff
.i_predictor
) / 2;
753 *p_sample
++ = sum
.i_predictor
+ i_diff_value
;
754 *p_sample
++ = sum
.i_predictor
- i_diff_value
;
756 AdpcmImaWavExpandNibble( &sum
,
760 *p_sample
++ = sum
.i_predictor
+ i_diff_value
;
761 *p_sample
++ = sum
.i_predictor
- i_diff_value
;
771 static void DecodeAdpcmEA( decoder_t
*p_dec
, int16_t *p_sample
,
774 static const int16_t EATable
[]=
776 0x0000, 0x00F0, 0x01CC, 0x0188, 0x0000, 0x0000, 0xFF30, 0xFF24,
777 0x0000, 0x0001, 0x0003, 0x0004, 0x0007, 0x0008, 0x000A, 0x000B,
778 0x0000, 0xFFFF, 0xFFFD, 0xFFFC,
780 decoder_sys_t
*p_sys
= p_dec
->p_sys
;
781 int_fast32_t c1
[MAX_CHAN
], c2
[MAX_CHAN
];
782 int_fast8_t d
[MAX_CHAN
];
784 unsigned chans
= p_dec
->fmt_out
.audio
.i_channels
;
785 const uint8_t *p_end
= &p_buffer
[p_sys
->i_block
];
786 int16_t *prev
= p_sys
->prev
;
787 int16_t *cur
= prev
+ chans
;
789 for (unsigned c
= 0; c
< chans
; c
++)
791 uint8_t input
= p_buffer
[c
];
793 c1
[c
] = EATable
[input
>> 4];
794 c2
[c
] = EATable
[(input
>> 4) + 4];
795 d
[c
] = (input
& 0xf) + 8;
798 for (p_buffer
+= chans
; p_buffer
< p_end
; p_buffer
+= chans
)
800 union { uint32_t u
; int32_t i
; } spl
;
802 for (unsigned c
= 0; c
< chans
; c
++)
804 spl
.u
= (p_buffer
[c
] & 0xf0u
) << 24u;
806 spl
.i
= (spl
.i
+ cur
[c
] * c1
[c
] + prev
[c
] * c2
[c
] + 0x80) >> 8;
807 CLAMP(spl
.i
, -32768, 32767);
811 *(p_sample
++) = spl
.i
;
814 for (unsigned c
= 0; c
< chans
; c
++)
816 spl
.u
= (p_buffer
[c
] & 0x0fu
) << 28u;
818 spl
.i
= (spl
.i
+ cur
[c
] * c1
[c
] + prev
[c
] * c2
[c
] + 0x80) >> 8;
819 CLAMP(spl
.i
, -32768, 32767);
823 *(p_sample
++) = spl
.i
;