Пример #1
0
unsigned int FlacDecoder::fetch(Signal& outleft, Signal& outright)
{
  outleft.reset();
  outright.reset();
  if (_opened)
  {
    unsigned int request_size=Signal::size;
    while (request_size > _bufferl.size() - _bufferpos)
    {
      if (!FLAC__stream_decoder_process_single(_streamdecoder) ||
          (FLAC__stream_decoder_get_state(_streamdecoder) != FLAC__STREAM_DECODER_READ_FRAME &&
           FLAC__stream_decoder_get_state(_streamdecoder) != FLAC__STREAM_DECODER_SEARCH_FOR_FRAME_SYNC &&
           FLAC__stream_decoder_get_state(_streamdecoder) != FLAC__STREAM_DECODER_SEARCH_FOR_METADATA &&
           FLAC__stream_decoder_get_state(_streamdecoder) != FLAC__STREAM_DECODER_READ_METADATA ))
      {
        break;
      }
    }

    const unsigned int to_read=request_size >_bufferl.size() - _bufferpos ? _bufferl.size() - _bufferpos : request_size;
    for (unsigned int i=0; i < to_read; i++)
    {
      outleft.samples[i]=_bufferl.at(_bufferpos);
      outright.samples[i]=_bufferr.at(_bufferpos++);
    }
    if (to_read == 0)
    {
      _ended=true;
    }
    return to_read;
  }
  _ended=true;
  return 0;
}
Пример #2
0
SINT SoundSourceFLAC::seekSampleFrame(SINT frameIndex) {
    DEBUG_ASSERT(isValidFrameIndex(m_curFrameIndex));
    DEBUG_ASSERT(isValidFrameIndex(frameIndex));

    // Avoid unnecessary seeking
    // NOTE(uklotzde): Disabling this optimization might reveal rare
    // seek errors on certain FLAC files were the decoder loses sync!
    if (m_curFrameIndex == frameIndex) {
        return m_curFrameIndex;
    }

    // Discard decoded sample data before seeking
    m_sampleBuffer.reset();

    // Seek to the new position
    if (FLAC__stream_decoder_seek_absolute(m_decoder, frameIndex)) {
        // Set the new position
        m_curFrameIndex = frameIndex;
        DEBUG_ASSERT(FLAC__STREAM_DECODER_SEEK_ERROR != FLAC__stream_decoder_get_state(m_decoder));
    } else {
        qWarning() << "Seek error at" << frameIndex << "in" << m_file.fileName();
        // Invalidate the current position
        m_curFrameIndex = getMaxFrameIndex();
        if (FLAC__STREAM_DECODER_SEEK_ERROR == FLAC__stream_decoder_get_state(m_decoder)) {
            // Flush the input stream of the decoder according to the
            // documentation of FLAC__stream_decoder_seek_absolute()
            if (!FLAC__stream_decoder_flush(m_decoder)) {
                qWarning() << "Failed to flush input buffer of the FLAC decoder after seeking in"
                        << m_file.fileName();
                // Invalidate the current position...
                m_curFrameIndex = getMaxFrameIndex();
                // ...and abort
                return m_curFrameIndex;
            }
            // Discard previously decoded sample data before decoding
            // the next block of samples
            m_sampleBuffer.reset();
            // Trigger decoding of the next block to update the current position
            if (!FLAC__stream_decoder_process_single(m_decoder)) {
                qWarning() << "Failed to resync FLAC decoder after seeking in"
                        << m_file.fileName();
                // Invalidate the current position...
                m_curFrameIndex = getMaxFrameIndex();
                // ...and abort
                return m_curFrameIndex;
            }
            DEBUG_ASSERT(isValidFrameIndex(m_curFrameIndex));
            if (m_curFrameIndex < frameIndex) {
                // Adjust the current position
                skipSampleFrames(frameIndex - m_curFrameIndex);
            }
        }
    }

    DEBUG_ASSERT(isValidFrameIndex(m_curFrameIndex));
    return m_curFrameIndex;
}
Пример #3
0
static void
flac_decoder_loop(struct flac_data *data, FLAC__StreamDecoder *flac_dec,
		  FLAC__uint64 t_start, FLAC__uint64 t_end)
{
	struct decoder *decoder = data->decoder;
	enum decoder_command cmd;

	data->first_frame = t_start;

	while (true) {
		if (data->tag != NULL && !tag_is_empty(data->tag)) {
			cmd = decoder_tag(data->decoder, data->input_stream,
					  data->tag);
			tag_free(data->tag);
			data->tag = tag_new();
		} else
			cmd = decoder_get_command(decoder);

		if (cmd == DECODE_COMMAND_SEEK) {
			FLAC__uint64 seek_sample = t_start +
				decoder_seek_where(decoder) *
				data->audio_format.sample_rate;
			if (seek_sample >= t_start &&
			    (t_end == 0 || seek_sample <= t_end) &&
			    FLAC__stream_decoder_seek_absolute(flac_dec, seek_sample)) {
				data->next_frame = seek_sample;
				data->position = 0;
				decoder_command_finished(decoder);
			} else
				decoder_seek_error(decoder);
		} else if (cmd == DECODE_COMMAND_STOP ||
			   FLAC__stream_decoder_get_state(flac_dec) == FLAC__STREAM_DECODER_END_OF_STREAM)
			break;

		if (t_end != 0 && data->next_frame >= t_end)
			/* end of this sub track */
			break;

		if (!FLAC__stream_decoder_process_single(flac_dec)) {
			cmd = decoder_get_command(decoder);
			if (cmd != DECODE_COMMAND_SEEK)
				break;
		}
	}

	if (cmd != DECODE_COMMAND_STOP) {
		flacPrintErroredState(FLAC__stream_decoder_get_state(flac_dec));
		FLAC__stream_decoder_finish(flac_dec);
	}
}
Пример #4
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;
}
Пример #5
0
FLAC__StreamDecoderState EasyFLAC__get_state(const EasyFLAC__StreamDecoder *decoder)
{
    if (decoder->is_oggflac)
        return OggFLAC__stream_decoder_get_FLAC_stream_decoder_state(decoder->oggflac);
    else
        return FLAC__stream_decoder_get_state(decoder->flac);
}
Пример #6
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;
}
Пример #7
0
bool_t read_metadata(FLAC__StreamDecoder *decoder, callback_info *info)
{
    FLAC__StreamDecoderState ret;

    reset_info(info);

    /* Reset the decoder */
    if (FLAC__stream_decoder_reset(decoder) == false)
    {
        FLACNG_ERROR("Could not reset the decoder!\n");
        return FALSE;
    }

    /* Try to decode the metadata */
    if (FLAC__stream_decoder_process_until_end_of_metadata(decoder) == false)
    {
        ret = FLAC__stream_decoder_get_state(decoder);
        AUDDBG("Could not read the metadata: %s(%d)!\n",
            FLAC__StreamDecoderStateString[ret], ret);
        reset_info(info);
        return FALSE;
    }

    return TRUE;
}
Пример #8
0
size_t clFLACDataProvider::StreamWaveData( size_t Size )
{
	m_BufferUsed = 0;

	auto State = FLAC__stream_decoder_get_state( m_StreamData->m_Decoder );

	while( State < FLAC__STREAM_DECODER_END_OF_STREAM && m_BufferUsed < Size )
	{
		FLAC__bool Result = FLAC__stream_decoder_process_single( m_StreamData->m_Decoder );
		State = FLAC__stream_decoder_get_state( m_StreamData->m_Decoder );
	}

	m_IsEndOfStream = State == FLAC__STREAM_DECODER_END_OF_STREAM;

	return m_BufferUsed;
}
Пример #9
0
int FLAC_plugin__seek(FLAC__StreamDecoder *decoder, stream_data_struct *stream_data)
{
	int pos;
	FLAC__uint64 target_sample = stream_data->total_samples * stream_data->seek_to / stream_data->length_in_msec;

	if (stream_data->total_samples > 0 && target_sample >= stream_data->total_samples && target_sample > 0)
		target_sample = stream_data->total_samples - 1;

	/* even if the seek fails we have to reset these so that we don't repeat the seek */
	stream_data->seek_to = -1;
	stream_data->eof = false;
	wide_samples_in_reservoir_ = 0;
	pos = (int)(target_sample*1000 / stream_data->sample_rate);

	if (!FLAC__stream_decoder_seek_absolute(decoder, target_sample)) {
		if(FLAC__stream_decoder_get_state(decoder) == FLAC__STREAM_DECODER_SEEK_ERROR)
			FLAC__stream_decoder_flush(decoder);
		pos = -1;
	}

	bh_index_last_o = bh_index_last_w = (pos/BITRATE_HIST_SEGMENT_MSEC) % BITRATE_HIST_SIZE;
	if (!FLAC__stream_decoder_get_decode_position(decoder, &decode_position))
		decode_position = 0;

	return pos;
}
Пример #10
0
void safe_decoder_finish_(FLAC__StreamDecoder *decoder)
{
	if(decoder && FLAC__stream_decoder_get_state(decoder) != FLAC__STREAM_DECODER_UNINITIALIZED)
		(void)FLAC__stream_decoder_finish(decoder);
	if(stream_data_.is_http_source)
		flac_http_close();
}
Пример #11
0
static gint
xmms_flac_read (xmms_xform_t *xform, xmms_sample_t *buf, gint len,
                xmms_error_t *err)
{
	FLAC__StreamDecoderState state;
	xmms_flac_data_t *data;
	gboolean ret;
	guint32 size;

	g_return_val_if_fail (xform, FALSE);

	data = xmms_xform_private_data_get (xform);
	g_return_val_if_fail (data, FALSE);

	size = MIN (data->buffer->len, len);

	if (size <= 0) {
		ret = FLAC__stream_decoder_process_single (data->flacdecoder);
	}

	state = FLAC__stream_decoder_get_state (data->flacdecoder);

	if (state == FLAC__STREAM_DECODER_END_OF_STREAM) {
		return 0;
	}

	size = MIN (data->buffer->len, len);

	memcpy (buf, data->buffer->str, size);
	g_string_erase (data->buffer, 0, size);

	return size;
}
Пример #12
0
long process_flac_file(void* in, float** buffer, int samples){
    flac_file_t *flac = (flac_file_t *)in;
    long realsamples = 0;
	FLAC__bool ret;
	int i,j;
	while (realsamples < samples){
    	if (flac->buffer_sample_count > 0){
			int copy = (flac->buffer_sample_count< (samples - realsamples)) ? flac->buffer_sample_count : (samples - realsamples);

			for (i = 0; i < flac->channels; i++){

				int permute = wav_permute_matrix[flac->channels-1][i];
				for (j = 0; j < copy; j++){
					buffer[i][j+realsamples] = flac->buf[permute][j+flac->buffer_sample_seek];
				}
			}
			flac->buffer_sample_seek += copy;
			flac->buffer_sample_count -= copy;
			realsamples += copy;
        }else if (!flac->eos){
        	ret = FLAC__stream_decoder_process_single(flac->stream_decoder);
        	if (!ret || FLAC__stream_decoder_get_state(flac->stream_decoder) == FLAC__STREAM_DECODER_END_OF_STREAM){
                flac->eos = 1;  /* Bail out! */
			}
        }else{
            break;
		}
    }

	return realsamples;
}
Пример #13
0
static void flacdecode_play(struct xlplayer *xlplayer)
    {
    struct flacdecode_vars *self = xlplayer->dec_data;

    FLAC__stream_decoder_process_single(self->decoder);
    if (FLAC__stream_decoder_get_state(self->decoder) == FLAC__STREAM_DECODER_END_OF_STREAM)
        xlplayer->playmode = PM_EJECTING;
    }
