bool OAFLACReader::open(const SPtr<DataStream>& stream, AudioFileInfo& info, UINT32 offset)
	{
		if (stream == nullptr)
			return false;

		stream->seek(offset);

		mDecoder = FLAC__stream_decoder_new();
		if (mDecoder == nullptr)
		{
			LOGERR("Failed to open a FLAC file.");
			return false;
		}

		mData.stream = stream;
		mData.streamOffset = offset;
		FLAC__stream_decoder_init_stream(mDecoder, &streamRead, &streamSeek, &streamTell, &streamLength, &streamEof,
			&streamWrite, &streamMetadata, &streamError, &mData);

		if (!FLAC__stream_decoder_process_until_end_of_metadata(mDecoder))
		{
			close();
			LOGERR("Failed to open a FLAC file.");
			return false;
		}

		info = mData.info;

		return true;
	}
Example #2
0
SoundSource::OpenResult SoundSourceFLAC::tryOpen(
        OpenMode /*mode*/,
        const OpenParams& /*config*/) {
    DEBUG_ASSERT(!m_file.isOpen());
    if (!m_file.open(QIODevice::ReadOnly)) {
        kLogger.warning() << "Failed to open FLAC file:" << m_file.fileName();
        return OpenResult::Failed;
    }

    m_decoder = FLAC__stream_decoder_new();
    if (m_decoder == nullptr) {
        kLogger.warning() << "Failed to create FLAC decoder!";
        return OpenResult::Failed;
    }
    FLAC__stream_decoder_set_md5_checking(m_decoder, false);
    const FLAC__StreamDecoderInitStatus initStatus(
            FLAC__stream_decoder_init_stream(m_decoder, FLAC_read_cb,
                    FLAC_seek_cb, FLAC_tell_cb, FLAC_length_cb, FLAC_eof_cb,
                    FLAC_write_cb, FLAC_metadata_cb, FLAC_error_cb, this));
    if (initStatus != FLAC__STREAM_DECODER_INIT_STATUS_OK) {
        kLogger.warning() << "Failed to initialize FLAC decoder:" << initStatus;
        return OpenResult::Failed;
    }
    if (!FLAC__stream_decoder_process_until_end_of_metadata(m_decoder)) {
        kLogger.warning() << "Failed to process FLAC metadata:"
                << FLAC__stream_decoder_get_state(m_decoder);
        return OpenResult::Failed;
    }

    m_curFrameIndex = frameIndexMin();

    return OpenResult::Succeeded;
}
Example #3
0
Result SoundSourceFLAC::tryOpen(const AudioSourceConfig& /*audioSrcCfg*/) {
    DEBUG_ASSERT(!m_file.isOpen());
    if (!m_file.open(QIODevice::ReadOnly)) {
        qWarning() << "Failed to open FLAC file:" << m_file.fileName();
        return ERR;
    }

    m_decoder = FLAC__stream_decoder_new();
    if (m_decoder == NULL) {
        qWarning() << "Failed to create FLAC decoder!";
        return ERR;
    }
    FLAC__stream_decoder_set_md5_checking(m_decoder, FALSE);
    const FLAC__StreamDecoderInitStatus initStatus(
            FLAC__stream_decoder_init_stream(m_decoder, FLAC_read_cb,
                    FLAC_seek_cb, FLAC_tell_cb, FLAC_length_cb, FLAC_eof_cb,
                    FLAC_write_cb, FLAC_metadata_cb, FLAC_error_cb, this));
    if (initStatus != FLAC__STREAM_DECODER_INIT_STATUS_OK) {
        qWarning() << "Failed to initialize FLAC decoder:" << initStatus;
        return ERR;
    }
    if (!FLAC__stream_decoder_process_until_end_of_metadata(m_decoder)) {
        qWarning() << "Failed to process FLAC metadata:"
                << FLAC__stream_decoder_get_state(m_decoder);
        return ERR;
    }

    m_curFrameIndex = getMinFrameIndex();

    return OK;
}
Example #4
0
static gboolean
gst_flac_dec_start (GstAudioDecoder * audio_dec)
{
  FLAC__StreamDecoderInitStatus s;
  GstFlacDec *dec;

  dec = GST_FLAC_DEC (audio_dec);

  dec->adapter = gst_adapter_new ();

  dec->decoder = FLAC__stream_decoder_new ();

  gst_audio_info_init (&dec->info);
  dec->depth = 0;

  /* no point calculating MD5 since it's never checked here */
  FLAC__stream_decoder_set_md5_checking (dec->decoder, false);

  GST_DEBUG_OBJECT (dec, "initializing decoder");
  s = FLAC__stream_decoder_init_stream (dec->decoder,
      gst_flac_dec_read_stream, NULL, NULL, NULL, NULL,
      gst_flac_dec_write_stream, gst_flac_dec_metadata_cb,
      gst_flac_dec_error_cb, dec);

  if (s != FLAC__STREAM_DECODER_INIT_STATUS_OK) {
    GST_ELEMENT_ERROR (GST_ELEMENT (dec), LIBRARY, INIT, (NULL), (NULL));
    return FALSE;
  }

  dec->got_headers = FALSE;

  return TRUE;
}
Example #5
0
bool SoundFileReaderFlac::open(InputStream& stream, Info& info)
{
    // Create the decoder
    m_decoder = FLAC__stream_decoder_new();
    if (!m_decoder)
    {
        err() << "Failed to open FLAC file (failed to allocate the decoder)" << std::endl;
        return false;
    }

    // Initialize the decoder with our callbacks
    m_clientData.stream = &stream;
    FLAC__stream_decoder_init_stream(m_decoder, &streamRead, &streamSeek, &streamTell, &streamLength, &streamEof, &streamWrite, &streamMetadata, &streamError, &m_clientData);

    // Read the header
    if (!FLAC__stream_decoder_process_until_end_of_metadata(m_decoder))
    {
        close();
        err() << "Failed to open FLAC file (failed to read metadata)" << std::endl;
        return false;
    }

    // Retrieve the sound properties
    info = m_clientData.info; // was filled in the "metadata" callback

    // We must keep the channel count for the seek function
    m_channelCount = info.channelCount;

    return true;
}
Example #6
0
FLAC__bool safe_decoder_init_(const char *filename, FLAC__StreamDecoder *decoder)
{
	if(decoder == 0)
		return false;

	safe_decoder_finish_(decoder);

	FLAC__stream_decoder_set_md5_checking(decoder, false);
	FLAC__stream_decoder_set_metadata_ignore_all(decoder);
	FLAC__stream_decoder_set_metadata_respond(decoder, FLAC__METADATA_TYPE_STREAMINFO);
	FLAC__stream_decoder_set_metadata_respond(decoder, FLAC__METADATA_TYPE_VORBIS_COMMENT);
	if(stream_data_.is_http_source) {
		flac_http_open(filename, 0);
		if(FLAC__stream_decoder_init_stream(decoder, http_read_callback_, /*seek_callback=*/0, /*tell_callback=*/0, /*length_callback=*/0, /*eof_callback=*/0, write_callback_, metadata_callback_, error_callback_, /*client_data=*/&stream_data_) != FLAC__STREAM_DECODER_INIT_STATUS_OK)
			return false;
	}
	else {
		if(FLAC__stream_decoder_init_file(decoder, filename, write_callback_, metadata_callback_, error_callback_, /*client_data=*/&stream_data_) != FLAC__STREAM_DECODER_INIT_STATUS_OK)
			return false;
	}

	if(!FLAC__stream_decoder_process_until_end_of_metadata(decoder))
		return false;

	return true;
}
Example #7
0
static FLAC__StreamDecoderInitStatus
stream_init_flac(FLAC__StreamDecoder *flac_dec, struct flac_data *data)
{
	return FLAC__stream_decoder_init_stream(flac_dec,
						flac_read_cb, flac_seek_cb,
						flac_tell_cb, flac_length_cb,
						flac_eof_cb, flac_write_cb,
						flacMetadata,
						flac_error_cb,
						data);
}
Example #8
0
/**
 * Main.
 */
