flac_status flacdec_read_verbatim_subframe(BitstreamReader* bitstream, unsigned block_size, unsigned bits_per_sample, array_i* samples) { unsigned i; samples->reset_for(samples, block_size); for (i = 0; i < block_size; i++) a_append(samples, bitstream->read_signed(bitstream, bits_per_sample)); return OK; }
flac_status flacdec_read_lpc_subframe(BitstreamReader* bitstream, array_i* qlp_coeffs, array_i* residuals, unsigned order, unsigned block_size, unsigned bits_per_sample, array_i* samples) { unsigned i; unsigned qlp_precision; unsigned qlp_shift_needed; int* s_data; int* r_data; int* qlp_data; flac_status error; qlp_coeffs->reset(qlp_coeffs); samples->reset_for(samples, block_size); s_data = samples->_; /*read order number of warm-up samples*/ for (i = 0; i < order; i++) { a_append(samples, bitstream->read_signed(bitstream, bits_per_sample)); } /*read QLP precision*/ qlp_precision = bitstream->read(bitstream, 4) + 1; /*read QLP shift needed*/ qlp_shift_needed = bitstream->read_signed(bitstream, 5); qlp_shift_needed = MAX(qlp_shift_needed, 0); /*read order number of QLP coefficients of size qlp_precision*/ for (i = 0; i < order; i++) { qlp_coeffs->append(qlp_coeffs, bitstream->read_signed(bitstream, qlp_precision)); } qlp_data = qlp_coeffs->_; /*read the residual*/ if ((error = flacdec_read_residual(bitstream, order, block_size, residuals)) != OK) return error; else r_data = residuals->_; /*calculate subframe samples from warm-up samples and residual*/ for (i = order; i < block_size; i++) { int64_t accumulator = 0; unsigned j; for (j = 0; j < order; j++) { accumulator += (int64_t)qlp_data[j] * (int64_t)s_data[i - j - 1]; } a_append(samples, (int)(accumulator >> qlp_shift_needed) + r_data[i - order]); } return OK; }
flac_status flacdec_read_fixed_subframe(BitstreamReader* bitstream, array_i* residuals, unsigned order, unsigned block_size, unsigned bits_per_sample, array_i* samples) { unsigned i; flac_status error; int* s_data; int* r_data; /*ensure that samples->data won't be realloc'ated*/ samples->reset_for(samples, block_size); s_data = samples->_; /*read "order" number of warm-up samples*/ for (i = 0; i < order; i++) { a_append(samples, bitstream->read_signed(bitstream, bits_per_sample)); } /*read the residual block*/ if ((error = flacdec_read_residual(bitstream, order, block_size, residuals)) != OK) return error; else r_data = residuals->_; /*calculate subframe samples from warm-up samples and residual*/ switch (order) { case 0: samples->extend(samples, residuals); break; case 1: for (i = 1; i < block_size; i++) a_append(samples, s_data[i - 1] + r_data[i - 1]); break; case 2: for (i = 2; i < block_size; i++) a_append(samples, (2 * s_data[i - 1]) - s_data[i - 2] + r_data[i - 2]); break; case 3: for (i = 3; i < block_size; i++) a_append(samples, (3 * s_data[i - 1]) - (3 * s_data[i - 2]) + s_data[i - 3] + r_data[i - 3]); break; case 4: for (i = 4; i < block_size; i++) a_append(samples, (4 * s_data[i - 1]) - (6 * s_data[i - 2]) + (4 * s_data[i - 3]) - s_data[i - 4] + r_data[i - 4]); break; default: return ERR_INVALID_FIXED_ORDER; } return OK; }
PyObject* ReplayGain_title_gain(replaygain_ReplayGain *self, PyObject *args) { double title_gain; double title_peak = 0.0; pcmreader* pcmreader = NULL; /*read PCMReader-compatible object from args*/ if (!PyArg_ParseTuple(args, "O&", pcmreader_converter, &pcmreader)) { return NULL; } else { array_ia* channels = array_ia_new(); array_fa* channels_f = array_fa_new(); const int32_t peak_shift = 1 << (pcmreader->bits_per_sample - 1); if (pcmreader->sample_rate != self->sample_rate) { PyErr_SetString(PyExc_ValueError, "pcmreader's sample rate doesn't match"); pcmreader->del(pcmreader); channels->del(channels); channels_f->del(channels_f); return NULL; } /*read a FrameList object from PCMReader*/ if (pcmreader->read(pcmreader, 4096, channels)) { pcmreader->del(pcmreader); channels->del(channels); channels_f->del(channels_f); return NULL; } /*while FrameList contains more samples*/ while (channels->_[0]->len) { unsigned c; /*ensure FrameList only contains 1 or 2 channels*/ if ((channels->len != 1) && (channels->len != 2)) { PyErr_SetString(PyExc_ValueError, "FrameList must contain only 1 or 2 channels"); pcmreader->del(pcmreader); channels->del(channels); channels_f->del(channels_f); return NULL; } /*if only one channel, duplicate it to the other channel*/ channels->_[0]->copy(channels->_[0], channels->append(channels)); channels_f->reset(channels_f); /*convert left and right channels to doubles, (but *not* doubles between -1.0 and 1.0) and store peak values*/ for (c = 0; c < 2; c++) { array_i* channel_i = channels->_[c]; array_f* channel_f = channels_f->append(channels_f); int i; double peak; channel_f->resize(channel_f, channel_i->len); switch (pcmreader->bits_per_sample) { case 8: for (i = 0; i < channel_i->len; i++) { a_append(channel_f, (double)(channel_i->_[i] << 8)); peak = ((double)(abs(channel_i->_[i])) / peak_shift); title_peak = MAX(title_peak, peak); self->album_peak = MAX(self->album_peak, peak); } break; case 16: for (i = 0; i < channel_i->len; i++) { a_append(channel_f, (double)(channel_i->_[i])); peak = ((double)(abs(channel_i->_[i])) / peak_shift); title_peak = MAX(title_peak, peak); self->album_peak = MAX(self->album_peak, peak); } break; case 24: for (i = 0; i < channel_i->len; i++) { a_append(channel_f, (double)(channel_i->_[i] >> 8)); peak = ((double)(abs(channel_i->_[i])) / peak_shift); title_peak = MAX(title_peak, peak); self->album_peak = MAX(self->album_peak, peak); } break; default: PyErr_SetString(PyExc_ValueError, "unsupported bits per sample"); pcmreader->del(pcmreader); channels->del(channels); channels_f->del(channels_f); return NULL; } } /*perform actual gain analysis on channels*/ if (ReplayGain_analyze_samples(self, channels_f->_[0]->_, channels_f->_[1]->_, channels_f->_[0]->len, 2) == GAIN_ANALYSIS_ERROR) { PyErr_SetString(PyExc_ValueError, "ReplayGain calculation error"); pcmreader->del(pcmreader); channels->del(channels); channels_f->del(channels_f); return NULL; } /*read next FrameList object from PCMReader*/ if (pcmreader->read(pcmreader, 4096, channels)) { pcmreader->del(pcmreader); channels->del(channels); channels_f->del(channels_f); return NULL; } } /*deallocate temporary variables*/ pcmreader->del(pcmreader); channels->del(channels); channels_f->del(channels_f); /*return calculated title gain and title peak*/ /*if enough samples have been read*/ if ((title_gain = ReplayGain_get_title_gain(self)) != GAIN_NOT_ENOUGH_SAMPLES) { return Py_BuildValue("(d,d)", title_gain, title_peak); } else { PyErr_SetString(PyExc_ValueError, "Not enough samples to perform calculation"); return NULL; } } }
int pcmreader_read(struct pcmreader_s* reader, unsigned pcm_frames, array_ia* channels) { unsigned bytes_to_read = (pcm_frames * reader->channels * reader->bytes_per_sample); size_t bytes_read; unsigned frames_read; array_i* channel_a; unsigned int byte; unsigned int sample; unsigned int channel; unsigned int frame; struct pcmreader_callback *callback; FrameList_int_to_char_converter callback_converter; uint8_t* callback_buffer; if (reader->buffer_size < bytes_to_read) { reader->buffer_size = bytes_to_read; reader->buffer = realloc(reader->buffer, bytes_to_read); } /*read data into "buffer" as plain bytes*/ bytes_read = fread(reader->buffer, sizeof(uint8_t), bytes_to_read, reader->file); /*remove partial PCM frames, if any*/ while (bytes_read % (reader->channels * reader->bytes_per_sample)) bytes_read--; frames_read = (unsigned)(bytes_read / (reader->channels * reader->bytes_per_sample)); /*place "buffer" into "channels", split up by channel*/ channels->reset(channels); for (channel = 0; channel < reader->channels; channel++) { channel_a = channels->append(channels); channel_a->resize(channel_a, frames_read); for (frame = 0; frame < frames_read; frame++) { sample = channel + (frame * reader->channels); a_append(channel_a, reader->buffer_converter(reader->buffer + (sample * reader->bytes_per_sample))); } } /*apply all callbacks on that collection of samples*/ for (callback = reader->callbacks; callback != NULL; callback = callback->next) { callback_converter = FrameList_get_int_to_char_converter(reader->bits_per_sample, !callback->little_endian, callback->is_signed); callback_buffer = malloc(bytes_read); for (byte = 0; byte < bytes_read; byte += reader->bytes_per_sample) { callback_converter(reader->buffer_converter(reader->buffer + byte), callback_buffer + byte); } callback->callback(callback->user_data, (unsigned char*)callback_buffer, (unsigned long)bytes_read); free(callback_buffer); } return 0; }
int pcmreader_read(struct pcmreader_s* reader, unsigned pcm_frames, array_ia* channels) { PyObject* framelist_obj; pcm_FrameList* framelist; unsigned frame; unsigned channel; array_i* channel_a; struct pcmreader_callback* callback; PyObject* string_obj; unsigned char* string; Py_ssize_t string_length; /*make a call to "pcmreader.read(bytes)" where "bytes" is set to the proper PCM frame count*/ if (((framelist_obj = PyObject_CallMethod(reader->pcmreader_obj, "read", "i", pcm_frames * reader->channels * reader->bytes_per_sample))) == NULL) { /*ensure result isn't an exception*/ return 1; } /*ensure result is a pcm.FrameList object*/ if (framelist_obj->ob_type != (PyTypeObject*)reader->framelist_type) { Py_DECREF(framelist_obj); PyErr_SetString(PyExc_TypeError, "results from pcmreader.read() must be FrameLists"); return 1; } else { framelist = (pcm_FrameList*)framelist_obj; } /*split framelist's packed ints into a set of channels*/ channels->reset(channels); for (channel = 0; channel < framelist->channels; channel++) { channel_a = channels->append(channels); for (frame = 0; frame < framelist->frames; frame++) { channel_a->resize(channel_a, framelist->frames); a_append(channel_a, framelist->samples[(frame * framelist->channels) + channel]); } } /*apply all callbacks to pcm.FrameList object*/ for (callback = reader->callbacks; callback != NULL; callback = callback->next) { string_obj = PyObject_CallMethod(framelist_obj, "to_bytes", "(ii)", !callback->little_endian, callback->is_signed); if (string_obj == NULL) { Py_DECREF(framelist_obj); return 1; } if (PyString_AsStringAndSize(string_obj, (char**)(&string), &string_length) == -1) { Py_DECREF(framelist_obj); Py_DECREF(string_obj); return 1; } callback->callback(callback->user_data, string, (unsigned long)string_length); Py_DECREF(string_obj); } /*free any allocated buffers and Python objects*/ Py_DECREF(framelist_obj); return 0; }
/*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; } }