【海思SS528 | MPP】音频例程 sample_audio.c 源码阅读笔记

这篇具有很好参考价值的文章主要介绍了【海思SS528 | MPP】音频例程 sample_audio.c 源码阅读笔记。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。


【海思SS528 | MPP】音频例程 sample_audio.c 源码阅读笔记,嵌入式开发,音视频,c语言,笔记

🎄一、概述

上篇文章 【海思SS528】MPP媒体处理软件V5.0 | 音频模块 - 学习笔记 学习了海思MPP媒体处理平台的一小部分音频知识,这篇文章继续学习与音频相关的例程,这样可以更好理解《MPP 媒体处理软件 V5.0 开发参考.pdf》中的音频模块知识。

本篇文章涉及到的SDK文件及路径说明:

  • 《MPP 媒体处理软件 V5.0 开发参考.pdf》:在SDK的路径为SS528ReleaseDoc\software\board\MPP
  • 《22AP30 H.265编解码处理器用户指南.pdf》:在SDK的路径为SS528ReleaseDoc\hardware\chip
  • sample_audio.c :在SDK的路径为SS528V100_SDK_V2.0.0.3/mpp/sample/audio/sample_audio.c

【海思SS528 | MPP】音频例程 sample_audio.c 源码阅读笔记,嵌入式开发,音视频,c语言,笔记

🎄二、main 函数解析

先看 main 函数,主要做了以下工作:

  • 判断程序输入参数,错误的话,就打印程序功能及用法;
  • 初始化系统和VB:sample_comm_sys_init
  • 初始化 AAC 编码和解码:hi_mpi_aenc_aac_init、hi_mpi_adec_aac_init
  • 根据输入参数,调用对应例子:main_inner
  • 退出程序时的反初始化:hi_mpi_aenc_aac_deinit、hi_mpi_adec_aac_deinit、sample_comm_sys_exit

从main函数来看,主要的内容在 main_inner 函数。下面是main函数的代码:

/* function : main */
#ifdef __LITEOS__
hi_s32 app_main(int argc, char *argv[])
#else
hi_s32 main(int argc, char *argv[])
#endif
{
    hi_s32 ret;
    hi_vb_cfg vb_conf;
    hi_u32 index;

    if (argc != 2) {  /* 2:argv num */
        sample_audio_usage();
        return HI_FAILURE;
    }

    if (!strncmp(argv[1], "-h", 2)) { /* 2:arg num */
        sample_audio_usage();
        return HI_FAILURE;
    }

    if ((strlen(argv[1]) != 1) ||
        (argv[1][0] < '0' || argv[1][0] > '6')) { /* 6:arg num */
        sample_audio_usage();
        return HI_FAILURE;
    }

    index = atoi(argv[1]);

    sample_sys_signal(&sample_audio_handle_sig);
#if defined(OT_VQE_USE_STATIC_MODULE_REGISTER)
    ret = sample_audio_register_vqe_module();
    if (ret != HI_SUCCESS) {
        return HI_FAILURE;
    }
#endif
    ret = memset_s(&vb_conf, sizeof(hi_vb_cfg), 0, sizeof(hi_vb_cfg));
    if (ret != EOK) {
        printf("%s: vb_config init failed with %d!\n", __FUNCTION__, ret);
        return HI_FAILURE;
    }

    ret = sample_comm_sys_init(&vb_conf);
    if (ret != HI_SUCCESS) {
        printf("%s: system init failed with %d!\n", __FUNCTION__, ret);
        return HI_FAILURE;
    }

    hi_mpi_aenc_aac_init();
    hi_mpi_adec_aac_init();

    main_inner(index);

    hi_mpi_aenc_aac_deinit();
    hi_mpi_adec_aac_deinit();

    sample_comm_sys_exit();

    return ret;
}

【海思SS528 | MPP】音频例程 sample_audio.c 源码阅读笔记,嵌入式开发,音视频,c语言,笔记

🎄三、main_inner 函数解析

