Пример #1
0
static void
flacdec_read_vorbis_comment(BitstreamReader *comment,
                            unsigned channel_count,
                            int *channel_mask)
{
    struct bs_buffer *line = buf_new();
    unsigned line_len;
    unsigned total_lines;
    const char mask_prefix[] =
        "WAVEFORMATEXTENSIBLE_CHANNEL_MASK=";

    if (!setjmp(*br_try(comment))) {
        /*skip over vendor string*/
        line_len = comment->read(comment, 32);
        comment->skip_bytes(comment, line_len);

        /*walk through all entries in the comment*/
        for (total_lines = comment->read(comment, 32);
             total_lines > 0;
             total_lines--) {
            const char *s;

            /*populate entry one character at a time
              (this avoids allocating a big chunk of space
               if the length field is something way too large)*/
            buf_reset(line);

            for (line_len = comment->read(comment, 32);
                 line_len > 0;
                 line_len--) {
                buf_putc(
                    toupper((int)comment->read(comment, 8)),
                    line);
            }
            buf_putc(0, line);  /*NULL terminator*/

            s = (const char *)buf_window_start(line);

            /*if line starts with mask prefix*/
            if (strstr(s, mask_prefix) == s) {
                /*convert rest of line to base-16 integer*/
                unsigned mask = (unsigned)strtoul(
                    s + strlen(mask_prefix), NULL, 16);
                /*and populate mask field if its number of channel bits
                  matches the stream's channel count*/
                if (channel_bits(mask) == channel_count) {
                    *channel_mask = mask;
                }
            }
        }
        br_etry(comment);
    } else {
        /*read error in VORBIS_COMMENT
          (probably invalid length field somewhere)*/
        br_etry(comment);
    }

    buf_close(line);
}
Пример #2
0
static PyObject*
ALACDecoder_read(decoders_ALACDecoder* self, PyObject *args)
{
    pcm_FrameList *framelist;
    status_t status;
    unsigned pcm_frames_read;

    if (self->closed) {
        PyErr_SetString(PyExc_ValueError, "cannot read closed stream");
        return NULL;
    }

    if (self->read_pcm_frames >= self->total_pcm_frames) {
        return empty_FrameList(self->audiotools_pcm,
                               self->channels,
                               self->bits_per_sample);
    }

    /*build FrameList based on alac decoding parameters*/
    framelist = new_FrameList(self->audiotools_pcm,
                              self->channels,
                              self->bits_per_sample,
                              self->params.block_size);

    /*decode ALAC frameset to FrameList*/
    if (!setjmp(*br_try(self->bitstream))) {
        status = decode_frameset(self,
                                 &pcm_frames_read,
                                 framelist->samples);
        br_etry(self->bitstream);
    } else {
        br_etry(self->bitstream);
        Py_DECREF((PyObject*)framelist);
        PyErr_SetString(PyExc_IOError, "I/O error reading stream");
        return NULL;
    }

    if (status != OK) {
        Py_DECREF((PyObject*)framelist);
        PyErr_SetString(alac_exception(status), alac_strerror(status));
        return NULL;
    }

    /*constrain FrameList to actual amount of PCM frames read
      which may be less than block size at the end of stream*/
    framelist->frames = pcm_frames_read;
    framelist->samples_length = pcm_frames_read * self->channels;

    /*reorder FrameList to .wav order*/
    reorder_channels(pcm_frames_read,
                     self->channels,
                     framelist->samples);

    self->read_pcm_frames += pcm_frames_read;

    /*return populated FrameList*/
    return (PyObject*)framelist;
}
Пример #3
0
int
oggflac_read_streaminfo(BitstreamReader *packet,
                        struct flac_STREAMINFO *streaminfo,
                        uint16_t *header_packets) {
    int i;

    if (!setjmp(*br_try(packet))) {
        if (packet->read(packet, 8) != 0x7F) {
            PyErr_SetString(PyExc_ValueError, "invalid packet byte");
            goto error;
        }
        if (packet->read_64(packet, 32) != 0x464C4143) {
            PyErr_SetString(PyExc_ValueError, "invalid Ogg signature");
            goto error;
        }
        if (packet->read(packet, 8) != 1) {
            PyErr_SetString(PyExc_ValueError, "invalid major version");
            goto error;
        }
        if (packet->read(packet, 8) != 0) {
            PyErr_SetString(PyExc_ValueError, "invalid minor version");
            goto error;
        }
        *header_packets = packet->read(packet, 16);
        if (packet->read_64(packet, 32) != 0x664C6143) {
            PyErr_SetString(PyExc_ValueError, "invalid fLaC signature");
            goto error;
        }
        packet->read(packet, 1); /*last block*/
        if (packet->read(packet, 7) != 0) {
            PyErr_SetString(PyExc_ValueError, "invalid block type");
            goto error;
        }
        packet->read(packet, 24); /*block length*/

        streaminfo->minimum_block_size = packet->read(packet, 16);
        streaminfo->maximum_block_size = packet->read(packet, 16);
        streaminfo->minimum_frame_size = packet->read(packet, 24);
        streaminfo->maximum_frame_size = packet->read(packet, 24);
        streaminfo->sample_rate = packet->read(packet, 20);
        streaminfo->channels = packet->read(packet, 3) + 1;
        streaminfo->bits_per_sample = packet->read(packet, 5) + 1;
        streaminfo->total_samples = packet->read_64(packet, 36);
        for (i = 0; i < 16; i++) {
            streaminfo->md5sum[i] = packet->read(packet, 8);
        }
    } else {
        PyErr_SetString(PyExc_IOError,
                        "EOF while reading STREAMINFO block");
        goto error;
    }

    br_etry(packet);
    return 1;
 error:
    br_etry(packet);
    return 0;
}
Пример #4
0
static int
read_atom_header(BitstreamReader *stream,
                 unsigned *atom_size,
                 char atom_name[4])
{
    if (!setjmp(*br_try(stream))) {
        *atom_size = stream->read(stream, 32);
        stream->read_bytes(stream, (uint8_t*)atom_name, 4);
        br_etry(stream);
        return 1;
    } else {
        br_etry(stream);
        return 0;
    }
}
Пример #5
0
ogg_status
read_ogg_page_header(BitstreamReader *ogg_stream,
                     struct ogg_page_header *header) {
    unsigned i;
    struct bs_callback callback;

    if ((header->magic_number =
         ogg_stream->read(ogg_stream, 32)) != 0x5367674F) {
        return OGG_INVALID_MAGIC_NUMBER;
    }

    if ((header->version = ogg_stream->read(ogg_stream, 8)) != 0) {
        return OGG_INVALID_STREAM_VERSION;
    }

    header->packet_continuation = ogg_stream->read(ogg_stream, 1);
    header->stream_beginning = ogg_stream->read(ogg_stream, 1);
    header->stream_end = ogg_stream->read(ogg_stream, 1);
    ogg_stream->skip(ogg_stream, 5);
    header->granule_position = ogg_stream->read_signed_64(ogg_stream, 64);
    header->bitstream_serial_number = ogg_stream->read(ogg_stream, 32);
    header->sequence_number = ogg_stream->read(ogg_stream, 32);

    /*the checksum field is *not* checksummed itself, naturally
      those 4 bytes are treated as 0*/
    ogg_stream->pop_callback(ogg_stream, &callback);
    if (!setjmp(*br_try(ogg_stream))) {
        header->checksum = ogg_stream->read(ogg_stream, 32);
        br_etry(ogg_stream);
        ogg_stream->push_callback(ogg_stream, &callback);
    } else {
        /*restore callback before propagating read error*/
        br_etry(ogg_stream);
        ogg_stream->push_callback(ogg_stream, &callback);
        br_abort(ogg_stream);
    }
    ogg_stream->call_callbacks(ogg_stream, 0);
    ogg_stream->call_callbacks(ogg_stream, 0);
    ogg_stream->call_callbacks(ogg_stream, 0);
    ogg_stream->call_callbacks(ogg_stream, 0);

    header->segment_count = ogg_stream->read(ogg_stream, 8);
    for (i = 0; i < header->segment_count; i++) {
        header->segment_lengths[i] = ogg_stream->read(ogg_stream, 8);
    }

    return OGG_OK;
}
Пример #6
0
ogg_status
oggreader_read_page_header(BitstreamReader *ogg_stream,
                           struct ogg_page_header *header) {
    int i;
    struct bs_callback callback;

    if (!setjmp(*br_try(ogg_stream))) {
        if ((header->magic_number =
             ogg_stream->read(ogg_stream, 32)) != 0x5367674F) {
            br_etry(ogg_stream);
            return OGG_INVALID_MAGIC_NUMBER;
        }

        if ((header->version = ogg_stream->read(ogg_stream, 8)) != 0) {
            br_etry(ogg_stream);
            return OGG_INVALID_STREAM_VERSION;
        }

        header->type = ogg_stream->read(ogg_stream, 8);
        header->granule_position = ogg_stream->read_64(ogg_stream, 64);
        header->bitstream_serial_number = ogg_stream->read(ogg_stream, 32);
        header->page_sequence_number = ogg_stream->read(ogg_stream, 32);

        /*the checksum field is *not* checksummed itself, naturally
          those 4 bytes are treated as 0*/
        br_pop_callback(ogg_stream, &callback);
        header->checksum = ogg_stream->read(ogg_stream, 32);
        br_push_callback(ogg_stream, &callback);
        br_call_callbacks(ogg_stream, 0);
        br_call_callbacks(ogg_stream, 0);
        br_call_callbacks(ogg_stream, 0);
        br_call_callbacks(ogg_stream, 0);

        header->page_segment_count = ogg_stream->read(ogg_stream, 8);
        header->segment_length_total = 0;
        for (i = 0; i < header->page_segment_count; i++) {
            header->page_segment_lengths[i] = ogg_stream->read(ogg_stream, 8);
            header->segment_length_total += header->page_segment_lengths[i];
        }

        br_etry(ogg_stream);
        return OGG_OK;
    } else {
        br_etry(ogg_stream);
        return OGG_PREMATURE_EOF;
    }
}
Пример #7
0
ogg_status
read_ogg_page(BitstreamReader *ogg_stream,
              struct ogg_page *page)
{
    uint32_t checksum = 0;