Пример #14
0
static gboolean
gst_flac_dec_set_format (GstAudioDecoder * dec, GstCaps * caps)
{
  const GValue *headers;
  GstFlacDec *flacdec;
  GstStructure *s;
  guint i, num;

  flacdec = GST_FLAC_DEC (dec);

  GST_LOG_OBJECT (dec, "sink caps: %" GST_PTR_FORMAT, caps);

  s = gst_caps_get_structure (caps, 0);
  headers = gst_structure_get_value (s, "streamheader");
  if (headers == NULL || !GST_VALUE_HOLDS_ARRAY (headers)) {
    GST_WARNING_OBJECT (dec, "no 'streamheader' field in input caps, try "
        "adding a flacparse element upstream");
    return FALSE;
  }

  if (gst_adapter_available (flacdec->adapter) > 0) {
    GST_WARNING_OBJECT (dec, "unexpected data left in adapter");
    gst_adapter_clear (flacdec->adapter);
  }

  num = gst_value_array_get_size (headers);
  for (i = 0; i < num; ++i) {
    const GValue *header_val;
    GstBuffer *header_buf;

    header_val = gst_value_array_get_value (headers, i);
    if (header_val == NULL || !GST_VALUE_HOLDS_BUFFER (header_val))
      return FALSE;

    header_buf = g_value_dup_boxed (header_val);
    GST_INFO_OBJECT (dec, "pushing header buffer of %" G_GSIZE_FORMAT " bytes "
        "into adapter", gst_buffer_get_size (header_buf));
    gst_adapter_push (flacdec->adapter, header_buf);
  }

  GST_DEBUG_OBJECT (dec, "Processing headers and metadata");
  if (!FLAC__stream_decoder_process_until_end_of_metadata (flacdec->decoder)) {
    GST_WARNING_OBJECT (dec, "process_until_end_of_metadata failed");
    if (FLAC__stream_decoder_get_state (flacdec->decoder) ==
        FLAC__STREAM_DECODER_ABORTED) {
      GST_WARNING_OBJECT (flacdec, "Read callback caused internal abort");
      /* allow recovery */
      gst_adapter_clear (flacdec->adapter);
      FLAC__stream_decoder_flush (flacdec->decoder);
      gst_flac_dec_handle_decoder_error (flacdec, TRUE);
    }
  }
  GST_INFO_OBJECT (dec, "headers and metadata are now processed");
  return TRUE;
}
Пример #15
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;
}
Пример #16
0
static void _LongSound_FLAC_process (LongSound me, long firstSample, long numberOfSamples) {
	my compressedSamplesLeft = numberOfSamples - 1;
	if (! FLAC__stream_decoder_seek_absolute (my flacDecoder, firstSample))
		Melder_throw (U"Cannot seek in FLAC file ", & my file, U".");
	while (my compressedSamplesLeft > 0) {
		if (FLAC__stream_decoder_get_state (my flacDecoder) == FLAC__STREAM_DECODER_END_OF_STREAM)
			Melder_throw (U"FLAC file ", & my file, U" too short.");
		if (! FLAC__stream_decoder_process_single (my flacDecoder))
			Melder_throw (U"Error decoding FLAC file ", & my file, U".");
	}
}
Пример #17
0
static FLAC__bool die_s_(const char *msg, const FLAC__StreamDecoder *decoder)
{
	FLAC__StreamDecoderState state = FLAC__stream_decoder_get_state(decoder);

	if(msg)
		printf("FAILED, %s", msg);
	else
		printf("FAILED");

	printf(", state = %u (%s)\n", (unsigned)state, FLAC__StreamDecoderStateString[state]);

	return false;
}
Пример #18
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 ] );
			}
		}
	}
