Esempio n. 1
0
FLAC__FileDecoderState FLAC__file_decoder_init(FLAC__FileDecoder *decoder)
{
	FLAC__ASSERT(0 != decoder);

	if(decoder->protected_->state != FLAC__FILE_DECODER_UNINITIALIZED)
		return decoder->protected_->state = FLAC__FILE_DECODER_ALREADY_INITIALIZED;

	if(0 == decoder->private_->write_callback || 0 == decoder->private_->metadata_callback || 0 == decoder->private_->error_callback)
		return decoder->protected_->state = FLAC__FILE_DECODER_INVALID_CALLBACK;

	if(0 == decoder->private_->filename)
		decoder->private_->file = get_binary_stdin_();
	else
		decoder->private_->file = fopen(decoder->private_->filename, "rb");

	if(decoder->private_->file == 0)
		return decoder->protected_->state = FLAC__FILE_DECODER_ERROR_OPENING_FILE;

	FLAC__seekable_stream_decoder_set_read_callback(decoder->private_->seekable_stream_decoder, read_callback_);
	FLAC__seekable_stream_decoder_set_seek_callback(decoder->private_->seekable_stream_decoder, seek_callback_);
	FLAC__seekable_stream_decoder_set_tell_callback(decoder->private_->seekable_stream_decoder, tell_callback_);
	FLAC__seekable_stream_decoder_set_length_callback(decoder->private_->seekable_stream_decoder, length_callback_);
	FLAC__seekable_stream_decoder_set_eof_callback(decoder->private_->seekable_stream_decoder, eof_callback_);
	FLAC__seekable_stream_decoder_set_write_callback(decoder->private_->seekable_stream_decoder, write_callback_);
	FLAC__seekable_stream_decoder_set_metadata_callback(decoder->private_->seekable_stream_decoder, metadata_callback_);
	FLAC__seekable_stream_decoder_set_error_callback(decoder->private_->seekable_stream_decoder, error_callback_);
	FLAC__seekable_stream_decoder_set_client_data(decoder->private_->seekable_stream_decoder, decoder);

	if(FLAC__seekable_stream_decoder_init(decoder->private_->seekable_stream_decoder) != FLAC__SEEKABLE_STREAM_DECODER_OK)
		return decoder->protected_->state = FLAC__FILE_DECODER_SEEKABLE_STREAM_DECODER_ERROR;

	return decoder->protected_->state = FLAC__FILE_DECODER_OK;
}
Esempio n. 2
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;

}
Esempio n. 3
0
  bool
  FLACInputStream::initialize(FilePtr file) {
    m_file = file;

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

#define SET_CALLBACK(name)                                   \
  FLAC__seekable_stream_decoder_set_##name##_callback(       \
    m_decoder,                                               \
    name##_callback)

    // set callbacks
    FLAC__seekable_stream_decoder_set_client_data      (m_decoder, this);
    SET_CALLBACK(read);
    SET_CALLBACK(seek);
    SET_CALLBACK(tell);
    SET_CALLBACK(length);
    SET_CALLBACK(eof);
    SET_CALLBACK(write);
    SET_CALLBACK(metadata);
    SET_CALLBACK(error);

    FLAC__SeekableStreamDecoderState state =
      FLAC__seekable_stream_decoder_init(m_decoder);
    if (state != FLAC__SEEKABLE_STREAM_DECODER_OK) {
      FLAC__seekable_stream_decoder_finish(m_decoder);
      FLAC__seekable_stream_decoder_delete(m_decoder);
      m_decoder = 0;
      m_file = 0;
      return false;
    }

    // make sure we have metadata before we return!
    if (!FLAC__seekable_stream_decoder_process_until_end_of_metadata(m_decoder)) {
      FLAC__seekable_stream_decoder_finish(m_decoder);
      FLAC__seekable_stream_decoder_delete(m_decoder);
      m_decoder = 0;
      m_file = 0;
      return false;
    }

    // process one frame so we can do something!
    if (!FLAC__seekable_stream_decoder_process_single(m_decoder)) {
      FLAC__seekable_stream_decoder_finish(m_decoder);
      FLAC__seekable_stream_decoder_delete(m_decoder);
      m_decoder = 0;
      m_file = 0;
      return false;
    }

    // get info about the flac file
    m_channel_count = FLAC__seekable_stream_decoder_get_channels(m_decoder);
    m_sample_rate   = FLAC__seekable_stream_decoder_get_sample_rate(m_decoder);
    int bps         = FLAC__seekable_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;
  }
Esempio n. 4
0
/* this is the codec entry point */
enum codec_status codec_start(struct codec_api* api)
{
    struct codec_api* ci = api;
    FLAC__SeekableStreamDecoder* flacDecoder;
    FLAC__uint64 offset;

    TEST_CODEC_API(ci);

#ifndef SIMULATOR
    ci->memcpy(iramstart, iramcopy, iramend-iramstart);
#endif

    ci->configure(CODEC_SET_FILEBUF_LIMIT, (int *)(1024*1024*10));
    ci->configure(CODEC_SET_FILEBUF_WATERMARK, (int *)(1024*512));
    ci->configure(CODEC_SET_FILEBUF_CHUNKSIZE, (int *)(1024*1024));

