1 /***************************************************************************
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
10 * Copyright (C) 2005 Dave Chapman
11 * Copyright (C) 2009 Yoshihisa Uchida
13 * This program is free software; you can redistribute it and/or
14 * modify it under the terms of the GNU General Public License
15 * as published by the Free Software Foundation; either version 2
16 * of the License, or (at your option) any later version.
18 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
19 * KIND, either express or implied.
21 ****************************************************************************/
23 #include "pcm_common.h"
24 #include "support_formats.h"
30 static struct pcm_format
*fmt
;
32 static bool set_format(struct pcm_format
*format
)
36 if (fmt
->bitspersample
> 32)
38 DEBUGF("CODEC_ERROR: pcm with more than 32 bitspersample "
43 fmt
->bytespersample
= fmt
->bitspersample
>> 3;
45 if (fmt
->totalsamples
== 0)
46 fmt
->totalsamples
= fmt
->numbytes
/fmt
->bytespersample
;
48 fmt
->samplesperblock
= fmt
->blockalign
/ (fmt
->bytespersample
* fmt
->channels
);
50 /* chunksize = about 1/50[sec] data */
51 fmt
->chunksize
= (ci
->id3
->frequency
/ (50 * fmt
->samplesperblock
))
57 static struct pcm_pos
*get_seek_pos(long seek_time
,
58 uint8_t *(*read_buffer
)(size_t *realsize
))
60 static struct pcm_pos newpos
;
61 uint32_t newblock
= ((uint64_t)seek_time
* ci
->id3
->frequency
)
62 / (1000LL * fmt
->samplesperblock
);
65 newpos
.pos
= newblock
* fmt
->blockalign
;
66 newpos
.samples
= newblock
* fmt
->samplesperblock
;
70 static int decode(const uint8_t *inbuf
, size_t inbufsize
, int32_t *outbuf
, int *outbufsize
)
74 if (fmt
->bitspersample
> 24)
76 for (i
= 0; i
< inbufsize
; i
+= 4)
78 if (fmt
->is_little_endian
)
81 outbuf
[i
/4] = (inbuf
[i
]>>3)|(inbuf
[i
+1]<<5)|(inbuf
[i
+2]<<13)|(SE(inbuf
[i
+3])<<21);
83 outbuf
[i
/4] = (inbuf
[i
]>>3)|(inbuf
[i
+1]<<5)|(inbuf
[i
+2]<<13)|(SFT(inbuf
[i
+3])<<21);
88 outbuf
[i
/4] = (inbuf
[i
+3]>>3)|(inbuf
[i
+2]<<5)|(inbuf
[i
+1]<<13)|(SE(inbuf
[i
])<<21);
90 outbuf
[i
/4] = (inbuf
[i
+3]>>3)|(inbuf
[i
+2]<<5)|(inbuf
[i
+1]<<13)|(SFT(inbuf
[i
])<<21);
93 *outbufsize
= inbufsize
>> 2;
95 else if (fmt
->bitspersample
> 16)
97 for (i
= 0; i
< inbufsize
; i
+= 3)
99 if (fmt
->is_little_endian
)
102 outbuf
[i
/3] = (inbuf
[i
]<<5)|(inbuf
[i
+1]<<13)|(SE(inbuf
[i
+2])<<21);
104 outbuf
[i
/3] = (inbuf
[i
]<<5)|(inbuf
[i
+1]<<13)|(SFT(inbuf
[i
+2])<<21);
109 outbuf
[i
/3] = (inbuf
[i
+2]<<5)|(inbuf
[i
+1]<<13)|(SE(inbuf
[i
])<<21);
111 outbuf
[i
/3] = (inbuf
[i
+2]<<5)|(inbuf
[i
+1]<<13)|(SFT(inbuf
[i
])<<21);
114 *outbufsize
= inbufsize
/3;
116 else if (fmt
->bitspersample
> 8)
118 for (i
= 0; i
< inbufsize
; i
+= 2)
120 if (fmt
->is_little_endian
)
123 outbuf
[i
/2] = (inbuf
[i
]<<13)|(SE(inbuf
[i
+1])<<21);
125 outbuf
[i
/2] = (inbuf
[i
]<<13)|(SFT(inbuf
[i
+1])<<21);
130 outbuf
[i
/2] = (inbuf
[i
+1]<<13)|(SE(inbuf
[i
])<<21);
132 outbuf
[i
/2] = (inbuf
[i
+1]<<13)|(SFT(inbuf
[i
])<<21);
135 *outbufsize
= inbufsize
>> 1;
139 for (i
= 0; i
< inbufsize
; i
++) {
141 outbuf
[i
] = SE(inbuf
[i
])<<21;
143 outbuf
[i
] = SFT(inbuf
[i
])<<21;
145 *outbufsize
= inbufsize
;
148 if (fmt
->channels
== 2)
154 static const struct pcm_codec codec
= {
160 const struct pcm_codec
*get_linear_pcm_codec(void)