int main(int argc, char *argv[])
{
    FLAC__bool ok = true;
	FLAC__StreamDecoder* decoder = 0;
	FLAC__StreamDecoderInitStatus init_status;

	// init system
	SystemInit();
	RCC_configure();
	GPIO_configure();

    //TODO
    // setup UART, LEDs, SDIO, I2S, etc

    // setup decoder
	if((decoder = FLAC__stream_decoder_new()) == NULL) {
		fprintf(stderr, "ERROR: allocating decoder\n");
		return 1;
	}

    // optional MD5 check. How much cycles does this cost?
	//FLAC__stream_decoder_set_md5_checking(decoder, true);

    // init decoder
    void* client_data = 0;  //TODO
	init_status = FLAC__stream_decoder_init_stream(decoder, 
        read_callback,
        seek_callback,
        tell_callback,
        length_callback,
        eof_callback,
        write_callback, 
        metadata_callback,
        error_callback,
        client_data);
	if (init_status != FLAC__STREAM_DECODER_INIT_STATUS_OK) {
		fprintf(stderr, "ERROR: initializing decoder: %s\n", FLAC__StreamDecoderInitStatusString[init_status]);
		ok = false;
	}

	if (ok) {
		ok = FLAC__stream_decoder_process_until_end_of_stream(decoder);
		fprintf(stderr, "decoding: %s\n", ok? "succeeded" : "FAILED");
		fprintf(stderr, "   state: %s\n", FLAC__StreamDecoderStateString[FLAC__stream_decoder_get_state(decoder)]);
	}

    // loop forever, just handle IRQs
	while(1);
     
    // never called but usefull to know
    //FLAC__stream_decoder_delete(decoder);
    
	return 0;
}
Example #9
0
static void flac_get_size (struct cdtoc *t)
{
	FLAC__StreamDecoder *decoder = FLAC__stream_decoder_new ();
	if (decoder) {
		FLAC__stream_decoder_set_md5_checking (decoder, false);
		int init_status = FLAC__stream_decoder_init_stream (decoder,
			&file_read_callback, &file_seek_callback, &file_tell_callback,
			&file_len_callback, &file_eof_callback,
			&flac_write_callback, &flac_metadata_callback, &flac_error_callback, t);
		FLAC__stream_decoder_process_until_end_of_metadata (decoder);
		FLAC__stream_decoder_delete (decoder);
	}
}
Example #10
0
bool CFlacDec::Open(FILE* in, FLAC__StreamDecoder* vf)
{
	FLAC__StreamDecoderInitStatus rval;

	mIn = in;

	/* we need to use our own functions, because we have */
	/* the netfile layer hooked in here. If we would not */
	/* provide callbacks, the tremor lib and the netfile */
	/* layer would clash and steal each other the data   */
	/* from the stream !                                 */

	/* test the dope ... */
	rval = FLAC__stream_decoder_init_stream(vf,
						flac_read,
						flac_seek,
						flac_tell,
						flac_length,
						flac_eof,
						flac_write,
						flac_metadata,
						flac_error,
						(void *)this);
	/* and tell our friends about the quality of the stuff */
	// initialize the sound device here

	if(rval<0)
	{
		switch(rval)
		{
			/* err_txt from netfile.cpp */
			case FLAC__STREAM_DECODER_INIT_STATUS_OK: 			sprintf(err_txt, "Initialization was successful"); break;
			case FLAC__STREAM_DECODER_INIT_STATUS_UNSUPPORTED_CONTAINER:	sprintf(err_txt, "The library was not compiled with support for the given container format"); break;
			case FLAC__STREAM_DECODER_INIT_STATUS_INVALID_CALLBACKS:	sprintf(err_txt, "A required callback was not supplied"); break;
			case FLAC__STREAM_DECODER_INIT_STATUS_MEMORY_ALLOCATION_ERROR:	sprintf(err_txt, "An error occurred allocating memory"); break;
			case FLAC__STREAM_DECODER_INIT_STATUS_ERROR_OPENING_FILE:	sprintf(err_txt, "fopen() failed in FLAC__stream_decoder_init_file() or FLAC__stream_decoder_init_ogg_file()"); break;
			case FLAC__STREAM_DECODER_INIT_STATUS_ALREADY_INITIALIZED:	sprintf(err_txt, "FLAC__stream_decoder_init_*() was called when the decoder was already initialized, usually because FLAC__stream_decoder_finish() was not called"); break;
			default:							sprintf(err_txt, "unknown error, code: %d", rval);
		}
//		fprintf(stderr,"%s: %s\n", ProgName, err_txt);
		printf("%s: %s\n", ProgName, err_txt);
		return false;
	}

	/* finish the opening and ignite the joint */
//	mSeekable = true;
	mSeekable = false;

	return true;
}
Example #11
0
	FlacReader::FlacReader( MemoryIo* source )
		: m_bitdepth( 0 )
		, m_channels( 0 )
		, m_samplerate( 0 )
		, m_decoder( 0 )
		, m_source( source )
		, m_sourcepos( 0 )
		, m_totalsamples( 0 )
	{
		m_decoder = FLAC__stream_decoder_new();
		if( !m_decoder )
		{
			throw std::runtime_error( "failed to create the flac decoder" );
		}
		FLAC__StreamDecoderInitStatus status = FLAC__stream_decoder_init_stream(
			m_decoder,
			&FlacReader::read_callback,
			&FlacReader::seek_callback,
			&FlacReader::tell_callback,
			&FlacReader::length_callback,
			&FlacReader::eof_callback,
			&FlacReader::write_callback,
			0,
			&FlacReader::error_callback,
			this );
		if( status != FLAC__STREAM_DECODER_INIT_STATUS_OK )
		{
			FLAC__stream_decoder_delete( m_decoder );
			throw std::runtime_error(
				FLAC__StreamDecoderInitStatusString[ status ] );
		}
		if( !FLAC__stream_decoder_process_until_end_of_stream( m_decoder ) )
		{
			FLAC__StreamDecoderState state =
				FLAC__stream_decoder_get_state( m_decoder );
			FLAC__stream_decoder_delete( m_decoder );
			if( m_error )
			{
				throw StrException( m_error );
			}
			else
			{
				throw std::runtime_error(
					FLAC__StreamDecoderStateString[ state ] );
			}
		}
	}
Example #12
0
static uae_u8 *flac_get_data (struct cdtoc *t)
{
	write_log (_T("FLAC: unpacking '%s'..\n"), zfile_getname (t->handle));
	t->writeoffset = 0;
	FLAC__StreamDecoder *decoder = FLAC__stream_decoder_new ();
	if (decoder) {
		FLAC__stream_decoder_set_md5_checking (decoder, false);
		int init_status = FLAC__stream_decoder_init_stream (decoder,
			&file_read_callback, &file_seek_callback, &file_tell_callback,
			&file_len_callback, &file_eof_callback,
			&flac_write_callback, &flac_metadata_callback, &flac_error_callback, t);
		FLAC__stream_decoder_process_until_end_of_stream (decoder);
		FLAC__stream_decoder_delete (decoder);
		write_log (_T("FLAC: %s unpacked\n"), zfile_getname (t->handle));
	}
	return t->data;
}
Example #13
0
// soundsource overrides
Result SoundSourceFLAC::open() {
    if (!m_file.open(QIODevice::ReadOnly)) {
        qWarning() << "SSFLAC: Could not read file!";
        return ERR;
    }

    m_decoder = FLAC__stream_decoder_new();
    if (m_decoder == NULL) {
        qWarning() << "SSFLAC: decoder allocation failed!";
        return ERR;
    }
    FLAC__StreamDecoderInitStatus initStatus(
        FLAC__stream_decoder_init_stream(
            m_decoder, FLAC_read_cb, FLAC_seek_cb, FLAC_tell_cb, FLAC_length_cb,
            FLAC_eof_cb, FLAC_write_cb, FLAC_metadata_cb, FLAC_error_cb,
            (void*) this)
    );
    if (initStatus != FLAC__STREAM_DECODER_INIT_STATUS_OK) {
        qWarning() << "SSFLAC: decoder init failed!";
        goto decoderError;
    }
    if (!FLAC__stream_decoder_process_until_end_of_metadata(m_decoder)) {
        qWarning() << "SSFLAC: process to end of meta failed!";
        qWarning() << "SSFLAC: decoder state: " << FLAC__stream_decoder_get_state(m_decoder);
        goto decoderError;
    } // now number of samples etc. should be populated
    if (m_flacBuffer == NULL) {
        // we want 2 samples per frame, see ::flacWrite code -- bkgood
        m_flacBuffer = new FLAC__int16[m_maxBlocksize * 2 /*m_iChannels*/];
    }
    if (m_leftoverBuffer == NULL) {
        m_leftoverBuffer = new FLAC__int16[m_maxBlocksize * 2 /*m_iChannels*/];
    }
//    qDebug() << "SSFLAC: Total samples: " << m_samples;
//    qDebug() << "SSFLAC: Sampling rate: " << m_iSampleRate << " Hz";
//    qDebug() << "SSFLAC: Channels: " << m_iChannels;
//    qDebug() << "SSFLAC: BPS: " << m_bps;
    return OK;
decoderError:
    FLAC__stream_decoder_finish(m_decoder);
    FLAC__stream_decoder_delete(m_decoder);
    m_decoder = NULL;

    qWarning() << "SSFLAC: Decoder error at file" << m_qFilename;
    return ERR;
}
Example #14
0
void GarlickDecodeFlac(GarlickFile *gf) {
	const char * zz = FLAC__VERSION_STRING;

	//prepare flac
	FLAC__StreamDecoder *decoder = FLAC__stream_decoder_new();
	FLAC__stream_decoder_init_stream(decoder, GarlickDecodeFlac_Read, 0, 0, 0, 0, GarlickDecodeFlac_Write, GarlickDecodeFlac_Metadata, GarickDecodeFlac_Error, (void*)gf);

	//read the size of the flac stream
	Garlick_cb_read(&gf->flac_in_counter,1,4,gf->lib);
	//prep the output buffer
	GarlickEnsureBuffer(gf, gf->chunkleft);
	gf->buf_counter = 0;

	//decode and finish
	FLAC__stream_decoder_process_until_end_of_stream(decoder);
	FLAC__stream_decoder_finish(decoder);
	FLAC__stream_decoder_delete(decoder);
	printf("%d - %d - %d\n",gf->encode_mode, gf->buf_counter,gf->chunkleft);
	gf->buf_counter = 0;
}
	bool OAFLACReader::isValid(const SPtr<DataStream>& stream, UINT32 offset)
	{
		stream->seek(offset);

		FLAC__StreamDecoder* decoder = FLAC__stream_decoder_new();
		if (!decoder)
			return false;

		FLACDecoderData data;
		data.stream = stream;
		mData.streamOffset = offset;
		FLAC__stream_decoder_init_stream(decoder, &streamRead, &streamSeek, &streamTell, &streamLength, &streamEof, 
			&streamWrite, nullptr, &streamError, &data);

		bool valid = FLAC__stream_decoder_process_until_end_of_metadata(decoder) != 0;

		FLAC__stream_decoder_finish(decoder);
		FLAC__stream_decoder_delete(decoder);

		return valid && !data.error;
	}
