Example #1
0
unsigned int SoundSourceFLAC::read(unsigned long size, const SAMPLE *destination) {
    if (!m_decoder) return 0;
    SAMPLE *destBuffer(const_cast<SAMPLE*>(destination));
    unsigned int samplesWritten = 0;
    unsigned int i = 0;
    while (samplesWritten < size) {
        // 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_flacBufferLength == 0) {
            i = 0;
            if (!FLAC__stream_decoder_process_single(m_decoder)) {
                qWarning() << "SSFLAC: decoder_process_single returned false";
                break;
            } else if (m_flacBufferLength == 0) {
                // EOF
                break;
            }
        }
        destBuffer[samplesWritten++] = m_flacBuffer[i++];
        --m_flacBufferLength;
    }
    if (m_flacBufferLength != 0) {
        memcpy(m_leftoverBuffer, &m_flacBuffer[i],
                m_flacBufferLength * sizeof(m_flacBuffer[0])); // safe because leftoverBuffer
                                                               // is as long as flacbuffer
        memcpy(m_flacBuffer, m_leftoverBuffer,
                m_flacBufferLength * sizeof(m_leftoverBuffer[0]));
        // this whole if block could go away if this just used a ring buffer but I'd
        // rather do that after I've gotten off the inital happiness of getting this right,
        // if I see SIGSEGV one more time I'll pop -- bkgood
    }
    return samplesWritten;
}
Example #2
0
int
FLACInputStream::doRead(int frame_count, void* samples) {
    const int frame_size = m_channel_count * GetSampleSize(m_sample_format);
    u8* out = (u8*)samples;

    // we keep reading till we finish topping up!
    int frames_read = 0;
    while (frames_read < frame_count) {

        // if the buffer is empty, ask FLAC to fill it p
        if (m_buffer.getSize() < frame_size) {
            if (!FLAC__stream_decoder_process_single(m_decoder)) {
                return frames_read;
            }

            // if the buffer still has a size of 0, we are probably at the
            // end of the stream
            if (m_buffer.getSize() < frame_size) {
                return frames_read;
            }
        }

        // read what we've got!
        const int to_read = std::min(
                                frame_count - frames_read,
                                m_buffer.getSize() / frame_size);
        m_buffer.read(out, to_read * frame_size);
        out += to_read * frame_size;
        frames_read += to_read;
    }

    return frames_read;
}
Example #3
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;
}
Example #4
0
int read_flac_file (apr_pool_t* pool,void** file_struct, const char* file_path, encoding_options_t* enc_opt){
	FLAC__StreamDecoderInitStatus status;
	FLAC__bool status2;
	flac_file_t* flac_file = *file_struct = (flac_file_t*) apr_pcalloc(pool, sizeof(flac_file_t));

	flac_file->stream_decoder = FLAC__stream_decoder_new();
	flac_file->channels = 0;
	flac_file->samples = 0;
	flac_file->total_samples = 0;
	flac_file->rate = 0;
	flac_file->buf = NULL;

	status = FLAC__stream_decoder_init_file(flac_file->stream_decoder, file_path, flac_write, flac_metadata, flac_errors, flac_file);
	if (status != FLAC__STREAM_DECODER_INIT_STATUS_OK){
		return -1;
	}

	status2 = FLAC__stream_decoder_process_until_end_of_metadata(flac_file->stream_decoder);
	if (status2 != true){
		return -2;
	}
	FLAC__stream_decoder_process_single(flac_file->stream_decoder);
	if (status2 != true){
			return -2;
	}
	enc_opt->channels = flac_file->channels;
	enc_opt->rate = flac_file->rate;
	enc_opt->total_samples_per_channel = flac_file->total_samples;
	enc_opt->samples_to_request = 1024;

	return 0;
}
Example #5
0
static bool
flac_decoder_initialize(struct flac_data *data, FLAC__StreamDecoder *sd,
			FLAC__uint64 duration)
{
	data->total_frames = duration;

	if (!FLAC__stream_decoder_process_until_end_of_metadata(sd)) {
		g_warning("problem reading metadata");
		return false;
	}

	if (data->initialized) {
		/* done */
		decoder_initialized(data->decoder, &data->audio_format,
				    data->input_stream->seekable,
				    (float)data->total_frames /
				    (float)data->audio_format.sample_rate);
		return true;
	}

	if (data->input_stream->seekable)
		/* allow the workaround below only for nonseekable
		   streams*/
		return false;

	/* no stream_info packet found; try to initialize the decoder
	   from the first frame header */
	FLAC__stream_decoder_process_single(sd);
	return data->initialized;
}
Example #6
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;
}
Example #7
0
static size_t read_samples(sox_format_t * const ft, sox_sample_t * sampleBuffer, size_t const requested)
{
  priv_t * p = (priv_t *)ft->priv;
  size_t actual = 0;

  if (p->seek_pending) {
    p->seek_pending = sox_false; 
    p->wide_sample_number = p->number_of_wide_samples = 0;
    if (!FLAC__stream_decoder_seek_absolute(p->decoder, (FLAC__uint64)(p->seek_offset / ft->signal.channels)))
      return 0;
  }
  while (!p->eof && actual < requested) {
    if (p->wide_sample_number >= p->number_of_wide_samples)
      FLAC__stream_decoder_process_single(p->decoder);
    if (p->wide_sample_number >= p->number_of_wide_samples)
      p->eof = sox_true;
    else { /* FIXME: this block should really be inside the decode callback */
      unsigned channel;

      for (channel = 0; channel < p->channels; channel++, actual++) {
        FLAC__int32 d = p->decoded_wide_samples[channel][p->wide_sample_number];
        switch (p->bits_per_sample) {
        case  8: *sampleBuffer++ = SOX_SIGNED_8BIT_TO_SAMPLE(d,); break;
        case 16: *sampleBuffer++ = SOX_SIGNED_16BIT_TO_SAMPLE(d,); break;
        case 24: *sampleBuffer++ = SOX_SIGNED_24BIT_TO_SAMPLE(d,); break;
        case 32: *sampleBuffer++ = SOX_SIGNED_32BIT_TO_SAMPLE(d,); break;
        }
      }
      ++p->wide_sample_number;
    }
  }
  return actual;
}
Example #8
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;
}
Example #9
0
FLAC__bool EasyFLAC__process_single(EasyFLAC__StreamDecoder *decoder)
{
    if (decoder->is_oggflac)
        return OggFLAC__stream_decoder_process_single(decoder->oggflac);
    else
        return FLAC__stream_decoder_process_single(decoder->flac);
}
Example #10
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;
    }
