首页 > 其他分享 >在不改变音调启动的情况下增加声音变化的音频速度

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

时间:2024-07-11 12:57:12浏览次数:11  
标签:swr tgt af 音频 启动 av 音调 audio frame

 

{

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

}

 

标签:swr,tgt,af,音频,启动,av,音调,audio,frame
From: https://www.cnblogs.com/YZFHKMS-X/p/18295934

相关文章

  • Mock server自启动
    使用Flask-testing客户端,实现mock server自启动1.创建mock_server#mock_server.pyfromflaskimportFlask,jsonifyapp=Flask(__name__)@app.route('/api/user',methods=['GET'])defmock_user():returnjsonify({'id':1,'name&#......
  • 启动hive元数据服务
    nohuphive--servicemetastore>>metastore.log2>&1&这条命令是用来在后台运行Hive的元数据存储服务(metastore)。让我来逐步解释:1.nohup:是一个Unix/Linux命令,用于在后台运行命令,同时忽略所有挂起(SIGHUP)信号。这意味着,即使用户退出终端或断开与服务器的连接,命令......
  • Redis中设置增量缓存,减少对数据库的交互查询;启动@Async;异步线程
    //当属于这个分支的报文传入调用processMessage方法if((newJSONObject(dataMessage).optString("documentStatus")).equals("carWeizi_redis_service")){processMessage(dataMessage);}//processMessage中先把增量数据插入数据库,同时缓存redispublic......
  • 音频带宽控制
    音频带宽控制是音频编码和传输中的关键概念,通过调整带宽,可以在不同的网络条件下优化音频质量和传输效率。Opus编码器具有灵活的带宽控制机制,能够动态调整音频带宽以适应网络条件和应用需求。1.带宽(Bandwidth)的定义音频带宽指的是音频信号中包含的频率范围。带宽越宽,包含的音频......
  • H5播放音频和视频
    H5播放音频和视频: <!DOCTYPEhtml><html><head><metacharset="UTF-8"><title>音乐在线试听</title><metaname="renderer"content="webkit"><metahttp-equiv="X-UA-Compati......
  • 在Linux中,系统的开机启动顺序是什么?
    在Linux中,系统的开机启动顺序是一个复杂但有序的过程,它涉及从硬件自检到用户登录的多个阶段。以下是Linux系统开机启动顺序的详细说明:一、BIOS自检与启动设备选择加载BIOS:BIOS(基本输入输出系统)是计算机启动时的第一个软件。它负责在硬件和软件之间提供接口,进行开机自检(POST),检......
  • Windows bat批处理启动git bash 自动提交git push
    前言全局说明Windowsbat批处理启动gitbash自动提交gitpush一、说明环境:Windows11家庭版23H222631.3737二、新窗口打开gitbash(和手动右键点gitbashhere一样)@echooff"C:\ProgramFiles\Git\git-bash.exe"--cd=D:\temp-c"ls-l&&pwd"--cd=指定......
  • Android Framework之Activity启动流程
    原文地址https://juejin.cn/post/7212432799848579133启动Activty触发点为Activity中的startActivity。ActivitystartActivity->Instrumentation-->execStartActivitytry{intent.migrateExtraStreamToClipData(who);intent.prepareToLeaveProcess(who);......
  • HomeActivity启动流程(launcher)
     简介:0.写在前面的话上一篇讲了各种Service是在何时启动的,最后提到了关于HomeActivity的启动。HomeActivity作为Android系统启动后第一个加载的Activity,今天就来分析下其启动流程。0.写在前面的话上一篇讲了各种Service是在何时启动的,最后提到了关于HomeActivity的启动......
  • 各种软件启动方式
    各种软件启动方式1.MySQL#启动servicemysqldstart#关闭servicemysqldstop#重启servicemysqldrestart2.Redis#启动serviceredisdstart#关闭serviceredisdstop3.nginx#启动./nginx#关闭./nginx-squit#快速关闭./nginx-sstop#重新加载......