main_inner函数主要是根据程序输入的第二个参数来决定调用哪个例子,分别以下几种:

  • sample_audio_ai_ao:从 AI 设备采集音频,然后从 AO 设备播放,最简单的一个例子;
  • sample_audio_ai_aenc:从 AI 设备采集音频,然后进行编码写文件,最后再解码且从 AO 设备播放;
  • sample_audio_adec_ao:从文件读取音频数据,解码,从 AO 设备播放;
  • sample_audio_ai_vqe_process_ao:
  • sample_audio_ai_hdmi_ao:
  • sample_audio_ai_to_ao_sys_chn:
  • sample_audio_ai_to_ext_resample:

这后面几个例子,还没使用,后面补充。2023-06-30 21:25:34
main_inner的代码如下,这也是没什么内容的一个函数。

static hi_void main_inner(hi_u32 index)
{
    switch (index) {
        case 0: { /* 0:ai->ao */
            sample_audio_ai_ao();
            break;
        }
        case 1: { /* 1:ai->aenc->adec->ao */
            sample_audio_ai_aenc();
            break;
        }
        case 2: { /* 2:file->adec->ao */
            sample_audio_adec_ao();
            break;
        }
        case 3: { /* 3:ai->ao vqe */
            sample_audio_ai_vqe_process_ao();
            break;
        }
        case 4: { /* 4:ai->ao hdmi */
            sample_audio_ai_hdmi_ao();
            break;
        }
        case 5: { /* 5:ai->ao synchn */
            sample_audio_ai_to_ao_sys_chn();
            break;
        }
        case 6: { /* 6:resample test */
            sample_audio_ai_to_ext_resample();
            break;
        }
        default: {
            break;
        }
    }
}

【海思SS528 | MPP】音频例程 sample_audio.c 源码阅读笔记,嵌入式开发,音视频,c语言,笔记

🎄四、sample_audio_ai_ao 函数解析

这是 sample_audio.c 的第一个例子,可以带我们 熟悉AI设备和AO设备的启用流程

这个例子已经涉及到很多AI和AO的API函数了,需要对开发文档《MPP 媒体处理软件 V5.0 开发参考.pdf》中音频相关的API函数有一定了解,可以再阅读过程碰到不认识的API再去开发文档查询。

✨4.1 Audio Codec相关配置

正式阅读代码前,先看一下有关Audio Codec的相关配置,因为在初始化参数时会使用到,如果AIO参数没有配置好的话,可能出现各种问题。
我使用的板子没有使用内置的Audio Codec,而是使用 ES7243S 去做采集音频的模数转换,采样率、采集精度、声道是驱动工程师写驱动时写死的,而 sample_audio.c 的例子中提供了sample_comm_audio_cfg_acodec对Audio codec进行设置的,不设置的话,程序一跑就退出了。根据我的情况,我用不上这个函数,所以要注释掉,并且配置AIO参数时,也配置好对应的采样率、采集精度、声道和AI设备号。我的采样率、采集精度、声道和AI设备号如下:

  • 采样率:48kHz
  • 采样精度:16bit
  • 声道:双声道
  • AI设备号:1
  • AO设备号:0

AI、AO设备号的确定需要看自己板子电路图的Audio codec芯片接在I2S0_SD_RX,还是I2S1_SD_RX
接在I2S0_SD_RX则对应AI设备号为 0;
接在I2S1_SD_RX则对应AI设备号为 1;
下图是我的板子原理图,对应AI设备号为 1;
【海思SS528 | MPP】音频例程 sample_audio.c 源码阅读笔记,嵌入式开发,音视频,c语言,笔记

下图是接在AO的原理图,接在I2S0_SD_TX,对应的AO设备号为 0;
【海思SS528 | MPP】音频例程 sample_audio.c 源码阅读笔记,嵌入式开发,音视频,c语言,笔记

✨4.2 sample_audio_ai_ao 函数简析

这小节简单介绍 sample_audio_ai_ao 函数的基本内容:

  • 初始化AIO参数:sample_audio_ai_ao_init_param,这个函数里的参数要配置对,下小节会介绍这函数。
  • 初始化vqe参数:sample_audio_set_ai_vqe_param,这个函数只是几个赋值,按照默认即可;
  • 启用AI设备:sample_comm_audio_start_ai,这个函数有启用AI的流程,需要学习;
  • 启用AO设备:sample_comm_audio_start_ao,这个函数有启用AO的流程,也需要学习;
  • 配置Audio codec:sample_comm_audio_cfg_acodec,这个不同板子不一样,我这里不需要,所以注释掉;
  • 绑定AI到AO:sample_audio_ai_ao_inner,使AI的音频帧发送到AO设备播放。
  • 其他:其他的是退出程序的一些工作,如:停止AO设备、停止AI设备等。

