Вот функция:
Код: Выделить всё
AudioResource::ReturnCode AudioResource::LoadFromFile(std::string FilePath)
{
std::string FileURL = "file:" + FilePath;
AVFormatContext* FormatContext = nullptr;
int Error = avformat_open_input(&FormatContext, FileURL.c_str(), nullptr, nullptr);
if (Error < 0)
{
return ERROR_OPENING_FILE;
}
Error = avformat_find_stream_info(FormatContext, nullptr);
if (Error < 0)
{
return ERROR_FINDING_STREAM_INFO;
}
int AudioStream = -1;
AVCodecParameters* CodecParams;
for (int i = 0; i < FormatContext->nb_streams; i++)
{
if (FormatContext->streams[i]->codecpar->codec_type == AVMEDIA_TYPE_AUDIO)
{
CodecParams = FormatContext->streams[i]->codecpar;
AudioStream = i;
}
}
if (AudioStream == -1)
{
return ERROR_AUDIO_STREAM_NOT_FOUND;
}
SampleRate = FormatContext->streams[AudioStream]->codecpar->sample_rate;
AVSampleFormat SampleFormat = (AVSampleFormat) FormatContext->streams[AudioStream]->codecpar->format;
Channels = FormatContext->streams[AudioStream]->codecpar->ch_layout.nb_channels;
if (Channels > 2)
{
return ERROR_UNSUPPORTED_CHANNEL_COUNT;
}
switch (SampleFormat)
{
case AV_SAMPLE_FMT_NONE:
return ERROR_UNKWON_SAMPLE_FORMAT;
break;
case AV_SAMPLE_FMT_U8:
BytesPerSample = 1;
if (Channels == 1)
{
SampleType == MONO_8BIT;
}
else
{
SampleType = STEREO_8BIT;
}
break;
case AV_SAMPLE_FMT_S16:
BytesPerSample = 2;
if (Channels == 1)
{
SampleType = MONO_16BIT;
}
else
{
SampleType = STEREO_16BIT;
}
break;
case AV_SAMPLE_FMT_S32:
BytesPerSample = 2;
if (Channels == 1)
{
SampleType = MONO_16BIT;
}
else
{
SampleType= STEREO_16BIT;
}
break;
case AV_SAMPLE_FMT_FLT:
BytesPerSample = 2;
if (Channels == 1)
{
SampleType = MONO_16BIT;
}
else
{
SampleType = STEREO_16BIT;
}
break;
case AV_SAMPLE_FMT_DBL:
BytesPerSample = 2;
if (Channels == 1)
{
SampleType = MONO_16BIT;
}
else
{
SampleType = STEREO_16BIT;
}
break;
case AV_SAMPLE_FMT_U8P:
BytesPerSample = 1;
if (Channels == 1)
{
SampleType = MONO_8BIT;
}
else
{
SampleType = STEREO_8BIT;
}
break;
case AV_SAMPLE_FMT_S16P:
BytesPerSample = 2;
if (Channels == 1)
{
SampleType = MONO_16BIT;
}
else
{
SampleType = STEREO_16BIT;
}
break;
case AV_SAMPLE_FMT_S32P:
BytesPerSample = 2;
if (Channels == 1)
{
SampleType = MONO_16BIT;
}
else
{
SampleType = STEREO_16BIT;
}
break;
case AV_SAMPLE_FMT_FLTP:
BytesPerSample = 2;
if (Channels == 1)
{
SampleType = MONO_16BIT;
}
else
{
SampleType = STEREO_16BIT;
}
break;
case AV_SAMPLE_FMT_DBLP:
BytesPerSample = 2;
if (Channels == 1)
{
SampleType = MONO_16BIT;
}
else
{
SampleType = STEREO_16BIT;
}
break;
case AV_SAMPLE_FMT_S64:
BytesPerSample = 2;
if (Channels == 1)
{
SampleType = MONO_16BIT;
}
else
{
SampleType = STEREO_16BIT;
}
break;
case AV_SAMPLE_FMT_S64P:
BytesPerSample = 2;
if (Channels == 1)
{
SampleType = MONO_16BIT;
}
else
{
SampleType = STEREO_16BIT;
}
break;
default:
return ERROR_UNKWON_SAMPLE_FORMAT;
break;
}
const AVCodec* AudioCodec = avcodec_find_decoder(CodecParams->codec_id);
AVCodecContext* CodecContext = avcodec_alloc_context3(AudioCodec);
avcodec_parameters_to_context(CodecContext, CodecParams);
avcodec_open2(CodecContext, AudioCodec, nullptr);
AVPacket* CurrentPacket = av_packet_alloc();
AVFrame* CurrentFrame = av_frame_alloc();
while (av_read_frame(FormatContext, CurrentPacket) >= 0)
{
avcodec_send_packet(CodecContext, CurrentPacket);
for (;;)
{
Error = avcodec_receive_frame(CodecContext, CurrentFrame);
if ((Error == AVERROR(EAGAIN)) || (Error == AVERROR_EOF))
{
break;
}
else if (Error == AVERROR(EINVAL))
{
return ERROR_RECIVING_FRAME;
}
else if (Error != 0)
{
return ERROR_UNEXSPECTED;
}
if (SampleFormat == AV_SAMPLE_FMT_U8)
{
}
else if (SampleFormat == AV_SAMPLE_FMT_S16)
{
}
else if (SampleFormat == AV_SAMPLE_FMT_S32)
{
}
else if (SampleFormat == AV_SAMPLE_FMT_FLT)
{
}
else if (SampleFormat == AV_SAMPLE_FMT_DBL)
{
}
else if (SampleFormat == AV_SAMPLE_FMT_U8P)
{
}
else if (SampleFormat == AV_SAMPLE_FMT_S16P)
{
}
else if (SampleFormat == AV_SAMPLE_FMT_S32P)
{
}
else if (SampleFormat == AV_SAMPLE_FMT_FLTP) //
{
if (Channels == 2)
{
for (size_t i = 0; i < CurrentFrame->linesize[0]; i += sizeof(float))
{
float CurrentLeftSample = 0.0f;
float CurrentRightSample = 0.0f;
memcpy(&CurrentLeftSample, &CurrentFrame->data[0][i], sizeof(float));
memcpy(&CurrentRightSample, &CurrentFrame->data[1][i], sizeof(float));
short int QuantizedLeftSample = roundf(CurrentLeftSample * 0x7fff);
short int QuantizedRightSample = roundf(CurrentRightSample * 0x7fff);
LoadByteData(QuantizedLeftSample, AudioData);
LoadByteData(QuantizedRightSample, AudioData);
}
}
else
{
}
}
else if (SampleFormat == AV_SAMPLE_FMT_DBLP)
{
}
else if (SampleFormat == AV_SAMPLE_FMT_S64)
{
}
else if (SampleFormat == AV_SAMPLE_FMT_S64P)
{
}
else
{
return ERROR_UNEXSPECTED;
}
}
}
av_frame_free(&CurrentFrame);
av_packet_free(&CurrentPacket);
avcodec_free_context(&CodecContext);
avformat_free_context(FormatContext);
return OK;
}
Код: Выделить всё
for (size_t i = 0; i < CurrentFrame->linesize[0]; i += sizeof(float))
{
float CurrentLeftSample = 0.0f;
float CurrentRightSample = 0.0f;
memcpy(&CurrentLeftSample, &CurrentFrame->data[0][i], sizeof(float));
memcpy(&CurrentRightSample, &CurrentFrame->data[1][i], sizeof(float));
short int QuantizedLeftSample = roundf(CurrentLeftSample * 0x7fff);
short int QuantizedRightSample = roundf(CurrentRightSample * 0x7fff);
LoadByteData(QuantizedLeftSample, AudioData);
LoadByteData(QuantizedRightSample, AudioData);
}
Будем очень благодарны за любую помощь.
Подробнее здесь: https://stackoverflow.com/questions/791 ... ld-samples
Мобильная версия