static void reorder_channels(unsigned channel_mask, aa_int *samples) { /*reorder channels if necessary based on assignment*/ switch (channel_mask) { default: break; case (0x1 | 0x2 | 0x4): /*fL fR fC -> fL fC fR*/ a_int_swap(samples->_[1], samples->_[2]); break; case (0x1 | 0x2 | 0x10 | 0x20): /*fL fR bL bR -> fL fR bL bR*/ /*no change*/ break; case (0x1 | 0x2 | 0x4 | 0x10 | 0x20): /*fL fR fC bL bR -> fL fC fR bL bR*/ a_int_swap(samples->_[1], samples->_[2]); break; case (0x1 | 0x2 | 0x4 | 0x8 | 0x10 | 0x20): /*fL fR fC LFE bL bR -> fL fR fC LFE bR bL*/ a_int_swap(samples->_[4], samples->_[5]); /*fL fR fC LFE bR bL -> fL fR fC bL bR LFE*/ a_int_swap(samples->_[3], samples->_[5]); /*fL fR fC bL bR LFE -> fL fC fR bL bR LFE*/ a_int_swap(samples->_[1], samples->_[2]); break; case (0x1 | 0x2 | 0x4 | 0x8 | 0x100 | 0x200 | 0x400): /*fL fR fC LFE bC sL sR -> fL fR fC LFE bC sR sL*/ a_int_swap(samples->_[5], samples->_[6]); /*fL fR fC LFE bC sR sL -> fL fR fC LFE sR bC sL*/ a_int_swap(samples->_[4], samples->_[5]); /*fL fR fC LFE sR bC sL -> fL fR fC sL sR bC LFE*/ a_int_swap(samples->_[3], samples->_[6]); /*fL fR fC sL sR bC LFE -> fL fC fR sL sR bC LFE*/ a_int_swap(samples->_[1], samples->_[2]); break; case (0x1 | 0x2 | 0x4 | 0x8 | 0x10 | 0x20 | 0x200 | 0x400): /*fL fR fC LFE bL bR sL sR -> fL fR fC LFE bL bR sR sL*/ a_int_swap(samples->_[6], samples->_[7]); /*fL fR fC LFE bL bR sR sL -> fL fR fC LFE bL sR bR sL*/ a_int_swap(samples->_[5], samples->_[6]); /*fL fR fC LFE bL sR bR sL -> fL fR fC LFE sR bL bR sL*/ a_int_swap(samples->_[4], samples->_[5]); /*fL fR fC LFE sR bL bR sL -> fL fR fC sL sR bL bR LFE*/ a_int_swap(samples->_[3], samples->_[6]); /*fL fR fC sL sR bL bR LFE -> fL fC fR sL sR bL bR LFE*/ a_int_swap(samples->_[1], samples->_[2]); break; } }
/*the OpusDecoder.read() method*/ static PyObject* OpusDecoder_read(decoders_OpusDecoder* self, PyObject *args) { static opus_int16 pcm[BUF_SIZE]; int pcm_frames_read; if (self->closed) { PyErr_SetString(PyExc_ValueError, "stream is closed"); return NULL; } if ((pcm_frames_read = op_read(self->opus_file, pcm, BUF_SIZE, NULL)) >= 0) { const int channel_count = op_head(self->opus_file, -1)->channel_count; aa_int *channels = self->channels; int c; channels->reset(channels); /*split buffer by channel*/ for (c = 0; c < channel_count; c++) { a_int *channel = channels->append(channels); int i; channel->resize(channel, pcm_frames_read); for (i = 0; i < pcm_frames_read; i++) { a_append(channel, pcm[c + (i * channel_count)]); } } /*reorder channels to .wav order if necessary*/ switch (channel_count) { case 1: case 2: default: /*no change*/ break; case 3: /*fL fC fR -> fL fR fC*/ a_int_swap(channels->_[1], channels->_[2]); break; case 4: /*fL fR bL bR -> fL fR bL bR*/ /*no change*/ break; case 5: /*fL fC fR bL bR -> fL fR fC bL bR*/ a_int_swap(channels->_[1], channels->_[2]); break; case 6: /*fL fC fR bL bR LFE -> fL fR fC bL bR LFE*/ a_int_swap(channels->_[1], channels->_[2]); /*fL fR fC bL bR LFE -> fL fR fC LFE bR bL*/ a_int_swap(channels->_[3], channels->_[5]); /*fL fR fC LFE bR bL -> fL fR fC LFE bL bR*/ a_int_swap(channels->_[4], channels->_[5]); break; case 7: /*fL fC fR sL sR bC LFE -> fL fR fC sL sR bC LFE*/ a_int_swap(channels->_[1], channels->_[2]); /*fL fR fC sL sR bC LFE -> fL fR fC LFE sR bC sL*/ a_int_swap(channels->_[3], channels->_[6]); /*fL fR fC LFE sR bC sL -> fL fR fC LFE bC sR sL*/ a_int_swap(channels->_[4], channels->_[5]); /*fL fR fC LFE bC sR sL -> fL fR fC LFE bC sL sR*/ a_int_swap(channels->_[5], channels->_[6]); break; case 8: /*fL fC fR sL sR bL bR LFE -> fL fR fC sL sR bL bR LFE*/ a_int_swap(channels->_[1], channels->_[2]); /*fL fR fC sL sR bL bR LFE -> fL fR fC LFE sR bL bR sL*/ a_int_swap(channels->_[3], channels->_[6]); /*fL fR fC LFE sR bL bR sL -> fL fR fC LFE bL sR bR sL*/ a_int_swap(channels->_[4], channels->_[5]); /*fL fR fC LFE bL sR bR sL -> fL fR fC LFE bL bR sR sL*/ a_int_swap(channels->_[5], channels->_[6]); /*fL fR fC LFE bL bR sR sL -> fL fR fC LFE bL bR sL sR*/ a_int_swap(channels->_[6], channels->_[7]); break; } /*return new FrameList object*/ return aa_int_to_FrameList(self->audiotools_pcm, channels, 16); } else { /*some sort of read error occurred*/ PyErr_SetString(PyExc_ValueError, "error reading from file"); return NULL; } }