Example #11
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;
}
MediaBuffer *FLACParser::readBuffer(bool doSeek, FLAC__uint64 sample)
{
    mWriteRequested = true;
    mWriteCompleted = false;
    if (doSeek) {
        // We implement the seek callback, so this works without explicit flush
        if (!FLAC__stream_decoder_seek_absolute(mDecoder, sample)) {
            ALOGE("FLACParser::readBuffer seek to sample %lld failed", (long long)sample);
            return NULL;
        }
        ALOGV("FLACParser::readBuffer seek to sample %lld succeeded", (long long)sample);
    } else {
        if (!FLAC__stream_decoder_process_single(mDecoder)) {
            ALOGE("FLACParser::readBuffer process_single failed");
            return NULL;
        }
    }
    if (!mWriteCompleted) {
        ALOGV("FLACParser::readBuffer write did not complete");
        return NULL;
    }
    // verify that block header keeps the promises made by STREAMINFO
    unsigned blocksize = mWriteHeader.blocksize;
    if (blocksize == 0 || blocksize > getMaxBlockSize()) {
        ALOGE("FLACParser::readBuffer write invalid blocksize %u", blocksize);
        return NULL;
    }
    if (mWriteHeader.sample_rate != getSampleRate() ||
        mWriteHeader.channels != getChannels() ||
        mWriteHeader.bits_per_sample != getBitsPerSample()) {
        ALOGE("FLACParser::readBuffer write changed parameters mid-stream: %d/%d/%d -> %d/%d/%d",
                getSampleRate(), getChannels(), getBitsPerSample(),
                mWriteHeader.sample_rate, mWriteHeader.channels, mWriteHeader.bits_per_sample);
        return NULL;
    }
    // acquire a media buffer
    CHECK(mGroup != NULL);
    MediaBuffer *buffer;
    status_t err = mGroup->acquire_buffer(&buffer);
    if (err != OK) {
        return NULL;
    }
    size_t bufferSize = blocksize * getChannels() * sizeof(short);
    CHECK(bufferSize <= mMaxBufferSize);
    short *data = (short *) buffer->data();
    buffer->set_range(0, bufferSize);
    // copy PCM from FLAC write buffer to our media buffer, with interleaving
    (*mCopy)(data, mWriteBuffer, blocksize, getChannels());
    // fill in buffer metadata
    CHECK(mWriteHeader.number_type == FLAC__FRAME_NUMBER_TYPE_SAMPLE_NUMBER);
    FLAC__uint64 sampleNumber = mWriteHeader.number.sample_number;
    int64_t timeUs = (1000000LL * sampleNumber) / getSampleRate();
    buffer->meta_data()->setInt64(kKeyTime, timeUs);
    buffer->meta_data()->setInt32(kKeyIsSyncFrame, 1);
    return buffer;
}
Example #13
0
static GstFlowReturn
gst_flac_dec_handle_frame (GstAudioDecoder * audio_dec, GstBuffer * buf)
{
  GstFlacDec *dec;

  dec = GST_FLAC_DEC (audio_dec);

  /* drain remaining data? */
  if (G_UNLIKELY (buf == NULL)) {
    gst_flac_dec_flush (audio_dec, FALSE);
    return GST_FLOW_OK;
  }

  GST_LOG_OBJECT (dec, "frame: ts %" GST_TIME_FORMAT ", flags 0x%04x, "
      "%" G_GSIZE_FORMAT " bytes", GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (buf)),
      GST_BUFFER_FLAGS (buf), gst_buffer_get_size (buf));

  /* drop any in-stream headers, we've processed those in set_format already */
  if (G_UNLIKELY (!dec->got_headers)) {
    gboolean got_audio_frame;
    GstMapInfo map;

    /* check if this is a flac audio frame (rather than a header or junk) */
    gst_buffer_map (buf, &map, GST_MAP_READ);
    got_audio_frame =
        gst_flac_dec_scan_got_frame (dec, map.data, map.size, NULL);
    gst_buffer_unmap (buf, &map);

    if (!got_audio_frame) {
      GST_INFO_OBJECT (dec, "dropping in-stream header, %" G_GSIZE_FORMAT " "
          "bytes", map.size);
      gst_audio_decoder_finish_frame (audio_dec, NULL, 1);
      return GST_FLOW_OK;
    }

    GST_INFO_OBJECT (dec, "first audio frame, got all in-stream headers now");
    dec->got_headers = TRUE;
  }

  gst_adapter_push (dec->adapter, gst_buffer_ref (buf));
  buf = NULL;

  dec->last_flow = GST_FLOW_OK;

  /* framed - there should always be enough data to decode something */
  GST_LOG_OBJECT (dec, "%" G_GSIZE_FORMAT " bytes available",
      gst_adapter_available (dec->adapter));

  if (!FLAC__stream_decoder_process_single (dec->decoder)) {
    GST_INFO_OBJECT (dec, "process_single failed");
  }

  return dec->last_flow;
}
Example #14
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".");
	}
}
Example #15
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);
	}
}
Example #16
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;
}
Example #17
0
static void *flac_thread(void *arg) {
	FLAC_FEED *feed;
	feed = (FLAC_FEED *)arg;
	pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, NULL);
	pthread_mutex_lock(&(feed->base.thread_lock));
	if (feeds == NULL) feeds = new_unit();
	link_unit((MASH_UNIT *)feed, feeds);
	feed->base.running = 1;
	while (feed->base.running) {
		FLAC__stream_decoder_process_single(feed->decoder);
		pthread_cond_wait(&(feed->base.data_ready),
				&(feed->base.thread_lock));
		}
	pthread_mutex_unlock(&(feed->base.thread_lock));
	return NULL;
	}