    ci->configure(CODEC_DSP_ENABLE, (bool *)true);
    ci->configure(DSP_DITHER, (bool *)false);
    ci->configure(DSP_SET_STEREO_MODE, (int *)STEREO_INTERLEAVED);
    ci->configure(DSP_SET_SAMPLE_DEPTH, (int *)(16));
  
next_track:
    metadata_length = 0;
    seek_table = NULL;
    stream_info = NULL;

    if (codec_init(api)) {
        return CODEC_ERROR;
    }

    while (!ci->taginfo_ready)
        ci->yield();
    
    ci->configure(DSP_SET_FREQUENCY, (long *)(ci->id3->frequency));
    codec_set_replaygain(ci->id3);
  
    /* Create a decoder instance */
    flacDecoder = FLAC__seekable_stream_decoder_new();

    /* Set up the decoder and the callback functions - this must be done before init */

    /* The following are required for stream_decoder and higher */
    FLAC__seekable_stream_decoder_set_client_data(flacDecoder,ci);
    FLAC__seekable_stream_decoder_set_write_callback(flacDecoder, flac_write_handler);
    FLAC__seekable_stream_decoder_set_read_callback(flacDecoder, flac_read_handler);
    FLAC__seekable_stream_decoder_set_metadata_callback(flacDecoder, flac_metadata_handler);
    FLAC__seekable_stream_decoder_set_error_callback(flacDecoder, flac_error_handler);
    FLAC__seekable_stream_decoder_set_metadata_respond_all(flacDecoder);

    /* The following are only for the seekable_stream_decoder */
    FLAC__seekable_stream_decoder_set_seek_callback(flacDecoder, flac_seek_handler);
    FLAC__seekable_stream_decoder_set_tell_callback(flacDecoder, flac_tell_handler);
    FLAC__seekable_stream_decoder_set_length_callback(flacDecoder, flac_length_handler);
    FLAC__seekable_stream_decoder_set_eof_callback(flacDecoder, flac_eof_handler);


    /* QUESTION: What do we do when the init fails? */
    if (FLAC__seekable_stream_decoder_init(flacDecoder)) {
        return CODEC_ERROR;
    }

    /* The first thing to do is to parse the metadata */
    FLAC__seekable_stream_decoder_process_until_end_of_metadata(flacDecoder);

    if (ci->id3->offset && stream_info) {
        FLAC__uint64 sample;

        sample = find_sample_number(ci, ci->id3->offset - metadata_length);
        ci->advance_buffer(ci->id3->offset);
        FLAC__seekable_stream_decoder_seek_absolute(flacDecoder, sample);
        FLAC__seekable_stream_decoder_get_decode_position(flacDecoder, &offset);
        ci->set_offset(offset);
        samplesdone = (uint32_t)sample;
        ci->set_elapsed(sample/(ci->id3->frequency/1000));
    } else {
        samplesdone = 0;
        ci->set_elapsed(0);
    }

    /* The main decoder loop */
    while (FLAC__seekable_stream_decoder_get_state(flacDecoder) != FLAC__SEEKABLE_STREAM_DECODER_END_OF_STREAM) {
        ci->yield();
        if (ci->stop_codec || ci->reload_codec) {
            break;
        }

        if (ci->seek_time) {
            int sample_loc;

            sample_loc = ci->seek_time/1000 * ci->id3->frequency;
            if (FLAC__seekable_stream_decoder_seek_absolute(flacDecoder, sample_loc)) {
                samplesdone = sample_loc;
                ci->set_elapsed(samplesdone/(ci->id3->frequency/1000));
            }
            ci->seek_time = 0;
        }

        FLAC__seekable_stream_decoder_process_single(flacDecoder);
        FLAC__seekable_stream_decoder_get_decode_position(flacDecoder, &offset);
        ci->set_offset(offset);
    }

    /* Flush the libFLAC buffers */
    FLAC__seekable_stream_decoder_finish(flacDecoder);

    if (ci->request_next_track()) {
        if (stream_info) {
            FLAC__metadata_object_delete(stream_info);
        }
        if (seek_table) {
            FLAC__metadata_object_delete(seek_table);
        }
        metadata_length = 0;
        goto next_track;
    }