Пример #19
0
double FlacDecoder::SetPosition(double seconds) {
    FLAC__uint64 seekToSample = (FLAC__uint64)((double) this->sampleRate * seconds);

    if (FLAC__stream_decoder_seek_absolute(this->decoder, seekToSample)) {
        return seconds;
    }

    if (FLAC__stream_decoder_get_state(this->decoder) == FLAC__STREAM_DECODER_SEEK_ERROR) {
        if (FLAC__stream_decoder_flush(this->decoder)) {
            if (FLAC__stream_decoder_seek_absolute(this->decoder, seekToSample)) {
                return seconds;
            }
        }
    }

    return -1;
}
Пример #20
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;
}
Пример #21
0
Uint64 SoundFileReaderFlac::read(Int16* samples, Uint64 maxCount)
{
    assert(m_decoder);

    // If there are leftovers from previous call, use it first
    Uint64 left = m_clientData.leftovers.size();
    if (left > 0)
    {
        if (left > maxCount)
        {
            // There are more leftovers than needed
            std::copy(m_clientData.leftovers.begin(), m_clientData.leftovers.end(), samples);
            std::vector<Int16> leftovers(m_clientData.leftovers.begin() + maxCount, m_clientData.leftovers.end());
            m_clientData.leftovers.swap(leftovers);
            return maxCount;
        }
        else
        {
            // We can use all the leftovers and decode new frames
            std::copy(m_clientData.leftovers.begin(), m_clientData.leftovers.end(), samples);
        }
    }

    // Reset the data that will be used in the callback
    m_clientData.buffer = samples + left;
    m_clientData.remaining = maxCount - left;
    m_clientData.leftovers.clear();

    // Decode frames one by one until we reach the requested sample count, the end of file or an error
    while (m_clientData.remaining > 0)
    {
        // Everything happens in the "write" callback
        // This will break on any fatal error (does not include EOF)
        if (!FLAC__stream_decoder_process_single(m_decoder))
            break;

        // Break on EOF
        if (FLAC__stream_decoder_get_state(m_decoder) == FLAC__STREAM_DECODER_END_OF_STREAM)
            break;
    }

    return maxCount - m_clientData.remaining;
}
Пример #22
0
int main(int argc, char *argv[])
{
	FLAC__bool ok = true;
	FLAC__StreamDecoder *decoder = 0;
	FLAC__StreamDecoderInitStatus init_status;
	FILE *fout;

	if(argc != 3) {
		fprintf(stderr, "usage: %s infile.flac outfile.wav\n", argv[0]);
		return 1;
	}

	if((fout = fopen(argv[2], "wb")) == NULL) {
		fprintf(stderr, "ERROR: opening %s for output\n", argv[2]);
		return 1;
	}

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

	(void)FLAC__stream_decoder_set_md5_checking(decoder, true);

	init_status = FLAC__stream_decoder_init_file(decoder, argv[1], write_callback, metadata_callback, error_callback, /*client_data=*/fout);
	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)]);
	}

	FLAC__stream_decoder_delete(decoder);
	fclose(fout);

	return 0;
}
Пример #23
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;
}
Пример #24
0
static int start_read(sox_format_t * const ft)
{
  priv_t * p = (priv_t *)ft->priv;
  lsx_debug("API version %u", FLAC_API_VERSION_CURRENT);
  p->decoder = FLAC__stream_decoder_new();
  if (p->decoder == NULL) {
    lsx_fail_errno(ft, SOX_ENOMEM, "FLAC ERROR creating the decoder instance");
    return SOX_EOF;
  }

  FLAC__stream_decoder_set_md5_checking(p->decoder, sox_true);
  FLAC__stream_decoder_set_metadata_respond_all(p->decoder);
  if (FLAC__stream_decoder_init_FILE(p->decoder, ft->fp, /* Not using SoX IO */
      FLAC__frame_decode_callback, FLAC__decoder_metadata_callback,
      FLAC__decoder_error_callback, ft) != FLAC__STREAM_DECODER_INIT_STATUS_OK){
    lsx_fail_errno(ft, SOX_EHDR, "FLAC ERROR initialising decoder");
    return SOX_EOF;
  }
  ft->fp = NULL; /* Transfer ownership of fp to FLAC */

  if (!FLAC__stream_decoder_process_until_end_of_metadata(p->decoder)) {
    lsx_fail_errno(ft, SOX_EHDR, "FLAC ERROR whilst decoding metadata");
    return SOX_EOF;
  }

  if (FLAC__stream_decoder_get_state(p->decoder) > FLAC__STREAM_DECODER_END_OF_STREAM) {
    lsx_fail_errno(ft, SOX_EHDR, "FLAC ERROR during metadata decoding");
    return SOX_EOF;
  }

  ft->encoding.encoding = SOX_ENCODING_FLAC;
  ft->signal.rate = p->sample_rate;
  ft->encoding.bits_per_sample = p->bits_per_sample;
  ft->signal.channels = p->channels;
  ft->signal.length = p->total_samples * p->channels;
  return SOX_SUCCESS;
}
	UINT32 OAFLACReader::read(UINT8* samples, UINT32 numSamples)
	{
		UINT32 overflowSize = (UINT32)mData.overflow.size();
		UINT32 overflowNumSamples = 0;
		
		UINT32 bytesPerSample = mData.info.bitDepth / 8;
		if (overflowSize > 0)
		{
			UINT32 sampleSize = numSamples * bytesPerSample;
			if (overflowSize > sampleSize)
			{
				std::copy(mData.overflow.begin(), mData.overflow.begin() + sampleSize, samples);
				mData.overflow.erase(mData.overflow.begin(), mData.overflow.begin() + sampleSize);

				return numSamples;
			}
			else
				std::copy(mData.overflow.begin(), mData.overflow.end(), samples);

			overflowNumSamples = overflowSize / bytesPerSample;
		}

		mData.output = samples + overflowSize;
		mData.samplesToRead = numSamples - overflowNumSamples;
		mData.overflow.clear();

		while (mData.samplesToRead > 0)
		{
			if (!FLAC__stream_decoder_process_single(mDecoder))
				break;

			if (FLAC__stream_decoder_get_state(mDecoder) == FLAC__STREAM_DECODER_END_OF_STREAM)
				break;
		}

		return numSamples - mData.samplesToRead;
	}