Example #16
0
clFLACDataProvider::clFLACDataProvider( const std::shared_ptr<clBlob>& Data )
: m_Data( Data )
, m_Format()
, m_StreamData( std::make_shared<sFLACStreamData>() )
, m_DecodingBuffer()
, m_BufferUsed( 0 )
, m_IsEndOfStream( false )
{
	{
		FLAC__StreamDecoderInitStatus Status = FLAC__stream_decoder_init_stream(
			m_StreamData->m_Decoder,
			&flacRead,
			&flacSeek,
			&flacTell,
			&flacLength,
			&flacEof,
			&flacWrite,
			&flacMeta,
			&flacError,
			this
		);
	}

	FLAC__bool Status = FLAC__stream_decoder_process_until_end_of_metadata( m_StreamData->m_Decoder );

	if ( !Status ) return;

	if ( !FLAC__stream_decoder_process_single( m_StreamData->m_Decoder ) ) return;

	m_Format.m_NumChannels = FLAC__stream_decoder_get_channels( m_StreamData->m_Decoder );
	m_Format.m_SamplesPerSecond = FLAC__stream_decoder_get_sample_rate( m_StreamData->m_Decoder );
	m_Format.m_BitsPerSample = FLAC__stream_decoder_get_bits_per_sample( m_StreamData->m_Decoder );

	int BufSize = FLAC__stream_decoder_get_blocksize( m_StreamData->m_Decoder ) * m_Format.m_BitsPerSample * 8 * m_Format.m_NumChannels;

	// store two blocks
	m_DecodingBuffer.resize( BufSize * 2 );

	int TotalSamples = FLAC__stream_decoder_get_total_samples( m_StreamData->m_Decoder );
}
Example #17
0
bool SoundFileReaderFlac::check(InputStream& stream)
{
    // Create a decoder
    FLAC__StreamDecoder* decoder = FLAC__stream_decoder_new();
    if (!decoder)
        return false;

    // Initialize the decoder with our callbacks
    ClientData data;
    data.stream = &stream;
    data.error = false;
    FLAC__stream_decoder_init_stream(decoder, &streamRead, &streamSeek, &streamTell, &streamLength, &streamEof, &streamWrite, NULL, &streamError, &data);

    // Read the header
    bool valid = FLAC__stream_decoder_process_until_end_of_metadata(decoder) != 0;

    // Destroy the decoder
    FLAC__stream_decoder_finish(decoder);
    FLAC__stream_decoder_delete(decoder);

    return valid && !data.error;
}
Example #18
0
flac_header_extractor_c::flac_header_extractor_c(const std::string &file_name,
                                                 int64_t p_sid,
                                                 oggflac_mode_e p_mode)
  : metadata_parsed(false)
  , sid(p_sid)
  , num_packets(0)
  , num_header_packets(0)
  , done(false)
  , mode(p_mode)
{
  file    = new mm_file_io_c(file_name);
  decoder = FLAC__stream_decoder_new();

  if (!decoder)
    mxerror(Y("flac_header_extraction: FLAC__stream_decoder_new() failed.\n"));
  if (!FLAC__stream_decoder_set_metadata_respond_all(decoder))
    mxerror(Y("flac_header_extraction: Could not set metadata_respond_all.\n"));
  if (FLAC__stream_decoder_init_stream(decoder, fhe_read_cb, nullptr, nullptr, nullptr, nullptr, fhe_write_cb, fhe_metadata_cb, fhe_error_cb, this) != FLAC__STREAM_DECODER_INIT_STATUS_OK)
    mxerror(Y("flac_header_extraction: Could not initialize the FLAC decoder.\n"));

  ogg_sync_init(&oy);
}
Example #19
0
static int audiosourceflac_InitFLAC(struct audiosource* source) {
    struct audiosourceflac_internaldata* idata =
            source->internaldata;

    // open up FLAC decoder:
    idata->decoder = FLAC__stream_decoder_new();
    if (!idata->decoder) {
        return 0;
    }

    idata->flacopened = 1;

    // initialise decoder:
    if (FLAC__stream_decoder_init_stream(idata->decoder,
                                         flacread,
                                         flacseek,
                                         flactell,
                                         flaclength,
                                         flaceof,
                                         flacwrite,
                                         flacmetadata,
                                         flacerror,
                                         source
                                        ) != FLAC__STREAM_DECODER_INIT_STATUS_OK) {
        return 0;
    }
    // run decoder up to first audio frame:
    while (idata->decodedbytes == 0) {
        FLAC__bool b;
        if ((b = FLAC__stream_decoder_process_single(idata->decoder)) == false
                || FLAC__stream_decoder_get_state(idata->decoder) ==
                FLAC__STREAM_DECODER_END_OF_STREAM) {
            return 0;
        }
    }

    // we should have some information now
    return 1;
}
Example #20
0
static bool_t flac_init (void)
{
    FLAC__StreamDecoderInitStatus ret;

    /* Callback structure and decoder for main decoding loop */

    if ((info = init_callback_info()) == NULL)
    {
        FLACNG_ERROR("Could not initialize the main callback structure!\n");
        return FALSE;
    }

    if ((decoder = FLAC__stream_decoder_new()) == NULL)
    {
        FLACNG_ERROR("Could not create the main FLAC decoder instance!\n");
        return FALSE;
    }

    if (FLAC__STREAM_DECODER_INIT_STATUS_OK != (ret = FLAC__stream_decoder_init_stream(
        decoder,
        read_callback,
        seek_callback,
        tell_callback,
        length_callback,
        eof_callback,
        write_callback,
        metadata_callback,
        error_callback,
        info)))
    {
        FLACNG_ERROR("Could not initialize the main FLAC decoder: %s(%d)\n",
            FLAC__StreamDecoderInitStatusString[ret], ret);
        return FALSE;
    }

    AUDDBG("Plugin initialized.\n");
    return TRUE;
}
Example #21
0
bool FlacDecoder::Open(musik::core::sdk::IDataStream *stream){
    this->stream = stream;

	FLAC__StreamDecoderInitStatus init_status =
        FLAC__stream_decoder_init_stream(
            this->decoder,
            FlacDecoder::FlacRead,
            FlacDecoder::FlacSeek,
            FlacDecoder::FlacTell,
            FlacDecoder::FlacFileSize,
            FlacDecoder::FlacEof,
            FlacDecoder::FlacWrite,
            FlacDecoder::FlacMetadata,
            FlacDecoder::FlacError,
            this);

    if (init_status == FLAC__STREAM_DECODER_INIT_STATUS_OK) {
        FLAC__stream_decoder_process_until_end_of_metadata(this->decoder);
        return true;
    }

    return false;
}
status_t FLACParser::init()
{
    // setup libFLAC parser
    mDecoder = FLAC__stream_decoder_new();
    if (mDecoder == NULL) {
        // The new should succeed, since probably all it does is a malloc
        // that always succeeds in Android.  But to avoid dependence on the
        // libFLAC internals, we check and log here.
        LOGE("new failed");
        return NO_INIT;
    }
    FLAC__stream_decoder_set_md5_checking(mDecoder, false);
    FLAC__stream_decoder_set_metadata_ignore_all(mDecoder);
    FLAC__stream_decoder_set_metadata_respond(
            mDecoder, FLAC__METADATA_TYPE_STREAMINFO);
    FLAC__stream_decoder_set_metadata_respond(
            mDecoder, FLAC__METADATA_TYPE_PICTURE);
    FLAC__stream_decoder_set_metadata_respond(
            mDecoder, FLAC__METADATA_TYPE_VORBIS_COMMENT);
    FLAC__StreamDecoderInitStatus initStatus;
    initStatus = FLAC__stream_decoder_init_stream(
            mDecoder,
            read_callback, seek_callback, tell_callback,
            length_callback, eof_callback, write_callback,
            metadata_callback, error_callback, (void *) this);
    if (initStatus != FLAC__STREAM_DECODER_INIT_STATUS_OK) {
        // A failure here probably indicates a programming error and so is
        // unlikely to happen. But we check and log here similarly to above.
        LOGE("init_stream failed %d", initStatus);
        return NO_INIT;
    }
    // parse all metadata
    if (!FLAC__stream_decoder_process_until_end_of_metadata(mDecoder)) {
        LOGE("end_of_metadata failed");
        return NO_INIT;
    }
    if (mStreamInfoValid) {
        // check channel count
        switch (getChannels()) {
        case 1:
        case 2:
            break;
        default:
            LOGE("unsupported channel count %u", getChannels());
            return NO_INIT;
        }
        // check bit depth
        switch (getBitsPerSample()) {
        case 8:
        case 16:
        case 24:
            break;
        default:
            LOGE("unsupported bits per sample %u", getBitsPerSample());
            return NO_INIT;
        }
        // check sample rate
        switch (getSampleRate()) {
        case  8000:
        case 11025:
        case 12000:
        case 16000:
        case 22050:
        case 24000:
        case 32000:
        case 44100:
        case 48000:
            break;
        default:
            // 96000 would require a proper downsampler in AudioFlinger
            LOGE("unsupported sample rate %u", getSampleRate());
            return NO_INIT;
        }
        // configure the appropriate copy function, defaulting to trespass
        static const struct {
            unsigned mChannels;
            unsigned mBitsPerSample;
            void (*mCopy)(short *dst, const int *const *src, unsigned nSamples);
        } table[] = {
            { 1,  8, copyMono8    },
            { 2,  8, copyStereo8  },
            { 1, 16, copyMono16   },
            { 2, 16, copyStereo16 },
            { 1, 24, copyMono24   },
            { 2, 24, copyStereo24 },
        };
        for (unsigned i = 0; i < sizeof(table)/sizeof(table[0]); ++i) {
            if (table[i].mChannels == getChannels() &&
                    table[i].mBitsPerSample == getBitsPerSample()) {
                mCopy = table[i].mCopy;
                break;
            }
        }
        // populate track metadata
        if (mTrackMetadata != 0) {
            mTrackMetadata->setCString(kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_RAW);
            mTrackMetadata->setInt32(kKeyChannelCount, getChannels());
            mTrackMetadata->setInt32(kKeySampleRate, getSampleRate());
            // sample rate is non-zero, so division by zero not possible
            mTrackMetadata->setInt64(kKeyDuration,
                    (getTotalSamples() * 1000000LL) / getSampleRate());
        }
    } else {
        LOGE("missing STREAMINFO");
        return NO_INIT;
    }
    if (mFileMetadata != 0) {
        mFileMetadata->setCString(kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_FLAC);
    }
    return OK;
}
Example #23
0
static FLAC__bool test_stream_decoder(Layer layer, FLAC__bool is_ogg)
{
	FLAC__StreamDecoder *decoder;
	FLAC__StreamDecoderInitStatus init_status;
	FLAC__StreamDecoderState state;
	StreamDecoderClientData decoder_client_data;
	FLAC__bool expect;

	decoder_client_data.layer = layer;

	printf("\n+++ libFLAC unit test: FLAC__StreamDecoder (layer: %s, format: %s)\n\n", LayerString[layer], is_ogg? "Ogg FLAC" : "FLAC");

	printf("testing FLAC__stream_decoder_new()... ");
	decoder = FLAC__stream_decoder_new();
	if(0 == decoder) {
		printf("FAILED, returned NULL\n");
		return false;
	}
	printf("OK\n");

	printf("testing FLAC__stream_decoder_delete()... ");
	FLAC__stream_decoder_delete(decoder);
	printf("OK\n");

	printf("testing FLAC__stream_decoder_new()... ");
	decoder = FLAC__stream_decoder_new();
	if(0 == decoder) {
		printf("FAILED, returned NULL\n");
		return false;
	}
	printf("OK\n");

	switch(layer) {
		case LAYER_STREAM:
		case LAYER_SEEKABLE_STREAM:
			printf("testing FLAC__stream_decoder_init_%sstream()... ", is_ogg? "ogg_":"");
			init_status = is_ogg?
				FLAC__stream_decoder_init_ogg_stream(decoder, 0, 0, 0, 0, 0, 0, 0, 0, 0) :
				FLAC__stream_decoder_init_stream(decoder, 0, 0, 0, 0, 0, 0, 0, 0, 0);
			break;
		case LAYER_FILE:
			printf("testing FLAC__stream_decoder_init_%sFILE()... ", is_ogg? "ogg_":"");
			init_status = is_ogg?
				FLAC__stream_decoder_init_ogg_FILE(decoder, stdin, 0, 0, 0, 0) :
				FLAC__stream_decoder_init_FILE(decoder, stdin, 0, 0, 0, 0);
			break;
		case LAYER_FILENAME:
			printf("testing FLAC__stream_decoder_init_%sfile()... ", is_ogg? "ogg_":"");
			init_status = is_ogg?
				FLAC__stream_decoder_init_ogg_file(decoder, flacfilename(is_ogg), 0, 0, 0, 0) :
				FLAC__stream_decoder_init_file(decoder, flacfilename(is_ogg), 0, 0, 0, 0);
			break;
		default:
			die_("internal error 003");
			return false;
	}
	if(init_status != FLAC__STREAM_DECODER_INIT_STATUS_INVALID_CALLBACKS)
		return die_s_(0, decoder);
	printf("OK\n");

	printf("testing FLAC__stream_decoder_delete()... ");
	FLAC__stream_decoder_delete(decoder);
	printf("OK\n");

	num_expected_ = 0;
	expected_metadata_sequence_[num_expected_++] = &streaminfo_;

	printf("testing FLAC__stream_decoder_new()... ");
	decoder = FLAC__stream_decoder_new();
	if(0 == decoder) {
		printf("FAILED, returned NULL\n");
		return false;
	}
	printf("OK\n");

	if(is_ogg) {
		printf("testing FLAC__stream_decoder_set_ogg_serial_number()... ");
		if(!FLAC__stream_decoder_set_ogg_serial_number(decoder, file_utils__ogg_serial_number))
			return die_s_("returned false", decoder);
		printf("OK\n");
	}

	printf("testing FLAC__stream_decoder_set_md5_checking()... ");
	if(!FLAC__stream_decoder_set_md5_checking(decoder, true))
		return die_s_("returned false", decoder);
	printf("OK\n");

	if(layer < LAYER_FILENAME) {
		printf("opening %sFLAC file... ", is_ogg? "Ogg ":"");
		decoder_client_data.file = fopen(flacfilename(is_ogg), "rb");
		if(0 == decoder_client_data.file) {
			printf("ERROR (%s)\n", strerror(errno));
			return false;
		}
		printf("OK\n");
	}

	switch(layer) {
		case LAYER_STREAM:
			printf("testing FLAC__stream_decoder_init_%sstream()... ", is_ogg? "ogg_":"");
			init_status = is_ogg?
				FLAC__stream_decoder_init_ogg_stream(decoder, stream_decoder_read_callback_, /*seek_callback=*/0, /*tell_callback=*/0, /*length_callback=*/0, /*eof_callback=*/0, stream_decoder_write_callback_, stream_decoder_metadata_callback_, stream_decoder_error_callback_, &decoder_client_data) :
				FLAC__stream_decoder_init_stream(decoder, stream_decoder_read_callback_, /*seek_callback=*/0, /*tell_callback=*/0, /*length_callback=*/0, /*eof_callback=*/0, stream_decoder_write_callback_, stream_decoder_metadata_callback_, stream_decoder_error_callback_, &decoder_client_data);
			break;
		case LAYER_SEEKABLE_STREAM:
			printf("testing FLAC__stream_decoder_init_%sstream()... ", is_ogg? "ogg_":"");
			init_status = is_ogg?
				FLAC__stream_decoder_init_ogg_stream(decoder, stream_decoder_read_callback_, stream_decoder_seek_callback_, stream_decoder_tell_callback_, stream_decoder_length_callback_, stream_decoder_eof_callback_, stream_decoder_write_callback_, stream_decoder_metadata_callback_, stream_decoder_error_callback_, &decoder_client_data) :
				FLAC__stream_decoder_init_stream(decoder, stream_decoder_read_callback_, stream_decoder_seek_callback_, stream_decoder_tell_callback_, stream_decoder_length_callback_, stream_decoder_eof_callback_, stream_decoder_write_callback_, stream_decoder_metadata_callback_, stream_decoder_error_callback_, &decoder_client_data);
			break;
		case LAYER_FILE:
			printf("testing FLAC__stream_decoder_init_%sFILE()... ", is_ogg? "ogg_":"");
			init_status = is_ogg?
				FLAC__stream_decoder_init_ogg_FILE(decoder, decoder_client_data.file, stream_decoder_write_callback_, stream_decoder_metadata_callback_, stream_decoder_error_callback_, &decoder_client_data) :
				FLAC__stream_decoder_init_FILE(decoder, decoder_client_data.file, stream_decoder_write_callback_, stream_decoder_metadata_callback_, stream_decoder_error_callback_, &decoder_client_data);
			break;
		case LAYER_FILENAME:
			printf("testing FLAC__stream_decoder_init_%sfile()... ", is_ogg? "ogg_":"");
			init_status = is_ogg?
				FLAC__stream_decoder_init_ogg_file(decoder, flacfilename(is_ogg), stream_decoder_write_callback_, stream_decoder_metadata_callback_, stream_decoder_error_callback_, &decoder_client_data) :
				FLAC__stream_decoder_init_file(decoder, flacfilename(is_ogg), stream_decoder_write_callback_, stream_decoder_metadata_callback_, stream_decoder_error_callback_, &decoder_client_data);
			break;
		default:
			die_("internal error 009");
			return false;
	}
	if(init_status != FLAC__STREAM_DECODER_INIT_STATUS_OK)
		return die_s_(0, decoder);
	printf("OK\n");

	printf("testing FLAC__stream_decoder_get_state()... ");
	state = FLAC__stream_decoder_get_state(decoder);
	printf("returned state = %u (%s)... OK\n", state, FLAC__StreamDecoderStateString[state]);

	decoder_client_data.current_metadata_number = 0;
	decoder_client_data.ignore_errors = false;
	decoder_client_data.error_occurred = false;

	printf("testing FLAC__stream_decoder_get_md5_checking()... ");
	if(!FLAC__stream_decoder_get_md5_checking(decoder)) {
		printf("FAILED, returned false, expected true\n");
		return false;
	}
	printf("OK\n");

	printf("testing FLAC__stream_decoder_process_until_end_of_metadata()... ");
	if(!FLAC__stream_decoder_process_until_end_of_metadata(decoder))
		return die_s_("returned false", decoder);
	printf("OK\n");

	printf("testing FLAC__stream_decoder_process_single()... ");
	if(!FLAC__stream_decoder_process_single(decoder))
		return die_s_("returned false", decoder);
	printf("OK\n");

	printf("testing FLAC__stream_decoder_skip_single_frame()... ");
	if(!FLAC__stream_decoder_skip_single_frame(decoder))
		return die_s_("returned false", decoder);
	printf("OK\n");

	if(layer < LAYER_FILE) {
		printf("testing FLAC__stream_decoder_flush()... ");
		if(!FLAC__stream_decoder_flush(decoder))
			return die_s_("returned false", decoder);
		printf("OK\n");

		decoder_client_data.ignore_errors = true;
		printf("testing FLAC__stream_decoder_process_single()... ");
		if(!FLAC__stream_decoder_process_single(decoder))
			return die_s_("returned false", decoder);
		printf("OK\n");
		decoder_client_data.ignore_errors = false;
	}

	expect = (layer != LAYER_STREAM);
	printf("testing FLAC__stream_decoder_seek_absolute()... ");
	if(FLAC__stream_decoder_seek_absolute(decoder, 0) != expect)
		return die_s_(expect? "returned false" : "returned true", decoder);
	printf("OK\n");

	printf("testing FLAC__stream_decoder_process_until_end_of_stream()... ");
	if(!FLAC__stream_decoder_process_until_end_of_stream(decoder))
		return die_s_("returned false", decoder);
	printf("OK\n");

	expect = (layer != LAYER_STREAM);
	printf("testing FLAC__stream_decoder_seek_absolute()... ");
	if(FLAC__stream_decoder_seek_absolute(decoder, 0) != expect)
		return die_s_(expect? "returned false" : "returned true", decoder);
	printf("OK\n");

	printf("testing FLAC__stream_decoder_get_channels()... ");
	{
		unsigned channels = FLAC__stream_decoder_get_channels(decoder);
		if(channels != streaminfo_.data.stream_info.channels) {
			printf("FAILED, returned %u, expected %u\n", channels, streaminfo_.data.stream_info.channels);
			return false;
		}
	}
	printf("OK\n");

	printf("testing FLAC__stream_decoder_get_bits_per_sample()... ");
	{
		unsigned bits_per_sample = FLAC__stream_decoder_get_bits_per_sample(decoder);
		if(bits_per_sample != streaminfo_.data.stream_info.bits_per_sample) {
			printf("FAILED, returned %u, expected %u\n", bits_per_sample, streaminfo_.data.stream_info.bits_per_sample);
			return false;
		}
	}
	printf("OK\n");

	printf("testing FLAC__stream_decoder_get_sample_rate()... ");
	{
		unsigned sample_rate = FLAC__stream_decoder_get_sample_rate(decoder);
		if(sample_rate != streaminfo_.data.stream_info.sample_rate) {
			printf("FAILED, returned %u, expected %u\n", sample_rate, streaminfo_.data.stream_info.sample_rate);
			return false;
		}
	}
	printf("OK\n");

	printf("testing FLAC__stream_decoder_get_blocksize()... ");
	{
		unsigned blocksize = FLAC__stream_decoder_get_blocksize(decoder);
		/* value could be anything since we're at the last block, so accept any reasonable answer */
		printf("returned %u... %s\n", blocksize, blocksize>0? "OK" : "FAILED");
		if(blocksize == 0)
			return false;
	}

	printf("testing FLAC__stream_decoder_get_channel_assignment()... ");
	{
		FLAC__ChannelAssignment ca = FLAC__stream_decoder_get_channel_assignment(decoder);
		printf("returned %u (%s)... OK\n", (unsigned)ca, FLAC__ChannelAssignmentString[ca]);
	}

	if(layer < LAYER_FILE) {
		printf("testing FLAC__stream_decoder_reset()... ");
		if(!FLAC__stream_decoder_reset(decoder)) {
			state = FLAC__stream_decoder_get_state(decoder);
			printf("FAILED, returned false, state = %u (%s)\n", state, FLAC__StreamDecoderStateString[state]);
			return false;
		}
		printf("OK\n");

		if(layer == LAYER_STREAM) {
			/* after a reset() we have to rewind the input ourselves */
			printf("rewinding input... ");
			if(fseeko(decoder_client_data.file, 0, SEEK_SET) < 0) {
				printf("FAILED, errno = %d\n", errno);
				return false;
			}
			printf("OK\n");
		}

		decoder_client_data.current_metadata_number = 0;

		printf("testing FLAC__stream_decoder_process_until_end_of_stream()... ");
		if(!FLAC__stream_decoder_process_until_end_of_stream(decoder))
			return die_s_("returned false", decoder);
		printf("OK\n");
	}

	printf("testing FLAC__stream_decoder_finish()... ");
	if(!FLAC__stream_decoder_finish(decoder))
		return die_s_("returned false", decoder);
	printf("OK\n");

	/*
	 * respond all
	 */

	printf("testing FLAC__stream_decoder_set_metadata_respond_all()... ");
	if(!FLAC__stream_decoder_set_metadata_respond_all(decoder))
		return die_s_("returned false", decoder);
	printf("OK\n");

	num_expected_ = 0;
	if(is_ogg) { /* encoder moves vorbis comment after streaminfo according to ogg mapping */
		expected_metadata_sequence_[num_expected_++] = &streaminfo_;
		expected_metadata_sequence_[num_expected_++] = &vorbiscomment_;
		expected_metadata_sequence_[num_expected_++] = &padding_;
		expected_metadata_sequence_[num_expected_++] = &seektable_;
		expected_metadata_sequence_[num_expected
Example #24
0
static gboolean
xmms_flac_init (xmms_xform_t *xform)
{
	xmms_flac_data_t *data;
	xmms_sample_format_t sample_fmt;
	FLAC__bool retval;
#if !defined(FLAC_API_VERSION_CURRENT) || FLAC_API_VERSION_CURRENT <= 7
	FLAC__StreamDecoderState init_status;
#else
	FLAC__StreamDecoderInitStatus init_status;
#endif
	gint filesize;
	const gchar *metakey;

	g_return_val_if_fail (xform, FALSE);

	data = g_new0 (xmms_flac_data_t, 1);

	xmms_xform_private_data_set (xform, data);

	data->flacdecoder = FLAC__stream_decoder_new ();

	/* we don't need to explicitly tell the decoder to respond to
	 * FLAC__METADATA_TYPE_STREAMINFO here, it always does.
	 */
#if !defined(FLAC_API_VERSION_CURRENT) || FLAC_API_VERSION_CURRENT <= 7
	FLAC__seekable_stream_decoder_set_metadata_respond (data->flacdecoder,
	                                                    FLAC__METADATA_TYPE_VORBIS_COMMENT);
	FLAC__seekable_stream_decoder_set_eof_callback (data->flacdecoder,
	                                                flac_callback_eof);
	FLAC__seekable_stream_decoder_set_read_callback (data->flacdecoder,
	                                                 flac_callback_read);
	FLAC__seekable_stream_decoder_set_seek_callback (data->flacdecoder,
	                                                 flac_callback_seek);
	FLAC__seekable_stream_decoder_set_tell_callback (data->flacdecoder,
	                                                 flac_callback_tell);
	FLAC__seekable_stream_decoder_set_write_callback (data->flacdecoder,
	                                                  flac_callback_write);
	FLAC__seekable_stream_decoder_set_error_callback (data->flacdecoder,
	                                                  flac_callback_error);
	FLAC__seekable_stream_decoder_set_length_callback (data->flacdecoder,
	                                                   flac_callback_length);
	FLAC__seekable_stream_decoder_set_metadata_callback (data->flacdecoder,
	                                                     flac_callback_metadata);

	FLAC__seekable_stream_decoder_set_client_data (data->flacdecoder, xform);

	init_status = FLAC__seekable_stream_decoder_init (data->flacdecoder);

	if (init_status != FLAC__SEEKABLE_STREAM_DECODER_OK) {
		const gchar *errmsg = FLAC__seekable_stream_decoder_get_resolved_state_string (data->flacdecoder);
		XMMS_DBG ("FLAC init failed: %s", errmsg);
		goto err;
	}
#else
	FLAC__stream_decoder_set_metadata_respond (data->flacdecoder,
	                                           FLAC__METADATA_TYPE_VORBIS_COMMENT);
	FLAC__stream_decoder_set_metadata_respond (data->flacdecoder,
	                                           FLAC__METADATA_TYPE_PICTURE);

	init_status =
		FLAC__stream_decoder_init_stream (data->flacdecoder,
		                                  flac_callback_read,
		                                  flac_callback_seek,
		                                  flac_callback_tell,
		                                  flac_callback_length,
		                                  flac_callback_eof,
		                                  flac_callback_write,
		                                  flac_callback_metadata,
		                                  flac_callback_error,
		                                  xform);

	if (init_status != FLAC__STREAM_DECODER_INIT_STATUS_OK) {
		XMMS_DBG ("FLAC init failed: %s",
		          FLAC__stream_decoder_get_resolved_state_string (data->flacdecoder));
		goto err;
	}
#endif

	retval = FLAC__stream_decoder_process_until_end_of_metadata (data->flacdecoder);
	if (!retval)
		goto err;

	if (data->vorbiscomment) {
		handle_comments (xform, data);
	}

	metakey = XMMS_MEDIALIB_ENTRY_PROPERTY_BITRATE;
	xmms_xform_metadata_set_int (xform, metakey, (gint) data->bit_rate);

	metakey = XMMS_MEDIALIB_ENTRY_PROPERTY_SIZE;
	if (xmms_xform_metadata_get_int (xform, metakey, &filesize)) {
		gint32 val = (gint32) data->total_samples / data->sample_rate * 1000;

		metakey = XMMS_MEDIALIB_ENTRY_PROPERTY_DURATION;
		xmms_xform_metadata_set_int (xform, metakey, val);
	}

	if (data->bits_per_sample == 8) {
		sample_fmt = XMMS_SAMPLE_FORMAT_S8;
	} else if (data->bits_per_sample == 16) {
		sample_fmt = XMMS_SAMPLE_FORMAT_S16;
	} else if (data->bits_per_sample == 24) {
		sample_fmt = XMMS_SAMPLE_FORMAT_S32;
	} else if (data->bits_per_sample == 32) {
		sample_fmt = XMMS_SAMPLE_FORMAT_S32;
	} else {
		goto err;
	}

	xmms_xform_outdata_type_add (xform,
	                             XMMS_STREAM_TYPE_MIMETYPE,
	                             "audio/pcm",
	                             XMMS_STREAM_TYPE_FMT_FORMAT,
	                             sample_fmt,
	                             XMMS_STREAM_TYPE_FMT_CHANNELS,
	                             data->channels,
	                             XMMS_STREAM_TYPE_FMT_SAMPLERATE,
	                             data->sample_rate,
	                             XMMS_STREAM_TYPE_END);

	data->buffer = g_string_new (NULL);

	return TRUE;

err:

	FLAC__stream_decoder_finish (data->flacdecoder);
	FLAC__stream_decoder_delete (data->flacdecoder);
	g_free (data);
	xmms_xform_private_data_set (xform, NULL);

	return FALSE;

}
Example #25
0
bool
FLACInputStream::initialize(FilePtr file) {
    m_file = file;

    // initialize the decoder
    m_decoder = FLAC__stream_decoder_new();
    if (!m_decoder) {
        m_file = 0;
        return false;
    }

    // initialize the stream decoder!
    FLAC__StreamDecoderInitStatus state = FLAC__stream_decoder_init_stream(
            m_decoder,
            read_callback,
            seek_callback,
            tell_callback,
            length_callback,
            eof_callback,
            write_callback,
            metadata_callback,
            error_callback,
            this);
    if (state != FLAC__STREAM_DECODER_INIT_STATUS_OK) {
        FLAC__stream_decoder_finish(m_decoder);
        FLAC__stream_decoder_delete(m_decoder);
        m_decoder = 0;
        m_file = 0;
        return false;
    }

    // make sure we have metadata before we return!
    if (!FLAC__stream_decoder_process_until_end_of_metadata(m_decoder)) {
        FLAC__stream_decoder_finish(m_decoder);
        FLAC__stream_decoder_delete(m_decoder);
        m_decoder = 0;
        m_file = 0;
        return false;
    }

    // process one frame so we can do something!
    if (!FLAC__stream_decoder_process_single(m_decoder)) {
        FLAC__stream_decoder_finish(m_decoder);
        FLAC__stream_decoder_delete(m_decoder);
        m_decoder = 0;
        m_file = 0;
        return false;
    }

    // get info about the flac file
    m_channel_count = FLAC__stream_decoder_get_channels(m_decoder);
    m_sample_rate   = FLAC__stream_decoder_get_sample_rate(m_decoder);
    int bps         = FLAC__stream_decoder_get_bits_per_sample(m_decoder);
    if (bps == 16) {
        m_sample_format = SF_S16;
    } else if (bps == 8) {
        m_sample_format = SF_U8;
    } else {
        return false;
    }

    return true;
}
Example #26
0
static void
flac_decode_internal(struct decoder * decoder,
		     struct input_stream *input_stream,
		     bool is_ogg)
{
	FLAC__StreamDecoder *flac_dec;
	struct flac_data data;
	const char *err = NULL;

	flac_dec = flac_decoder_new();
	if (flac_dec == NULL)
		return;

	flac_data_init(&data, decoder, input_stream);
	data.tag = tag_new();

	if (is_ogg) {
#if defined(FLAC_API_VERSION_CURRENT) && FLAC_API_VERSION_CURRENT > 7
		FLAC__StreamDecoderInitStatus status =
			FLAC__stream_decoder_init_ogg_stream(flac_dec,
							     flac_read_cb,
							     flac_seek_cb,
							     flac_tell_cb,
							     flac_length_cb,
							     flac_eof_cb,
							     flac_write_cb,
							     flacMetadata,
							     flac_error_cb,
							     (void *)&data);
		if (status != FLAC__STREAM_DECODER_INIT_STATUS_OK) {
			err = "doing Ogg init()";
			goto fail;
		}
#else
		goto fail;
#endif
	} else {
		FLAC__StreamDecoderInitStatus status =
			FLAC__stream_decoder_init_stream(flac_dec,
							 flac_read_cb,
							 flac_seek_cb,
							 flac_tell_cb,
							 flac_length_cb,
							 flac_eof_cb,
							 flac_write_cb,
							 flacMetadata,
							 flac_error_cb,
							 (void *)&data);
		if (status != FLAC__STREAM_DECODER_INIT_STATUS_OK) {
			err = "doing init()";
			goto fail;
		}
	}

	if (!flac_decoder_initialize(&data, flac_dec, 0)) {
		flac_data_deinit(&data);
		FLAC__stream_decoder_delete(flac_dec);
		return;
	}

	flac_decoder_loop(&data, flac_dec, 0, 0);

fail:
	flac_data_deinit(&data);
	FLAC__stream_decoder_delete(flac_dec);

	if (err)
		g_warning("%s\n", err);
}
Example #27
0
static FLAC__bool stream_decoder_test_respond_(FLAC__StreamDecoder *decoder, StreamDecoderClientData *dcd, FLAC__bool is_ogg)
{
	FLAC__StreamDecoderInitStatus init_status;

	if(!FLAC__stream_decoder_set_md5_checking(decoder, true))
		return die_s_("at FLAC__stream_decoder_set_md5_checking(), returned false", decoder);

	/* for FLAC__stream_encoder_init_FILE(), the FLAC__stream_encoder_finish() closes the file so we have to keep re-opening: */
	if(dcd->layer == LAYER_FILE) {
		printf("opening %sFLAC file... ", is_ogg? "Ogg ":"");
		dcd->file = fopen(flacfilename(is_ogg), "rb");
		if(0 == dcd->file) {
			printf("ERROR (%s)\n", strerror(errno));
			return false;
		}
		printf("OK\n");
	}

	switch(dcd->layer) {
		case LAYER_STREAM:
			printf("testing FLAC__stream_decoder_init_%sstream()... ", is_ogg? "ogg_":"");
			init_status = is_ogg?
				FLAC__stream_decoder_init_ogg_stream(decoder, stream_decoder_read_callback_, /*seek_callback=*/0, /*tell_callback=*/0, /*length_callback=*/0, /*eof_callback=*/0, stream_decoder_write_callback_, stream_decoder_metadata_callback_, stream_decoder_error_callback_, dcd) :
				FLAC__stream_decoder_init_stream(decoder, stream_decoder_read_callback_, /*seek_callback=*/0, /*tell_callback=*/0, /*length_callback=*/0, /*eof_callback=*/0, stream_decoder_write_callback_, stream_decoder_metadata_callback_, stream_decoder_error_callback_, dcd)
			;
			break;
		case LAYER_SEEKABLE_STREAM:
			printf("testing FLAC__stream_decoder_init_%sstream()... ", is_ogg? "ogg_":"");
			init_status = is_ogg?
				FLAC__stream_decoder_init_ogg_stream(decoder, stream_decoder_read_callback_, stream_decoder_seek_callback_, stream_decoder_tell_callback_, stream_decoder_length_callback_, stream_decoder_eof_callback_, stream_decoder_write_callback_, stream_decoder_metadata_callback_, stream_decoder_error_callback_, dcd) :
				FLAC__stream_decoder_init_stream(decoder, stream_decoder_read_callback_, stream_decoder_seek_callback_, stream_decoder_tell_callback_, stream_decoder_length_callback_, stream_decoder_eof_callback_, stream_decoder_write_callback_, stream_decoder_metadata_callback_, stream_decoder_error_callback_, dcd);
			break;
		case LAYER_FILE:
			printf("testing FLAC__stream_decoder_init_%sFILE()... ", is_ogg? "ogg_":"");
			init_status = is_ogg?
				FLAC__stream_decoder_init_ogg_FILE(decoder, dcd->file, stream_decoder_write_callback_, stream_decoder_metadata_callback_, stream_decoder_error_callback_, dcd) :
				FLAC__stream_decoder_init_FILE(decoder, dcd->file, stream_decoder_write_callback_, stream_decoder_metadata_callback_, stream_decoder_error_callback_, dcd);
			break;
		case LAYER_FILENAME:
			printf("testing FLAC__stream_decoder_init_%sfile()... ", is_ogg? "ogg_":"");
			init_status = is_ogg?
				FLAC__stream_decoder_init_ogg_file(decoder, flacfilename(is_ogg), stream_decoder_write_callback_, stream_decoder_metadata_callback_, stream_decoder_error_callback_, dcd) :
				FLAC__stream_decoder_init_file(decoder, flacfilename(is_ogg), stream_decoder_write_callback_, stream_decoder_metadata_callback_, stream_decoder_error_callback_, dcd);
			break;
		default:
			die_("internal error 000");
			return false;
	}
	if(init_status != FLAC__STREAM_DECODER_INIT_STATUS_OK)
		return die_s_(0, decoder);
	printf("OK\n");

	dcd->current_metadata_number = 0;

	if(dcd->layer < LAYER_FILE && fseeko(dcd->file, 0, SEEK_SET) < 0) {
		printf("FAILED rewinding input, errno = %d\n", errno);
		return false;
	}

	printf("testing FLAC__stream_decoder_process_until_end_of_stream()... ");
	if(!FLAC__stream_decoder_process_until_end_of_stream(decoder))
		return die_s_("returned false", decoder);
	printf("OK\n");

	printf("testing FLAC__stream_decoder_finish()... ");
	if(!FLAC__stream_decoder_finish(decoder))
		return die_s_("returned false", decoder);
	printf("OK\n");

	return true;
}
Example #28
0
bool
flac_reader_c::parse_file() {
  FLAC__StreamDecoder *decoder;
  FLAC__StreamDecoderState state;
  flac_block_t block;
  uint64_t u, old_pos;
  int result, progress, old_progress;
  bool ok;

  m_in->setFilePointer(0);
  metadata_parsed = false;

  mxinfo(Y("+-> Parsing the FLAC file. This can take a LONG time.\n"));
  decoder = FLAC__stream_decoder_new();
  if (decoder == NULL)
    mxerror(Y("flac_reader: FLAC__stream_decoder_new() failed.\n"));
  if (!FLAC__stream_decoder_set_metadata_respond_all(decoder))
    mxerror(Y("flac_reader: Could not set metadata_respond_all.\n"));
  if (FLAC__stream_decoder_init_stream(decoder, flac_read_cb, flac_seek_cb, flac_tell_cb, flac_length_cb, flac_eof_cb, flac_write_cb,
                                       flac_metadata_cb, flac_error_cb, this) != FLAC__STREAM_DECODER_INIT_STATUS_OK)
    mxerror(Y("flac_reader: Could not initialize the FLAC decoder.\n"));

  result = FLAC__stream_decoder_process_until_end_of_metadata(decoder);

  mxverb(2, boost::format("flac_reader: extract->metadata, result: %1%, mdp: %2%, num blocks: %3%\n") % result % metadata_parsed % blocks.size());

  if (!metadata_parsed)
    mxerror_fn(m_ti.m_fname, Y("No metadata block found. This file is broken.\n"));

  FLAC__stream_decoder_get_decode_position(decoder, &u);

  block.type    = FLAC_BLOCK_TYPE_HEADERS;
  block.filepos = 0;
  block.len     = u;
  old_pos       = u;

  blocks.push_back(block);

  mxverb(2, boost::format("flac_reader: headers: block at %1% with size %2%\n") % block.filepos % block.len);

  old_progress = -5;
  ok = FLAC__stream_decoder_skip_single_frame(decoder);
  while (ok) {
    state = FLAC__stream_decoder_get_state(decoder);

    progress = m_in->getFilePointer() * 100 / m_size;
    if ((progress - old_progress) >= 5) {
      mxinfo(boost::format(Y("+-> Pre-parsing FLAC file: %1%%%%2%")) % progress % "\r");
      old_progress = progress;
    }

    if (FLAC__stream_decoder_get_decode_position(decoder, &u) && (u != old_pos)) {
      block.type    = FLAC_BLOCK_TYPE_DATA;
      block.filepos = old_pos;
      block.len     = u - old_pos;
      old_pos       = u;
      blocks.push_back(block);

      mxverb(2, boost::format("flac_reader: skip/decode frame, block at %1% with size %2%\n") % block.filepos % block.len);
    }

    if (state > FLAC__STREAM_DECODER_READ_FRAME)
      break;

    ok = FLAC__stream_decoder_skip_single_frame(decoder);
  }

  if (100 != old_progress)
    mxinfo(Y("+-> Pre-parsing FLAC file: 100%\n"));
  else
    mxinfo("\n");

  if ((blocks.size() == 0) || (blocks[0].type != FLAC_BLOCK_TYPE_HEADERS))
    mxerror(Y("flac_reader: Could not read all header packets.\n"));

  FLAC__stream_decoder_reset(decoder);
  FLAC__stream_decoder_delete(decoder);

  m_in->setFilePointer(0);
  blocks[0].len     -= 4;
  blocks[0].filepos  = 4;

  return metadata_parsed;
}
Example #29
0
int32_t MV_PlayFLAC
(
 char *ptr,
 uint32_t ptrlength,
 int32_t   loopstart,
 int32_t   loopend,
 int32_t   pitchoffset,
 int32_t   vol,
 int32_t   left,
 int32_t   right,
 int32_t   priority,
 uint32_t callbackval
 )

{
   VoiceNode   *voice;
   flac_data * fd = 0;
   FLAC__Metadata_Chain* metadata_chain;

   UNREFERENCED_PARAMETER(loopend);

   if ( !MV_Installed )
   {
      MV_SetErrorCode( MV_NotInstalled );
      return MV_Error;
   }

   fd = (flac_data *) malloc( sizeof(flac_data) );
   if (!fd) {
      MV_SetErrorCode( MV_InvalidFLACFile );
      return MV_Error;
   }

   memset(fd, 0, sizeof(flac_data));
   fd->ptr = ptr;
   fd->pos = 0;
   fd->blocksize = 0;
   fd->length = ptrlength;

   fd->block = NULL;

   fd->stream = FLAC__stream_decoder_new();
   fd->sample_pos = 0;

    FLAC__stream_decoder_set_metadata_ignore_all(fd->stream);

   if (FLAC__stream_decoder_init_stream(fd->stream,
            read_flac_stream,
            seek_flac_stream,
            tell_flac_stream,
            length_flac_stream,
            eof_flac_stream,
            write_flac_stream,
            /*metadata_flac_stream*/ NULL,
            error_flac_stream,
            (void*) fd) != FLAC__STREAM_DECODER_INIT_STATUS_OK) {
      MV_Printf("MV_PlayFLAC: %s\n", FLAC__stream_decoder_get_resolved_state_string(fd->stream));
      MV_SetErrorCode( MV_InvalidFLACFile );
      return MV_Error;
   }

   // Request a voice from the voice pool
   voice = MV_AllocVoice( priority );
   if ( voice == NULL )
   {
      FLAC__stream_decoder_finish(fd->stream);
      FLAC__stream_decoder_delete(fd->stream);
      free(fd);
      MV_SetErrorCode( MV_NoVoices );
      return MV_Error;
   }

   fd->owner = voice;

   voice->wavetype    = FLAC;
   voice->extra       = (void*)fd;
   voice->GetSound    = MV_GetNextFLACBlock;
   voice->NextBlock   = fd->block;
   voice->DemandFeed  = NULL;
   voice->LoopCount   = 0;
   voice->BlockLength = 0;
   voice->PitchScale  = PITCH_GetScale( pitchoffset );
   voice->next        = NULL;
   voice->prev        = NULL;
   voice->priority    = priority;
   voice->callbackval = callbackval;

   voice->Playing     = TRUE;
   voice->Paused      = FALSE;

   voice->LoopStart   = 0;
   voice->LoopEnd     = 0;
   voice->LoopSize    = (loopstart >= 0 ? 1 : 0);

    // parse metadata
    // loop parsing designed with multiple repetitions in mind
    // In retrospect, it may be possible to MV_GetVorbisCommentLoops(voice, (vorbis_comment *) tags->data.vorbis_comment)
    // but libvorbisfile may be confused by the signedness of char* vs FLAC__byte* and this code does not depend on HAVE_VORBIS.
    metadata_chain = FLAC__metadata_chain_new();
    if (metadata_chain != NULL)
    {
        if (FLAC__metadata_chain_read_with_callbacks(metadata_chain, fd, flac_callbacks))
        {
            FLAC__Metadata_Iterator* metadata_iterator = FLAC__metadata_iterator_new();
            if (metadata_iterator != NULL)
            {
                char *vc_loopstart = NULL;
                char *vc_loopend = NULL;
                char *vc_looplength = NULL;

                FLAC__metadata_iterator_init(metadata_iterator, metadata_chain);

                do
                {
                    FLAC__StreamMetadata *tags = FLAC__metadata_iterator_get_block(metadata_iterator);

                    if (tags->type == FLAC__METADATA_TYPE_STREAMINFO)
                    {
                        const FLAC__StreamMetadata_StreamInfo *info = &tags->data.stream_info;

                        if (info->channels != 1 && info->channels != 2) {
                           FLAC__metadata_object_delete(tags);
                           FLAC__metadata_iterator_delete(metadata_iterator);
                          // FLAC__metadata_chain_delete(metadata_chain);
                           FLAC__stream_decoder_finish(fd->stream);
                           FLAC__stream_decoder_delete(fd->stream);
                           free(fd);
                           MV_SetErrorCode( MV_InvalidFLACFile );
                           return MV_Error;
                        }

                        voice->channels     = info->channels;
                        voice->bits         = info->bits_per_sample;
                        voice->SamplingRate = info->sample_rate;
                    }

                    // load loop tags from metadata
                    if (tags->type == FLAC__METADATA_TYPE_VORBIS_COMMENT)
                    {
                        FLAC__uint32 comment;
                        uint8_t loopTagCount;
                        for (comment = 0; comment < tags->data.vorbis_comment.num_comments; ++comment)
                        {
                            const char *entry = (const char *) tags->data.vorbis_comment.comments[comment].entry;
                            if (entry != NULL && entry[0] != '\0')
                            {
                                const char *value = strchr(entry,'=');
                                const size_t field = value-entry;
                                value += 1;

                                for (loopTagCount = 0; loopTagCount < loopStartTagCount && vc_loopstart == NULL; ++loopTagCount)
                                    if (strncasecmp(entry, loopStartTags[loopTagCount], field) == 0)
                                        vc_loopstart = strdup(value);

                                for (loopTagCount = 0; loopTagCount < loopEndTagCount && vc_loopend == NULL; ++loopTagCount)
                                    if (strncasecmp(entry, loopEndTags[loopTagCount], field) == 0)
                                        vc_loopend = strdup(value);

                                for (loopTagCount = 0; loopTagCount < loopLengthTagCount && vc_looplength == NULL; ++loopTagCount)
                                    if (strncasecmp(entry, loopLengthTags[loopTagCount], field) == 0)
                                        vc_looplength = strdup(value);
                            }
                        }
                    }

                    FLAC__metadata_object_delete(tags); // If it wasn't for this I would assign pointers instead of strdup().
                }
                while (FLAC__metadata_iterator_next(metadata_iterator));

                if (vc_loopstart != NULL)
                {
                    {
                        const FLAC__int64 flac_loopstart = atol(vc_loopstart);
                        if (flac_loopstart >= 0) // a loop starting at 0 is valid
                        {
                            voice->LoopStart = (const char *) (intptr_t) flac_loopstart;
                            voice->LoopSize = 1;
                        }
                    }
                    free(vc_loopstart);
                }
                if (vc_loopend != NULL)
                {
                    if (voice->LoopSize > 0)
                    {
                        const FLAC__int64 flac_loopend = atol(vc_loopend);
                        if (flac_loopend > 0) // a loop ending at 0 is invalid
                            voice->LoopEnd = (const char *) (intptr_t) flac_loopend;
                    }
                    free(vc_loopend);
                }
                if (vc_looplength != NULL)
                {
                    if (voice->LoopSize > 0 && voice->LoopEnd == 0)
                    {
                        const FLAC__int64 flac_looplength = atol(vc_looplength);
                        if (flac_looplength > 0) // a loop of length 0 is invalid
                            voice->LoopEnd = (const char *) ((intptr_t) flac_looplength + (intptr_t) voice->LoopStart);
                    }
                    free(vc_looplength);
                }

                FLAC__metadata_iterator_delete(metadata_iterator);
            }
            else
                MV_Printf("Error allocating FLAC__Metadata_Iterator!\n");
        }
        else
            MV_Printf("%s\n", FLAC__Metadata_ChainStatusString[FLAC__metadata_chain_status(metadata_chain)]);

       // FLAC__metadata_chain_delete(metadata_chain); // when run with GDB, this throws SIGTRAP about freed heap memory being modified
    }
    else
        MV_Printf("Error allocating FLAC__Metadata_Chain!\n");

   // CODEDUP multivoc.c MV_SetVoicePitch
   voice->RateScale    = ( voice->SamplingRate * voice->PitchScale ) / MV_MixRate;
   voice->FixedPointBufferSize = ( voice->RateScale * MV_MIXBUFFERSIZE ) -
      voice->RateScale;
   MV_SetVoiceMixMode( voice );

   MV_SetVoiceVolume( voice, vol, left, right );
   MV_PlayVoice( voice );

   return voice->handle;
}