aboutsummaryrefslogtreecommitdiff
path: root/src/ReadFlac.cpp.seekable
diff options
context:
space:
mode:
Diffstat (limited to 'src/ReadFlac.cpp.seekable')
-rw-r--r--src/ReadFlac.cpp.seekable398
1 files changed, 0 insertions, 398 deletions
diff --git a/src/ReadFlac.cpp.seekable b/src/ReadFlac.cpp.seekable
deleted file mode 100644
index 17992b9..0000000
--- a/src/ReadFlac.cpp.seekable
+++ /dev/null
@@ -1,398 +0,0 @@
-/*
- * readanysf~ external for pd.
- *
- * Copyright (C) 2003,2004 August Black
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- * ReadFlac.cpp
- *
- * much of the code comes from FLAC input plugin for Winamp3
- * distributed with the flac source under the GPL
- * Copyright (C) 2000,2001,2002,2003 Josh Coalson
- */
-
-#ifdef READ_FLAC
-
-//#include <m_pd.h>
-#include "ReadFlac.h"
-#include <iostream>
-
-extern "C" {
-#include "FLAC/metadata.h"
-};
-
-using namespace std;
-
-ReadFlac::ReadFlac( Input *input ) {
- in=input;
- needs_seek = false;
- seek_sample = 0;
- samples_in_reservoir =0;
- abort_flag = false;
- decoder = NULL;
- filelength = 0;
-}
-
-ReadFlac::~ReadFlac() {
- cout << "exiting FLAC ..." << endl;
- //exit(1);
- cleanup();
-}
-
-bool ReadFlac::Initialize( ) {
-
-
- //@@@ to be really "clean" we should go through the reader instead of directly to the file...
- if(!FLAC__metadata_get_streaminfo(in->get_filename(), &streaminfo)) {
- cout << "what the fuck" << endl;
- return 1;
- }
-
- //length_msec = lengthInMsec();
- /*cout << "FLAC:<%ihz:%ibps:%dch>",
- streaminfo.data.stream_info.sample_rate,
- streaminfo.data.stream_info.bits_per_sample,
- streaminfo.data.stream_info.channels); //@@@ fix later
- */
-
- samplerate = (double)streaminfo.data.stream_info.sample_rate;
- num_channels = streaminfo.data.stream_info.channels;
- lengthinseconds = streaminfo.data.stream_info.total_samples/samplerate;
-
- filelength = in->SeekEnd(0);
- filelength = in->SeekCur(0);
- in->SeekSet(0);
-
- decoder = FLAC__seekable_stream_decoder_new();
- if(decoder == 0)
- return false;
- FLAC__seekable_stream_decoder_set_md5_checking(decoder, false);
- FLAC__seekable_stream_decoder_set_read_callback(decoder, readCallback_);
- FLAC__seekable_stream_decoder_set_seek_callback(decoder, seekCallback_);
- FLAC__seekable_stream_decoder_set_tell_callback(decoder, tellCallback_);
- FLAC__seekable_stream_decoder_set_length_callback(decoder, lengthCallback_);
- FLAC__seekable_stream_decoder_set_eof_callback(decoder, eofCallback_);
- FLAC__seekable_stream_decoder_set_write_callback(decoder, writeCallback_);
- FLAC__seekable_stream_decoder_set_metadata_callback(decoder, metadataCallback_);
- FLAC__seekable_stream_decoder_set_error_callback(decoder, errorCallback_);
- FLAC__seekable_stream_decoder_set_client_data(decoder, this);
-
- if(FLAC__seekable_stream_decoder_init(decoder) != FLAC__SEEKABLE_STREAM_DECODER_OK) {
- cleanup();
- return false;
- }
- if(!FLAC__seekable_stream_decoder_process_until_end_of_metadata(decoder)) {
- cleanup();
- return false;
- }
-
- return true;
-}
-
-
-
-int ReadFlac::Decode(float *buffer, int size) {
-
- if(decoder == NULL)
- return 0;
-
- if(needs_seek) {
- FLAC__seekable_stream_decoder_seek_absolute(decoder, seek_sample);
- //cout << "seeking " << seek_sample << " samples" << endl;
- needs_seek = false;
- }
-
- //while (samples_in_reservoir < 576) {
- //if (samples_in_reservoir < 576) {
- if(FLAC__seekable_stream_decoder_get_state(decoder) == FLAC__SEEKABLE_STREAM_DECODER_END_OF_STREAM) {
- cout << "FLAC: end of file" << endl;
- return 0;
- } else if(!FLAC__seekable_stream_decoder_process_single(decoder)) {
-
- //ErrorCheck( FLAC__seekable_stream_decoder_get_state(decoder) );
- //ErrorCheck( FLAC__seekable_stream_decoder_finish(decoder) );
- //ErrorCheck( FLAC__seekable_stream_decoder_init(decoder) );
- //FLAC__seekable_stream_decoder_reset(decoder);
- //FLAC__seekable_stream_decoder_flush(decoder);
- cout << "FLAC: no process single " << endl;
- //break;
- //exit(1);
- //return 0;
- //return samples_in_reservoir;
- }
- //}
-
- int n = samples_in_reservoir; // > 576 ? samples_in_reservoir: 576;
- const unsigned channels = streaminfo.data.stream_info.channels;
-
- if(samples_in_reservoir == 0) {
- //cout << "FLAC: reservoir is empty" << endl;
- return 0;
- } else {
-
- //const unsigned bits_per_sample = streaminfo.data.stream_info.bits_per_sample;
- //const unsigned bytes_per_sample = (bits_per_sample+7)/8;
- //const unsigned sample_rate = streaminfo.data.stream_info.sample_rate;
- unsigned i;
- //16 > WHDR2 + 2 ? 16 : WHDR2 + 2
-
- //unsigned delta;
-
-
- for(i = 0; i < n*channels; i++)
- buffer[i] = (float) ( reservoir[i]/ 32768.0 );
-
-
- samples_in_reservoir = 0;
-
- //const int bytes = n * channels * bytes_per_sample;
- }
-
- //if(eof)
- //return 0;
-
- return n*channels; //1;
-}
-
-bool ReadFlac::Rewind() {
- needs_seek = true;
- seek_sample = 0;
- samples_in_reservoir = 0;
- //ErrorCheck( FLAC__seekable_stream_decoder_get_state(decoder) );
- //FLAC__seekable_stream_decoder_seek_absolute(decoder, 0);
- return true;
-}
-
-bool ReadFlac::PCM_seek(long bytes) {
-
- if ( bytes < (long) streaminfo.data.stream_info.total_samples ) {
- needs_seek = true;
- //bool ret = FLAC__seekable_stream_decoder_seek_absolute(decoder, bytes);
- //if (ret) {
- //samples_in_reservoir = 0;
- //FLAC__seekable_stream_decoder_flush(decoder);
- //cout << "successfull seeking" << endl;
- //return true;
- // }else {
- //cout << "UNsuccessfull seeking" << endl;
- //return false;
- //}
- seek_sample = bytes;
- return true;
- } else {
- cout << " GOT HERE " << endl;
- return false;
- }
-}
-
-bool ReadFlac::TIME_seek(double seconds) {
-
- //lengthInMsec();
- if ( seconds < lengthinseconds ) {
- //cout << "FLAC: time seek" << endl;
- needs_seek = true;
- seek_sample = (FLAC__uint64)(seconds * streaminfo.data.stream_info.sample_rate);
- return true;
- } else {
-
- return false;
- }
-
-}
-
-
-void ReadFlac::cleanup()
-{
- if(decoder) {
- FLAC__seekable_stream_decoder_finish(decoder);
- FLAC__seekable_stream_decoder_delete(decoder);
- decoder = NULL;
- }
-}
-
-FLAC__SeekableStreamDecoderReadStatus ReadFlac::readCallback_(const FLAC__SeekableStreamDecoder *decoder,
- FLAC__byte buffer[],
- unsigned *bytes,
- void *client_data) {
- ReadFlac *instance = (ReadFlac*)client_data;
- *bytes = instance->in->Read( (char *)buffer, *bytes);
- if (*bytes == 0) {
- cout << "FLAC: read returned 0" << endl;
- return FLAC__SEEKABLE_STREAM_DECODER_READ_STATUS_ERROR;
- } else {
- return FLAC__SEEKABLE_STREAM_DECODER_READ_STATUS_OK;
- }
-}
-
-FLAC__SeekableStreamDecoderSeekStatus ReadFlac::seekCallback_(const FLAC__SeekableStreamDecoder *decoder,
- FLAC__uint64 absolute_byte_offset,
- void *client_data) {
-
- //if (!client_data)
- //return FLAC__SEEKABLE_STREAM_DECODER_SEEK_STATUS_ERROR;
-
- ReadFlac *instance = (ReadFlac*)client_data;
- //if (!instance)
- //return FLAC__SEEKABLE_STREAM_DECODER_SEEK_STATUS_ERROR;
-
- instance->ErrorCheck( FLAC__seekable_stream_decoder_get_state(decoder) );
-
- //if (absolute_byte_offset < 0)
- //absolute_byte_offset = 0;
- long pos = instance->in->SeekSet( (long)absolute_byte_offset ) ;
- if ( pos == -1 ) {
- cout << "COULD NOT seek " << absolute_byte_offset << " bytes" << endl;
- return FLAC__SEEKABLE_STREAM_DECODER_SEEK_STATUS_ERROR;
- } else {
- //cout << "seeked %ld bytes", pos);
- return FLAC__SEEKABLE_STREAM_DECODER_SEEK_STATUS_OK;
- }
-}
-
-
-FLAC__SeekableStreamDecoderTellStatus ReadFlac::tellCallback_(const FLAC__SeekableStreamDecoder *decoder,
- FLAC__uint64 *absolute_byte_offset,
- void *client_data) {
- ReadFlac *instance = (ReadFlac*)client_data;
-
- long pos = instance->in->SeekCur( *absolute_byte_offset );
- if ( pos != -1 ) {
- *absolute_byte_offset = pos;
- //cout << "FLAC: tell is ok" << endl;
- return FLAC__SEEKABLE_STREAM_DECODER_TELL_STATUS_OK;
- } else {
- cout << "FLAC: tell is NOT ok" << endl;
- return FLAC__SEEKABLE_STREAM_DECODER_TELL_STATUS_ERROR;
- }
-}
-
-FLAC__SeekableStreamDecoderLengthStatus ReadFlac::lengthCallback_(const FLAC__SeekableStreamDecoder *decoder,
- FLAC__uint64 *stream_length,
- void *client_data) {
- ReadFlac *instance = (ReadFlac*)client_data;
- *stream_length = (FLAC__uint64)instance->filelength;
- return FLAC__SEEKABLE_STREAM_DECODER_LENGTH_STATUS_OK;
-}
-
-FLAC__bool ReadFlac::eofCallback_(const FLAC__SeekableStreamDecoder *decoder,
- void *client_data) {
- ReadFlac *instance = (ReadFlac*)client_data;
- long pos = instance->in->SeekCur(0);
- if ( pos == instance->filelength ) {
- //instance->in->SeekSet(pos);
- cout << "FLAC: eofCallback: it is EOF" << endl;
- //exit(1);
- return 1;
- } else {
- //post ("FLAC: eofCallback: not eof %ld, filelength %ld", pos, instance->filelength);
- //instance->in->SeekSet(pos);
- return 0;
- }
-}
-
-FLAC__StreamDecoderWriteStatus ReadFlac::writeCallback_(const FLAC__SeekableStreamDecoder *decoder,
- const FLAC__Frame *frame,
- const FLAC__int32 * const buffer[],
- void *client_data) {
- ReadFlac *instance = (ReadFlac*)client_data;
- //const unsigned bps = instance->streaminfo.data.stream_info.bits_per_sample;
- const unsigned channels = instance->streaminfo.data.stream_info.channels;
- const unsigned wide_samples = frame->header.blocksize;
- unsigned wide_sample, sample, channel;
-
- (void)decoder;
-
- if(instance->abort_flag) {
- return FLAC__STREAM_DECODER_WRITE_STATUS_ABORT;
- }
- //cout << "FLAC: blocksize = " << wide_samples << endl;
- for(sample = instance->samples_in_reservoir*channels, wide_sample = 0;
- wide_sample < wide_samples; wide_sample++)
- for(channel = 0; channel < channels; channel++, sample++)
- instance->reservoir[sample] = (FLAC__int16)buffer[channel][wide_sample];
-
- instance->samples_in_reservoir += wide_samples;
-
- return FLAC__STREAM_DECODER_WRITE_STATUS_CONTINUE;
-}
-
-void ReadFlac::metadataCallback_(const FLAC__SeekableStreamDecoder *decoder,
- const FLAC__StreamMetadata *metadata,
- void *client_data) {
- ReadFlac *instance = (ReadFlac*)client_data;
- (void)decoder;
-
- //cout << "FLAC: metadata callback" << endl;
- if(metadata->type == FLAC__METADATA_TYPE_STREAMINFO) {
- instance->streaminfo = *metadata;
-
- if(instance->streaminfo.data.stream_info.bits_per_sample != 16) {
- cout << "\nFLAC: bps is not 16 ..Aboorting ...\n" << endl;
- instance->abort_flag = true;
- //exit(1);
- return;
- }
- }
-}
-
-void ReadFlac::errorCallback_(const FLAC__SeekableStreamDecoder *decoder,
- FLAC__StreamDecoderErrorStatus status,
- void *client_data) {
- ReadFlac *instance = (ReadFlac*)client_data;
- (void)decoder;
- if(status != FLAC__STREAM_DECODER_ERROR_STATUS_LOST_SYNC) {
- cout << "FLAC: error callback - lost sync, trying reset,flush" << endl;
- FLAC__seekable_stream_decoder_reset(instance->decoder);
- FLAC__seekable_stream_decoder_flush(instance->decoder);
- //instance->abort_flag = true;
- }
-}
-
-void ReadFlac::ErrorCheck(int state) {
- switch (state) {
- case FLAC__SEEKABLE_STREAM_DECODER_SEEKING:
- //cout << "SEEKING " << endl;
- break;
- case FLAC__SEEKABLE_STREAM_DECODER_END_OF_STREAM :
- cout << "END_OF_STREAM " << endl;
- break;
- case FLAC__SEEKABLE_STREAM_DECODER_MEMORY_ALLOCATION_ERROR :
- cout << "MEMORY_ALLOCATION_ERROR " << endl;
- break;
- case FLAC__SEEKABLE_STREAM_DECODER_STREAM_DECODER_ERROR :
- cout << "STREAM_DECODER_ERROR " << endl;
- break;
- case FLAC__SEEKABLE_STREAM_DECODER_READ_ERROR :
- cout << "READ_ERROR " << endl;
- break;
- case FLAC__SEEKABLE_STREAM_DECODER_SEEK_ERROR :
- cout << "SEEK_ERROR " << endl;
- break;
- case FLAC__SEEKABLE_STREAM_DECODER_INVALID_CALLBACK :
- cout << "INVALID_CALLBACK " << endl;
- break;
- case FLAC__SEEKABLE_STREAM_DECODER_UNINITIALIZED :
- cout << "UNINITIALIZED " << endl;
- break;
- case FLAC__SEEKABLE_STREAM_DECODER_OK :
- default:
- cout << "OK" << endl;
- break;
- }
-}
-
-
-#endif