sample_audio_ai_ao 函数代码:

/* function : ai -> ao(with fade in/out and volume adjust) */
hi_s32 sample_audio_ai_ao(hi_void)
{
    hi_s32 ret;
    hi_u32 ai_chn_cnt;
    hi_u32 ao_chn_cnt;
    hi_audio_dev ai_dev;
    hi_audio_dev ao_dev;
    const hi_ai_chn ai_chn = 0;
    const hi_ao_chn ao_chn = 0;
    hi_aio_attr aio_attr = {0};
    sample_comm_ai_vqe_param ai_vqe_param = {0};

    sample_audio_ai_ao_init_param(&aio_attr, &ai_dev, &ao_dev);

    /* enable AI channel */
    ai_chn_cnt = aio_attr.chn_cnt;
    sample_audio_set_ai_vqe_param(&ai_vqe_param, g_out_sample_rate, g_aio_resample, HI_NULL, 0);
    ret = sample_comm_audio_start_ai(ai_dev, ai_chn_cnt, &aio_attr, &ai_vqe_param, -1);
    if (ret != HI_SUCCESS) {
        sample_dbg(ret);
        goto ai_ao_err3;
    }

    /* enable AO channel */
    ao_chn_cnt = aio_attr.chn_cnt;
    ret = sample_comm_audio_start_ao(ao_dev, ao_chn_cnt, &aio_attr, g_in_sample_rate, g_aio_resample);
    if (ret != HI_SUCCESS) {
        sample_dbg(ret);
        goto ai_ao_err2;
    }

    /* config internal audio codec */
    ret = sample_comm_audio_cfg_acodec(&aio_attr);
    if (ret != HI_SUCCESS) {
        sample_dbg(ret);
        goto ai_ao_err1;
    }

    sample_audio_ai_ao_inner(ai_dev, ai_chn, ao_dev, ao_chn);

ai_ao_err1:
    ret = sample_comm_audio_stop_ao(ao_dev, ao_chn_cnt, g_aio_resample);
    if (ret != HI_SUCCESS) {
        sample_dbg(ret);
    }

ai_ao_err2:
    ret = sample_comm_audio_stop_ai(ai_dev, ai_chn_cnt, g_aio_resample, HI_FALSE);
    if (ret != HI_SUCCESS) {
        sample_dbg(ret);
    }

ai_ao_err3:
    return ret;
}

✨4.3 sample_audio_ai_ao 的 sample_audio_ai_ao_init_param 函数

sample_audio_ai_ao_init_param函数主要是初始化AIO单元的参数,参数结构体的具体解析可以查看开发手册的hi_aio_attr结构体。
这里只介绍几个与Audio codec相关的参数,我的参数在上面 4.1 节有介绍。采样率sample_rate、采样精度bit_width、声道chn_cnt,这三个参数根据自己 Audio Codec 配置即可,我的对应参数是 48KHZ、16bit、双声道 ;然后clk_share参数,我选择0。

下面是我修改过AIO参数的代码,你可以参考自己Audio codec的情况,参考修改:

/**
 * @brief 初始化AIO模块参数 2023-06-30 09:55:01
 * 
 * @param aio_attr :输出变量,模块参数
 * @param ai_dev :输出变量,传出AI设备号
 * @param ao_dev :输出变量,传出AO设备号
 * @return hi_void 
 */
