Exemplo n.º 1
0
bool CFlacDec::GetMetaData(FILE *in, const bool /*nice*/, CAudioMetaData* m)
{
	FLAC__StreamDecoder *vf;

	vf = FLAC__stream_decoder_new();
	FLAC__stream_decoder_set_metadata_ignore_all(vf);
	// we need streaminfo (default on) and FLAC__METADATA_TYPE_VORBIS_COMMENT (default off) for ID3 tags
	FLAC__stream_decoder_set_metadata_respond(vf, FLAC__METADATA_TYPE_STREAMINFO);
	FLAC__stream_decoder_set_metadata_respond(vf, FLAC__METADATA_TYPE_VORBIS_COMMENT);
	if (!Open(in, vf))
	{
		return false;
	}

	if (FLAC__stream_decoder_process_until_end_of_metadata(vf)) {
		// if the metadata callback was called mMetadata should be filled with infos
		if (mMetadata) {
			SetMetaData(mMetadata, m);
		}
	}
	// clean up stuff, the mMetadata may be used later again so let the decoder free it
	FLAC__stream_decoder_finish(vf);
	FLAC__stream_decoder_delete(vf);

	return true;
}
Exemplo n.º 2
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;
}
static status_t HandleFLAC(const char *filename, MediaScannerClient* client)
{
    status_t status = UNKNOWN_ERROR;
    FLAC__StreamDecoder *decoder;

    decoder = FLAC__stream_decoder_new();
    if (!decoder)
        return status;

    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);

    FLAC__StreamDecoderInitStatus init_status;
    init_status = FLAC__stream_decoder_init_file(decoder, filename, flac_write, flac_metadata, flac_error, client);
    if (init_status != FLAC__STREAM_DECODER_INIT_STATUS_OK)
        goto exit;

    if (!FLAC__stream_decoder_process_until_end_of_metadata(decoder))
        goto exit;

    status = OK;

