1 /***************************************************************************
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
10 * Copyright (C) 2010 Yoshihisa Uchida
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation; either version 2
15 * of the License, or (at your option) any later version.
17 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
18 * KIND, either express or implied.
20 ****************************************************************************/
22 #include "pcm_common.h"
23 #include "support_formats.h"
29 * [1] Microsoft, New Multimedia Data Types and Data Techniques Revision 3.0, 1994
30 * [2] MulitimediaWiki, Microsoft ADPCM, 2006
31 * (http://wiki.multimedia.cx/index.php?title=Microsoft_ADPCM)
32 * [3] ffmpeg source code, libavcodec/adpcm.c
35 #define ADPCM_NUM_COEFF 7
37 static int16_t dec_coeff
[2][2];
38 static uint16_t delta
[2];
39 static int16_t sample
[2][2];
41 static struct pcm_format
*fmt
;
43 static const int16_t adaptation_table
[] ICONST_ATTR
= {
44 230, 230, 230, 230, 307, 409, 512, 614,
45 768, 614, 512, 409, 307, 230, 230, 230
48 static bool set_format(struct pcm_format
*format
)
52 if (fmt
->bitspersample
!= 4)
54 DEBUGF("CODEC_ERROR: microsoft adpcm must be 4 bitspersample: %d\n",
59 fmt
->chunksize
= fmt
->blockalign
;
64 static struct pcm_pos
*get_seek_pos(long seek_time
,
65 uint8_t *(*read_buffer
)(size_t *realsize
))
67 static struct pcm_pos newpos
;
68 uint32_t newblock
= ((uint64_t)seek_time
* ci
->id3
->frequency
)
69 / (1000LL * fmt
->samplesperblock
);
72 newpos
.pos
= newblock
* fmt
->blockalign
;
73 newpos
.samples
= newblock
* fmt
->samplesperblock
;
77 static int16_t create_pcmdata(int ch
, uint8_t nibble
)
81 pcmdata
= (sample
[ch
][0] * dec_coeff
[ch
][0] +
82 sample
[ch
][1] * dec_coeff
[ch
][1]) / 256;
83 pcmdata
+= (delta
[ch
] * (nibble
- ((nibble
& 0x8) << 1)));
85 CLIP(pcmdata
, -32768, 32767);
87 sample
[ch
][1] = sample
[ch
][0];
88 sample
[ch
][0] = pcmdata
;
90 delta
[ch
] = (adaptation_table
[nibble
] * delta
[ch
]) >> 8;
94 return (int16_t)pcmdata
;
97 static int decode(const uint8_t *inbuf
, size_t inbufsize
,
98 int32_t *outbuf
, int *outbufcount
)
102 int size
= fmt
->samplesperblock
;
104 /* read block header */
105 for (ch
= 0; ch
< fmt
->channels
; ch
++)
107 if (*inbuf
>= ADPCM_NUM_COEFF
)
109 DEBUGF("CODEC_ERROR: microsoft adpcm illegal initial coeff=%d > 7\n",
113 dec_coeff
[ch
][0] = fmt
->coeffs
[*inbuf
][0];
114 dec_coeff
[ch
][1] = fmt
->coeffs
[*inbuf
][1];
118 for (ch
= 0; ch
< fmt
->channels
; ch
++)
120 delta
[ch
] = inbuf
[0] | (SE(inbuf
[1]) << 8);
124 for (ch
= 0; ch
< fmt
->channels
; ch
++)
126 sample
[ch
][0] = inbuf
[0] | (SE(inbuf
[1]) << 8);
130 for (ch
= 0; ch
< fmt
->channels
; ch
++)
132 sample
[ch
][1] = inbuf
[0] | (SE(inbuf
[1]) << 8);
136 inbufsize
-= 7 * fmt
->channels
;
137 ch
= fmt
->channels
- 1;
141 *outbuf
++ = create_pcmdata(0, *inbuf
>> 4 ) << 13;
142 *outbuf
++ = create_pcmdata(ch
, *inbuf
& 0xf) << 13;
151 if (fmt
->channels
== 2)
153 *outbufcount
= nsamples
;
158 static const struct pcm_codec codec
= {
164 const struct pcm_codec
*get_ms_adpcm_codec(void)