    if (!setjmp(*br_try(ogg_stream))) {
        uint8_t i;
        ogg_status result;

        /*attach checksum calculator to stream*/
        ogg_stream->add_callback(ogg_stream, (bs_callback_f)ogg_crc, &checksum);

        /*read header*/
        if ((result = read_ogg_page_header(ogg_stream,
                                           &(page->header))) != OGG_OK) {
            /*abort if error in header*/
            ogg_stream->pop_callback(ogg_stream, NULL);
            br_etry(ogg_stream);
            return result;
        }

        /*populate segments based on lengths in header*/
        for (i = 0; i < page->header.segment_count; i++) {
            ogg_stream->read_bytes(ogg_stream,
                                   page->segment[i],
                                   page->header.segment_lengths[i]);
        }

        /*remove checksum calculator from stream*/
        ogg_stream->pop_callback(ogg_stream, NULL);

        /*no more I/O needed for page*/
        br_etry(ogg_stream);

        /*validate checksum*/
        if (checksum == page->header.checksum) {
            return OGG_OK;
        } else {
            return OGG_CHECKSUM_MISMATCH;
        }
    } else {
        ogg_stream->pop_callback(ogg_stream, NULL);
        br_etry(ogg_stream);
        return OGG_PREMATURE_EOF;
    }
}
Пример #8
0
vorbis_status
vorbis_read_setup_packet(BitstreamReader *packet) {
    vorbis_status result;

    if (!setjmp(*br_try(packet))) {
        if (vorbis_read_common_header(packet) != 5) {
            br_etry(packet);
            return VORBIS_SETUP_NOT_3RD;
        }

        /*read codebooks*/
        if ((result = vorbis_read_codebooks(packet)) != VORBIS_OK) {
            br_etry(packet);
            return result;
        }

        /*read time domain transforms*/
        if ((result =
             vorbis_read_time_domain_transforms(packet)) != VORBIS_OK) {
            br_etry(packet);
            return result;
        }
        /*read floors*/
        /*FIXME*/

        /*read residues*/
        /*FIXME*/

        /*read mappings*/
        /*FIXME*/

        /*read modes*/
        /*FIXME*/

        /*read framing bit*/
        /*FIXME*/

    } else {
        br_etry(packet);
        return VORBIS_PREMATURE_EOF;
    }

    br_etry(packet);
    return VORBIS_OK;
}
Пример #9
0
ogg_status
oggreader_next_segment(OggReader *reader,
                       BitstreamReader *packet,
                       uint8_t *segment_size) {
    ogg_status status;

    if (reader->current_segment < reader->current_header.page_segment_count) {
        /*return an Ogg segment from the current page*/
        *segment_size = reader->current_header.page_segment_lengths[
                                                reader->current_segment++];
        if (!setjmp(*br_try(reader->ogg_stream))) {
            reader->ogg_stream->substream_append(reader->ogg_stream,
                                                 packet,
                                                 *segment_size);
            br_etry(reader->ogg_stream);
            return OGG_OK;
        } else {
            br_etry(reader->ogg_stream);
            return OGG_PREMATURE_EOF;
        }
    } else {
        /*the current page is finished*/

        /*validate page checksum*/
        if (reader->current_header.checksum != reader->checksum) {
            return OGG_CHECKSUM_MISMATCH;
        }

        /*if the current page isn't the final page,
          read the next page from the stream*/
        if (reader->current_header.type & 0x4) {
            return OGG_STREAM_FINISHED;
        } else {
            reader->checksum = 0;
            status = oggreader_read_page_header(reader->ogg_stream,
                                                &(reader->current_header));
            reader->current_segment = 0;
            if (status == OGG_OK) {
                return oggreader_next_segment(reader, packet, segment_size);
            } else
                return status;
        }
    }
}
Пример #10
0
static status
seek_mdat(BitstreamReader* alac_stream)
{
    unsigned int atom_size;
    uint8_t atom_type[4];

    if (!setjmp(*br_try(alac_stream))) {
        alac_stream->parse(alac_stream, "32u 4b", &atom_size, atom_type);
        while (memcmp(atom_type, "mdat", 4)) {
            alac_stream->skip_bytes(alac_stream, atom_size - 8);
            alac_stream->parse(alac_stream, "32u 4b", &atom_size, atom_type);
        }
        br_etry(alac_stream);
        return OK;
    } else {
        br_etry(alac_stream);
        return ERROR;
    }
}
Пример #11
0
static PyObject*
ALACDecoder_seek(decoders_ALACDecoder* self, PyObject *args)
{
    long long seeked_offset;

    if (self->closed) {
        PyErr_SetString(PyExc_ValueError, "cannot seek closed stream");
        return NULL;
    }

    if (!PyArg_ParseTuple(args, "L", &seeked_offset)) {
        return NULL;
    }

    if (seeked_offset < 0) {
        PyErr_SetString(PyExc_ValueError, "cannot seek to negative value");
        return NULL;
    }

    if (!self->seektable) {
        /*no seektable, so seek to beginning of file*/
        if (!setjmp(*br_try(self->bitstream))) {
            self->bitstream->setpos(self->bitstream, self->mdat_start);
            br_etry(self->bitstream);
            self->read_pcm_frames = 0;
            return Py_BuildValue("i", 0);
        } else {
            br_etry(self->bitstream);
            PyErr_SetString(PyExc_IOError, "I/O error seeking in stream");
            return NULL;
        }
    } else {
        unsigned i;
        unsigned pcm_frames_offset = 0;
        long byte_offset = 0;

        /*find latest seekpoint whose first sample is <= seeked_offset
          or 0 if there are no seekpoints in the seektable*/
        for (i = 0; i < self->total_alac_frames; i++) {
            if (seeked_offset >= self->seektable[i].pcm_frames) {
                seeked_offset -= self->seektable[i].pcm_frames;
                pcm_frames_offset += self->seektable[i].pcm_frames;
                byte_offset += self->seektable[i].byte_size;
            } else {
                break;
            }
        }

        /*position bitstream to indicated position in file*/
        if (!setjmp(*br_try(self->bitstream))) {
            self->bitstream->setpos(self->bitstream, self->mdat_start);
            self->bitstream->seek(self->bitstream, byte_offset, BS_SEEK_CUR);
            br_etry(self->bitstream);
        } else {
            br_etry(self->bitstream);
            PyErr_SetString(PyExc_IOError, "I/O error seeking in stream");
            return NULL;
        }

        /*reset stream's total remaining frames*/
        self->read_pcm_frames = pcm_frames_offset;

        /*return actual PCM frame position in file*/
        return Py_BuildValue("I", pcm_frames_offset);
    }

}
Пример #12
0
static PyObject*
FlacDecoder_offsets(decoders_FlacDecoder* self, PyObject *args)
{
    int channel;
    struct flac_frame_header frame_header;
    flac_status error;
    PyObject* offsets = PyList_New(0);
    PyObject* offset_pair;
    uint32_t samples;
    long offset;
    PyThreadState *thread_state = PyEval_SaveThread();

    while (self->remaining_samples > 0) {
        self->subframe_data->reset(self->subframe_data);
        offset = br_ftell(self->bitstream);

        if (!setjmp(*br_try(self->bitstream))) {
            /*read frame header*/
            if ((error = flacdec_read_frame_header(self->bitstream,
                                                   &(self->streaminfo),
                                                   &frame_header)) != OK) {
                PyEval_RestoreThread(thread_state);
                PyErr_SetString(PyExc_ValueError, FlacDecoder_strerror(error));
                goto error;
            }

            samples = frame_header.block_size;

            /*read 1 subframe per channel*/
            for (channel = 0; channel < frame_header.channel_count; channel++)
                if ((error =
                     flacdec_read_subframe(
                         self->bitstream,
                         self->qlp_coeffs,
                         self->residuals,
                         (unsigned int)MIN(frame_header.block_size,
                                           self->remaining_samples),
                         flacdec_subframe_bits_per_sample(&frame_header,
                                                          channel),
                         self->subframe_data->append(self->subframe_data))) !=
                    OK) {
                    PyEval_RestoreThread(thread_state);
                    PyErr_SetString(PyExc_ValueError,
                                    FlacDecoder_strerror(error));
                    goto error;
                }

            /*read CRC-16*/
            self->bitstream->byte_align(self->bitstream);
            self->bitstream->read(self->bitstream, 16);

            /*decrement remaining samples*/
            self->remaining_samples -= frame_header.block_size;

            /*add offset pair to our list*/
            PyEval_RestoreThread(thread_state);
            offset_pair = Py_BuildValue("(i, I)", offset, samples);
            PyList_Append(offsets, offset_pair);
            Py_DECREF(offset_pair);
            thread_state = PyEval_SaveThread();
        } else {
            /*handle I/O error during read*/
            PyEval_RestoreThread(thread_state);
            PyErr_SetString(PyExc_IOError, "EOF reading frame");
            goto error;
        }

        br_etry(self->bitstream);
    }

    self->stream_finalized = 1;

    PyEval_RestoreThread(thread_state);
    return offsets;
error:
    Py_XDECREF(offsets);
    br_etry(self->bitstream);
    return NULL;
}
Пример #13
0
flac_status
flacdec_read_frame_header(BitstreamReader *bitstream,
                          struct flac_STREAMINFO *streaminfo,
                          struct flac_frame_header *header)
{
    unsigned block_size_bits;
    unsigned sample_rate_bits;
    uint8_t crc8 = 0;