exit:
    FLAC__stream_decoder_finish(decoder);
    FLAC__stream_decoder_delete(decoder);

    return status;
}
Exemplo n.º 4
0
bool FlacDecoder::_open(const string_t& filename)
{
#if defined(LIBTOOLS_WINDOWS) && defined(string_t_w_available)
  _file=_wfopen(string_t_to_stdw(filename).c_str(),L"rb");
#else
  _file=fopen(string_t_to_std(filename).c_str(),"rb");
#endif
   if (!_file)
   { 
#ifndef NDEBUG
     std::cerr << "FlacDecoder cannot open file: " << string_t_to_std(filename) << std::endl;
#endif
     return false;
   }
   _error=false;
   FLAC__StreamDecoderInitStatus init_status=
   FLAC__stream_decoder_init_FILE(_streamdecoder,_file,
                                  &FlacDecoder::_write_callback,
                                  &FlacDecoder::_metadata_callback,
                                  &FlacDecoder::_error_callback,
                                  (void*) this);

   assert(init_status==FLAC__STREAM_DECODER_INIT_STATUS_OK);
   FLAC__stream_decoder_set_metadata_respond(_streamdecoder,FLAC__METADATA_TYPE_STREAMINFO);
   FLAC__stream_decoder_set_metadata_respond(_streamdecoder,FLAC__METADATA_TYPE_VORBIS_COMMENT);
   if (!FLAC__stream_decoder_process_until_end_of_metadata(_streamdecoder) || _error)
   {
     _error=false;
     FLAC__stream_decoder_finish(_streamdecoder);
     init_status=
     FLAC__stream_decoder_init_ogg_FILE(_streamdecoder,_file,
                                        &FlacDecoder::_write_callback,
                                        &FlacDecoder::_metadata_callback,
                                        &FlacDecoder::_error_callback,
                                        (void*) this);
     assert(init_status==FLAC__STREAM_DECODER_INIT_STATUS_OK);
     FLAC__stream_decoder_set_metadata_respond(_streamdecoder,FLAC__METADATA_TYPE_STREAMINFO);
     FLAC__stream_decoder_set_metadata_respond(_streamdecoder,FLAC__METADATA_TYPE_VORBIS_COMMENT);
     if (!FLAC__stream_decoder_process_until_end_of_metadata(_streamdecoder)||_error)
     {

#ifndef NDEBUG
       std::cerr << "FlacDecoder file: " << string_t_to_std(filename) << " is not a FLAC or OGG FLAC file" << std::endl;
#endif
       FLAC__stream_decoder_finish(_streamdecoder);
       fclose(_file);
       return false;
     }
   }
   uint64_t music_len=FLAC__stream_decoder_get_total_samples(_streamdecoder);
   _bufferl.reserve(music_len);
   _bufferr.reserve(music_len);
   _opened=true;
   _ended=false;
   return true;
}
Exemplo n.º 5
0
FLAC__bool FLAC_plugin__decoder_init(FLAC__StreamDecoder *decoder, const char *filename, FLAC__int64 filesize, stream_data_struct *stream_data, output_config_t *config)
{
	FLAC__StreamDecoderInitStatus init_status;

	FLAC__ASSERT(decoder);
	FLAC_plugin__decoder_finish(decoder);
	/* init 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 ((init_status = FLAC__stream_decoder_init_file(decoder, filename, write_callback, metadata_callback, error_callback, /*client_data=*/stream_data)) != FLAC__STREAM_DECODER_INIT_STATUS_OK)
	{
		FLAC_plugin__show_error("Error while initializing decoder (%s [%s]).", FLAC__StreamDecoderInitStatusString[init_status], FLAC__stream_decoder_get_resolved_state_string(decoder));
		return false;
	}
	/* process */
	cfg = *config;
	wide_samples_in_reservoir_ = 0;
	stream_data->is_playing = false;
	stream_data->abort_flag = false;
	stream_data->has_replaygain = false;

	if (!FLAC__stream_decoder_process_until_end_of_metadata(decoder))
	{
		FLAC_plugin__show_error("Error while processing metadata (%s).", FLAC__stream_decoder_get_resolved_state_string(decoder));
		return false;
	}
	/* check results */
	if (stream_data->abort_flag) return false;                /* metadata callback already popped up the error dialog */
	/* init replaygain */
	stream_data->output_bits_per_sample = stream_data->has_replaygain && cfg.replaygain.enable ?
		cfg.resolution.replaygain.bps_out :
		cfg.resolution.normal.dither_24_to_16 ? min(stream_data->bits_per_sample, 16) : stream_data->bits_per_sample;

	if (stream_data->has_replaygain && cfg.replaygain.enable && cfg.resolution.replaygain.dither)
		FLAC__replaygain_synthesis__init_dither_context(&stream_data->dither_context, stream_data->bits_per_sample, cfg.resolution.replaygain.noise_shaping);
	/* more inits */
	stream_data->eof = false;
	stream_data->seek_to = -1;
	stream_data->is_playing = true;
	stream_data->average_bps = (unsigned)(filesize / (125.*(double)(FLAC__int64)stream_data->total_samples/(double)stream_data->sample_rate));
	
	bh_index_last_w = 0;
	bh_index_last_o = BITRATE_HIST_SIZE;
	decode_position = 0;
	decode_position_last = 0;
	written_time_last = 0;

	return true;
}
Exemplo n.º 6
0
FLAC_API FLAC__bool FLAC__seekable_stream_decoder_set_metadata_ignore_all(FLAC__SeekableStreamDecoder *decoder)
{
	FLAC__ASSERT(0 != decoder);
	FLAC__ASSERT(0 != decoder->private_);
	FLAC__ASSERT(0 != decoder->protected_);
	FLAC__ASSERT(0 != decoder->private_->stream_decoder);
	if(decoder->protected_->state != FLAC__SEEKABLE_STREAM_DECODER_UNINITIALIZED)
		return false;
	decoder->private_->ignore_stream_info_block = true;
	decoder->private_->ignore_seek_table_block = true;
	return
		FLAC__stream_decoder_set_metadata_ignore_all(decoder->private_->stream_decoder) &&
		FLAC__stream_decoder_set_metadata_respond(decoder->private_->stream_decoder, FLAC__METADATA_TYPE_STREAMINFO) &&
		FLAC__stream_decoder_set_metadata_respond(decoder->private_->stream_decoder, FLAC__METADATA_TYPE_SEEKTABLE);
}
Exemplo n.º 7
0
FLAC__bool EasyFLAC__set_metadata_respond(EasyFLAC__StreamDecoder *decoder, FLAC__MetadataType type)
{
    if (decoder->is_oggflac)
        return OggFLAC__stream_decoder_set_metadata_respond(decoder->oggflac, type);
    else
        return FLAC__stream_decoder_set_metadata_respond(decoder->flac, type);
}
Exemplo n.º 8
0
FlacDecoder::FlacDecoder():
  MusicDecoder("FlacDecoder"),
  _streamdecoder(NULL),
  _file(NULL),
  _data(NULL),
  _dataindex(0),
  _datasize(0),
  _bufferpos(0),
  _opened(false),
  _ended(true),
  _error(false)
{
  _streamdecoder=FLAC__stream_decoder_new();
  assert(_streamdecoder);
  FLAC__stream_decoder_set_metadata_respond(_streamdecoder,FLAC__METADATA_TYPE_STREAMINFO);
  FLAC__stream_decoder_set_metadata_respond(_streamdecoder,FLAC__METADATA_TYPE_VORBIS_COMMENT);
}
Exemplo n.º 9
0
FLAC__bool OggFLAC__stream_decoder_set_metadata_respond(OggFLAC__StreamDecoder *decoder, FLAC__MetadataType type)
{
	FLAC__ASSERT(0 != decoder);
	FLAC__ASSERT(0 != decoder->private_);
	FLAC__ASSERT(0 != decoder->protected_);
	if(decoder->protected_->state != OggFLAC__STREAM_DECODER_UNINITIALIZED)
		return false;
	return FLAC__stream_decoder_set_metadata_respond(decoder->private_->FLAC_stream_decoder, type);
}
Exemplo n.º 10
0
FLAC_API FLAC__SeekableStreamDecoderState FLAC__seekable_stream_decoder_init(FLAC__SeekableStreamDecoder *decoder)
{
	FLAC__ASSERT(0 != decoder);

	if(decoder->protected_->state != FLAC__SEEKABLE_STREAM_DECODER_UNINITIALIZED)
		return decoder->protected_->state = FLAC__SEEKABLE_STREAM_DECODER_ALREADY_INITIALIZED;

	if(0 == decoder->private_->read_callback || 0 == decoder->private_->seek_callback || 0 == decoder->private_->tell_callback || 0 == decoder->private_->length_callback || 0 == decoder->private_->eof_callback)
		return decoder->protected_->state = FLAC__SEEKABLE_STREAM_DECODER_INVALID_CALLBACK;

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

	decoder->private_->seek_table = 0;

	decoder->private_->do_md5_checking = decoder->protected_->md5_checking;

	/* We initialize the FLAC__MD5Context even though we may never use it.  This
	 * is because md5 checking may be turned on to start and then turned off if
	 * a seek occurs.  So we always init the context here and finalize it in
	 * FLAC__seekable_stream_decoder_finish() to make sure things are always
	 * cleaned up properly.
	 */
	FLAC__MD5Init(&decoder->private_->md5context);

	FLAC__stream_decoder_set_read_callback(decoder->private_->stream_decoder, read_callback_);
	FLAC__stream_decoder_set_write_callback(decoder->private_->stream_decoder, write_callback_);
	FLAC__stream_decoder_set_metadata_callback(decoder->private_->stream_decoder, metadata_callback_);
	FLAC__stream_decoder_set_error_callback(decoder->private_->stream_decoder, error_callback_);
	FLAC__stream_decoder_set_client_data(decoder->private_->stream_decoder, decoder);

	/* We always want to see these blocks.  Whether or not we pass them up
	 * through the metadata callback will be determined by flags set in our
	 * implementation of ..._set_metadata_respond/ignore...()
	 */
	FLAC__stream_decoder_set_metadata_respond(decoder->private_->stream_decoder, FLAC__METADATA_TYPE_STREAMINFO);
	FLAC__stream_decoder_set_metadata_respond(decoder->private_->stream_decoder, FLAC__METADATA_TYPE_SEEKTABLE);

	if(FLAC__stream_decoder_init(decoder->private_->stream_decoder) != FLAC__STREAM_DECODER_SEARCH_FOR_METADATA)
		return decoder->protected_->state = FLAC__SEEKABLE_STREAM_DECODER_STREAM_DECODER_ERROR;

	return decoder->protected_->state = FLAC__SEEKABLE_STREAM_DECODER_OK;
}
Exemplo n.º 11
0
int flac_open(FILE *in,oe_enc_opt *opt,unsigned char *oldbuf,int buflen){
  flacfile *flac;
  /*Ok. At this point, we know we have a FLAC or an OggFLAC file.
    Set up the FLAC decoder.*/
  flac=malloc(sizeof(*flac));
  flac->decoder=FLAC__stream_decoder_new();
  FLAC__stream_decoder_set_md5_checking(flac->decoder,false);
  /*We get STREAMINFO packets by default, but not VORBIS_COMMENT or PICTURE.*/
  FLAC__stream_decoder_set_metadata_respond(flac->decoder,
     FLAC__METADATA_TYPE_VORBIS_COMMENT);
  FLAC__stream_decoder_set_metadata_respond(flac->decoder,
     FLAC__METADATA_TYPE_PICTURE);
  flac->inopt=opt;
  flac->f=in;
  flac->oldbuf=malloc(buflen*sizeof(*flac->oldbuf));
  memcpy(flac->oldbuf,oldbuf,buflen*sizeof(*flac->oldbuf));
  flac->bufpos=0;
  flac->buflen=buflen;
  flac->block_buf=NULL;
  if((*(flac_id(oldbuf,buflen)?
     FLAC__stream_decoder_init_stream:FLAC__stream_decoder_init_ogg_stream))(
        flac->decoder,read_callback,NULL,NULL,NULL,eof_callback,
        write_callback,metadata_callback,error_callback,flac)==
     FLAC__STREAM_DECODER_INIT_STATUS_OK){
    /*Decode until we get the file length, sample rate, the number of channels,
      and the Vorbis comments (if any).*/
    if(FLAC__stream_decoder_process_until_end_of_metadata(flac->decoder)){
      opt->read_samples=flac_read;
      opt->readdata=flac;
      /*FLAC supports 1 to 8 channels only.*/
      speex_assert(flac->channels>0&&flac->channels<=8);
      /*It uses the same channel mappings as WAV.*/
      flac->channel_permute=wav_permute_matrix[flac->channels-1];
      return 1;
    }
  }
  flac_close(flac);
  fprintf(stderr,_("ERROR: Could not open FLAC stream.\n"));
  return 0;
}
Exemplo n.º 12
0
FLAC__bool FLAC__seekable_stream_decoder_set_metadata_respond(FLAC__SeekableStreamDecoder *decoder, FLAC__MetadataType type)
{
	FLAC__ASSERT(0 != decoder);
	FLAC__ASSERT(0 != decoder->private_);
	FLAC__ASSERT(0 != decoder->protected_);
	FLAC__ASSERT(0 != decoder->private_->stream_decoder);
	if(decoder->protected_->state != FLAC__SEEKABLE_STREAM_DECODER_UNINITIALIZED)
		return false;
	if(type == FLAC__METADATA_TYPE_STREAMINFO)
		decoder->private_->ignore_stream_info_block = false;
	else if(type == FLAC__METADATA_TYPE_SEEKTABLE)
		decoder->private_->ignore_seek_table_block = false;
	return FLAC__stream_decoder_set_metadata_respond(decoder->private_->stream_decoder, type);
}
Exemplo n.º 13
0
void FlacDecoder::_reset()
{
  if (_opened)
  {
    FLAC__stream_decoder_finish(_streamdecoder);
    if (_file)
    {
      fclose(_file);
    }
  }
  _file=NULL;
  _opened=false;
  _ended=true;
  _error=false;
  _data=NULL;
  _datasize=0;
  _dataindex=0;
  _sampleRate=0;
  _bufferpos=0;
  _bufferl.clear();
  _bufferr.clear();
  FLAC__stream_decoder_set_metadata_respond(_streamdecoder,FLAC__METADATA_TYPE_STREAMINFO);
  FLAC__stream_decoder_set_metadata_respond(_streamdecoder,FLAC__METADATA_TYPE_VORBIS_COMMENT);
}
Exemplo n.º 14
0
/**
 * Some glue code around FLAC__stream_decoder_new().
 */