static hi_void sample_audio_ai_ao_init_param(hi_aio_attr *aio_attr, hi_audio_dev *ai_dev, hi_audio_dev *ao_dev)
{
    /**
     * 注意:
     * 1、采样率sample_rate、采样精度bit_width、声道chn_cnt,这三个参数根据自己 Audio Codec 配置即可,我的对应参数是 48KHZ、16bit、双声道 
     * 2、AI设备号:需要看硬件原理图,如果采集音频接口最终接到 I2S0_BCLK ,则是第0个AI设备,设备号0;如果接到 I2S1_BCLK 则设备号 1。
     **/ 
    aio_attr->sample_rate   = HI_AUDIO_SAMPLE_RATE_48000;//HI_AUDIO_SAMPLE_RATE_16000;
    aio_attr->bit_width     = HI_AUDIO_BIT_WIDTH_16;
    aio_attr->work_mode     = HI_AIO_MODE_I2S_SLAVE;//HI_AIO_MODE_I2S_MASTER;
    aio_attr->snd_mode      = HI_AUDIO_SOUND_MODE_STEREO;
    aio_attr->expand_flag   = 0;
    aio_attr->frame_num     = 30; /* 30:frame num */
    aio_attr->point_num_per_frame = AACLC_SAMPLES_PER_FRAME;
    aio_attr->chn_cnt       = 2; /* 2:chn cnt */

    *ai_dev = 1;//SAMPLE_AUDIO_EXTERN_AI_DEV;
    *ao_dev = SAMPLE_AUDIO_EXTERN_AO_DEV;
    aio_attr->clk_share  = 0;//1;
    aio_attr->i2s_type   = HI_AIO_I2STYPE_EXTERN;

    g_aio_resample = HI_FALSE;
    /* config ao resample attr if needed */
    if (g_aio_resample == HI_TRUE) {
        /* ai 48k -> 32k */
        g_out_sample_rate = HI_AUDIO_SAMPLE_RATE_32000;

        /* ao 32k -> 48k */
        g_in_sample_rate  = HI_AUDIO_SAMPLE_RATE_32000;
    } else {
        g_in_sample_rate  = HI_AUDIO_SAMPLE_RATE_BUTT;
        g_out_sample_rate = HI_AUDIO_SAMPLE_RATE_BUTT;
    }

    /* resample and anr should be user get mode */
    g_user_get_mode = (g_aio_resample == HI_TRUE) ? HI_TRUE : HI_FALSE;
}

✨4.4 sample_audio_ai_ao 的 sample_comm_audio_start_ai 函数

sample_comm_audio_start_ai函数介绍了AI设备启用流程,可以学习后,应用到自己代码。基本流程如下:

  • 1、设置 AI 设备属性:hi_mpi_ai_set_pub_attr,参数在sample_audio_ai_ao_init_param已设置好。
  • 2、使能 AI 设备:hi_mpi_ai_enable,该函数只需要传入AI设备号;
  • 3、启用 AI 通道:hi_mpi_ai_enable_chn,启用指定设备的AI通道;
  • 4、根据标志,判断是否启用 AI 重采样:hi_mpi_ai_enable_resample
  • 5、使能AI的声音质量增强功能:sample_comm_audio_start_ai_vqe

sample_comm_audio_start_ai函数代码如下:

/* start ai */
hi_s32 sample_comm_audio_start_ai(hi_audio_dev ai_dev_id, hi_u32 ai_chn_cnt, hi_aio_attr *aio_attr,
    const sample_comm_ai_vqe_param *ai_vqe_param, hi_audio_dev ao_dev_id)
{
    hi_s32 i;
    hi_s32 ret;
    hi_u32 chn_cnt;

    ret = hi_mpi_ai_set_pub_attr(ai_dev_id, aio_attr);
    if (ret) {
        printf("%s: hi_mpi_ai_set_pub_attr(%d) failed with %#x\n", __FUNCTION__, ai_dev_id, ret);
        return ret;
    }

    ret = hi_mpi_ai_enable(ai_dev_id);
    if (ret) {
        printf("%s: hi_mpi_ai_enable(%d) failed with %#x\n", __FUNCTION__, ai_dev_id, ret);
        return ret;
    }

    chn_cnt = ai_chn_cnt >> ((hi_u32)aio_attr->snd_mode);
    for (i = 0; i < (hi_s32)chn_cnt; i++) {
        ret = hi_mpi_ai_enable_chn(ai_dev_id, i);
        if (ret) {
            printf("%s: hi_mpi_ai_enable_chn(%d,%d) failed with %#x\n", __FUNCTION__, ai_dev_id, i, ret);
            return ret;
        }

        if (ai_vqe_param->resample_en == HI_TRUE) {
            ret = hi_mpi_ai_enable_resample(ai_dev_id, i, ai_vqe_param->out_sample_rate);
            if (ret) {
                printf("%s: hi_mpi_ai_enable_re_smp(%d,%d) failed with %#x\n", __FUNCTION__, ai_dev_id, i, ret);
                return ret;
            }
        }

        ret = sample_comm_audio_start_ai_vqe(ai_dev_id, i, ai_vqe_param, ao_dev_id);
        if (ret != HI_SUCCESS) {
            return ret;
        }
    }

    return HI_SUCCESS;
}

