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; int i; pcm_FrameList *framelist = new_FrameList(self->audiotools_pcm, channel_count, BITS_PER_SAMPLE, pcm_frames_read); int *samples = framelist->samples; for (i = 0; i < pcm_frames_read * channel_count; i++) { samples[i] = pcm[i]; } /*reorder channels to .wav order if necessary*/ switch (self->channel_count) { case 1: case 2: default: /*no change*/ break; case 3: /*fL fC fR -> fL fR fC*/ swap_channel_data(samples, 1, 2, self->channel_count, (unsigned)pcm_frames_read); 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*/ swap_channel_data(samples, 1, 2, self->channel_count, (unsigned)pcm_frames_read); break; case 6: /*fL fC fR bL bR LFE -> fL fR fC bL bR LFE*/ swap_channel_data(samples, 1, 2, self->channel_count, (unsigned)pcm_frames_read); /*fL fR fC bL bR LFE -> fL fR fC LFE bR bL*/ swap_channel_data(samples, 3, 5, self->channel_count, (unsigned)pcm_frames_read); /*fL fR fC LFE bR bL -> fL fR fC LFE bL bR*/ swap_channel_data(samples, 4, 5, self->channel_count, (unsigned)pcm_frames_read); break; case 7: /*fL fC fR sL sR bC LFE -> fL fR fC sL sR bC LFE*/ swap_channel_data(samples, 1, 2, self->channel_count, (unsigned)pcm_frames_read); /*fL fR fC sL sR bC LFE -> fL fR fC LFE sR bC sL*/ swap_channel_data(samples, 3, 6, self->channel_count, (unsigned)pcm_frames_read); /*fL fR fC LFE sR bC sL -> fL fR fC LFE bC sR sL*/ swap_channel_data(samples, 4, 5, self->channel_count, (unsigned)pcm_frames_read); /*fL fR fC LFE bC sR sL -> fL fR fC LFE bC sL sR*/ swap_channel_data(samples, 5, 6, self->channel_count, (unsigned)pcm_frames_read); break; case 8: /*fL fC fR sL sR bL bR LFE -> fL fR fC sL sR bL bR LFE*/ swap_channel_data(samples, 1, 2, self->channel_count, (unsigned)pcm_frames_read); /*fL fR fC sL sR bL bR LFE -> fL fR fC LFE sR bL bR sL*/ swap_channel_data(samples, 3, 6, self->channel_count, (unsigned)pcm_frames_read); /*fL fR fC LFE sR bL bR sL -> fL fR fC LFE bL sR bR sL*/ swap_channel_data(samples, 4, 5, self->channel_count, (unsigned)pcm_frames_read); /*fL fR fC LFE bL sR bR sL -> fL fR fC LFE bL bR sR sL*/ swap_channel_data(samples, 5, 6, self->channel_count, (unsigned)pcm_frames_read); /*fL fR fC LFE bL bR sR sL -> fL fR fC LFE bL bR sL sR*/ swap_channel_data(samples, 6, 7, self->channel_count, (unsigned)pcm_frames_read); break; } return (PyObject*)framelist; } else { /*some sort of read error occurred*/ PyErr_SetString(PyExc_ValueError, "error reading from file"); return NULL; } }
static void reorder_channels(unsigned channel_mask, unsigned pcm_frames, int *samples) { /*reorder channels if necessary based on assignment*/ switch (channel_mask) { default: break; case (fL | fR | fC): /*fL fR fC -> fL fC fR*/ swap_channel_data(samples, 1, 2, 3, pcm_frames); break; case (fL | fR | bL | bR): /*fL fR bL bR -> fL fR bL bR*/ /*no change*/ break; case (fL | fR | fC | bL | bR): /*fL fR fC bL bR -> fL fC fR bL bR*/ swap_channel_data(samples, 1, 2, 5, pcm_frames); break; case (fL | fR | fC | LFE | bL | bR): /*fL fR fC LFE bL bR -> fL fR fC LFE bR bL*/ swap_channel_data(samples, 4, 5, 6, pcm_frames); /*fL fR fC LFE bR bL -> fL fR fC bL bR LFE*/ swap_channel_data(samples, 3, 5, 6, pcm_frames); /*fL fR fC bL bR LFE -> fL fC fR bL bR LFE*/ swap_channel_data(samples, 1, 2, 6, pcm_frames); break; case (fL | fR | fC | LFE | bC | sL | sR): /*fL fR fC LFE bC sL sR -> fL fR fC LFE bC sR sL*/ swap_channel_data(samples, 5, 6, 7, pcm_frames); /*fL fR fC LFE bC sR sL -> fL fR fC LFE sR bC sL*/ swap_channel_data(samples, 4, 5, 7, pcm_frames); /*fL fR fC LFE sR bC sL -> fL fR fC sL sR bC LFE*/ swap_channel_data(samples, 3, 6, 7, pcm_frames); /*fL fR fC sL sR bC LFE -> fL fC fR sL sR bC LFE*/ swap_channel_data(samples, 1, 2, 7, pcm_frames); break; case (fL | fR | fC | LFE | bL | bR | sL | sR): /*fL fR fC LFE bL bR sL sR -> fL fR fC LFE bL bR sR sL*/ swap_channel_data(samples, 6, 7, 8, pcm_frames); /*fL fR fC LFE bL bR sR sL -> fL fR fC LFE bL sR bR sL*/ swap_channel_data(samples, 5, 6, 8, pcm_frames); /*fL fR fC LFE bL sR bR sL -> fL fR fC LFE sR bL bR sL*/ swap_channel_data(samples, 4, 5, 8, pcm_frames); /*fL fR fC LFE sR bL bR sL -> fL fR fC sL sR bL bR LFE*/ swap_channel_data(samples, 3, 6, 8, pcm_frames); /*fL fR fC sL sR bL bR LFE -> fL fC fR sL sR bL bR LFE*/ swap_channel_data(samples, 1, 2, 8, pcm_frames); break; } }
static PyObject* VorbisDecoder_read(decoders_VorbisDecoder *self, PyObject *args) { int current_bitstream; long samples_read; float **pcm_channels; if (self->closed) { PyErr_SetString(PyExc_ValueError, "stream is closed"); return NULL; } samples_read = ov_read_float(&(self->vorbisfile), &pcm_channels, 4096, ¤t_bitstream); if (samples_read >= 0) { /*convert floating point samples to integer-based ones*/ pcm_FrameList *framelist; int *samples; int c; if (samples_read == 0) { if (self->vorbisfile.os.e_o_s == 0) { /*EOF encountered without EOF being marked in stream*/ PyErr_SetString(PyExc_IOError, "I/O error reading from Ogg stream"); return NULL; } else { return empty_FrameList(self->audiotools_pcm, self->channel_count, BITS_PER_SAMPLE); } } framelist = new_FrameList(self->audiotools_pcm, self->channel_count, BITS_PER_SAMPLE, (unsigned)samples_read); samples = framelist->samples; for (c = 0; c < self->channel_count; c++) { int channel[samples_read]; float_to_int_converter(BITS_PER_SAMPLE)( (unsigned)samples_read, pcm_channels[c], channel); put_channel_data(samples, c, self->channel_count, (unsigned)samples_read, channel); } /*reorder channels to .wav order if necessary*/ switch (self->channel_count) { case 1: case 2: default: /*no change*/ break; case 3: /*fL fC fR -> fL fR fC*/ swap_channel_data(samples, 1, 2, self->channel_count, (unsigned)samples_read); 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*/ swap_channel_data(samples, 1, 2, self->channel_count, (unsigned)samples_read); break; case 6: /*fL fC fR bL bR LFE -> fL fR fC bL bR LFE*/ swap_channel_data(samples, 1, 2, self->channel_count, (unsigned)samples_read); /*fL fR fC bL bR LFE -> fL fR fC LFE bR bL*/ swap_channel_data(samples, 3, 5, self->channel_count, (unsigned)samples_read); /*fL fR fC LFE bR bL -> fL fR fC LFE bL bR*/ swap_channel_data(samples, 4, 5, self->channel_count, (unsigned)samples_read); break; case 7: /*fL fC fR sL sR bC LFE -> fL fR fC sL sR bC LFE*/ swap_channel_data(samples, 1, 2, self->channel_count, (unsigned)samples_read); /*fL fR fC sL sR bC LFE -> fL fR fC LFE sR bC sL*/ swap_channel_data(samples, 3, 6, self->channel_count, (unsigned)samples_read); /*fL fR fC LFE sR bC sL -> fL fR fC LFE bC sR sL*/ swap_channel_data(samples, 4, 5, self->channel_count, (unsigned)samples_read); /*fL fR fC LFE bC sR sL -> fL fR fC LFE bC sL sR*/ swap_channel_data(samples, 5, 6, self->channel_count, (unsigned)samples_read); break; case 8: /*fL fC fR sL sR bL bR LFE -> fL fR fC sL sR bL bR LFE*/ swap_channel_data(samples, 1, 2, self->channel_count, (unsigned)samples_read); /*fL fR fC sL sR bL bR LFE -> fL fR fC LFE sR bL bR sL*/ swap_channel_data(samples, 3, 6, self->channel_count, (unsigned)samples_read); /*fL fR fC LFE sR bL bR sL -> fL fR fC LFE bL sR bR sL*/ swap_channel_data(samples, 4, 5, self->channel_count, (unsigned)samples_read); /*fL fR fC LFE bL sR bR sL -> fL fR fC LFE bL bR sR sL*/ swap_channel_data(samples, 5, 6, self->channel_count, (unsigned)samples_read); /*fL fR fC LFE bL bR sR sL -> fL fR fC LFE bL bR sL sR*/ swap_channel_data(samples, 6, 7, self->channel_count, (unsigned)samples_read); break; } return (PyObject*)framelist; } else { switch (samples_read) { case OV_HOLE: PyErr_SetString(PyExc_ValueError, "data interruption detected"); return NULL; case OV_EBADLINK: PyErr_SetString(PyExc_ValueError, "invalid stream section"); return NULL; case OV_EINVAL: PyErr_SetString(PyExc_ValueError, "initial file headers corrupt"); return NULL; default: PyErr_SetString(PyExc_ValueError, "unspecified error"); return NULL; } } }