    return CODEC_OK;
}
Esempio n. 5
0
int main(int argc, char *argv[])
{
	if (argc!=2)
	{
		fprintf(stderr, "usage: %s flacfile\n", argv[0]);
		return -1;
	}
	myfile = fopen(argv[1], "ro");
	if (!myfile)
	{
		perror("fopen()");
		return -1;
	}

	decoder = FLAC__seekable_stream_decoder_new();
	if (!decoder)
	{
		fprintf(stderr, "FLAC__seekable_stream_decoder_new() failed, out of memory?\n");
		return 1;
	}
	
	FLAC__seekable_stream_decoder_set_md5_checking(decoder, 0);

	FLAC__seekable_stream_decoder_set_read_callback(decoder, read_callback);
	FLAC__seekable_stream_decoder_set_write_callback(decoder, write_callback);
	FLAC__seekable_stream_decoder_set_metadata_callback(decoder, metadata_callback);
	FLAC__seekable_stream_decoder_set_seek_callback(decoder, seek_callback);
	FLAC__seekable_stream_decoder_set_tell_callback(decoder, tell_callback);
	FLAC__seekable_stream_decoder_set_length_callback(decoder, length_callback);
	FLAC__seekable_stream_decoder_set_eof_callback(decoder, eof_callback);

	FLAC__seekable_stream_decoder_set_client_data(decoder, myvar);

	FLAC__seekable_stream_decoder_set_error_callback(decoder, error_callback);

	switch (FLAC__seekable_stream_decoder_init(decoder))
	{
		case FLAC__SEEKABLE_STREAM_DECODER_OK:
			fprintf(stderr, "init ok\n");
			break;
		case FLAC__SEEKABLE_STREAM_DECODER_SEEKING:
			fprintf(stderr, "seeking\n");
			break;
		case FLAC__SEEKABLE_STREAM_DECODER_END_OF_STREAM:
			fprintf(stderr, "eof\n");
			break;
		case FLAC__SEEKABLE_STREAM_DECODER_MEMORY_ALLOCATION_ERROR:
			fprintf(stderr, "malloc failed\n");
			break;
		case FLAC__SEEKABLE_STREAM_DECODER_STREAM_DECODER_ERROR:
			fprintf(stderr, "decoder error\n");
			break;
		case FLAC__SEEKABLE_STREAM_DECODER_READ_ERROR:
			fprintf(stderr, "read error\n");
			break;
		case FLAC__SEEKABLE_STREAM_DECODER_SEEK_ERROR:
			fprintf(stderr, "seek error\n");
			break;
		case FLAC__SEEKABLE_STREAM_DECODER_ALREADY_INITIALIZED:
			fprintf(stderr, "already init'ed\n");
			break;
		case FLAC__SEEKABLE_STREAM_DECODER_INVALID_CALLBACK:
			fprintf(stderr, "invalid callback\n");
			break;
		case FLAC__SEEKABLE_STREAM_DECODER_UNINITIALIZED:
			fprintf(stderr, "decoder uninted\n");
			break;
		default:
			fprintf(stderr, "init not ok\n");
			break;
	}

	FLAC__seekable_stream_decoder_process_until_end_of_metadata(decoder);

	FLAC__seekable_stream_decoder_process_single(decoder);

	fprintf(stderr, "channels=%d\n", FLAC__seekable_stream_decoder_get_channels(decoder));
	fprintf(stderr, "bits per sample=%d\n", FLAC__seekable_stream_decoder_get_bits_per_sample(decoder));

/*
	fprintf(stderr, "position=%d\n", FLAC__seekable_stream_decoder_get_decode_position(decoder));
*/


	FLAC__seekable_stream_decoder_finish(decoder);
	FLAC__seekable_stream_decoder_delete(decoder);

	fclose(myfile);

	return 0;
}
Esempio n. 6
0
int FlacPcm::processData(MediaInfo *infos, ChunkList *chunk_list, bool *killswitch)
{
	reader = infos->getReader();
	if(reader == 0)
		return 0;

	if(decoder == 0) {
		decoder = FLAC__seekable_stream_decoder_new();
		if(decoder == 0)
			return 0;
		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 0;
		}
		if(!FLAC__seekable_stream_decoder_process_until_end_of_metadata(decoder)) {
			cleanup();
			return 0;
		}
	}

	if(needs_seek) {
		FLAC__seekable_stream_decoder_seek_absolute(decoder, seek_sample);
		needs_seek = false;
	}

	bool eof = false;

	while(samples_in_reservoir < 576) {
		if(FLAC__seekable_stream_decoder_get_state(decoder) == FLAC__SEEKABLE_STREAM_DECODER_END_OF_STREAM) {
			eof = true;
			break;
		}
		else if(!FLAC__seekable_stream_decoder_process_single(decoder)) {
			//@@@ how to do this?  MessageBox(mod_.hMainWindow, FLAC__FileDecoderStateString[FLAC__file_decoder_get_state(decoder_)], "READ ERROR processing frame", 0);
			eof = true;
			break;
		}
	}

	if(samples_in_reservoir == 0) {
		eof = true;
	}
	else {
		const unsigned channels = streaminfo.data.stream_info.channels;
		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, n = min(samples_in_reservoir, 576), delta;
		signed short *ssbuffer = (signed short*)output;

		for(i = 0; i < n*channels; i++)
			ssbuffer[i] = reservoir[i];
		delta = i;
		for( ; i < samples_in_reservoir*channels; i++)
			reservoir[i-delta] = reservoir[i];
		samples_in_reservoir -= n;

		const int bytes = n * channels * bytes_per_sample;

		ChunkInfosI *ci=new ChunkInfosI();
		ci->addInfo("srate", sample_rate);
		ci->addInfo("bps", bits_per_sample);
		ci->addInfo("nch", channels);

		chunk_list->setChunk("PCM", output, bytes, ci);
	}

	if(eof)
		return 0;

	return 1;
}