Пример #26
0
CBaseDec::RetCode CFlacDec::Decoder(FILE *in, const int /*OutputFd*/, State* const state, CAudioMetaData* meta_data, time_t* const time_played, unsigned int* const secondsToSkip)
{
	int rval;
//	FLAC__uint64 jumptime=0;
	Status = OK;
	mState = state;
	mTimePlayed = time_played;
	mFrameCount = 0;
	mSamplesProcessed = 0;
	struct stat s;
	FLAC__uint64 filesize = 0;

	mFlacDec = FLAC__stream_decoder_new();

	if (!Open(in, mFlacDec))
	{
		Status=DATA_ERR;
		return Status;
	}

	if (fstat(fileno(in), &s))
	{
		perror("CFlacDec::Decoder fstat");
		*time_played = 0;
	}
	else
		filesize = (FLAC__uint64)s.st_size;

	/* up and away ... */
	mSlotSize = MAX_OUTPUT_SAMPLES * 2 * FLAC__stream_decoder_get_channels(mFlacDec);
//	State oldstate=*state;
	int jumppos=0;
	int actSecsToSkip = (*secondsToSkip != 0) ? *secondsToSkip : MSECS_TO_SKIP / 1000;
	int bytes_to_skip = actSecsToSkip * meta_data->bitrate / 8;
	int bytes_to_play = MSECS_TO_PLAY * meta_data->bitrate / 8000;
	unsigned int oldSecsToSkip = *secondsToSkip;
	FLAC__uint64 position;

	do
	{
		while(*state==PAUSE)
			usleep(10000);

		if(*state==FF || *state==REV)
		{
			if (oldSecsToSkip != *secondsToSkip)
			{
				actSecsToSkip = (*secondsToSkip != 0) ? *secondsToSkip : MSECS_TO_SKIP / 1000;
				bytes_to_skip = actSecsToSkip * meta_data->bitrate / 8;
				oldSecsToSkip = *secondsToSkip;
			}
			printf("skipping %d secs and %d bytes\n",actSecsToSkip,bytes_to_skip);
			if(std::abs(ftell(in)-jumppos) > bytes_to_play)
			{
				if(*state==FF)
				{
					fseek(in, bytes_to_skip, SEEK_CUR);
					jumppos=ftell(in);
				}
				else
				{
					if(ftell(in) < bytes_to_skip)
					{
						fseek(in, 0, SEEK_SET);
						*state=PLAY;
					}
					else
					{
						fseek(in, -bytes_to_skip, SEEK_CUR);
						jumppos=ftell(in);
					}
				}
			}

			// if a custom value was set we only jump once
			if (*secondsToSkip != 0) {
				*state=PLAY;
			}
		}

		if (FLAC__stream_decoder_get_state(mFlacDec) == FLAC__STREAM_DECODER_END_OF_STREAM) {
			rval = false;
			break;
		}

		rval = FLAC__stream_decoder_process_single(mFlacDec);

		/* update playback position */
		if (filesize > 0 && FLAC__stream_decoder_get_decode_position(mFlacDec, &position))
			*time_played = position / 1000ULL * mLengthInMsec / filesize;

	} while (rval && *state != STOP_REQ && Status == OK);

	// let buffer run dry
	printf("let buffer run dry\n");
	while (rval == true && *state != STOP_REQ && Status == OK /* && mReadSlot != mWriteSlot*/)
	{
		printf("...drying - *state=%x, Status=%x\n", *state, Status);
		usleep(100000);
	}

	/* clean up the junk from the party */
	if (mMetadata)
		FLAC__metadata_object_delete(mMetadata);
	mMetadata = NULL;
	FLAC__stream_decoder_finish(mFlacDec);
	FLAC__stream_decoder_delete(mFlacDec);
	mFlacDec = NULL;

	audioDecoder->StopClip();

	/* and drive home ;) */
	return Status;
}
Пример #27
0
CBaseDec::RetCode CFlacDec::Decoder(FILE *in, const int OutputFd, State* const state, CAudioMetaData* meta_data, time_t* const time_played, unsigned int* const secondsToSkip)
{
    int rval;
    //FLAC__uint64 jumptime=0;
    Status = OK;
    mOutputFd = OutputFd;
    mState = state;
    mTimePlayed = time_played;
    mFrameCount = 0;
    mSamplesProcessed = 0;

    mFlacDec = FLAC__stream_decoder_new();

    if (!Open(in, mFlacDec))
    {
        Status=DATA_ERR;
        return Status;
    }

    //test
    //audioDecoder->PrepareClipPlay(frame->header.channels, frame->header.sample_rate, frame->header.bits_per_sample, 1);
    //audioDecoder->PrepareClipPlay(2, 16, 16, 1);

    /* up and away ... */
    mSlotSize = MAX_OUTPUT_SAMPLES * 2 * FLAC__stream_decoder_get_channels(mFlacDec);
    //State oldstate=*state;
    int jumppos=0;
    int actSecsToSkip = (*secondsToSkip != 0) ? *secondsToSkip : MSECS_TO_SKIP / 1000;
    int bytes_to_skip = (int) (1.0 * actSecsToSkip * meta_data->bitrate / 8);
    int bytes_to_play = (int) (1.0 * MSECS_TO_PLAY / 1000 * meta_data->bitrate / 8);
    unsigned int oldSecsToSkip = *secondsToSkip;
    //FLAC__uint64 position;

    do
    {
        while(*state==PAUSE)
            usleep(10000);

        if(*state==FF || *state==REV)
        {
            if (oldSecsToSkip != *secondsToSkip)
            {
                actSecsToSkip = (*secondsToSkip != 0) ? *secondsToSkip : MSECS_TO_SKIP / 1000;
                bytes_to_skip = (int) (1.0 * actSecsToSkip * meta_data->bitrate / 8);
                oldSecsToSkip = *secondsToSkip;
            }
            printf("skipping %d secs and %d bytes\n",actSecsToSkip,bytes_to_skip);
            if(std::abs(ftell(in)-jumppos) > bytes_to_play)
            {
                if(*state==FF)
                {
                    fseek(in, bytes_to_skip, SEEK_CUR);
                    jumppos=ftell(in);
                }
                else
                {
                    if(ftell(in) < bytes_to_skip)
                    {
                        fseek(in, 0, SEEK_SET);
                        *state=PLAY;
                    }
                    else
                    {
                        fseek(in, -bytes_to_skip, SEEK_CUR);
                        jumppos=ftell(in);
                    }
                }
            }

            // if a custom value was set we only jump once
            if (*secondsToSkip != 0)
            {
                *state=PLAY;
            }
        }

        if (FLAC__stream_decoder_get_state(mFlacDec) == FLAC__STREAM_DECODER_END_OF_STREAM)
        {
            rval = false;
            break;
        }

        rval = FLAC__stream_decoder_process_single(mFlacDec);
        // TODO: calculate time_played from the actual file position so that REW/FF actions will be included
        *time_played = (mSamplesProcessed * (mLengthInMsec/1000)) / mTotalSamples;

    } while (rval && *state!=STOP_REQ && Status==OK);

    // let buffer run dry
    printf("let buffer run dry\n");
    while (rval==true && *state!=STOP_REQ && Status==OK /* && mReadSlot != mWriteSlot*/)
    {
        printf("...drying - *state=%x, Status=%x\n", *state, Status);
        usleep(100000);
    }

    if(audioDecoder)
        audioDecoder->StopClip();

    /* clean up the junk from the party */
    if (mMetadata)
        FLAC__metadata_object_delete(mMetadata);
    mMetadata = NULL;
    FLAC__stream_decoder_finish(mFlacDec);
    FLAC__stream_decoder_delete(mFlacDec);
    mFlacDec = NULL;

    /* and drive home ;) */
    return Status;
}
Пример #28
0
ReadableSampleFrames SoundSourceFLAC::readSampleFramesClamped(
        WritableSampleFrames writableSampleFrames) {
    const SINT firstFrameIndex = writableSampleFrames.frameIndexRange().start();

    if (m_curFrameIndex != firstFrameIndex) {
        // Seek to the new position
        SINT seekFrameIndex = firstFrameIndex;
        int retryCount = 0;
        // NOTE(uklotzde): This loop avoids unnecessary seek operations.
        // If the file is decoded from the beginning to the end during
        // continuous playback no seek operations are necessary. This
        // may hide rare seek errors that we have observed in some "flaky"
        // FLAC files. The retry strategy implemented by this loop tries
        // to solve these issues when randomly seeking through such a file.
        while ((seekFrameIndex != m_curFrameIndex) &&
                (retryCount <= kSeekErrorMaxRetryCount)) {
            // Discard decoded sample data before seeking
            m_sampleBuffer.clear();
            invalidateCurFrameIndex();
            if (FLAC__stream_decoder_seek_absolute(m_decoder, seekFrameIndex)) {
                // Success: Set the new position
                m_curFrameIndex = seekFrameIndex;
                DEBUG_ASSERT(FLAC__STREAM_DECODER_SEEK_ERROR != FLAC__stream_decoder_get_state(m_decoder));
            } else {
                // Failure
                kLogger.warning()
                        << "Seek error at" << seekFrameIndex
                        << "in file" << m_file.fileName();
                if (FLAC__STREAM_DECODER_SEEK_ERROR == FLAC__stream_decoder_get_state(m_decoder)) {
                    // Flush the input stream of the decoder according to the
                    // documentation of FLAC__stream_decoder_seek_absolute()
                    if (!FLAC__stream_decoder_flush(m_decoder)) {
                        kLogger.warning()
                                << "Failed to flush input buffer of the FLAC decoder after seek failure"
                                << "in file" << m_file.fileName();
                        invalidateCurFrameIndex();
                        // ...and abort
                        return ReadableSampleFrames(
                                IndexRange::between(
                                        m_curFrameIndex,
                                        m_curFrameIndex));
                    }
                }
                if (frameIndexMin() < seekFrameIndex) {
                    // The next seek position should start at a preceding sample block.
                    // By subtracting max. blocksize from the current seek position it
                    // is guaranteed that the targeted sample blocks of subsequent seek
                    // operations will differ.
                    DEBUG_ASSERT(0 < m_maxBlocksize);
                    seekFrameIndex -= m_maxBlocksize;
                    if (seekFrameIndex < frameIndexMin()) {
                        seekFrameIndex = frameIndexMin();
                    }
                } else {
                    // We have already reached the beginning of the file
                    // and cannot move the seek position backwards any
                    // further!
                    break; // exit loop
                }
            }
        }

        // Decoding starts before the actual target position
        DEBUG_ASSERT(m_curFrameIndex <= firstFrameIndex);
        const auto precedingFrames =
                IndexRange::between(m_curFrameIndex, firstFrameIndex);
        if (!precedingFrames.empty() &&
                (precedingFrames != readSampleFramesClamped(WritableSampleFrames(precedingFrames)).frameIndexRange())) {
            kLogger.warning()
                    << "Failed to skip preceding frames"
                    << precedingFrames;
            // Abort
            return ReadableSampleFrames(
                    IndexRange::between(
                            m_curFrameIndex,
                            m_curFrameIndex));
        }
    }
    DEBUG_ASSERT(m_curFrameIndex == firstFrameIndex);

    const SINT numberOfSamplesTotal = frames2samples(writableSampleFrames.frameLength());

    SINT numberOfSamplesRemaining = numberOfSamplesTotal;
    SINT outputSampleOffset = 0;
    while (0 < numberOfSamplesRemaining) {
        // If our buffer from libflac is empty (either because we explicitly cleared
        // it or because we've simply used all the samples), ask for a new buffer
        if (m_sampleBuffer.empty()) {
            // Save the current frame index
            const SINT curFrameIndexBeforeProcessing = m_curFrameIndex;
            // Documentation of FLAC__stream_decoder_process_single():
            // "Depending on what was decoded, the metadata or write callback
            // will be called with the decoded metadata block or audio frame."
            // See also: https://xiph.org/flac/api/group__flac__stream__decoder.html#ga9d6df4a39892c05955122cf7f987f856
            if (!FLAC__stream_decoder_process_single(m_decoder)) {
                kLogger.warning()
                        << "Failed to decode FLAC file"
                        << m_file.fileName();
                break; // abort
            }
            // After decoding we might first need to skip some samples if the
            // decoder complained that it has lost sync for some malformed(?)
            // files
            if (m_curFrameIndex != curFrameIndexBeforeProcessing) {
                if (m_curFrameIndex < curFrameIndexBeforeProcessing) {
                    kLogger.warning()
                            << "Trying to adjust frame index"
                            << m_curFrameIndex << "<" << curFrameIndexBeforeProcessing
                            << "while decoding FLAC file"
                            << m_file.fileName();
                    const auto skipFrames =
                            IndexRange::between(m_curFrameIndex, curFrameIndexBeforeProcessing);
                    if (skipFrames != readSampleFramesClamped(WritableSampleFrames(skipFrames)).frameIndexRange()) {
                        kLogger.warning()
                                << "Failed to skip sample frames"
                                << skipFrames
                                << "while decoding FLAC file"
                                << m_file.fileName();
                        break; // abort
                    }
                } else {
                    kLogger.warning()
                            << "Unexpected frame index"
                            << m_curFrameIndex << ">" << curFrameIndexBeforeProcessing
                            << "while decoding FLAC file"
                            << m_file.fileName();
                    break; // abort
                }
            }
            DEBUG_ASSERT(curFrameIndexBeforeProcessing == m_curFrameIndex);
        }
        if (m_sampleBuffer.empty()) {
            break; // EOF
        }

        const SINT numberOfSamplesRead =
                std::min(m_sampleBuffer.readableLength(), numberOfSamplesRemaining);
        const SampleBuffer::ReadableSlice readableSlice(
                m_sampleBuffer.shrinkForReading(numberOfSamplesRead));
        DEBUG_ASSERT(readableSlice.length() == numberOfSamplesRead);
        if (writableSampleFrames.writableData()) {
            SampleUtil::copy(
                    writableSampleFrames.writableData(outputSampleOffset),
                    readableSlice.data(),
                    readableSlice.length());
            outputSampleOffset += numberOfSamplesRead;
        }
        m_curFrameIndex += samples2frames(numberOfSamplesRead);
        numberOfSamplesRemaining -= numberOfSamplesRead;
    }

    DEBUG_ASSERT(isValidFrameIndex(m_curFrameIndex));
    DEBUG_ASSERT(numberOfSamplesTotal >= numberOfSamplesRemaining);
    const SINT numberOfSamples = numberOfSamplesTotal - numberOfSamplesRemaining;
    return ReadableSampleFrames(
            IndexRange::forward(firstFrameIndex, samples2frames(numberOfSamples)),
            SampleBuffer::ReadableSlice(
                    writableSampleFrames.writableData(),
                    std::min(writableSampleFrames.writableLength(), numberOfSamples)));
}
Пример #29
0
FLAC_API FLAC__StreamDecoderState FLAC__seekable_stream_decoder_get_stream_decoder_state(const FLAC__SeekableStreamDecoder *decoder)
{
	FLAC__ASSERT(0 != decoder);
	FLAC__ASSERT(0 != decoder->private_);
	return FLAC__stream_decoder_get_state(decoder->private_->stream_decoder);
}
Пример #30
0
bool
flac_reader_c::parse_file() {
  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"));

  init_flac_decoder();
  result = FLAC__stream_decoder_process_until_end_of_metadata(m_flac_decoder.get());

  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(m_flac_decoder.get(), &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(m_flac_decoder.get());
  while (ok) {
    state = FLAC__stream_decoder_get_state(m_flac_decoder.get());

    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(m_flac_decoder.get(), &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(m_flac_decoder.get());
  }

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

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

  return metadata_parsed;
}