Example #18
0
bool FlacDecoder::GetBuffer(IBuffer *buffer) {
    buffer->SetSampleRate(this->sampleRate);
    buffer->SetChannels(this->channels);

    /* read the next chunk */
    if (FLAC__stream_decoder_process_single(this->decoder)) {
        if (this->outputBuffer && this->outputBufferUsed > 0) {
            buffer->SetSamples(this->outputBufferUsed);
            memcpy(buffer->BufferPointer(), this->outputBuffer, this->outputBufferUsed * sizeof(float));
            this->outputBufferUsed = 0; /* mark consumed */
            return true;
        }
    }

    this->exhausted = true;
    return false;
}
FLAC_API FLAC__bool FLAC__seekable_stream_decoder_process_single(FLAC__SeekableStreamDecoder *decoder)
{
	FLAC__bool ret;
	FLAC__ASSERT(0 != decoder);

	if(decoder->private_->stream_decoder->protected_->state == FLAC__STREAM_DECODER_END_OF_STREAM)
		decoder->protected_->state = FLAC__SEEKABLE_STREAM_DECODER_END_OF_STREAM;

	if(decoder->protected_->state == FLAC__SEEKABLE_STREAM_DECODER_END_OF_STREAM)
		return true;

	FLAC__ASSERT(decoder->protected_->state == FLAC__SEEKABLE_STREAM_DECODER_OK);

	ret = FLAC__stream_decoder_process_single(decoder->private_->stream_decoder);
	if(!ret)
		decoder->protected_->state = FLAC__SEEKABLE_STREAM_DECODER_STREAM_DECODER_ERROR;

	return ret;
}
Example #20
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;
}
Example #21
0
clFLACDataProvider::clFLACDataProvider( const std::shared_ptr<clBlob>& Data )
: m_Data( Data )
, m_Format()
, m_StreamData( std::make_shared<sFLACStreamData>() )
, m_DecodingBuffer()
, m_BufferUsed( 0 )
, m_IsEndOfStream( false )
{
	{
		FLAC__StreamDecoderInitStatus Status = FLAC__stream_decoder_init_stream(
			m_StreamData->m_Decoder,
			&flacRead,
			&flacSeek,
			&flacTell,
			&flacLength,
			&flacEof,
			&flacWrite,
			&flacMeta,
			&flacError,
			this
		);
	}

	FLAC__bool Status = FLAC__stream_decoder_process_until_end_of_metadata( m_StreamData->m_Decoder );

	if ( !Status ) return;

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

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

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

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

	int TotalSamples = FLAC__stream_decoder_get_total_samples( m_StreamData->m_Decoder );
}
Example #22
0
static int audiosourceflac_InitFLAC(struct audiosource* source) {
    struct audiosourceflac_internaldata* idata =
            source->internaldata;

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

    idata->flacopened = 1;

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

    // we should have some information now
    return 1;
}
Example #23
0
/*Read more data for the encoder.*/
static long flac_read(void *client_data,float *buffer,int samples){
  flacfile *flac;
  int channels;
  float *block_buf;
  long ret;
  flac=(flacfile *)client_data;
  channels=flac->channels;
  block_buf=flac->block_buf;
  ret=0;
  /*Keep reading until we get all the samples or hit an error/EOF.
    Short reads are not allowed.*/
  while(samples>0){
    opus_int32 block_buf_pos;
    opus_int32 block_buf_len;
    size_t samples_to_copy;
    block_buf_pos=flac->block_buf_pos;
    block_buf_len=flac->block_buf_len;
    if(block_buf_pos>=block_buf_len){
      /*Read the next frame from the stream.*/
      if(!FLAC__stream_decoder_process_single(flac->decoder))return ret;
      block_buf_pos=flac->block_buf_pos;
      block_buf_len=flac->block_buf_len;
      /*If we didn't get another block, we hit EOF.
        FLAC__stream_decoder_process_single still returns successfully in this
        case.*/
      if(block_buf_pos>=block_buf_len)return ret;
    }
    block_buf_len-=block_buf_pos;
    samples_to_copy=samples<block_buf_len?samples:block_buf_len;
    memcpy(buffer,block_buf+block_buf_pos*channels,
       samples_to_copy*channels*sizeof(*buffer));
    flac->block_buf_pos+=samples_to_copy;
    ret+=samples_to_copy;
    buffer+=samples_to_copy*channels;
    samples-=samples_to_copy;
  }
  return ret;
}
	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;
	}