    if (!setjmp(*br_try(bitstream))) {
        br_add_callback(bitstream, (bs_callback_f)flac_crc8, &crc8);

        /*read and verify sync code*/
        if (bitstream->read(bitstream, 14) != 0x3FFE) {
            br_pop_callback(bitstream, NULL);
            br_etry(bitstream);
            return ERR_INVALID_SYNC_CODE;
        }

        /*read and verify reserved bit*/
        if (bitstream->read(bitstream, 1) != 0) {
            br_pop_callback(bitstream, NULL);
            br_etry(bitstream);
            return ERR_INVALID_RESERVED_BIT;
        }

        header->blocking_strategy = bitstream->read(bitstream, 1);

        block_size_bits = bitstream->read(bitstream, 4);
        sample_rate_bits = bitstream->read(bitstream, 4);
        header->channel_assignment = bitstream->read(bitstream, 4);
        switch (header->channel_assignment) {
        case 0x8:
        case 0x9:
        case 0xA:
            header->channel_count = 2;
            break;
        default:
            header->channel_count = header->channel_assignment + 1;
            break;
        }

        switch (bitstream->read(bitstream, 3)) {
        case 0:
            header->bits_per_sample = streaminfo->bits_per_sample;
            break;
        case 1:
            header->bits_per_sample = 8; break;
        case 2:
            header->bits_per_sample = 12; break;
        case 4:
            header->bits_per_sample = 16; break;
        case 5:
            header->bits_per_sample = 20; break;
        case 6:
            header->bits_per_sample = 24; break;
        default:
            return ERR_INVALID_BITS_PER_SAMPLE;
        }
        bitstream->read(bitstream, 1); /*padding*/

        header->frame_number = read_utf8(bitstream);

        switch (block_size_bits) {
        case 0x0: header->block_size = streaminfo->maximum_block_size;
            break;
        case 0x1: header->block_size = 192; break;
        case 0x2: header->block_size = 576; break;
        case 0x3: header->block_size = 1152; break;
        case 0x4: header->block_size = 2304; break;
        case 0x5: header->block_size = 4608; break;
        case 0x6: header->block_size = bitstream->read(bitstream, 8) + 1;
            break;
        case 0x7: header->block_size = bitstream->read(bitstream, 16) + 1;
            break;
        case 0x8: header->block_size = 256; break;
        case 0x9: header->block_size = 512; break;
        case 0xA: header->block_size = 1024; break;
        case 0xB: header->block_size = 2048; break;
        case 0xC: header->block_size = 4096; break;
        case 0xD: header->block_size = 8192; break;
        case 0xE: header->block_size = 16384; break;
        case 0xF: header->block_size = 32768; break;
        }

        switch (sample_rate_bits) {
        case 0x0: header->sample_rate = streaminfo->sample_rate; break;
        case 0x1: header->sample_rate = 88200; break;
        case 0x2: header->sample_rate = 176400; break;
        case 0x3: header->sample_rate = 192000; break;
        case 0x4: header->sample_rate = 8000; break;
        case 0x5: header->sample_rate = 16000; break;
        case 0x6: header->sample_rate = 22050; break;
        case 0x7: header->sample_rate = 24000; break;
        case 0x8: header->sample_rate = 32000; break;
        case 0x9: header->sample_rate = 44100; break;
        case 0xA: header->sample_rate = 48000; break;
        case 0xB: header->sample_rate = 96000; break;
        case 0xC: header->sample_rate = bitstream->read(bitstream, 8) * 1000;
            break;
        case 0xD: header->sample_rate = bitstream->read(bitstream, 16);
            break;
        case 0xE: header->sample_rate = bitstream->read(bitstream, 16) * 10;
            break;
        case 0xF:
            return ERR_INVALID_SAMPLE_RATE;
        }

        /*check for valid CRC-8 value*/
        bitstream->read(bitstream, 8);

        /*no more I/O after this point*/
        br_pop_callback(bitstream, NULL);
        br_etry(bitstream);

        if (crc8 != 0)
            return ERR_INVALID_FRAME_CRC;

        /*Once we've read everything,
          ensure the values are compatible with STREAMINFO.*/

        if (streaminfo->sample_rate != header->sample_rate) {
            return ERR_SAMPLE_RATE_MISMATCH;
        }
        if (streaminfo->channels != header->channel_count) {
            return ERR_CHANNEL_COUNT_MISMATCH;
        }
        if (streaminfo->bits_per_sample != header->bits_per_sample) {
            return ERR_BITS_PER_SAMPLE_MISMATCH;
        }
        if (header->block_size > streaminfo->maximum_block_size) {
            return ERR_MAXIMUM_BLOCK_SIZE_EXCEEDED;
        }

        return OK;
    } else {
        /*push read error to calling function*/
        br_pop_callback(bitstream, NULL);
        br_etry(bitstream);
        br_abort(bitstream);
        return OK;  /*won't get here*/
    }
}
Пример #14
0
static int
read_audio_packet(DVDA_Packet_Reader* packets,
                  DVDA_Packet* packet, struct bs_buffer* packet_data)
{
    if (packets->total_sectors) {
        BitstreamReader* reader = packets->reader;
        struct bs_buffer* buffer = reader->input.substream;
        buf_reset(buffer);
        if (!read_sector(packets->sectors, buffer)) {
            if (buf_window_size(buffer) == 0) {
                return 0;
            }

            if (!setjmp(*br_try(reader))) {
                unsigned sync_bytes;
                unsigned pad[6];
                unsigned PTS_high;
                unsigned PTS_mid;
                unsigned PTS_low;
                unsigned SCR_extension;
                unsigned bitrate;
                unsigned stuffing_count;
                int audio_packet_found = 0;

                /*read pack header*/
                reader->parse(reader,
                              "32u 2u 3u 1u 15u 1u 15u 1u 9u 1u 22u 2u 5p 3u",
                              &sync_bytes, &(pad[0]), &PTS_high,
                              &(pad[1]), &PTS_mid, &(pad[2]),
                              &PTS_low, &(pad[3]), &SCR_extension,
                              &(pad[4]), &bitrate, &(pad[5]),
                              &stuffing_count);
                if (sync_bytes != 0x000001BA) {
                    br_etry(reader);
                    return 1;
                }

                if ((pad[0] != 1) || (pad[1] != 1) || (pad[2] != 1) ||
                    (pad[3] != 1) || (pad[4] != 1) || (pad[5] != 3)) {
                    br_etry(reader);
                    return 1;
                }

                for (; stuffing_count; stuffing_count--) {
                    reader->skip(reader, 8);
                }

                /*read packets from sector until sector is empty*/
                while (buf_window_size(buffer) > 0) {
                    unsigned start_code;
                    unsigned stream_id;
                    unsigned packet_length;

                    reader->parse(reader, "24u 8u 16u",
                                  &start_code, &stream_id, &packet_length);

                    if (start_code != 0x000001) {
                        br_etry(reader);
                        return 1;
                    }

                    if (stream_id == 0xBD) {
                        /*audio packets are forwarded to packet*/
                        unsigned pad1_size;
                        unsigned pad2_size;

                        reader->parse(reader, "16p 8u", &pad1_size);
                        reader->skip_bytes(reader, pad1_size);
                        reader->parse(reader, "8u 8u 8p 8u",
                                      &(packet->codec_ID),
                                      &(packet->CRC),
                                      &pad2_size);

                        if (packet->codec_ID == 0xA0) { /*PCM*/
                            reader->parse(reader,
                                          "16u 8p 4u 4u 4u 4u 8p 8u 8p 8u",
                                          &(packet->PCM.first_audio_frame),
                                          &(packet->PCM.group_1_bps),
                                          &(packet->PCM.group_2_bps),
                                          &(packet->PCM.group_1_rate),
                                          &(packet->PCM.group_2_rate),
                                          &(packet->PCM.channel_assignment),
                                          &(packet->PCM.CRC));
                            reader->skip_bytes(reader, pad2_size - 9);
                        } else {                        /*probably MLP*/
                            reader->skip_bytes(reader, pad2_size);
                        }

                        packet_length -= 3 + pad1_size + 4 + pad2_size;

                        buf_reset(packet_data);
                        while (packet_length) {
                            static uint8_t buffer[4096];
                            const unsigned to_read = MIN(packet_length, 4096);
                            reader->read_bytes(reader, buffer, to_read);
                            buf_write(packet_data, buffer, to_read);
                            packet_length -= to_read;
                        }

                        audio_packet_found = 1;
                    } else {
                        /*other packets are ignored*/
                        reader->skip_bytes(reader, packet_length);
                    }
                }

                /*return success if an audio packet was read*/
                br_etry(reader);
                if (audio_packet_found) {
                    return 0;
                } else {
                    return 1;
                }
            } else {
                /*error reading sector*/
                br_etry(reader);
                return 1;
            }
        } else {
            /*error reading sector*/
            return 1;
        }
    } else {
        /*no more sectors, so return EOF*/
        return 0;
    }
}
Пример #15
0
static PyObject*
DVDA_Title_next_track(decoders_DVDA_Title *self, PyObject *args)
{
    unsigned PTS_ticks;
    DVDA_Packet next_packet;
    struct bs_buffer* packet_data = self->packet_data;
    unsigned i;

    if (!PyArg_ParseTuple(args, "I", &PTS_ticks))
        return NULL;

    /*ensure previous track has been exhausted, if any*/
    if (self->pcm_frames_remaining) {
        PyErr_SetString(PyExc_ValueError,
                        "current track has not been exhausted");
        return NULL;
    }

    /*read the next packet*/
    if (read_audio_packet(self->packet_reader,
                          &next_packet, packet_data)) {
        PyErr_SetString(PyExc_IOError,
                        "I/O error reading initialization packet");
        return NULL;
    }
#else
int
DVDA_Title_next_track(decoders_DVDA_Title *self, unsigned PTS_ticks)
{
    DVDA_Packet next_packet;
    struct bs_buffer* packet_data = self->packet_data;
    unsigned i;

    if (self->pcm_frames_remaining) {
        fprintf(stderr, "current track has not been exhausted\n");
        return 0;
    }

    if (read_audio_packet(self->packet_reader,
                          &next_packet, packet_data)) {
        fprintf(stderr, "I/O error reading initialization packet\n");
        return 0;
    }
#endif

    if (next_packet.codec_ID == PCM_CODEC_ID) {
        /*if the packet is PCM, initialize Title's stream attributes
          (bits-per-sample, sample rate, channel assignment/mask)
          with values taken from the first packet*/

        /*PCM stores stream attributes in the second padding block*/
        self->bits_per_sample =
            dvda_bits_per_sample(next_packet.PCM.group_1_bps);
        self->sample_rate =
            dvda_sample_rate(next_packet.PCM.group_1_rate);
        self->channel_assignment =
            next_packet.PCM.channel_assignment;
        self->channel_count =
            dvda_channel_count(next_packet.PCM.channel_assignment);
        self->channel_mask =
            dvda_channel_mask(next_packet.PCM.channel_assignment);

        self->frame_codec = PCM;

        init_aobpcm_decoder(&(self->pcm_decoder),
                            self->bits_per_sample,
                            self->channel_count);

        buf_extend(packet_data, self->frames);

    } else if (next_packet.codec_ID == MLP_CODEC_ID) {
        /*if the packet is MLP,
          check if the first frame starts with a major sync*/
        enum {PACKET_DATA};
        BitstreamReader* r = br_open_buffer(packet_data, BS_BIG_ENDIAN);
        r->mark(r, PACKET_DATA);
        if (!setjmp(*br_try(r))) {
            unsigned sync_words;
            unsigned stream_type;

            r->parse(r, "32p 24u 8u", &sync_words, &stream_type);
            if ((sync_words == 0xF8726F) && (stream_type == 0xBB)) {
                /*if so, discard any unconsumed packet data
                  and initialize Title's stream attributes
                  with values taken from the major sync*/

                unsigned group_1_bps;
                unsigned group_2_bps;
                unsigned group_1_rate;
                unsigned group_2_rate;

                r->parse(r, "4u 4u 4u 4u 11p 5u 48p",
                         &group_1_bps, &group_2_bps,
                         &group_1_rate, &group_2_rate,
                         &(self->channel_assignment));

                self->bits_per_sample =
                    dvda_bits_per_sample(group_1_bps);
                self->sample_rate =
                    dvda_sample_rate(group_1_rate);
                self->channel_count =
                    dvda_channel_count(self->channel_assignment);
                self->channel_mask =
                    dvda_channel_mask(self->channel_assignment);
                self->frame_codec = MLP;
                self->mlp_decoder->major_sync_read = 0;

                r->rewind(r, PACKET_DATA);
                r->unmark(r, PACKET_DATA);
                br_etry(r);
                r->close(r);

                buf_reset(self->frames);
                buf_extend(packet_data, self->frames);
            } else {
                /*if not, append packet data to any unconsumed data
                  and leave Title's stream attributes as they were*/

                r->rewind(r, PACKET_DATA);
                r->unmark(r, PACKET_DATA);
                br_etry(r);
                r->close(r);

                buf_extend(packet_data, self->frames);
            }
        } else {
            /*if I/O error reading major sync,
              append packet data to any unconsumed data
              and leave Title's stream attributes as they were*/

            r->rewind(r, PACKET_DATA);
            r->unmark(r, PACKET_DATA);
            br_etry(r);
            r->close(r);

            buf_extend(packet_data, self->frames);
        }

    } else {
#ifndef STANDALONE
        PyErr_SetString(PyExc_ValueError, "unknown codec ID");
        return NULL;
#else
        return 0;
#endif
    }

    /*convert PTS ticks to PCM frames based on sample rate*/
    self->pcm_frames_remaining = (unsigned)round((double)PTS_ticks *
                                                 (double)self->sample_rate /
                                                 (double)PTS_PER_SECOND);

    /*initalize codec's framelist with the proper number of channels*/
    if (self->codec_framelist->len != self->channel_count) {
        self->codec_framelist->reset(self->codec_framelist);
        for (i = 0; i < self->channel_count; i++)
            self->codec_framelist->append(self->codec_framelist);
    }

#ifndef STANDALONE
    Py_INCREF(Py_None);
    return Py_None;
#else
    return 1;
#endif
}
Пример #16
0
PyObject*
verifymodule_ogg(PyObject *dummy, PyObject *args) {
    PyObject *file_obj;
    BitstreamReader *bitstream;
    int has_previous_header = 0;
    struct ogg_header previous_header;
    struct ogg_header header;
    uint8_t *data_buffer = NULL;
    int data_buffer_size = 0;
    int i;
    uint32_t checksum;

    /*fixes a "may be used unitialized" warning*/
    previous_header.bitstream_serial_number =
        previous_header.page_sequence_number = 0;

    if (!PyArg_ParseTuple(args, "O", &file_obj))
        return NULL;

    if (!PyFile_CheckExact(file_obj)) {
        PyErr_SetString(PyExc_TypeError,
                        "first argument must be an actual file object");
        return NULL;
    } else {
        bitstream = br_open(PyFile_AsFile(file_obj), BS_LITTLE_ENDIAN);
        br_add_callback(bitstream, ogg_crc, &checksum);
    }

    if (!setjmp(*br_try(bitstream))) {
        do {
            checksum = 0;
            if (verifymodule_read_ogg_header(bitstream, &header) == OK) {
                if (data_buffer_size < header.segment_length_total) {
                    data_buffer = realloc(data_buffer,
                                          header.segment_length_total);
                    data_buffer_size = header.segment_length_total;
                }
                if (fread(data_buffer,
                          sizeof(uint8_t),
                          header.segment_length_total,
                          bitstream->input.file) !=
                    header.segment_length_total) {
                    PyErr_SetString(PyExc_IOError, "I/O error reading stream");
                    goto error;
                }

                for (i = 0; i < header.segment_length_total; i++)
                    ogg_crc(data_buffer[i], &checksum);
                if (header.checksum != checksum) {
                    PyErr_SetString(PyExc_ValueError,
                                    "checksum mismatch in stream");
                    goto error;
                }

                /* printf("calculated checksum : 0x%8.8X\n", checksum); */

                if (has_previous_header) {
                    if (header.bitstream_serial_number !=
                        previous_header.bitstream_serial_number) {
                        PyErr_SetString(PyExc_ValueError,
                                        "differing serial numbers in stream");
                        goto error;
                    }
                    if (header.page_sequence_number !=
                        (previous_header.page_sequence_number + 1)) {
                        PyErr_SetString(PyExc_ValueError,
                                        "page sequence number not incrementing");
                        goto error;
                    }
                    previous_header = header;
                } else {
                    previous_header = header;
                    has_previous_header = 1;
                }
            } else {
                goto error;
            }
        } while (!(header.type & 0x4));
    } else {
        PyErr_SetString(PyExc_IOError, "I/O error reading stream");
        goto error;
    }

    br_etry(bitstream);
    free(data_buffer);
    bitstream->input.file = NULL;
    bitstream->free(bitstream);
    Py_INCREF(Py_None);
    return Py_None;
 error:
    br_etry(bitstream);
    if (data_buffer != NULL)
        free(data_buffer);
    bitstream->input.file = NULL;
    bitstream->free(bitstream);
    return NULL;
}
Пример #17
0
int
flacdec_read_metadata(BitstreamReader *bitstream,
                      struct flac_STREAMINFO *streaminfo,
                      a_obj *seektable,
                      int *channel_mask)
{
    BitstreamReader *comment = br_substream_new(BS_LITTLE_ENDIAN);

    enum {
        fL =  0x1,
        fR =  0x2,
        fC =  0x4,
        LFE = 0x8,
        bL =  0x10,
        bR =  0x20,
        bC =  0x100,
        sL =  0x200,
        sR =  0x400
    };

    if (!setjmp(*br_try(bitstream))) {
        unsigned last_block;

        if (bitstream->read(bitstream, 32) != 0x664C6143u) {
#ifndef STANDALONE
            PyErr_SetString(PyExc_ValueError, "not a FLAC file");
#endif
            br_etry(bitstream);
            comment->close(comment);
            return 1;
        }

        do {
            last_block = bitstream->read(bitstream, 1);
            const unsigned block_type = bitstream->read(bitstream, 7);
            const unsigned block_length = bitstream->read(bitstream, 24);

            switch (block_type) {
            case 0:   /*STREAMINFO*/
                streaminfo->minimum_block_size =
                    bitstream->read(bitstream, 16);
                streaminfo->maximum_block_size =
                    bitstream->read(bitstream, 16);
                streaminfo->minimum_frame_size =
                    bitstream->read(bitstream, 24);
                streaminfo->maximum_frame_size =
                    bitstream->read(bitstream, 24);
                streaminfo->sample_rate =
                    bitstream->read(bitstream, 20);
                streaminfo->channels =
                    bitstream->read(bitstream, 3) + 1;
                streaminfo->bits_per_sample =
                    bitstream->read(bitstream, 5) + 1;
                streaminfo->total_samples =
                    bitstream->read_64(bitstream, 36);

                bitstream->read_bytes(bitstream, streaminfo->md5sum, 16);

                /*default channel mask based on channel count*/
                switch (streaminfo->channels) {
                case 1:
                    *channel_mask = fC;
                    break;
                case 2:
                    *channel_mask = fL | fR;
                    break;
                case 3:
                    *channel_mask = fL | fR | fC;
                    break;
                case 4:
                    *channel_mask = fL | fR | bL | bR;
                    break;
                case 5:
                    *channel_mask = fL | fR | fC | bL | bR;
                    break;
                case 6:
                    *channel_mask = fL | fR | fC | LFE | bL | bR;
                    break;
                case 7:
                    *channel_mask = fL | fR | fC | LFE | bC | sL | sR;
                    break;
                case 8:
                    *channel_mask = fL | fR | fC | LFE | bL | bR | sL | sR;
                    break;
                default:
                    /*shouldn't be able to happen*/
                    *channel_mask = 0;
                    break;
                }
                break;
            case 3: /*SEEKTABLE*/
                {
                    unsigned seekpoints = block_length / 18;
                    seektable->reset_for(seektable, seekpoints);

                    for (; seekpoints > 0; seekpoints--) {
                        struct flac_SEEKPOINT seekpoint;
                        seekpoint.sample_number =
                            bitstream->read_64(bitstream, 64);
                        seekpoint.byte_offset =
                            bitstream->read_64(bitstream, 64);
                        seekpoint.samples =
                            bitstream->read(bitstream, 16);
                        seektable->append(seektable, &seekpoint);
                    }
                }
                break;
            case 4: /*VORBIS_COMMENT*/
                {
                    /*Vorbis comment's channel mask - if any -
                      overrides default one from channel count */

                    br_substream_reset(comment);
                    bitstream->substream_append(bitstream,
                                                comment,
                                                block_length);

                    flacdec_read_vorbis_comment(comment,
                                                streaminfo->channels,
                                                channel_mask);
                }
                break;
            default:  /*all other blocks*/
                bitstream->skip(bitstream, block_length * 8);
                break;
            }
        } while (!last_block);

        br_etry(bitstream);
        comment->close(comment);
        return 0;
    } else {
#ifndef STANDALONE
        PyErr_SetString(PyExc_IOError, "EOF while reading metadata");
#endif
        br_etry(bitstream);
        comment->close(comment);
        return 1;
    }
}
Пример #18
0
static PyObject*
OggFlacDecoder_read(decoders_OggFlacDecoder *self, PyObject *args) {
    ogg_status ogg_status;
    flac_status flac_status;
    struct flac_frame_header frame_header;
    int channel;
    PyObject *framelist;
    PyThreadState *thread_state;

    if (self->closed) {
        PyErr_SetString(PyExc_ValueError, "cannot read closed stream");
        return NULL;
    }

    self->subframe_data->reset(self->subframe_data);

    /*if all samples have been read, return an empty FrameList*/
    if (self->stream_finalized) {
        return empty_FrameList(self->audiotools_pcm,
                               self->streaminfo.channels,
                               self->streaminfo.bits_per_sample);
    }

    thread_state = PyEval_SaveThread();
    ogg_status = oggreader_next_packet(self->ogg_stream, self->packet);
    PyEval_RestoreThread(thread_state);

    if (ogg_status == OGG_OK) {
        /*decode the next FrameList from the stream*/

        thread_state = PyEval_SaveThread();
        self->crc16 = 0;

        if (!setjmp(*br_try(self->packet))) {
            /*read frame header*/
            if ((flac_status =
                 flacdec_read_frame_header(self->packet,
                                           &(self->streaminfo),
                                           &frame_header)) != OK) {
                PyEval_RestoreThread(thread_state);
                PyErr_SetString(PyExc_ValueError,
                                FlacDecoder_strerror(flac_status));
                br_etry(self->packet);
                return NULL;
            }

            /*read 1 subframe per channel*/
            for (channel = 0; channel < frame_header.channel_count; channel++)
                if ((flac_status = flacdec_read_subframe(
                        self->packet,
                        self->qlp_coeffs,
                        self->residuals,
                        frame_header.block_size,
                        flacdec_subframe_bits_per_sample(&frame_header,
                                                         channel),
                        self->subframe_data->append(self->subframe_data))) !=
                    OK) {
                    PyEval_RestoreThread(thread_state);
                    PyErr_SetString(PyExc_ValueError,
                                    FlacDecoder_strerror(flac_status));
                    br_etry(self->packet);
                    return NULL;
                }

            br_etry(self->packet);

            /*handle difference channels, if any*/
            flacdec_decorrelate_channels(frame_header.channel_assignment,
                                         self->subframe_data,
                                         self->framelist_data);

            /*check CRC-16*/
            self->packet->byte_align(self->packet);
            self->packet->read(self->packet, 16);
            if (self->crc16 != 0) {
                PyEval_RestoreThread(thread_state);
                PyErr_SetString(PyExc_ValueError, "invalid checksum in frame");
                return NULL;
            }

            PyEval_RestoreThread(thread_state);

            framelist = a_int_to_FrameList(self->audiotools_pcm,
                                           self->framelist_data,
                                           frame_header.channel_count,
                                           frame_header.bits_per_sample);

            if (framelist != NULL) {
                /*update MD5 sum*/
                if (OggFlacDecoder_update_md5sum(self, framelist) == 1)
                    /*return pcm.FrameList Python object*/
                    return framelist;
                else {
                    Py_DECREF(framelist);
                    return NULL;
                }
            } else {
                return NULL;
            }
        } else {
            /*read error decoding FLAC frame*/
            PyEval_RestoreThread(thread_state);
            PyErr_SetString(PyExc_IOError, "I/O error decoding FLAC frame");
            br_etry(self->packet);
            return NULL;
        }
    } else if (ogg_status == OGG_STREAM_FINISHED) {
        /*Ogg stream is finished so verify stream's MD5 sum
          then return an empty FrameList if it matches correctly*/

        if (OggFlacDecoder_verify_okay(self)) {
            self->stream_finalized = 1;
            return empty_FrameList(self->audiotools_pcm,
                                   self->streaminfo.channels,
                                   self->streaminfo.bits_per_sample);
        } else {
            PyErr_SetString(PyExc_ValueError,
                            "MD5 mismatch at end of stream");
            return NULL;
        }
    } else {
        /*error reading the next Ogg packet,
          so raise the appropriate exception*/
        PyErr_SetString(ogg_exception(ogg_status), ogg_strerror(ogg_status));
        return NULL;
    }
}
Пример #19
0
static PyObject*
ALACDecoder_read(decoders_ALACDecoder* self, PyObject *args)
{
    unsigned channel_count;
    BitstreamReader* mdat = self->bitstream;
    array_ia* frameset_channels = self->frameset_channels;
    PyThreadState *thread_state;

    /*return an empty framelist if total samples are exhausted*/
    if (self->remaining_frames == 0) {
        return empty_FrameList(self->audiotools_pcm,
                               self->channels,
                               self->bits_per_sample);
    }

    thread_state = PyEval_SaveThread();

    if (!setjmp(*br_try(mdat))) {
        frameset_channels->reset(frameset_channels);

        /*get initial frame's channel count*/
        channel_count = mdat->read(mdat, 3) + 1;
        while (channel_count != 8) {
            /*read a frame from the frameset into "channels"*/
            if (read_frame(self, mdat,
                           frameset_channels, channel_count) != OK) {
                br_etry(mdat);
                PyEval_RestoreThread(thread_state);
                PyErr_SetString(PyExc_ValueError, self->error_message);
                return NULL;
            } else {
                /*ensure all frames have the same sample count*/
                /*FIXME*/

                /*read the channel count of the next frame
                  in the frameset, if any*/
                channel_count = mdat->read(mdat, 3) + 1;
            }
        }

        /*once all the frames in the frameset are read,
          byte-align the output stream*/
        mdat->byte_align(mdat);
        br_etry(mdat);
        PyEval_RestoreThread(thread_state);

        /*decrement the remaining sample count*/
        self->remaining_frames -= MIN(self->remaining_frames,
                                      frameset_channels->_[0]->len);

        /*convert ALAC channel assignment to standard audiotools assignment*/
        alac_order_to_wave_order(frameset_channels);

        /*finally, build and return framelist object from the sample data*/
        return array_ia_to_FrameList(self->audiotools_pcm,
                                     frameset_channels,
                                     self->bits_per_sample);
    } else {
        br_etry(mdat);
        PyEval_RestoreThread(thread_state);
        PyErr_SetString(PyExc_IOError, "EOF during frame reading");
        return NULL;
    }
}
Пример #20
0
int main(int argc, char* argv[]) {
    FILE* ogg_file;
    OggReader* ogg_stream = NULL;
    BitstreamReader* packet = NULL;
    struct flac_STREAMINFO streaminfo;
    uint16_t header_packets;
    a_int* residuals = NULL;
    a_int* qlp_coeffs = NULL;
    aa_int* subframe_data = NULL;
    a_int* framelist_data = NULL;
    ogg_status result;
    uint16_t crc16 = 0;

    FrameList_int_to_char_converter converter;
    unsigned pcm_size;
    unsigned output_data_size = 1;
    uint8_t* output_data = NULL;

    audiotools__MD5Context md5;
    unsigned char stream_md5sum[16];
    const static unsigned char blank_md5sum[16] = {0, 0, 0, 0, 0, 0, 0, 0,
                                                   0, 0, 0, 0, 0, 0, 0, 0};

    if (argc < 2) {
        fprintf(stderr, "*** Usage: %s <file.oga>\n", argv[0]);
        return 1;
    }

    /*open input file for reading*/
    if ((ogg_file = fopen(argv[1], "rb")) == NULL) {
        fprintf(stderr, "*** %s: %s\n", argv[1], strerror(errno));
        return 1;
    } else {
        /*open bitstream and setup temporary arrays/buffers*/
        ogg_stream = oggreader_open(ogg_file);
        packet = br_substream_new(BS_BIG_ENDIAN);
        subframe_data = aa_int_new();
        residuals = a_int_new();
        qlp_coeffs = a_int_new();
        framelist_data = a_int_new();
        output_data = malloc(output_data_size);
    }

    /*the first packet should be the FLAC's STREAMINFO*/
    if ((result = oggreader_next_packet(ogg_stream, packet)) == OGG_OK) {
        if (!oggflac_read_streaminfo(packet, &streaminfo, &header_packets)) {
            goto error;
        } else {
            converter = FrameList_get_int_to_char_converter(
                streaminfo.bits_per_sample, 0, 1);
        }
    } else {
        fprintf(stderr, "*** Error: %s\n", ogg_strerror(result));
        goto error;
    }

    /*skip subsequent header packets*/
    for (; header_packets > 0; header_packets--) {
        if ((result = oggreader_next_packet(ogg_stream, packet)) != OGG_OK) {
            fprintf(stderr, "*** Error: %s\n", ogg_strerror(result));
            goto error;
        }
    }

    /*initialize the output MD5 sum*/
    audiotools__MD5Init(&md5);

    /*add callback for CRC16 calculation*/
    br_add_callback(packet, (bs_callback_f)flac_crc16, &crc16);

    /*decode the next FrameList from the stream*/
    result = oggreader_next_packet(ogg_stream, packet);

    while (result != OGG_STREAM_FINISHED) {
        if (result == OGG_OK) {
            flac_status flac_status;
            struct flac_frame_header frame_header;
            unsigned channel;

            subframe_data->reset(subframe_data);

            if (!setjmp(*br_try(packet))) {
                /*read frame header*/
                if ((flac_status =
                     flacdec_read_frame_header(packet,
                                               &streaminfo,
                                               &frame_header)) != OK) {
                    fprintf(stderr, "*** Error: %s\n",
                            FlacDecoder_strerror(flac_status));
                    br_etry(packet);
                    goto error;
                }

                /*read 1 subframe per channel*/
                for (channel = 0;
                     channel < frame_header.channel_count;
                     channel++)
                    if ((flac_status = flacdec_read_subframe(
                        packet,
                        qlp_coeffs,
                        residuals,
                        frame_header.block_size,
                        flacdec_subframe_bits_per_sample(&frame_header,
                                                         channel),
                        subframe_data->append(subframe_data))) != OK) {
                        fprintf(stderr, "*** Error: %s\n",
                                FlacDecoder_strerror(flac_status));
                        br_etry(packet);
                        goto error;
                    }

                br_etry(packet);
            } else {
                br_etry(packet);
                fprintf(stderr, "*** I/O Error reading FLAC frame\n");
                goto error;
            }

            /*handle difference channels, if any*/
            flacdec_decorrelate_channels(frame_header.channel_assignment,
                                         subframe_data,
                                         framelist_data);

            /*check CRC-16*/
            packet->byte_align(packet);
            packet->read(packet, 16);
            if (crc16 != 0) {
                fprintf(stderr, "*** Error: invalid checksum in frame\n");
                goto error;
            }

            /*turn FrameList into string of output*/
            pcm_size = (streaminfo.bits_per_sample / 8) * framelist_data->len;
            if (pcm_size > output_data_size) {
                output_data_size = pcm_size;
                output_data = realloc(output_data, output_data_size);
            }
            FrameList_samples_to_char(output_data,
                                      framelist_data->_,
                                      converter,
                                      framelist_data->len,
                                      streaminfo.bits_per_sample);

            /*update MD5 sum*/
            audiotools__MD5Update(&md5, output_data, pcm_size);

            /*output string to stdout*/
            fwrite(output_data, sizeof(unsigned char), pcm_size, stdout);

            result = oggreader_next_packet(ogg_stream, packet);
        } else {
            /*some error reading Ogg stream*/
            fprintf(stderr, "*** Error: %s\n", ogg_strerror(result));
            goto error;
        }
    }

    /*Ogg stream is finished so verify stream's MD5 sum*/
    audiotools__MD5Final(stream_md5sum, &md5);

    if (!((memcmp(streaminfo.md5sum, blank_md5sum, 16) == 0) ||
          (memcmp(stream_md5sum, streaminfo.md5sum, 16) == 0))) {
        fprintf(stderr, "*** MD5 mismatch at end of stream\n");
        goto error;
    }

    /*close streams, temporary buffers*/
    oggreader_close(ogg_stream);
    packet->close(packet);
    subframe_data->del(subframe_data);
    residuals->del(residuals);
    qlp_coeffs->del(qlp_coeffs);
    framelist_data->del(framelist_data);
    free(output_data);

    return 0;

error:
    oggreader_close(ogg_stream);
    packet->close(packet);
    subframe_data->del(subframe_data);
    residuals->del(residuals);
    qlp_coeffs->del(qlp_coeffs);
    framelist_data->del(framelist_data);
    free(output_data);

    return 1;
}
Пример #21
0
PyObject*
FlacDecoder_read(decoders_FlacDecoder* self, PyObject *args)
{
    uint16_t crc16 = 0;
    int channel;
    struct flac_frame_header frame_header;
    PyObject* framelist;
    PyThreadState *thread_state;
    flac_status error;

    if (self->closed) {
        PyErr_SetString(PyExc_ValueError, "cannot read closed stream");
        return NULL;
    }

    self->subframe_data->reset(self->subframe_data);

    /*if all samples have been read, return an empty FrameList*/
    if (self->stream_finalized) {
        return empty_FrameList(self->audiotools_pcm,
                               self->streaminfo.channels,
                               self->streaminfo.bits_per_sample);
    }

    if (self->remaining_samples < 1) {
        self->stream_finalized = 1;

        if (FlacDecoder_verify_okay(self)) {
            return empty_FrameList(self->audiotools_pcm,
                                   self->streaminfo.channels,
                                   self->streaminfo.bits_per_sample);
        } else {
            PyErr_SetString(PyExc_ValueError,
                            "MD5 mismatch at end of stream");
            return NULL;
        }
    }

    thread_state = PyEval_SaveThread();

    if (!setjmp(*br_try(self->bitstream))) {
        /*add callback for CRC16 calculation*/
        br_add_callback(self->bitstream, (bs_callback_f)flac_crc16, &crc16);

        /*read frame header*/
        if ((error = flacdec_read_frame_header(self->bitstream,
                                               &(self->streaminfo),
                                               &frame_header)) != OK) {
            br_pop_callback(self->bitstream, NULL);
            PyEval_RestoreThread(thread_state);
            PyErr_SetString(PyExc_ValueError, FlacDecoder_strerror(error));
            br_etry(self->bitstream);
            return NULL;
        }

        /*read 1 subframe per channel*/
        for (channel = 0; channel < frame_header.channel_count; channel++)
            if ((error =
                 flacdec_read_subframe(
                     self->bitstream,
                     self->qlp_coeffs,
                     self->residuals,
                     (unsigned int)MIN(frame_header.block_size,
                                       self->remaining_samples),
                     flacdec_subframe_bits_per_sample(&frame_header,
                                                      channel),
                     self->subframe_data->append(self->subframe_data))) != OK) {
                br_pop_callback(self->bitstream, NULL);
                PyEval_RestoreThread(thread_state);
                PyErr_SetString(PyExc_ValueError, FlacDecoder_strerror(error));
                br_etry(self->bitstream);
                return NULL;
            }

        /*handle difference channels, if any*/
        flacdec_decorrelate_channels(frame_header.channel_assignment,
                                     self->subframe_data,
                                     self->framelist_data);

        /*check CRC-16*/
        self->bitstream->byte_align(self->bitstream);
        self->bitstream->read(self->bitstream, 16);
        br_pop_callback(self->bitstream, NULL);
        if (crc16 != 0) {
            PyEval_RestoreThread(thread_state);
            PyErr_SetString(PyExc_ValueError, "invalid checksum in frame");
            br_etry(self->bitstream);
            return NULL;
        }

        /*decrement remaining samples*/
        self->remaining_samples -= frame_header.block_size;
    } else {
        /*handle I/O error during read*/
        br_pop_callback(self->bitstream, NULL);
        PyEval_RestoreThread(thread_state);
        PyErr_SetString(PyExc_IOError, "EOF reading frame");
        br_etry(self->bitstream);
        return NULL;
    }

    br_etry(self->bitstream);
    PyEval_RestoreThread(thread_state);

    framelist = array_i_to_FrameList(self->audiotools_pcm,
                                     self->framelist_data,
                                     frame_header.channel_count,
                                     frame_header.bits_per_sample);
    if (framelist != NULL) {
        /*update MD5 sum*/
        if (FlacDecoder_update_md5sum(self, framelist) == OK)
            /*return pcm.FrameList Python object*/
            return framelist;
        else {
            Py_DECREF(framelist);
            return NULL;
        }
    } else {
        return NULL;
    }
}
Пример #22
0
int
ALACDecoder_init(decoders_ALACDecoder *self,
                 PyObject *args, PyObject *kwds)
{
    PyObject *file;
    unsigned atom_size;
    char atom_name[4];
    int got_decoding_parameters = 0;
    int got_seektable = 0;

    self->bitstream = NULL;
    self->mdat_start = NULL;
    self->total_pcm_frames = 0;
    self->read_pcm_frames = 0;
    self->seektable = NULL;
    self->closed = 0;
    self->audiotools_pcm = NULL;

    /*setup some dummy parameters*/
    self->params.block_size = 4096;
    self->params.history_multiplier = 40;
    self->params.initial_history = 10;
    self->params.maximum_K = 14;

    if (!PyArg_ParseTuple(args, "O", &file)) {
        return -1;
    } else {
        Py_INCREF(file);
    }

    self->bitstream = br_open_external(file,
                                       BS_BIG_ENDIAN,
                                       4096,
                                       br_read_python,
                                       bs_setpos_python,
                                       bs_getpos_python,
                                       bs_free_pos_python,
                                       bs_fseek_python,
                                       bs_close_python,
                                       bs_free_python_decref);

    /*walk through atoms*/
    while (read_atom_header(self->bitstream, &atom_size, atom_name)) {
        if (!memcmp(atom_name, "mdat", 4)) {
            /*get mdat atom's starting position*/
            if (self->mdat_start) {
                PyErr_SetString(PyExc_ValueError,
                                "multiple mdat atoms found in stream");
                return -1;
            } else {
                self->mdat_start = self->bitstream->getpos(self->bitstream);
                self->bitstream->seek(self->bitstream,
                                      atom_size - 8,
                                      BS_SEEK_CUR);
            }
        } else if (!memcmp(atom_name, "moov", 4)) {
            /*find and parse metadata from moov atom*/

            struct qt_atom *moov_atom;

            if (!setjmp(*br_try(self->bitstream))) {
                moov_atom = qt_atom_parse_by_name(self->bitstream,
                                                  atom_size,
                                                  atom_name);

                br_etry(self->bitstream);
            } else {
                br_etry(self->bitstream);
                PyErr_SetString(PyExc_IOError, "I/O error parsing moov atom");
                return -1;
            }

            if (!got_decoding_parameters &&
                get_decoding_parameters(self, moov_atom)) {

                /*this is an arbitrary block size limit
                  to keep from blowing up the stack

                  Apple's reference encoder uses 4096 exclusively
                  but the file format allows sizes up to 32 bits(!)
                  which would break the whole world if anybody used
                  them all for a single ALAC frame.

                  so I'll just assume such files are malicious
                  and reject them outright*/
                if (self->params.block_size > 65535) {
                    PyErr_SetString(PyExc_ValueError, "block size too large");
                    return -1;
                }

                got_decoding_parameters = 1;
            }

            if (!got_seektable && get_seektable(self, moov_atom)) {
                got_seektable = 1;
            }

            moov_atom->free(moov_atom);
        } else {
            /*skip remaining atoms*/

            if (atom_size >= 8) {
                self->bitstream->seek(self->bitstream,
                                      atom_size - 8,
                                      BS_SEEK_CUR);
            }
        }
    }

    if (!got_decoding_parameters) {
        PyErr_SetString(PyExc_ValueError, "no decoding parameters");
        return -1;
    }

    /*seek to start of mdat atom*/
    if (self->mdat_start) {
        self->bitstream->setpos(self->bitstream, self->mdat_start);
    } else {
        PyErr_SetString(PyExc_ValueError, "no mdat atom found in stream");
        return -1;
    }

    /*open FrameList generator*/
    if ((self->audiotools_pcm = open_audiotools_pcm()) == NULL) {
        return -1;
    }

    return 0;
}
Пример #23
0
int
flacdec_read_metadata(BitstreamReader *bitstream,
                      struct flac_STREAMINFO *streaminfo,
                      array_o *seektable)
{
    if (!setjmp(*br_try(bitstream))) {
        unsigned last_block;

        if (bitstream->read(bitstream, 32) != 0x664C6143u) {
#ifndef STANDALONE
            PyErr_SetString(PyExc_ValueError, "not a FLAC file");
#endif
            br_etry(bitstream);
            return 1;
        }

        do {
            last_block = bitstream->read(bitstream, 1);
            const unsigned block_type = bitstream->read(bitstream, 7);
            const unsigned block_length = bitstream->read(bitstream, 24);

            switch (block_type) {
            case 0:   /*STREAMINFO*/
                streaminfo->minimum_block_size =
                    bitstream->read(bitstream, 16);
                streaminfo->maximum_block_size =
                    bitstream->read(bitstream, 16);
                streaminfo->minimum_frame_size =
                    bitstream->read(bitstream, 24);
                streaminfo->maximum_frame_size =
                    bitstream->read(bitstream, 24);
                streaminfo->sample_rate =
                    bitstream->read(bitstream, 20);
                streaminfo->channels =
                    bitstream->read(bitstream, 3) + 1;
                streaminfo->bits_per_sample =
                    bitstream->read(bitstream, 5) + 1;
                streaminfo->total_samples =
                    bitstream->read_64(bitstream, 36);

                bitstream->read_bytes(bitstream, streaminfo->md5sum, 16);
                break;
            case 3: /*SEEKTABLE*/
                {
                    unsigned seekpoints = block_length / 18;
                    seektable->reset_for(seektable, seekpoints);

                    for (; seekpoints > 0; seekpoints--) {
                        struct flac_SEEKPOINT seekpoint;
                        seekpoint.sample_number =
                            bitstream->read_64(bitstream, 64);
                        seekpoint.byte_offset =
                            bitstream->read_64(bitstream, 64);
                        seekpoint.samples =
                            bitstream->read(bitstream, 16);
                        seektable->append(seektable, &seekpoint);
                    }
                }
                break;
            default:  /*all other blocks*/
                bitstream->skip(bitstream, block_length * 8);
                break;
            }
        } while (!last_block);

        br_etry(bitstream);
        return 0;
    } else {
#ifndef STANDALONE
        PyErr_SetString(PyExc_IOError, "EOF while reading metadata");
#endif
        br_etry(bitstream);
        return 1;
    }
}
Пример #24
0
vorbis_status
vorbis_read_identification_packet(
                        BitstreamReader *packet,
                        struct vorbis_identification_header *identification) {
    if (!setjmp(*br_try(packet))) {
        if (vorbis_read_common_header(packet) != 1) {
            br_etry(packet);
            return VORBIS_ID_HEADER_NOT_1ST;
        }

        identification->vorbis_version = packet->read(packet, 32);
        if (identification->vorbis_version != 0) {
            br_etry(packet);
            return VORBIS_UNSUPPORTED_VERSION;
        }

        identification->channel_count = packet->read(packet, 8);
        if (identification->channel_count < 1) {
            br_etry(packet);
            return VORBIS_INVALID_CHANNEL_COUNT;
        }

        identification->sample_rate = packet->read(packet, 32);
        if (identification->sample_rate < 1) {
            br_etry(packet);
            return VORBIS_INVALID_SAMPLE_RATE;
        }

        identification->bitrate_maximum = packet->read(packet, 32);
        identification->bitrate_nominal = packet->read(packet, 32);
        identification->bitrate_minimum = packet->read(packet, 32);
        identification->blocksize_0 = 1 << packet->read(packet, 4);
        if ((identification->blocksize_0 != 64) &&
            (identification->blocksize_0 != 128) &&
            (identification->blocksize_0 != 256) &&
            (identification->blocksize_0 != 512) &&
            (identification->blocksize_0 != 1024) &&
            (identification->blocksize_0 != 2048) &&
            (identification->blocksize_0 != 4096) &&
            (identification->blocksize_0 != 8192)) {
            br_etry(packet);
            return VORBIS_INVALID_BLOCK_SIZE_0;
        }

        identification->blocksize_1 = 1 << packet->read(packet, 4);
        if ((identification->blocksize_1 != 64) &&
            (identification->blocksize_1 != 128) &&
            (identification->blocksize_1 != 256) &&
            (identification->blocksize_1 != 512) &&
            (identification->blocksize_1 != 1024) &&
            (identification->blocksize_1 != 2048) &&
            (identification->blocksize_1 != 4096) &&
            (identification->blocksize_1 != 8192)) {
            br_etry(packet);
            return VORBIS_INVALID_BLOCK_SIZE_1;
        }

        if (identification->blocksize_0 > identification->blocksize_1) {
            br_etry(packet);
            return VORBIS_INVALID_BLOCK_SIZE_1;
        }

        if (packet->read(packet, 1) != 1) {
            br_etry(packet);
            return VORBIS_INVALID_FRAMING_BIT;
        }
    } else {
        br_etry(packet);
        return VORBIS_PREMATURE_EOF;
    }

    br_etry(packet);
    return VORBIS_OK;
}