<commit_before>#include "MP3DataProvider.h"
#include "Utils.h"

extern "C"
{
#include "minimp3/minimp3.h"
}

clMP3DataProvider::clMP3DataProvider( const std::shared_ptr<clBlob>& Data )
: m_Data( Data )
, m_Format()
, m_DecodingBuffer( MP3_MAX_SAMPLES_PER_FRAME * 16 )
, m_BufferUsed( 0 )
, m_StreamPos( 0 )
, m_InitialStreamPos( 0 )
, m_IsEndOfStream( false )
, m_MP3Decoder( mp3_create() )
{
	LoadMP3Info();

	m_Format.m_NumChannels      = m_MP3Info.channels;
	m_Format.m_SamplesPerSecond = m_MP3Info.sample_rate;
	m_Format.m_BitsPerSample    = 16;
}

clMP3DataProvider::~clMP3DataProvider()
{
	mp3_done( (mp3_decoder_t*)m_MP3Decoder );
}

void clMP3DataProvider::LoadMP3Info()
{
	int byteCount = mp3_decode(
		(mp3_decoder_t*)m_MP3Decoder,
		m_Data ? const_cast<uint8_t*>( m_Data->GetDataPtr() ) : nullptr,
		m_Data ? m_Data->GetDataSize() : 0,
		(signed short*)m_DecodingBuffer.data(),
		&m_MP3Info
	);

	m_StreamPos += byteCount;
	m_InitialStreamPos = m_StreamPos;
}

const uint8_t* clMP3DataProvider::GetWaveData() const
{
	return m_DecodingBuffer.data();
}

size_t clMP3DataProvider::GetWaveDataSize() const
{
	return m_BufferUsed;
}

int clMP3DataProvider::DecodeFromFile( size_t BytesRead )
{
	if ( m_IsEndOfStream || !m_Data )
	{
		return 0;
	}

	size_t ByteCount = mp3_decode(
		(mp3_decoder_t*)m_MP3Decoder,
		const_cast<uint8_t*>( m_Data->GetDataPtr() + m_StreamPos ),
		m_Data->GetDataSize() - m_StreamPos,
		(signed short*)( m_DecodingBuffer.data() + BytesRead ),
		&m_MP3Info
	);

	m_StreamPos += ByteCount;

	if ( m_StreamPos >= m_Data->GetDataSize() )
	{
		m_IsEndOfStream = true;
	}

	return m_MP3Info.audio_bytes;
}

size_t clMP3DataProvider::StreamWaveData( size_t Size )
{
	if ( m_IsEndOfStream )
	{
		return 0;
	}

	size_t OldSize = m_DecodingBuffer.size();

	if ( Size > OldSize )
	{
		m_DecodingBuffer.resize( Size, 0 );
	}

	size_t BytesRead = 0;

	while ( BytesRead + MP3_MAX_SAMPLES_PER_FRAME * 2 < Size )
	{
		int Ret = DecodeFromFile( BytesRead );

		if ( Ret > 0 )
		{
			BytesRead += Ret;
		}
		else if ( Ret == 0 )
		{
			m_IsEndOfStream = true;
			break;
		}
		else
		{
			// there is no audio data in this frame, just skip it
		}
	}									

	m_BufferUsed = BytesRead;

	return m_BufferUsed;
}

void clMP3DataProvider::Seek( float Seconds )
{
	mp3_done( (mp3_decoder_t*)m_MP3Decoder );
	m_MP3Decoder = mp3_create();

	m_StreamPos = 0;
	m_IsEndOfStream = false;

	LoadMP3Info();
}
<commit_msg>MP3: fixed empty frames<commit_after>#include "MP3DataProvider.h"
#include "Utils.h"

extern "C"
{
#include "minimp3/minimp3.h"
}

clMP3DataProvider::clMP3DataProvider( const std::shared_ptr<clBlob>& Data )
: m_Data( Data )
, m_Format()
, m_DecodingBuffer( MP3_MAX_SAMPLES_PER_FRAME * 16 )
, m_BufferUsed( 0 )
, m_StreamPos( 0 )
, m_InitialStreamPos( 0 )
, m_IsEndOfStream( false )
, m_MP3Decoder( mp3_create() )
{
	LoadMP3Info();

	m_Format.m_NumChannels      = m_MP3Info.channels;
	m_Format.m_SamplesPerSecond = m_MP3Info.sample_rate;
	m_Format.m_BitsPerSample    = 16;
}

clMP3DataProvider::~clMP3DataProvider()
{
	mp3_done( (mp3_decoder_t*)m_MP3Decoder );
}

void clMP3DataProvider::LoadMP3Info()
{
	int byteCount = mp3_decode(
		(mp3_decoder_t*)m_MP3Decoder,
		m_Data ? const_cast<uint8_t*>( m_Data->GetDataPtr() ) : nullptr,
		m_Data ? m_Data->GetDataSize() : 0,
		(signed short*)m_DecodingBuffer.data(),
		&m_MP3Info
	);

	m_StreamPos += byteCount;
	m_InitialStreamPos = m_StreamPos;
}

const uint8_t* clMP3DataProvider::GetWaveData() const
{
	return m_DecodingBuffer.data();
}

size_t clMP3DataProvider::GetWaveDataSize() const
{
	return m_BufferUsed;
}

int clMP3DataProvider::DecodeFromFile( size_t BytesRead )
{
	if ( m_IsEndOfStream || !m_Data )
	{
		return 0;
	}

	size_t ByteCount = mp3_decode(
		(mp3_decoder_t*)m_MP3Decoder,
		const_cast<uint8_t*>( m_Data->GetDataPtr() + m_StreamPos ),
		m_Data->GetDataSize() - m_StreamPos,
		(signed short*)( m_DecodingBuffer.data() + BytesRead ),
		&m_MP3Info
	);

	m_StreamPos += ByteCount;

	if ( m_StreamPos >= m_Data->GetDataSize() || !ByteCount )
	{
		m_IsEndOfStream = true;
	}

	return m_MP3Info.audio_bytes;
}

size_t clMP3DataProvider::StreamWaveData( size_t Size )
{
	if ( m_IsEndOfStream )
	{
		return 0;
	}

	size_t OldSize = m_DecodingBuffer.size();

	if ( Size > OldSize )
	{
		m_DecodingBuffer.resize( Size, 0 );
	}

	size_t BytesRead = 0;

	while ( BytesRead + MP3_MAX_SAMPLES_PER_FRAME * 2 < Size )
	{
		int Ret = DecodeFromFile( BytesRead );

		if ( Ret > 0 )
		{
			BytesRead += Ret;
		}
		else if ( Ret == 0 )
		{
			m_IsEndOfStream = true;
			break;
		}
		else
		{
			// there is no audio data in this frame, just skip it
		}
	}									

	m_BufferUsed = BytesRead;

	return m_BufferUsed;
}

void clMP3DataProvider::Seek( float Seconds )
{
	mp3_done( (mp3_decoder_t*)m_MP3Decoder );
	m_MP3Decoder = mp3_create();

	m_StreamPos = 0;
	m_IsEndOfStream = false;

	LoadMP3Info();
}

{'fraction_non_alphanumeric': 0.12505125051250512, 'fraction_numerical': 0.023985239852398525, 'mean_word_length': 4.4453125, 'pattern_counts': {'":': 0, '<': 11, '<?xml version=': 0, '>': 25, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 24, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5269493', 'n_tokens_mistral': 2182, 'n_tokens_neox': 2029, 'n_words': 346}