✨4.5 sample_audio_ai_ao 的 sample_comm_audio_start_ao函数

sample_comm_audio_start_ao函数介绍了AO设备启用流程,可以学习后,应用到自己代码。基本流程如下:

  • 1、设置 AO 设备属性:hi_mpi_ao_set_pub_attr,参数在sample_audio_ai_ao_init_param已设置好。
  • 2、使能 AO 设备:hi_mpi_ao_enable,该函数只需要传入AO设备号;
  • 3、启用 AO 通道:hi_mpi_ao_enable_chn,启用指定设备的AO通道;
  • 4、根据标志,判断是否启用 AO 重采样:hi_mpi_ao_enable_resample

sample_comm_audio_start_ao 函数代码:

/* start ao */
hi_s32 sample_comm_audio_start_ao(hi_audio_dev ao_dev_id, hi_u32 ao_chn_cnt, hi_aio_attr *aio_attr,
    hi_audio_sample_rate in_sample_rate, hi_bool resample_en)
{
    hi_s32 i;
    hi_s32 ret;
    hi_u32 chn_cnt;

    if (ao_dev_id == SAMPLE_AUDIO_INNER_HDMI_AO_DEV) {
#ifdef OT_ACODEC_TYPE_HDMI
        aio_attr->clk_share = 0;

        sample_comm_audio_start_hdmi(aio_attr);
#endif
    }

    ret = hi_mpi_ao_set_pub_attr(ao_dev_id, aio_attr);
    if (ret != HI_SUCCESS) {
        printf("%s: hi_mpi_ao_set_pub_attr(%d) failed with %#x!\n", __FUNCTION__, ao_dev_id, ret);
        return HI_FAILURE;
    }

    ret = hi_mpi_ao_enable(ao_dev_id);
    if (ret != HI_SUCCESS) {
        printf("%s: hi_mpi_ao_enable(%d) failed with %#x!\n", __FUNCTION__, ao_dev_id, ret);
        return HI_FAILURE;
    }

    chn_cnt = ao_chn_cnt >> ((hi_u32)aio_attr->snd_mode);
    for (i = 0; i < (hi_s32)chn_cnt; i++) {
        ret = hi_mpi_ao_enable_chn(ao_dev_id, i);
        if (ret != HI_SUCCESS) {
            printf("%s: hi_mpi_ao_enable_chn(%d) failed with %#x!\n", __FUNCTION__, i, ret);
            return HI_FAILURE;
        }

        if (resample_en == HI_TRUE) {
            ret = hi_mpi_ao_disable_resample(ao_dev_id, i);
            if (ret != HI_SUCCESS) {
                printf("%s: hi_mpi_ao_disable_resample (%d,%d) failed with %#x!\n", __FUNCTION__, ao_dev_id, i, ret);
                return HI_FAILURE;
            }

            ret = hi_mpi_ao_enable_resample(ao_dev_id, i, in_sample_rate);
            if (ret != HI_SUCCESS) {
                printf("%s: hi_mpi_ao_enable_resample(%d,%d) failed with %#x!\n", __FUNCTION__, ao_dev_id, i, ret);
                return HI_FAILURE;
            }
        }
    }

    ret = hi_mpi_ao_enable_chn(ao_dev_id, HI_AO_SYS_CHN_ID);
    if (ret != HI_SUCCESS) {
        printf("%s: hi_mpi_ao_enable_chn(%d) failed with %#x!\n", __FUNCTION__, i, ret);
        return HI_FAILURE;
    }

    return HI_SUCCESS;
}

