summaryrefslogtreecommitdiff
path: root/apps/codecs
diff options
context:
space:
mode:
authorYoshihisa Uchida <uchida@rockbox.org>2010-02-20 10:15:36 +0000
committerYoshihisa Uchida <uchida@rockbox.org>2010-02-20 10:15:36 +0000
commit9f63f4f2fcb5400a2c043504799228e79c424cab (patch)
tree4781560a69f642f44c8c1ab95d7ad1c1a042bdfc /apps/codecs
parentbc8cefd1a472072e575a81ca10d548d7e83209a6 (diff)
downloadrockbox-9f63f4f2fcb5400a2c043504799228e79c424cab.tar.gz
rockbox-9f63f4f2fcb5400a2c043504799228e79c424cab.zip
libpcm: linear pcm decode logic separates according to each bitspersample, endian, and signess.
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@24785 a1c6a512-1295-4272-9138-f99709370657
Diffstat (limited to 'apps/codecs')
-rw-r--r--apps/codecs/libpcm/linear_pcm.c216
1 files changed, 160 insertions, 56 deletions
diff --git a/apps/codecs/libpcm/linear_pcm.c b/apps/codecs/libpcm/linear_pcm.c
index 5360d79901..451154cc9b 100644
--- a/apps/codecs/libpcm/linear_pcm.c
+++ b/apps/codecs/libpcm/linear_pcm.c
@@ -59,7 +59,7 @@ static struct pcm_pos *get_seek_pos(long seek_time,
59{ 59{
60 static struct pcm_pos newpos; 60 static struct pcm_pos newpos;
61 uint32_t newblock = ((uint64_t)seek_time * ci->id3->frequency) 61 uint32_t newblock = ((uint64_t)seek_time * ci->id3->frequency)
62 / (1000LL * fmt->samplesperblock); 62 / (1000LL * fmt->samplesperblock);
63 63
64 (void)read_buffer; 64 (void)read_buffer;
65 newpos.pos = newblock * fmt->blockalign; 65 newpos.pos = newblock * fmt->blockalign;
@@ -67,86 +67,190 @@ static struct pcm_pos *get_seek_pos(long seek_time,
67 return &newpos; 67 return &newpos;
68} 68}
69 69
70static int decode(const uint8_t *inbuf, size_t inbufsize, int32_t *outbuf, int *outbufsize) 70/* 8bit decode functions */
71static inline void decode_s8(const uint8_t *inbuf, size_t inbufsize, int32_t *outbuf)
71{ 72{
72 uint32_t i; 73 size_t i = 0;
73 74
75 for ( ; i < inbufsize; i++)
76 outbuf[i] = SE(inbuf[i])<<21;
77}
78
79static inline void decode_u8(const uint8_t *inbuf, size_t inbufsize, int32_t *outbuf)
80{
81 size_t i = 0;
82
83 for ( ; i < inbufsize; i++)
84 outbuf[i] = SFT(inbuf[i])<<21;
85}
86
87/* 16bit decode functions */
88static inline void decode_s16le(const uint8_t *inbuf, size_t inbufsize, int32_t *outbuf)
89{
90 size_t i = 0;
91
92 for ( ; i < inbufsize; i += 2)
93 outbuf[i/2] = (inbuf[i]<<13)|(SE(inbuf[i+1])<<21);
94}
95
96static inline void decode_u16le(const uint8_t *inbuf, size_t inbufsize, int32_t *outbuf)
97{
98 size_t i = 0;
99
100 for ( ; i < inbufsize; i += 2)
101 outbuf[i/2] = (inbuf[i]<<13)|(SFT(inbuf[i+1])<<21);
102}
103
104static inline void decode_s16be(const uint8_t *inbuf, size_t inbufsize, int32_t *outbuf)
105{
106 size_t i = 0;
107
108 for ( ; i < inbufsize; i += 2)
109 outbuf[i/2] = (inbuf[i+1]<<13)|(SE(inbuf[i])<<21);
110}
111
112static inline void decode_u16be(const uint8_t *inbuf, size_t inbufsize, int32_t *outbuf)
113{
114 size_t i = 0;
115
116 for ( ; i < inbufsize; i += 2)
117 outbuf[i/2] = (inbuf[i+1]<<13)|(SFT(inbuf[i])<<21);
118}
119
120/* 24bit decode functions */
121static inline void decode_s24le(const uint8_t *inbuf, size_t inbufsize, int32_t *outbuf)
122{
123 size_t i = 0;
124
125 for ( ; i < inbufsize; i += 3)
126 outbuf[i/3] = (inbuf[i]<<5)|(inbuf[i+1]<<13)|(SE(inbuf[i+2])<<21);
127}
128
129static inline void decode_u24le(const uint8_t *inbuf, size_t inbufsize, int32_t *outbuf)
130{
131 size_t i = 0;
132
133 for ( ; i < inbufsize; i += 3)
134 outbuf[i/3] = (inbuf[i]<<5)|(inbuf[i+1]<<13)|(SFT(inbuf[i+2])<<21);
135}
136
137static inline void decode_s24be(const uint8_t *inbuf, size_t inbufsize, int32_t *outbuf)
138{
139 size_t i = 0;
140
141 for ( ; i < inbufsize; i += 3)
142 outbuf[i/3] = (inbuf[i+2]<<5)|(inbuf[i+1]<<13)|(SE(inbuf[i])<<21);
143}
144
145static inline void decode_u24be(const uint8_t *inbuf, size_t inbufsize, int32_t *outbuf)
146{
147 size_t i = 0;
148
149 for ( ; i < inbufsize; i += 3)
150 outbuf[i/3] = (inbuf[i+2]<<5)|(inbuf[i+1]<<13)|(SFT(inbuf[i])<<21);
151}
152
153/* 32bit decode functions */
154static inline void decode_s32le(const uint8_t *inbuf, size_t inbufsize, int32_t *outbuf)
155{
156 size_t i = 0;
157
158 for ( ; i < inbufsize; i += 4)
159 outbuf[i/4] = (inbuf[i]>>3)|(inbuf[i+1]<<5)|(inbuf[i+2]<<13)|(SE(inbuf[i+3])<<21);
160}
161
162static inline void decode_u32le(const uint8_t *inbuf, size_t inbufsize, int32_t *outbuf)
163{
164 size_t i = 0;
165
166 for ( ; i < inbufsize; i += 4)
167 outbuf[i/4] = (inbuf[i]>>3)|(inbuf[i+1]<<5)|(inbuf[i+2]<<13)|(SFT(inbuf[i+3])<<21);
168}
169
170static inline void decode_s32be(const uint8_t *inbuf, size_t inbufsize, int32_t *outbuf)
171{
172 size_t i = 0;
173
174 for ( ; i < inbufsize; i += 4)
175 outbuf[i/4] = (inbuf[i+3]>>3)|(inbuf[i+2]<<5)|(inbuf[i+1]<<13)|(SE(inbuf[i])<<21);
176}
177
178static inline void decode_u32be(const uint8_t *inbuf, size_t inbufsize, int32_t *outbuf)
179{
180 size_t i = 0;
181
182 for ( ; i < inbufsize; i += 4)
183 outbuf[i/4] = (inbuf[i+3]>>3)|(inbuf[i+2]<<5)|(inbuf[i+1]<<13)|(SFT(inbuf[i])<<21);
184}
185
186static int decode(const uint8_t *inbuf, size_t inbufsize, int32_t *outbuf, int *outbufcount)
187{
74 if (fmt->bitspersample > 24) 188 if (fmt->bitspersample > 24)
75 { 189 {
76 for (i = 0; i < inbufsize; i += 4) 190 if (fmt->is_little_endian)
77 { 191 {
78 if (fmt->is_little_endian) 192 if (fmt->is_signed)
79 { 193 decode_s32le(inbuf, inbufsize, outbuf);
80 if (fmt->is_signed)
81 outbuf[i/4] = (inbuf[i]>>3)|(inbuf[i+1]<<5)|(inbuf[i+2]<<13)|(SE(inbuf[i+3])<<21);
82 else
83 outbuf[i/4] = (inbuf[i]>>3)|(inbuf[i+1]<<5)|(inbuf[i+2]<<13)|(SFT(inbuf[i+3])<<21);
84 }
85 else 194 else
86 { 195 decode_u32le(inbuf, inbufsize, outbuf);
87 if (fmt->is_signed)
88 outbuf[i/4] = (inbuf[i+3]>>3)|(inbuf[i+2]<<5)|(inbuf[i+1]<<13)|(SE(inbuf[i])<<21);
89 else
90 outbuf[i/4] = (inbuf[i+3]>>3)|(inbuf[i+2]<<5)|(inbuf[i+1]<<13)|(SFT(inbuf[i])<<21);
91 }
92 } 196 }
93 *outbufsize = inbufsize >> 2; 197 else
198 {
199 if (fmt->is_signed)
200 decode_s32be(inbuf, inbufsize, outbuf);
201 else
202 decode_u32be(inbuf, inbufsize, outbuf);
203 }
204 *outbufcount = inbufsize >> 2;
94 } 205 }
95 else if (fmt->bitspersample > 16) 206 else if (fmt->bitspersample > 16)
96 { 207 {
97 for (i = 0; i < inbufsize; i += 3) 208 if (fmt->is_little_endian)
98 { 209 {
99 if (fmt->is_little_endian) 210 if (fmt->is_signed)
100 { 211 decode_s24le(inbuf, inbufsize, outbuf);
101 if (fmt->is_signed) 212 else
102 outbuf[i/3] = (inbuf[i]<<5)|(inbuf[i+1]<<13)|(SE(inbuf[i+2])<<21); 213 decode_u24le(inbuf, inbufsize, outbuf);
103 else 214 }
104 outbuf[i/3] = (inbuf[i]<<5)|(inbuf[i+1]<<13)|(SFT(inbuf[i+2])<<21); 215 else
105 } 216 {
217 if (fmt->is_signed)
218 decode_s24be(inbuf, inbufsize, outbuf);
106 else 219 else
107 { 220 decode_u24be(inbuf, inbufsize, outbuf);
108 if (fmt->is_signed)
109 outbuf[i/3] = (inbuf[i+2]<<5)|(inbuf[i+1]<<13)|(SE(inbuf[i])<<21);
110 else
111 outbuf[i/3] = (inbuf[i+2]<<5)|(inbuf[i+1]<<13)|(SFT(inbuf[i])<<21);
112 }
113 } 221 }
114 *outbufsize = inbufsize/3; 222 *outbufcount = inbufsize / 3;
115 } 223 }
116 else if (fmt->bitspersample > 8) 224 else if (fmt->bitspersample > 8)
117 { 225 {
118 for (i = 0; i < inbufsize; i += 2) 226 if (fmt->is_little_endian)
119 { 227 {
120 if (fmt->is_little_endian) 228 if (fmt->is_signed)
121 { 229 decode_s16le(inbuf, inbufsize, outbuf);
122 if (fmt->is_signed)
123 outbuf[i/2] = (inbuf[i]<<13)|(SE(inbuf[i+1])<<21);
124 else
125 outbuf[i/2] = (inbuf[i]<<13)|(SFT(inbuf[i+1])<<21);
126 }
127 else 230 else
128 { 231 decode_u16le(inbuf, inbufsize, outbuf);
129 if (fmt->is_signed)
130 outbuf[i/2] = (inbuf[i+1]<<13)|(SE(inbuf[i])<<21);
131 else
132 outbuf[i/2] = (inbuf[i+1]<<13)|(SFT(inbuf[i])<<21);
133 }
134 } 232 }
135 *outbufsize = inbufsize >> 1; 233 else
136 } 234 {
137 else
138 {
139 for (i = 0; i < inbufsize; i++) {
140 if (fmt->is_signed) 235 if (fmt->is_signed)
141 outbuf[i] = SE(inbuf[i])<<21; 236 decode_s16be(inbuf, inbufsize, outbuf);
142 else 237 else
143 outbuf[i] = SFT(inbuf[i])<<21; 238 decode_u16be(inbuf, inbufsize, outbuf);
144 } 239 }
145 *outbufsize = inbufsize; 240 *outbufcount = inbufsize >> 1;
241 }
242 else
243 {
244 if (fmt->is_signed)
245 decode_s8(inbuf, inbufsize, outbuf);
246 else
247 decode_u8(inbuf, inbufsize, outbuf);
248
249 *outbufcount = inbufsize;
146 } 250 }
147 251
148 if (fmt->channels == 2) 252 if (fmt->channels == 2)
149 *outbufsize >>= 1; 253 *outbufcount >>= 1;
150 254
151 return CODEC_OK; 255 return CODEC_OK;
152} 256}