| 240 | } |
| 241 | |
| 242 | static hb_buffer_t *Decode( hb_work_object_t *w ) |
| 243 | { |
| 244 | hb_work_private_t *pv = w->private_data; |
| 245 | hb_buffer_t *out; |
| 246 | |
| 247 | if (pv->nsamples == 0) |
| 248 | return NULL; |
| 249 | |
| 250 | int size = pv->nsamples * pv->nchannels * sizeof( float ); |
| 251 | if (pv->alloc_size != size) |
| 252 | { |
| 253 | pv->data = realloc( pv->data, size ); |
| 254 | pv->alloc_size = size; |
| 255 | } |
| 256 | |
| 257 | float *odat = (float *)pv->data; |
| 258 | int count = pv->nchunks / pv->nchannels; |
| 259 | |
| 260 | switch( pv->sample_size ) |
| 261 | { |
| 262 | case 16: // 2 byte, big endian, signed (the right shift sign extends) |
| 263 | { |
| 264 | uint8_t *frm = pv->frame; |
| 265 | while ( count-- ) |
| 266 | { |
| 267 | int cc; |
| 268 | for( cc = 0; cc < pv->nchannels; cc++ ) |
| 269 | { |
| 270 | // Shifts below result in sign extension which gives |
| 271 | // us proper signed values. The final division adjusts |
| 272 | // the range to [-1.0 ... 1.0] |
| 273 | *odat++ = (float)( ( (int)( frm[0] << 24 ) >> 16 ) | |
| 274 | frm[1] ) / 32768.0; |
| 275 | frm += 2; |
| 276 | } |
| 277 | } |
| 278 | } break; |
| 279 | case 20: |
| 280 | { |
| 281 | // There will always be 2 groups of samples. A group is |
| 282 | // a collection of samples that spans all channels. |
| 283 | // The data for the samples is split. The first 2 msb |
| 284 | // bytes for all samples is encoded first, then the remaining |
| 285 | // lsb bits are encoded. |
| 286 | uint8_t *frm = pv->frame; |
| 287 | while ( count-- ) |
| 288 | { |
| 289 | int gg, cc; |
| 290 | int shift = 4; |
| 291 | uint8_t *lsb = frm + 4 * pv->nchannels; |
| 292 | for( gg = 0; gg < 2; gg++ ) |
| 293 | { |
| 294 | for( cc = 0; cc < pv->nchannels; cc++ ) |
| 295 | { |
| 296 | // Shifts below result in sign extension which gives |
| 297 | // us proper signed values. The final division adjusts |
| 298 | // the range to [-1.0 ... 1.0] |
| 299 | *odat = (float)( ( (int)( frm[0] << 24 ) >> 12 ) | |
no test coverage detected