Example #25
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;
}
Example #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;
    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;
}
Example #27
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)));
}
FLAC__bool seek_to_absolute_sample_(FLAC__SeekableStreamDecoder *decoder, FLAC__uint64 stream_length, FLAC__uint64 target_sample)
{
	FLAC__uint64 first_frame_offset, lower_bound, upper_bound;
	FLAC__int64 pos = -1, last_pos = -1;
	int i, lower_seek_point = -1, upper_seek_point = -1;
	unsigned approx_bytes_per_frame;
	FLAC__uint64 last_frame_sample = FLAC__U64L(0xffffffffffffffff);
	FLAC__bool needs_seek;
	const FLAC__uint64 total_samples = decoder->private_->stream_info.total_samples;
	const unsigned min_blocksize = decoder->private_->stream_info.min_blocksize;
	const unsigned max_blocksize = decoder->private_->stream_info.max_blocksize;
	const unsigned max_framesize = decoder->private_->stream_info.max_framesize;
	const unsigned channels = FLAC__seekable_stream_decoder_get_channels(decoder);
	const unsigned bps = FLAC__seekable_stream_decoder_get_bits_per_sample(decoder);

	/* we are just guessing here, but we want to guess high, not low */
	if(max_framesize > 0) {
		approx_bytes_per_frame = max_framesize;
	}
	/*
	 * Check if it's a known fixed-blocksize stream.  Note that though
	 * the spec doesn't allow zeroes in the STREAMINFO block, we may
	 * never get a STREAMINFO block when decoding so the value of
	 * min_blocksize might be zero.
	 */
	else if(min_blocksize == max_blocksize && min_blocksize > 0) {
		/* note there are no () around 'bps/8' to keep precision up since it's an integer calulation */
		approx_bytes_per_frame = min_blocksize * channels * bps/8 + 64;
	}
	else
		approx_bytes_per_frame = 4608 * channels * bps/8 + 64;

	/*
	 * The decode position is currently at the first frame since we
	 * rewound and processed metadata.
	 */
	if(!FLAC__seekable_stream_decoder_get_decode_position(decoder, &first_frame_offset)) {
		decoder->protected_->state = FLAC__SEEKABLE_STREAM_DECODER_SEEK_ERROR;
		return false;
	}

	/*
	 * First, we set an upper and lower bound on where in the
	 * stream we will search.  For now we assume the worst case
	 * scenario, which is our best guess at the beginning of
	 * the first and last frames.
	 */
	lower_bound = first_frame_offset;

	/* calc the upper_bound, beyond which we never want to seek */
	if(max_framesize > 0)
		upper_bound = stream_length - (max_framesize + 128 + 2); /* 128 for a possible ID3V1 tag, 2 for indexing differences */
	else
		upper_bound = stream_length - ((channels * bps * FLAC__MAX_BLOCK_SIZE) / 8 + 128 + 2);

	/*
	 * Now we refine the bounds if we have a seektable with
	 * suitable points.  Note that according to the spec they
	 * must be ordered by ascending sample number.
	 */
	if(0 != decoder->private_->seek_table) {
		/* find the closest seek point <= target_sample, if it exists */
		for(i = (int)decoder->private_->seek_table->num_points - 1; i >= 0; i--) {
			if(decoder->private_->seek_table->points[i].sample_number != FLAC__STREAM_METADATA_SEEKPOINT_PLACEHOLDER && decoder->private_->seek_table->points[i].sample_number <= target_sample)
				break;
		}
		if(i >= 0) { /* i.e. we found a suitable seek point... */
			lower_bound = first_frame_offset + decoder->private_->seek_table->points[i].stream_offset;
			lower_seek_point = i;
		}

		/* find the closest seek point > target_sample, if it exists */
		for(i = 0; i < (int)decoder->private_->seek_table->num_points; i++) {
			if(decoder->private_->seek_table->points[i].sample_number != FLAC__STREAM_METADATA_SEEKPOINT_PLACEHOLDER && decoder->private_->seek_table->points[i].sample_number > target_sample)
				break;
		}
		if(i < (int)decoder->private_->seek_table->num_points) { /* i.e. we found a suitable seek point... */
			upper_bound = first_frame_offset + decoder->private_->seek_table->points[i].stream_offset;
			upper_seek_point = i;
		}
	}

	/*
	 * Now guess at where within those bounds our target
	 * sample will be.
	 */
	if(lower_seek_point >= 0) {
		/* first see if our sample is within a few frames of the lower seekpoint */
		if(decoder->private_->seek_table->points[lower_seek_point].sample_number <= target_sample && target_sample < decoder->private_->seek_table->points[lower_seek_point].sample_number + (decoder->private_->seek_table->points[lower_seek_point].frame_samples * 4)) {
			pos = (FLAC__int64)lower_bound;
		}
		else if(upper_seek_point >= 0) {
			const FLAC__uint64 target_offset = target_sample - decoder->private_->seek_table->points[lower_seek_point].sample_number;
			const FLAC__uint64 range_samples = decoder->private_->seek_table->points[upper_seek_point].sample_number - decoder->private_->seek_table->points[lower_seek_point].sample_number;
			const FLAC__uint64 range_bytes = upper_bound - lower_bound;
#if defined _MSC_VER || defined __MINGW32__
			/* with VC++ you have to spoon feed it the casting */
			pos = (FLAC__int64)lower_bound + (FLAC__int64)((double)(FLAC__int64)target_offset / (double)(FLAC__int64)range_samples * (double)(FLAC__int64)(range_bytes-1)) - approx_bytes_per_frame;
#else
			pos = (FLAC__int64)lower_bound + (FLAC__int64)((double)target_offset / (double)range_samples * (double)(range_bytes-1)) - approx_bytes_per_frame;
#endif
		}
	}

	/*
	 * If there's no seek table, we need to use the metadata (if we
	 * have it) and the filelength to estimate the position of the
	 * frame with the correct sample.
	 */
	if(pos < 0 && total_samples > 0) {
#if defined _MSC_VER || defined __MINGW32__
		/* with VC++ you have to spoon feed it the casting */
		pos = (FLAC__int64)first_frame_offset + (FLAC__int64)((double)(FLAC__int64)target_sample / (double)(FLAC__int64)total_samples * (double)(FLAC__int64)(stream_length-first_frame_offset-1)) - approx_bytes_per_frame;
#else
		pos = (FLAC__int64)first_frame_offset + (FLAC__int64)((double)target_sample / (double)total_samples * (double)(stream_length-first_frame_offset-1)) - approx_bytes_per_frame;
#endif
	}

	/*
	 * If there's no seek table and total_samples is unknown, we
	 * don't even bother trying to figure out a target, we just use
	 * our current position.
	 */
	if(pos < 0) {
		FLAC__uint64 upos;
		if(decoder->private_->tell_callback(decoder, &upos, decoder->private_->client_data) != FLAC__SEEKABLE_STREAM_DECODER_TELL_STATUS_OK) {
			decoder->protected_->state = FLAC__SEEKABLE_STREAM_DECODER_SEEK_ERROR;
			return false;
		}
		pos = (FLAC__int64)upos;
		needs_seek = false;
	}
	else
		needs_seek = true;

	/* clip the position to the bounds, lower bound takes precedence */
	if(pos >= (FLAC__int64)upper_bound) {
		pos = (FLAC__int64)upper_bound-1;
		needs_seek = true;
	}
	if(pos < (FLAC__int64)lower_bound) {
		pos = (FLAC__int64)lower_bound;
		needs_seek = true;
	}

	decoder->private_->target_sample = target_sample;
	while(1) {
		if(needs_seek) {
			if(decoder->private_->seek_callback(decoder, (FLAC__uint64)pos, decoder->private_->client_data) != FLAC__SEEKABLE_STREAM_DECODER_SEEK_STATUS_OK) {
				decoder->protected_->state = FLAC__SEEKABLE_STREAM_DECODER_SEEK_ERROR;
				return false;
			}
			if(!FLAC__stream_decoder_flush(decoder->private_->stream_decoder)) {
				decoder->protected_->state = FLAC__SEEKABLE_STREAM_DECODER_STREAM_DECODER_ERROR;
				return false;
			}
		}
		/* Now we need to get a frame.  It is possible for our seek
		 * to land in the middle of audio data that looks exactly like
		 * a frame header from a future version of an encoder.  When
		 * that happens, FLAC__stream_decoder_process_single() will
		 * return false and the state will be
		 * FLAC__STREAM_DECODER_UNPARSEABLE_STREAM.  But there is a
		 * remote possibility that it is properly synced at such a
		 * "future-codec frame", so to make sure, we wait to see
		 * several "unparseable" errors in a row before bailing out.
		 */
		{
			unsigned unparseable_count;
			FLAC__bool got_a_frame = false;
			for (unparseable_count = 0; !got_a_frame && unparseable_count < 10; unparseable_count++) {
				if(FLAC__stream_decoder_process_single(decoder->private_->stream_decoder))
					got_a_frame = true;
				else if(decoder->private_->stream_decoder->protected_->state == FLAC__STREAM_DECODER_UNPARSEABLE_STREAM)
					/* try again.  we don't want to flush the decoder since that clears the bitbuffer */
					decoder->private_->stream_decoder->protected_->state = FLAC__STREAM_DECODER_SEARCH_FOR_FRAME_SYNC;
				else /* it's a real error */
					break;
			}
			if (!got_a_frame) {
				decoder->protected_->state = FLAC__SEEKABLE_STREAM_DECODER_SEEK_ERROR;
				return false;
			}
		}
		/* our write callback will change the state when it gets to the target frame */
		if(decoder->protected_->state != FLAC__SEEKABLE_STREAM_DECODER_SEEKING) {
			break;
		}
		else { /* we need to narrow the search */
			const FLAC__uint64 this_frame_sample = decoder->private_->last_frame.header.number.sample_number;
			FLAC__ASSERT(decoder->private_->last_frame.header.number_type == FLAC__FRAME_NUMBER_TYPE_SAMPLE_NUMBER);
			if(this_frame_sample == last_frame_sample && pos < last_pos) {
				/* our last move backwards wasn't big enough, double it */
				pos -= (last_pos - pos);
				needs_seek = true;
			}
			else {
				if(target_sample < this_frame_sample) {
					last_pos = pos;
					approx_bytes_per_frame = decoder->private_->last_frame.header.blocksize * channels * bps/8 + 64;
					pos -= approx_bytes_per_frame;
					needs_seek = true;
				}
				else { /* target_sample >= this_frame_sample + this frame's blocksize */
					FLAC__uint64 upos;
					if(decoder->private_->tell_callback(decoder, &upos, decoder->private_->client_data) != FLAC__SEEKABLE_STREAM_DECODER_TELL_STATUS_OK) {
						decoder->protected_->state = FLAC__SEEKABLE_STREAM_DECODER_SEEK_ERROR;
						return false;
					}
					last_pos = pos;
					pos = (FLAC__int64)upos;
					pos -= FLAC__stream_decoder_get_input_bytes_unconsumed(decoder->private_->stream_decoder);
					needs_seek = false;
					/*
					 * if we haven't hit the target frame yet and our position hasn't changed,
					 * it means we're at the end of the stream and the seek target does not exist.
					 */
					if(last_pos == pos) {
						decoder->protected_->state = FLAC__SEEKABLE_STREAM_DECODER_SEEK_ERROR;
						return false;
					}
				}
			}
			if(pos < (FLAC__int64)lower_bound)
				pos = (FLAC__int64)lower_bound;
			last_frame_sample = this_frame_sample;
		}
	}

	return true;
}
Example #29
0
/* read mode:
 * 0 - no read after seek
 * 1 - read 2 frames
 * 2 - read until end
 */