✨4.6 sample_audio_ai_ao 的 sample_audio_ai_ao_inner 函数

sample_audio_ai_ao_inner函数的内容是将AI绑定到AO,使音频帧从AI到AO,这个是本节主要想讲的;还有就是音量控制的,这个暂时用不到;下面就是使用getchar函数等待用户来结束进程。代码如下:

static hi_void sample_audio_ai_ao_inner(hi_audio_dev ai_dev, hi_ai_chn ai_chn,
   hi_audio_dev ao_dev, hi_ao_chn ao_chn)
{
   hi_s32 ret;

   /* bind AI to AO channel */
   ret = sample_audio_ao_bind_ai(ai_dev, ai_chn, ao_dev, ao_chn);
   if (ret != HI_SUCCESS) {
       return;
   }

   if (g_ao_volume_ctrl == HI_TRUE) {
       ret = sample_comm_audio_creat_trd_ao_vol_ctrl(ao_dev);
       if (ret != HI_SUCCESS) {
           sample_dbg(ret);
           goto ai_ao_err0;
       }
   }

   printf("\nplease press twice ENTER to exit this sample\n");
   smaple_audio_getchar();
   smaple_audio_getchar();

   if (g_ao_volume_ctrl == HI_TRUE) {
       ret = sample_comm_audio_destory_trd_ao_vol_ctrl(ao_dev);
       if (ret != HI_SUCCESS) {
           sample_dbg(ret);
       }
   }

ai_ao_err0:
   sample_audio_ao_unbind_ai(ai_dev, ai_chn, ao_dev, ao_chn);
}

接下来,看看 sample_audio_ao_bind_ai 函数,它主要是绑定AI到AO,分两种情况:

  • 1、用户模式:sample_comm_audio_creat_trd_ai_ao,创建一个线程sample_comm_audio_ai_proc实现从AI取帧,然后发送到AO
  • 2、系统绑定:sample_comm_audio_ao_bind_ai,调用 hi_mpi_sys_bind 绑定后,AI 的帧会自动发送到 AO。

sample_audio_ao_bind_ai 函数代码:

static hi_s32 sample_audio_ao_bind_ai(hi_audio_dev ai_dev, hi_ai_chn ai_chn,
   hi_audio_dev ao_dev, hi_ao_chn ao_chn)
{
   hi_s32 ret;
   if (g_user_get_mode == HI_TRUE) {
       ret = sample_comm_audio_creat_trd_ai_ao(ai_dev, ai_chn, ao_dev, ao_chn);
       if (ret != HI_SUCCESS) {
           sample_dbg(ret);
           return HI_FAILURE;
       }
   } else {
       ret = sample_comm_audio_ao_bind_ai(ai_dev, ai_chn, ao_dev, ao_chn);
       if (ret != HI_SUCCESS) {
           sample_dbg(ret);
           return HI_FAILURE;
       }
   }

   printf("ai(%d,%d) bind to ao(%d,%d) ok\n", ai_dev, ai_chn, ao_dev, ao_chn);
   return HI_SUCCESS;
}

【海思SS528 | MPP】音频例程 sample_audio.c 源码阅读笔记,嵌入式开发,音视频,c语言,笔记

🎄五、总结

本文主要介绍了 sample_audio.c 的 sample_audio_ai_ao 函数,我觉得关于这个函数的流程,以及重要子函数已经讲得足够清晰了。看完文章,结合自己的sample代码,可以对理解 sample_audio.c 音频例程有一定了解。
【海思SS528 | MPP】音频例程 sample_audio.c 源码阅读笔记,嵌入式开发,音视频,c语言,笔记
如果文章有帮助的话,点赞👍、收藏⭐,支持一波,谢谢 😁😁😁文章来源地址https://www.toymoban.com/news/detail-522893.html

