static PyObject* DVDA_Title_read(decoders_DVDA_Title *self, PyObject *args) { DVDA_Packet next_packet; struct bs_buffer* packet_data = self->packet_data; mlp_status mlp_status; /*if track has been exhausted, return empty FrameList*/ if (!self->pcm_frames_remaining) { return empty_FrameList(self->audiotools_pcm, self->channel_count, self->bits_per_sample); } /*otherwise, build FrameList from PCM or MLP packet data*/ switch (self->frame_codec) { case PCM: /*if not enough bytes in buffer, read another packet*/ while (aobpcm_packet_empty(&(self->pcm_decoder), self->frames)) { if (read_audio_packet(self->packet_reader, &next_packet, packet_data)) { PyErr_SetString(PyExc_IOError, "I/O reading PCM packet"); return NULL; } /*FIXME - ensure packet has same format as PCM*/ buf_extend(packet_data, self->frames); } /*FIXME - make this thread friendly*/ read_aobpcm(&(self->pcm_decoder), self->frames, self->codec_framelist); break; case MLP: /*if not enough bytes in buffer, read another packet*/ while (mlp_packet_empty(self->mlp_decoder)) { if (read_audio_packet(self->packet_reader, &next_packet, packet_data)) { PyErr_SetString(PyExc_IOError, "I/O reading MLP packet"); return NULL; } /*FIXME - ensure packet has same format as MLP*/ buf_extend(packet_data, self->frames); } /*FIXME - make this thread friendly*/ if ((mlp_status = read_mlp_frames(self->mlp_decoder, self->codec_framelist)) != OK) { PyErr_SetString(mlp_python_exception(mlp_status), mlp_python_exception_msg(mlp_status)); return NULL; } } /*account for framelists larger than frames remaining*/ self->codec_framelist->cross_split(self->codec_framelist, MIN(self->pcm_frames_remaining, self->codec_framelist->_[0]->len), self->output_framelist, self->codec_framelist); /*deduct output FrameList's PCM frames from remaining count*/ self->pcm_frames_remaining -= self->output_framelist->_[0]->len; /*and return output FrameList*/ return aa_int_to_FrameList(self->audiotools_pcm, self->output_framelist, self->bits_per_sample); }
/*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; } }