static FLAC__bool seek_barrage(FLAC__bool is_ogg, const char *filename, off_t filesize, unsigned count, FLAC__int64 total_samples, unsigned read_mode)
{
	FLAC__StreamDecoder *decoder;
	DecoderClientData decoder_client_data;
	unsigned i;
	long int n;

	decoder_client_data.got_data = false;
	decoder_client_data.total_samples = 0;
	decoder_client_data.quiet = false;
	decoder_client_data.ignore_errors = false;
	decoder_client_data.error_occurred = false;

	printf("\n+++ seek test: FLAC__StreamDecoder (%s FLAC, read_mode=%u)\n\n", is_ogg? "Ogg":"native", read_mode);

	decoder = FLAC__stream_decoder_new();
	if(0 == decoder)
		return die_("FLAC__stream_decoder_new() FAILED, returned NULL\n");

	if(is_ogg) {
		if(FLAC__stream_decoder_init_ogg_file(decoder, filename, write_callback_, metadata_callback_, error_callback_, &decoder_client_data) != FLAC__STREAM_DECODER_INIT_STATUS_OK)
			return die_s_("FLAC__stream_decoder_init_file() FAILED", decoder);
	}
	else {
		if(FLAC__stream_decoder_init_file(decoder, filename, write_callback_, metadata_callback_, error_callback_, &decoder_client_data) != FLAC__STREAM_DECODER_INIT_STATUS_OK)
			return die_s_("FLAC__stream_decoder_init_file() FAILED", decoder);
	}

	if(!FLAC__stream_decoder_process_until_end_of_metadata(decoder))
		return die_s_("FLAC__stream_decoder_process_until_end_of_metadata() FAILED", decoder);

	if(!is_ogg) { /* not necessary to do this for Ogg because of its seeking method */
	/* process until end of stream to make sure we can still seek in that state */
		decoder_client_data.quiet = true;
		if(!FLAC__stream_decoder_process_until_end_of_stream(decoder))
			return die_s_("FLAC__stream_decoder_process_until_end_of_stream() FAILED", decoder);
		decoder_client_data.quiet = false;

		printf("stream decoder state is %s\n", FLAC__stream_decoder_get_resolved_state_string(decoder));
		if(FLAC__stream_decoder_get_state(decoder) != FLAC__STREAM_DECODER_END_OF_STREAM)
			return die_s_("expected FLAC__STREAM_DECODER_END_OF_STREAM", decoder);
	}

#ifdef _MSC_VER
	printf("file's total_samples is %I64u\n", decoder_client_data.total_samples);
#else
	printf("file's total_samples is %llu\n", (unsigned long long)decoder_client_data.total_samples);
#endif
#if !defined _MSC_VER && !defined __MINGW32__ && !defined __EMX__
	if (decoder_client_data.total_samples > (FLAC__uint64)RAND_MAX) {
		printf("ERROR: must be total_samples < %u\n", (unsigned)RAND_MAX);
		return false;
	}
#endif
	n = (long int)decoder_client_data.total_samples;

	if(n == 0 && total_samples >= 0)
		n = (long int)total_samples;

	/* if we don't have a total samples count, just guess based on the file size */
	/* @@@ for is_ogg we should get it from last page's granulepos */
	if(n == 0) {
		/* 8 would imply no compression, 9 guarantees that we will get some samples off the end of the stream to test that case */
		n = 9 * filesize / (decoder_client_data.channels * decoder_client_data.bits_per_sample);
#if !defined _MSC_VER && !defined __MINGW32__
		if(n > RAND_MAX)
			n = RAND_MAX;
#endif
	}

	printf("Begin seek barrage, count=%u\n", count);

	for (i = 0; !stop_signal_ && (count == 0 || i < count); i++) {
		FLAC__uint64 pos;

		/* for the first 10, seek to the first 10 samples */
		if (n >= 10 && i < 10) {
			pos = i;
		}
		/* for the second 10, seek to the last 10 samples */
		else if (n >= 10 && i < 20) {
			pos = n - 1 - (i-10);
		}
		/* for the third 10, seek past the end and make sure we fail properly as expected */
		else if (i < 30) {
			pos = n + (i-20);
		}
		else {
#if !defined _MSC_VER && !defined __MINGW32__
			pos = (FLAC__uint64)(random() % n);
#else
			/* RAND_MAX is only 32767 in my MSVC */
			pos = (FLAC__uint64)((rand()<<15|rand()) % n);
#endif
		}

#ifdef _MSC_VER
		printf("seek(%I64u)... ", pos);
#else
		printf("seek(%llu)... ", (unsigned long long)pos);
#endif
		fflush(stdout);
		if(!FLAC__stream_decoder_seek_absolute(decoder, pos)) {
			if(pos >= (FLAC__uint64)n)
				printf("seek past end failed as expected... ");
			else if(decoder_client_data.total_samples == 0 && total_samples <= 0)
				printf("seek failed, assuming it was past EOF... ");
			else
				return die_s_("FLAC__stream_decoder_seek_absolute() FAILED", decoder);
			if(!FLAC__stream_decoder_flush(decoder))
				return die_s_("FLAC__stream_decoder_flush() FAILED", decoder);
		}
		else if(read_mode == 1) {
			printf("decode_frame... ");
			fflush(stdout);
			if(!FLAC__stream_decoder_process_single(decoder))
				return die_s_("FLAC__stream_decoder_process_single() FAILED", decoder);

			printf("decode_frame... ");
			fflush(stdout);
			if(!FLAC__stream_decoder_process_single(decoder))
				return die_s_("FLAC__stream_decoder_process_single() FAILED", decoder);
		}
		else if(read_mode == 2) {
			printf("decode_all... ");
			fflush(stdout);
			decoder_client_data.quiet = true;
			if(!FLAC__stream_decoder_process_until_end_of_stream(decoder))
				return die_s_("FLAC__stream_decoder_process_until_end_of_stream() FAILED", decoder);
			decoder_client_data.quiet = false;
		}

		printf("OK\n");
		fflush(stdout);
	}

	if(FLAC__stream_decoder_get_state(decoder) != FLAC__STREAM_DECODER_UNINITIALIZED) {
		if(!FLAC__stream_decoder_finish(decoder))
			return die_s_("FLAC__stream_decoder_finish() FAILED", decoder);
	}

	FLAC__stream_decoder_delete(decoder);
	printf("\nPASSED!\n");

	return true;
}
Example #30
0
unsigned FLAC_plugin__decode(FLAC__StreamDecoder *decoder, stream_data_struct *stream_data, char *sample_buffer)
{
	/* fill reservoir */
	while (wide_samples_in_reservoir_ < SAMPLES_PER_WRITE)
	{
		if (FLAC__stream_decoder_get_state(decoder) == FLAC__STREAM_DECODER_END_OF_STREAM)
		{
			stream_data->eof = true;
			break;
		}
		else if (!FLAC__stream_decoder_process_single(decoder))
		{
			FLAC_plugin__show_error("Error while processing frame (%s).", FLAC__stream_decoder_get_resolved_state_string(decoder));
			stream_data->eof = true;
			break;
		}
		if (!FLAC__stream_decoder_get_decode_position(decoder, &decode_position))
			decode_position = 0;
	}
	/* output samples */
	if (wide_samples_in_reservoir_ > 0)
	{
		const unsigned n = min(wide_samples_in_reservoir_, SAMPLES_PER_WRITE);
		const unsigned channels = stream_data->channels;
		unsigned i;
		int bytes;

		if (cfg.replaygain.enable && stream_data->has_replaygain)
		{
			bytes = FLAC__replaygain_synthesis__apply_gain(
				sample_buffer,
				true, /* little_endian_data_out */
				stream_data->output_bits_per_sample == 8, /* unsigned_data_out */
				reservoir__,
				n,
				channels,
				stream_data->bits_per_sample,
				stream_data->output_bits_per_sample,
				stream_data->replay_scale,
				cfg.replaygain.hard_limit,
				cfg.resolution.replaygain.dither,
				&stream_data->dither_context
			);
		}
		else
		{
			bytes = FLAC__plugin_common__pack_pcm_signed_little_endian(
				sample_buffer,
				reservoir__,
				n,
				channels,
				stream_data->bits_per_sample,
				stream_data->output_bits_per_sample
			);
		}

		wide_samples_in_reservoir_ -= n;
		for (i = 0; i < channels; i++)
			memmove(&reservoir_[i][0], &reservoir_[i][n], sizeof(reservoir_[0][0]) * wide_samples_in_reservoir_);

		return bytes;
	}
	else
	{
		stream_data->eof = true;
		return 0;
	}
}