在不改变音调启动的情况下增加声音变化的音频速度
{
//--------------------------------------------------------------------------------------
/*add sonic change audio speed without changing tone start*/
if (!is->sonic_handle)
{
is->sonic_handle = sonicCreateStream(is->audio_tgt.freq, is->audio_tgt.channels);
}
sonicStream sStream = is->sonic_handle;
sonicSetSpeed(sStream, is->pf_playback_rate);
sonicWriteShortToStream(sStream, (short *)is->audio_buf, len2);
int shortRead;
//Read short data out of the stream
shortRead = sonicReadShortFromStream(sStream, (short *)is->audio_buf1, len2 / is->pf_playback_rate);
if (shortRead <= 0)
{
//no data will be available
av_log(NULL, AV_LOG_WARNING, "sonicReadShortFromStream , no data will be available\n");
return -1;
}
else
{
is->audio_buf = is->audio_buf1;
resampled_data_size = shortRead * is->audio_tgt.channels * av_get_bytes_per_sample(is->audio_tgt.fmt);
}
/*add sonic change audio speed end*/
//--------------------------------------------------------------------------------------
}
full
{
int DecodeEngine::audio_decode_frame(AVState *is)
{
int data_size, resampled_data_size;
int64_t dec_channel_layout;
av_unused double audio_clock0;
int wanted_nb_samples;
Frame *af;
if (is->paused)
return -1;
do
{
#if defined(_WIN32)
while (FrameQueues::frame_queue_nb_remaining(&is->sampq) == 0)
{
is->audio_hw_buf_size = 8192;
if ((av_gettime_relative() - audio_callback_time) > 1000000LL * is->audio_hw_buf_size / is->audio_tgt.bytes_per_sec / 2)
return -1;
av_usleep(1000);
}
#endif
if (!(af = FrameQueues::frame_queue_peek_readable(&is->sampq)))
return -1;
FrameQueues::frame_queue_next(&is->sampq);
} while (af->serial != is->audioq.serial);
data_size = av_samples_get_buffer_size(NULL, af->frame->channels,
af->frame->nb_samples,
(AVSampleFormat)af->frame->format, 1);
dec_channel_layout =
(af->frame->channel_layout && af->frame->channels == av_get_channel_layout_nb_channels(af->frame->channel_layout)) ?
af->frame->channel_layout : av_get_default_channel_layout(af->frame->channels);
wanted_nb_samples = synchronize_audio(is, af->frame->nb_samples);
if (af->frame->format != is->audio_src.fmt ||
dec_channel_layout != is->audio_src.channel_layout ||
af->frame->sample_rate != is->audio_src.freq ||
(wanted_nb_samples != af->frame->nb_samples && !is->swr_ctx))
{
swr_free(&is->swr_ctx);
is->swr_ctx = swr_alloc_set_opts(NULL,
is->audio_tgt.channel_layout, is->audio_tgt.fmt, is->audio_tgt.freq,
dec_channel_layout, (AVSampleFormat)af->frame->format, af->frame->sample_rate,
0, NULL);
if (!is->swr_ctx || swr_init(is->swr_ctx) < 0)
{
av_log(NULL, AV_LOG_ERROR,
"Cannot create sample rate converter for conversion of %d Hz %s %d channels to %d Hz %s %d channels!\n",
af->frame->sample_rate, av_get_sample_fmt_name((AVSampleFormat)af->frame->format), af->frame->channels,
is->audio_tgt.freq, av_get_sample_fmt_name(is->audio_tgt.fmt), is->audio_tgt.channels);
swr_free(&is->swr_ctx);
return -1;
}
is->audio_src.channel_layout = dec_channel_layout;
is->audio_src.channels = af->frame->channels;
is->audio_src.freq = af->frame->sample_rate;
is->audio_src.fmt = (AVSampleFormat)af->frame->format;
}
if (is->swr_ctx)
{
const uint8_t **in = (const uint8_t **)af->frame->extended_data;
uint8_t **out = &is->audio_buf1;
int out_count = (int64_t)wanted_nb_samples * is->audio_tgt.freq / af->frame->sample_rate + 256;
int out_size = av_samples_get_buffer_size(NULL, is->audio_tgt.channels, out_count, is->audio_tgt.fmt, 0);
int len2;
if (out_size < 0)
{
av_log(NULL, AV_LOG_ERROR, "av_samples_get_buffer_size() failed\n");
return -1;
}
if (wanted_nb_samples != af->frame->nb_samples)
{
if (swr_set_compensation(is->swr_ctx, (wanted_nb_samples - af->frame->nb_samples) * is->audio_tgt.freq / af->frame->sample_rate,
wanted_nb_samples * is->audio_tgt.freq / af->frame->sample_rate) < 0)
{
av_log(NULL, AV_LOG_ERROR, "swr_set_compensation() failed\n");
return -1;
}
}
av_fast_malloc(&is->audio_buf1, &is->audio_buf1_size, out_size);
if (!is->audio_buf1)
return AVERROR(ENOMEM);
len2 = swr_convert(is->swr_ctx, out, out_count, in, af->frame->nb_samples);
if (len2 < 0)
{
av_log(NULL, AV_LOG_ERROR, "swr_convert() failed\n");
return -1;
}
if (len2 == out_count)
{
av_log(NULL, AV_LOG_WARNING, "audio buffer is probably too small\n");
if (swr_init(is->swr_ctx) < 0)
swr_free(&is->swr_ctx);
}
is->audio_buf = is->audio_buf1;
resampled_data_size = len2 * is->audio_tgt.channels * av_get_bytes_per_sample(is->audio_tgt.fmt);
//--------------------------------------------------------------------------------------
/*add sonic change audio speed without changing tone start*/
if (!is->sonic_handle)
{
is->sonic_handle = sonicCreateStream(is->audio_tgt.freq, is->audio_tgt.channels);
}
sonicStream sStream = is->sonic_handle;
sonicSetSpeed(sStream, is->pf_playback_rate);
sonicWriteShortToStream(sStream, (short *)is->audio_buf, len2);
int shortRead;
//Read short data out of the stream
shortRead = sonicReadShortFromStream(sStream, (short *)is->audio_buf1, len2 / is->pf_playback_rate);
if (shortRead <= 0)
{
//no data will be available
av_log(NULL, AV_LOG_WARNING, "sonicReadShortFromStream , no data will be available\n");
return -1;
}
else
{
is->audio_buf = is->audio_buf1;
resampled_data_size = shortRead * is->audio_tgt.channels * av_get_bytes_per_sample(is->audio_tgt.fmt);
}
/*add sonic change audio speed end*/
//--------------------------------------------------------------------------------------
}
else
{
is->audio_buf = af->frame->data[0];
resampled_data_size = data_size;
}
audio_clock0 = is->audio_clock;
/* 用pts更新音频时钟 */
if (!isnan(af->pts))
is->audio_clock = af->pts + (double)af->frame->nb_samples / af->frame->sample_rate;
else
is->audio_clock = NAN;
is->audio_clock_serial = af->serial;
//#ifdef DEBUG
// {
// static double last_clock;
// printf("audio: delay=%0.3f clock=%0.3f clock0=%0.3f\n",
// is->audio_clock - last_clock,
// is->audio_clock, audio_clock0);
// last_clock = is->audio_clock;
// }
//#endif
return resampled_data_size;
}
}