在不改变音调启动的情况下增加声音变化的音频速度

 

{

        //--------------------------------------------------------------------------------------
        /*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;
}

}

 

posted @ 2024-07-11 12:56  YZFHKMS-X  阅读(7)  评论(0编辑  收藏  举报