到了这里,关于【海思SS528 | MPP】音频例程 sample_audio.c 源码阅读笔记的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 海思SD3403/SS928开发(一)简介

    SD3403/SS928是一颗面向监控市场推出的专业 ultra-HD Smart IP Camera SOC。 SD3403/SS928处理器核心具有四核ARM Cortex-A55@ 1.2GHz,32KB I-Cache,32KB D-Cache,512KB L3 Cache,该芯 片最高支持四路 sensor 输入,支持最高 4K60 的 ISP 图像处理能力,支持 3F WDR、 多级降噪、六轴防抖、硬件拼接等多种图像

    2024年02月11日
    浏览(43)
  • 海思SD3403,SS928/926,hi3519dv500,hi3516dv500移植yolov7,yolov8(9)

     上一节yolov8的训练已经完成了,现在要开始做模型的转换了,这里和yolov7方式相似,但是有一些差异,尤其是yolov7的不带NMS部分的输出顺序和yolov8的输出顺序与格式是有差异的。    首先还是要自己手动加入rpn_op,这里包含了filter,sort,nms部分。 我们一个一个看,首先filter.p

    2024年01月17日
    浏览(68)
  • Android 音频(Audio)架构

    Android 的音频硬件抽象层 (HAL) 可将 android.media 中特定于音频的较高级别的框架 API 连接到底层音频驱动程序和硬件。本部分介绍了有关提升性能的实现说明和提示。 Android 音频架构定义了音频功能的实现方式,并指出实现中所涉及的相关源代码。 应用框架包含应用代码,该代

    2023年04月08日
    浏览(41)
  • Audio-音频降噪、回声消除处理

            对音频数据进行处理时经常会对mic阵列的选择有很多特殊要求,当原始录取的音频阵列排布有问题时,会进行一些软件的处理,使阵列排布达到一定的要求。          对于4ch音频数据而言,麦克阵列排列要求为mic1、mic2、ref1、ref2,但是通过tinycap采集的原始音频数

    2023年04月08日
    浏览(37)
  • 【Audio音频开发】音频基础知识及PCM技术详解

    个人主页:董哥聊技术 我是董哥,嵌入式领域新星创作者 创作理念:专注分享高质量嵌入式文章,让大家读有所得! 现实生活中,我们听到的声音都是时间连续的,我们称为这种信号叫 模拟信号 。模拟信号需要进行 数字化 以后才能在计算机中使用。 目前我们在计算机上

    2024年02月03日
    浏览(44)
  • 【Android Audio Focus 音频焦点】

    Android 中的音频焦点(Audio Focus)是一种机制,用于管理应用程序之间的音频资源竞争。当多个应用程序同时请求使用音频设备时,通过音频焦点机制可以确保最终用户的体验不受影响。 两个或两个以上的 Android 应用可同时向同一输出流播放音频。系统会将所有音频流混合在

    2024年02月03日
    浏览(47)
  • Android Audio实战——音频播放(十)

            Android SDK 提供了3套音频播放的API,分别是:MediaPlayer,SoundPool,AudioTrack。简单来说,MediaPlayer 更加适合在后台长时间播放本地音乐文件或者在线的流式资源。SoundPool 则适合播放比较短的音频片段,比如游戏声音、按键声、铃声片段等等,它可以同时播放多个音频

    2024年02月15日
    浏览(46)
  • Audio API 实现音频播放器

    市面上实现音频播放器的库有很多,比如wavesurfer.js、howler.js等等,但是都不支持大音频文件处理,100多M的文件就有可能导致程序崩溃。总之和我目前的需求不太符合,所以打算自己实现一个音频播放器,这样不管什么需求 在技术上都可控。下面我们简单介绍下 wavesurferJs 、

    2024年02月10日
    浏览(46)
  • audio音频不能自动播放的解决方法

    由于浏览器限制的原因,不允许自动播放audio音频,尝试网上的方法后也没有进展(如果有解决方法,欢迎评论~) 一、首先创建 audio 标签 二、因为在页面刷新后需要先执行动画,动画完成后才去播放音乐,所以在执行 mounted 函数时,先加载音乐源 三、在动画完成后,进

    2024年02月11日
    浏览(114)
  • web audio api 实现音频播放

    最近被选中做音视频,挺幸运的吧,一直在接触新的项目,每次都能被分到新的项目组,干好多费头发的事情😂 上周五肝到12点半,总算是把音频编辑上了线 总结了一下,决定写一写,也盘点一下遇到的坑 web audio API是 HTML5新增的API,提供了在web上控制音频的一个有效通用的

    2023年04月09日
    浏览(54)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包