static FLAC__StreamDecoder *
flac_decoder_new(void)
{
	FLAC__StreamDecoder *sd = FLAC__stream_decoder_new();
	if (sd == NULL) {
		g_warning("FLAC__stream_decoder_new() failed");
		return NULL;
	}

#if defined(FLAC_API_VERSION_CURRENT) && FLAC_API_VERSION_CURRENT > 7
	if(!FLAC__stream_decoder_set_metadata_respond(sd, FLAC__METADATA_TYPE_VORBIS_COMMENT))
		g_debug("FLAC__stream_decoder_set_metadata_respond() has failed");
#endif

	return sd;
}
Exemplo n.º 15
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;

}
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;
}
Exemplo n.º 17
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_++] = &application1_;
		expected_metadata_sequence_[num_expected_++] = &application2_;
		expected_metadata_sequence_[num_expected_++] = &cuesheet_;
		expected_metadata_sequence_[num_expected_++] = &picture_;
		expected_metadata_sequence_[num_expected_++] = &unknown_;
	}
	else {
		expected_metadata_sequence_[num_expected_++] = &streaminfo_;
		expected_metadata_sequence_[num_expected_++] = &padding_;
		expected_metadata_sequence_[num_expected_++] = &seektable_;
		expected_metadata_sequence_[num_expected_++] = &application1_;
		expected_metadata_sequence_[num_expected_++] = &application2_;
		expected_metadata_sequence_[num_expected_++] = &vorbiscomment_;
		expected_metadata_sequence_[num_expected_++] = &cuesheet_;
		expected_metadata_sequence_[num_expected_++] = &picture_;
		expected_metadata_sequence_[num_expected_++] = &unknown_;
	}

	if(!stream_decoder_test_respond_(decoder, &decoder_client_data, is_ogg))
		return false;

	/*
	 * ignore all
	 */

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

	num_expected_ = 0;

	if(!stream_decoder_test_respond_(decoder, &decoder_client_data, is_ogg))
		return false;

	/*
	 * respond all, ignore VORBIS_COMMENT
	 */

	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");

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

	num_expected_ = 0;
	expected_metadata_sequence_[num_expected_++] = &streaminfo_;
	expected_metadata_sequence_[num_expected_++] = &padding_;
	expected_metadata_sequence_[num_expected_++] = &seektable_;
	expected_metadata_sequence_[num_expected_++] = &application1_;
	expected_metadata_sequence_[num_expected_++] = &application2_;
	expected_metadata_sequence_[num_expected_++] = &cuesheet_;
	expected_metadata_sequence_[num_expected_++] = &picture_;
	expected_metadata_sequence_[num_expected_++] = &unknown_;

	if(!stream_decoder_test_respond_(decoder, &decoder_client_data, is_ogg))
		return false;

	/*
	 * respond all, ignore APPLICATION
	 */

	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");

	printf("testing FLAC__stream_decoder_set_metadata_ignore(APPLICATION)... ");
	if(!FLAC__stream_decoder_set_metadata_ignore(decoder, FLAC__METADATA_TYPE_APPLICATION))
		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_++] = &cuesheet_;
		expected_metadata_sequence_[num_expected_++] = &picture_;
		expected_metadata_sequence_[num_expected_++] = &unknown_;
	}
	else {
		expected_metadata_sequence_[num_expected_++] = &streaminfo_;
		expected_metadata_sequence_[num_expected_++] = &padding_;
		expected_metadata_sequence_[num_expected_++] = &seektable_;
		expected_metadata_sequence_[num_expected_++] = &vorbiscomment_;
		expected_metadata_sequence_[num_expected_++] = &cuesheet_;
		expected_metadata_sequence_[num_expected_++] = &picture_;
		expected_metadata_sequence_[num_expected_++] = &unknown_;
	}

	if(!stream_decoder_test_respond_(decoder, &decoder_client_data, is_ogg))
		return false;

	/*
	 * respond all, ignore APPLICATION id of app#1
	 */

	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");

	printf("testing FLAC__stream_decoder_set_metadata_ignore_application(of app block #1)... ");
	if(!FLAC__stream_decoder_set_metadata_ignore_application(decoder, application1_.data.application.id))
		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_++] = &application2_;
		expected_metadata_sequence_[num_expected_++] = &cuesheet_;
		expected_metadata_sequence_[num_expected_++] = &picture_;
		expected_metadata_sequence_[num_expected_++] = &unknown_;
	}
	else {
		expected_metadata_sequence_[num_expected_++] = &streaminfo_;
		expected_metadata_sequence_[num_expected_++] = &padding_;
		expected_metadata_sequence_[num_expected_++] = &seektable_;
		expected_metadata_sequence_[num_expected_++] = &application2_;
		expected_metadata_sequence_[num_expected_++] = &vorbiscomment_;
		expected_metadata_sequence_[num_expected_++] = &cuesheet_;
		expected_metadata_sequence_[num_expected_++] = &picture_;
		expected_metadata_sequence_[num_expected_++] = &unknown_;
	}

	if(!stream_decoder_test_respond_(decoder, &decoder_client_data, is_ogg))
		return false;

	/*
	 * respond all, ignore APPLICATION id of app#1 & app#2
	 */

	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");

	printf("testing FLAC__stream_decoder_set_metadata_ignore_application(of app block #1)... ");
	if(!FLAC__stream_decoder_set_metadata_ignore_application(decoder, application1_.data.application.id))
		return die_s_("returned false", decoder);
	printf("OK\n");

	printf("testing FLAC__stream_decoder_set_metadata_ignore_application(of app block #2)... ");
	if(!FLAC__stream_decoder_set_metadata_ignore_application(decoder, application2_.data.application.id))
		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_++] = &cuesheet_;
		expected_metadata_sequence_[num_expected_++] = &picture_;
		expected_metadata_sequence_[num_expected_++] = &unknown_;
	}
	else {
		expected_metadata_sequence_[num_expected_++] = &streaminfo_;
		expected_metadata_sequence_[num_expected_++] = &padding_;
		expected_metadata_sequence_[num_expected_++] = &seektable_;
		expected_metadata_sequence_[num_expected_++] = &vorbiscomment_;
		expected_metadata_sequence_[num_expected_++] = &cuesheet_;
		expected_metadata_sequence_[num_expected_++] = &picture_;
		expected_metadata_sequence_[num_expected_++] = &unknown_;
	}

	if(!stream_decoder_test_respond_(decoder, &decoder_client_data, is_ogg))
		return false;

	/*
	 * ignore all, respond VORBIS_COMMENT
	 */

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

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

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

	if(!stream_decoder_test_respond_(decoder, &decoder_client_data, is_ogg))
		return false;

	/*
	 * ignore all, respond APPLICATION
	 */

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

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

	num_expected_ = 0;
	expected_metadata_sequence_[num_expected_++] = &application1_;
	expected_metadata_sequence_[num_expected_++] = &application2_;

	if(!stream_decoder_test_respond_(decoder, &decoder_client_data, is_ogg))
		return false;

	/*
	 * ignore all, respond APPLICATION id of app#1
	 */

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

	printf("testing FLAC__stream_decoder_set_metadata_respond_application(of app block #1)... ");
	if(!FLAC__stream_decoder_set_metadata_respond_application(decoder, application1_.data.application.id))
		return die_s_("returned false", decoder);
	printf("OK\n");

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

	if(!stream_decoder_test_respond_(decoder, &decoder_client_data, is_ogg))
		return false;

	/*
	 * ignore all, respond APPLICATION id of app#1 & app#2
	 */

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

	printf("testing FLAC__stream_decoder_set_metadata_respond_application(of app block #1)... ");
	if(!FLAC__stream_decoder_set_metadata_respond_application(decoder, application1_.data.application.id))
		return die_s_("returned false", decoder);
	printf("OK\n");

	printf("testing FLAC__stream_decoder_set_metadata_respond_application(of app block #2)... ");
	if(!FLAC__stream_decoder_set_metadata_respond_application(decoder, application2_.data.application.id))
		return die_s_("returned false", decoder);
	printf("OK\n");

	num_expected_ = 0;
	expected_metadata_sequence_[num_expected_++] = &application1_;
	expected_metadata_sequence_[num_expected_++] = &application2_;

	if(!stream_decoder_test_respond_(decoder, &decoder_client_data, is_ogg))
		return false;

	/*
	 * respond all, ignore APPLICATION, respond APPLICATION id of app#1
	 */

	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");

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

	printf("testing FLAC__stream_decoder_set_metadata_respond_application(of app block #1)... ");
	if(!FLAC__stream_decoder_set_metadata_respond_application(decoder, application1_.data.application.id))
		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_++] = &application1_;
		expected_metadata_sequence_[num_expected_++] = &cuesheet_;
		expected_metadata_sequence_[num_expected_++] = &picture_;
		expected_metadata_sequence_[num_expected_++] = &unknown_;
	}
	else {
		expected_metadata_sequence_[num_expected_++] = &streaminfo_;
		expected_metadata_sequence_[num_expected_++] = &padding_;
		expected_metadata_sequence_[num_expected_++] = &seektable_;
		expected_metadata_sequence_[num_expected_++] = &application1_;
		expected_metadata_sequence_[num_expected_++] = &vorbiscomment_;
		expected_metadata_sequence_[num_expected_++] = &cuesheet_;
		expected_metadata_sequence_[num_expected_++] = &picture_;
		expected_metadata_sequence_[num_expected_++] = &unknown_;
	}

	if(!stream_decoder_test_respond_(decoder, &decoder_client_data, is_ogg))
		return false;

	/*
	 * ignore all, respond APPLICATION, ignore APPLICATION id of app#1
	 */

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

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

	printf("testing FLAC__stream_decoder_set_metadata_ignore_application(of app block #1)... ");
	if(!FLAC__stream_decoder_set_metadata_ignore_application(decoder, application1_.data.application.id))
		return die_s_("returned false", decoder);
	printf("OK\n");

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

	if(!stream_decoder_test_respond_(decoder, &decoder_client_data, is_ogg))
		return false;

	if(layer < LAYER_FILE) /* for LAYER_FILE, FLAC__stream_decoder_finish() closes the file */
		fclose(decoder_client_data.file);

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

	printf("\nPASSED!\n");

	return true;
}
Exemplo n.º 18
0
int __stdcall
WWFlacRW_DecodeAll(const wchar_t *path)
{
    FLAC__bool                    ok = true;
    FILE *fp = NULL;
    errno_t ercd;
    FLAC__StreamDecoderInitStatus initStatus = FLAC__STREAM_DECODER_INIT_STATUS_ERROR_OPENING_FILE;

    FlacDecodeInfo *fdi = FlacTInfoNew<FlacDecodeInfo>(g_flacDecodeInfoMap);
    if (NULL == fdi) {
        return FRT_OtherError;
    }

    fdi->errorCode = FRT_Success;

    fdi->decoder = FLAC__stream_decoder_new();
    if(fdi->decoder == NULL) {
        fdi->errorCode = FRT_FlacStreamDecoderNewFailed;
        dprintf("%s Flac decode error %d. set complete event.\n",
                __FUNCTION__, fdi->errorCode);
        goto end;
    }

    wcsncpy_s(fdi->path, path, (sizeof fdi->path)/2-1);

    FLAC__stream_decoder_set_md5_checking(fdi->decoder, true);
    
    FLAC__stream_decoder_set_metadata_respond(fdi->decoder, FLAC__METADATA_TYPE_STREAMINFO);
    FLAC__stream_decoder_set_metadata_respond(fdi->decoder, FLAC__METADATA_TYPE_VORBIS_COMMENT);
    FLAC__stream_decoder_set_metadata_respond(fdi->decoder, FLAC__METADATA_TYPE_PICTURE);
    FLAC__stream_decoder_set_metadata_respond(fdi->decoder, FLAC__METADATA_TYPE_CUESHEET);

    // Windowsでは、この方法でファイルを開かなければならぬ。
    ercd = _wfopen_s(&fp, fdi->path, L"rb");
    if (ercd != 0 || NULL == fp) {
        fdi->errorCode = FRT_FileOpenError;
        goto end;
    }

    initStatus = FLAC__stream_decoder_init_FILE(
            fdi->decoder, fp, WriteCallback, MetadataCallback, ErrorCallback, fdi);

    // FLAC__stream_decoder_finish()がfcloseしてくれるので、忘れる。
    fp = NULL;

    if(initStatus != FLAC__STREAM_DECODER_INIT_STATUS_OK) {
        fdi->errorCode = FRT_FlacStreamDecoderInitFailed;
        dprintf("%s Flac decode error %d. set complete event.\n",
                __FUNCTION__, fdi->errorCode);
        goto end;
    }

    fdi->errorCode = FRT_Success;
    ok = FLAC__stream_decoder_process_until_end_of_metadata(fdi->decoder);
    if (!ok) {
        if (fdi->errorCode == FRT_Success) {
            fdi->errorCode = FRT_DecorderProcessFailed;
        }
        dprintf("%s Flac metadata process error fdi->errorCode=%d\n",
                __FUNCTION__, fdi->errorCode);
        goto end;
    }

    ok = FLAC__stream_decoder_process_until_end_of_stream(fdi->decoder);
    if (!ok) {
        if (fdi->errorCode == FRT_Success) {
                fdi->errorCode = FRT_DecorderProcessFailed;
        }
        dprintf("%s Flac decode error fdi->errorCode=%d\n",
                __FUNCTION__, fdi->errorCode);
        goto end;
    }

    fdi->errorCode = FRT_Completed;

end:
    if (fdi->errorCode < 0) {
        if (NULL != fdi->decoder) {
            if (initStatus == FLAC__STREAM_DECODER_INIT_STATUS_OK) {
                FLAC__stream_decoder_finish(fdi->decoder);
            }
            FLAC__stream_decoder_delete(fdi->decoder);
            fdi->decoder = NULL;
        }

        int result = fdi->errorCode;
        FlacTInfoDelete<FlacDecodeInfo>(g_flacDecodeInfoMap, fdi);
        fdi = NULL;

        return result;
    }

    return fdi->id;
}