色哟哟视频在线观看-色哟哟视频在线-色哟哟欧美15最新在线-色哟哟免费在线观看-国产l精品国产亚洲区在线观看-国产l精品国产亚洲区久久

0
  • 聊天消息
  • 系統(tǒng)消息
  • 評(píng)論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會(huì)員中心
創(chuàng)作中心

完善資料讓更多小伙伴認(rèn)識(shí)你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

【潤和軟件DAYU200開發(fā)板體驗(yàn)】移植speexdsp到OpenHarmony標(biāo)準(zhǔn)系統(tǒng)⑤

開發(fā)板試用精選 ? 來源:開發(fā)板試用 ? 作者:電子發(fā)燒友論壇 ? 2022-10-12 10:09 ? 次閱讀

本文來源電子發(fā)燒友社區(qū),作者:離北況歸, 帖子地址:https://bbs.elecfans.com/jishu_2308799_1_1.html


由于想要分享的內(nèi)容較多,為避免讀者姥爺們失去看下去的耐心,分享將以連載的方式進(jìn)行。感謝潤和軟件提供的硬件支持。
下期預(yù)告:OAT開源掃描和三方庫上倉基本要求

本期為移植speexdspOpenHarmony標(biāo)準(zhǔn)系統(tǒng)的第⑤期,主要內(nèi)容如下:

image.png


speexdsp移植后已提交至openhamrony sig倉庫:https://gitee.com/openharmony-sig/contest/tree/master/2022_OpenHarmony_thirdparty/speexdsp


七、Speexdsp功能分析

  • 將speexdsp加入openharmony編譯體系后,能成功編譯出來動(dòng)態(tài)鏈接庫和測(cè)試用的可執(zhí)行文件,并不代表移植三方庫成功。還要在開發(fā)板上運(yùn)行測(cè)試其功能是否正常。

speexdsp核心庫分析

1.庫實(shí)現(xiàn)方式

2.依賴分析

  • 除C標(biāo)準(zhǔn)庫外,無其他第三方庫依賴

3.license以及版權(quán)

  • 根據(jù)speex官網(wǎng)https://speex.org/的信息,speexdsp使用的開源協(xié)議為revised BSD license(revised BSD license又稱為3-clause BSD License或者BSD 3-Clause License,一般使用BSD 3-Clause)
    image.png
  • OpenHamorny第三方開源軟件許可證類型必須是OSI明確定義的。
  • OSI明確定義的開源許可證有:https://opensource.org/licenses/alphabetical
  • BSD 3-Clause LicenseOSI明確定義的開源許可。

如下類型許可證可以引入到OpenHarmony項(xiàng)目中:

Apache License 2.0
Mulan Permissive Software License, Version 2
BSD 2-clause
BSD 3-clause
DOM4J License
PostgreSQL License
Eclipse Distribution License 1.0
MIT
ISC
ICU
University of Illinois/NCSA
W3C Software License
zlib/libpng
Academic Free License 3.0
Python Software Foundation License
Python Imaging Library Software License
Boost Software License Version 1.0
WTF Public License
UNICODE, INC. LICENSE AGREEMENT - DATA FILES AND SOFTWARE
Zope Public License 2.0

如下類型許可證不建議引入到OpenHarmony項(xiàng)目中:

GNU GPL 1, 2, 3
GNU Affero GPL 3
GNU LGPL 2, 2.1, 3
QPL
Sleepycat License
Server Side Public License (SSPL) version 1
Code Project Open License (CPOL)
BSD-4-Clause/BSD-4-Clause (University of California-Specific)
Facebook BSD+Patents license
NPL 1.0/NPL 1.1
The Solipsistic Eclipse Public License
The "Don't Be A Dick" Public License
JSON License
Binary Code License (BCL)
Intel Simplified Software License
JSR-275 License
Microsoft Limited Public License
Amazon Software License (ASL)
Java SDK for Satori RTM license
Redis Source Available License (RSAL)
Booz Allen Public License
Creative Commons Non-Commercial
Sun Community Source License 3.0
Common Development and Distribution Licenses: CDDL 1.0 and CDDL 1.1
Common Public License: CPL 1.0
Eclipse Public License: EPL 1.0
IBM Public License: IPL 1.0
Mozilla Public Licenses: MPL 1.0, MPL 1.1, and MPL 2.0
Sun Public License: SPL 1.0
Open Software License 3.0
Erlang Public License
UnRAR License
SIL Open Font License
Ubuntu Font License Version 1.0
IPA Font License Agreement v1.0
Ruby License
Eclipse Public License 2.0: EPL 2.0

speexdsp的license以及版權(quán)內(nèi)容如下:

Copyright 2002-2008 	Xiph.org Foundation
Copyright 2002-2008 	Jean-Marc Valin
Copyright 2005-2007	Analog Devices Inc.
Copyright 2005-2008	Commonwealth Scientific and Industrial Research
                        Organisation (CSIRO)
Copyright 1993, 2002, 2006 David Rowe
Copyright 2003 		EpicGames
Copyright 1992-1994	Jutta Degener, Carsten Bormann

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:

- Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.

- Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.

- Neither the name of the Xiph.org Foundation nor the names of its
contributors may be used to endorse or promote products derived from
this software without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

4.最新一次版本

  • 2022年6月16日,版本號(hào)1.2.1

5.代碼規(guī)模

linux系統(tǒng)提供了wc命令來統(tǒng)計(jì)文件的行數(shù),統(tǒng)計(jì)當(dāng)前目錄下的所有文件行數(shù),終端輸入如下命令:

wc -l *
文件名 代碼行數(shù)
arch.h 232
bfin.h 15
buffer.c 176
fftwrap.c 448
fftwrap.h 58
filterbank.c 227
filterbank.h 66
fixed_arm4.h 135
fixed_arm5e.h 160
fixed_bfin.h 141
fixed_debug.h 497
fixed_generic.h 106
jitter.c 839
kiss_fft.c 523
_kiss_fft_guts.h 160
kiss_fft.h 108
kiss_fftr.c 297
kiss_fftr.h 51
math_approx.h 332
mdf.c 1279
misc_bfin.h 56
os_support.h 169
preprocess.c 1215
pseudofloat.h 379
resample.c 1239
resample_neon.h 339
resample_sse.h 128
scal.c 293
smallft.c 1261
smallft.h 46
vorbis_psy.h 97
speex_buffer.h 68
speexdsp_config_types.h 12
speexdsp_types.h 126
speex_echo.h 170
speex_jitter.h 197
speex_preprocess.h 219
speex_resampler.h 343
總行數(shù) 12207

功能分析

可以參考speexdsp提供的文檔分析功能
image.png

預(yù)處理器

預(yù)處理器被設(shè)計(jì)為在運(yùn)行編碼器之前在音頻上使用。預(yù)處理器提供三個(gè)主要功能:

  • 噪聲抑制
  • 自動(dòng)增益控制(AGC)
  • 語音活動(dòng)檢測(cè)(V AD)

自適應(yīng)抖動(dòng)緩沖區(qū)

  • 當(dāng)通過UDP或RTP傳輸語音(或任何相關(guān)內(nèi)容)時(shí),包可能會(huì)丟失,以不同的延遲到達(dá),甚至亂序。
  • 抖動(dòng)緩沖區(qū)的目的是重新排序數(shù)據(jù)包,并緩沖足夠長(zhǎng)的時(shí)間,以便它們可以被發(fā)送以進(jìn)行解碼。

聲學(xué)回聲消除器

回聲消除是為了提高遠(yuǎn)端質(zhì)量。

  • 在任何免提通信系統(tǒng)中,遠(yuǎn)端語音通過本地?fù)P聲器播放。音頻在房間內(nèi)傳播,并被麥克風(fēng)捕獲。如果從麥克風(fēng)捕獲的音頻被直接發(fā)送到遠(yuǎn)端,那么用戶就會(huì)聽到遠(yuǎn)端語音的回聲。聲學(xué)回聲消除器設(shè)計(jì)用于在聲學(xué)回聲發(fā)送到遠(yuǎn)端之前消除它。

image.png

重采樣器

這個(gè)重采樣器可以用于在任意兩個(gè)速率之間進(jìn)行轉(zhuǎn)換(比率必須是有理數(shù)),并且可以控制質(zhì)量/復(fù)雜性的權(quán)衡。

  • 重采樣器在某些情況下將音頻從一個(gè)采樣率轉(zhuǎn)換到另一個(gè)采樣率。
  • 它可以用于混合具有不同采樣率的流、用于支持聲卡不支持的采樣率、用于轉(zhuǎn)碼等。

八、Speexdsp功能測(cè)試

測(cè)試邏輯

  • 在speexdsp原生庫的libspeexdsp目錄下有原生的測(cè)試源文件testresample.c、testresample2.c、testecho.c、testdenoise.c、testjitter.c。
    image.png
  • 進(jìn)行功能測(cè)試需要對(duì)比pc端開發(fā)板的運(yùn)行效果,因此需要在pc端編譯出測(cè)試用的可執(zhí)行文件(開發(fā)板上的已經(jīng)編譯出來了)。
    image.png

重采樣功能

  • 查看源碼可知,運(yùn)行測(cè)試重采樣率的可執(zhí)行文件時(shí),輸入一份音頻文件的同時(shí)需要指定處理后輸出的音頻文件。
  • 測(cè)試重采樣功能的源文件為testresample.c和testresample2.c。

testresample.c源碼分析如下:

#ifdef HAVE_CONFIG_H
#include "config.h"
#endif

//要使用重采樣器,必須包含它的頭文件speex_resampler.h:
#include "speex/speex_resampler.h"
//基本輸入輸出函數(shù)的聲明
#include 
////頭文件中聲明了一些數(shù)學(xué)函數(shù)和宏
#include 

/*
stdlib.h中,包含了C語言的一些常用庫函數(shù)。
如動(dòng)態(tài)內(nèi)存相關(guān)的malloc, realloc,zalloc,calloc,free等。
隨機(jī)數(shù)相關(guān)的rand,srand等。
系統(tǒng)相關(guān)的system, getenv,setenv等。
字符串轉(zhuǎn)數(shù)值函數(shù),atoi, atof,strtoul等。
如果在代碼中,調(diào)用了這個(gè)頭文件中的函數(shù)或者宏定義,則需引用該頭文件。
*/
#include 

//NN定義的是幀長(zhǎng)度
#define NN 256

int main()
{
   spx_uint32_t i;
   short *in;
   short *out;
   float *fin, *fout;
   int count = 0;

//對(duì)于每一個(gè)被重采樣的流(流是一種抽象的概念,表示一連串的數(shù)據(jù)元素;流中的數(shù)據(jù)元素稱為幀F(xiàn)rame。),有必要?jiǎng)?chuàng)建一個(gè)重采樣狀態(tài):SpeexResamplerState *resampler;
//resampler = speex_resampler_init(nb_channels, input_rate, output_rate, quality, &err);
// nb_channels聲道數(shù)量,這段測(cè)試程序要求輸入的音頻聲道數(shù)量為1
// input_rate和output_rate指的是輸入音頻的采樣率和輸出音頻的采樣率。
// err錯(cuò)誤碼
/*
    quality 是語音編解碼器方面的概念,范圍是0~10.通常,
   對(duì)于一般使用質(zhì)量為3是可以接受的,
   而對(duì)于專業(yè)音頻工作,質(zhì)量為10是最推薦的。
   質(zhì)量0通常具有良好的聲音(當(dāng)然比使用線性插值重采樣更好),但可能會(huì)聽到偽影。 
*/
/*在數(shù)字音頻領(lǐng)域,常用的采樣率有:
        8000 Hz - 電話所用采樣率, 對(duì)于人的說話已經(jīng)足夠
        11025 Hz - 電話所用采樣率
        22050 Hz - 無線電廣播所用采樣率
        32000 Hz - miniDV 數(shù)碼視頻 camcorder、DAT (LP mode)所用采樣率
        44100 Hz - 音頻 CD, 也常用于 MPEG-1 音頻(VCD,SVCD,MP3)所用采樣率
        47250 Hz - 商用 PCM 錄音機(jī)所用采樣率
        48000 Hz - miniDV、數(shù)字電視、DVD、DAT、電影和專業(yè)音頻所用的數(shù)字聲音所用采樣率
        50000 Hz - 商用數(shù)字錄音機(jī)所用采樣率
*/
   SpeexResamplerState *st = speex_resampler_init(1, 8000, 12000, 10, NULL);

//96000是輸入音頻的采樣率,44100是輸出音頻的采樣率。單位為Hz
   speex_resampler_set_rate(st, 96000, 44100);

   speex_resampler_skip_zeros(st);

 /* 
   malloc函數(shù)的作用是讓系統(tǒng)尋找空閑地址后為你分配一塊指定大小的空間來給你使用,
   這一塊空間其實(shí)要比你申請(qǐng)的空間大一些,它包含兩個(gè)部分:1.你申請(qǐng)的空間;2.記錄這個(gè)空間信息的空間。
*/
   in = malloc(NN*sizeof(short));
   out = malloc(2*NN*sizeof(short));
   fin = malloc(NN*sizeof(float));
   fout = malloc(2*NN*sizeof(float));

//while(1):這是一個(gè)死循環(huán),一直在while里循環(huán).
//調(diào)試代碼時(shí),為了檢測(cè)一部分代碼是否OK,可加測(cè)試點(diǎn)while(1),測(cè)試這段代碼。
   while (1)
   {
      spx_uint32_t in_len;
      spx_uint32_t out_len;
/*從終端獲取音頻數(shù)據(jù)*/
      fread(in, sizeof(short), NN, stdin);

//feof()是檢測(cè)流上的文件結(jié)束符的函數(shù),如果文件結(jié)束,則返回非0值,否則返回0
      if (feof(stdin))
         break;
      for (i=0;i2*NN;
      /*if (count==2)
         speex_resampler_set_quality(st, 10);*/

//實(shí)際的重采樣是使用speex_resampler_process_int(resampler, channelID, in, &in_length, out, &out_length);
//其中"channelID"是輸入的音頻的聲道。對(duì)于單聲道,使用0。也可以同時(shí)處理多個(gè)通道。
//其中"in"指針指向所選通道的輸入緩沖區(qū)的第一個(gè)樣本,輸出指向輸出的第一個(gè)樣本。
//in_length和out_length分別指定輸入和輸出緩沖區(qū)的大小。
      speex_resampler_process_float(st, 0, fin, &in_len, fout, &out_len);
      for (i=0;ifloor(.5+fout[i]);
      /*speex_warning_int("writing", out_len);*/

/*轉(zhuǎn)換后的數(shù)據(jù)輸入到終端顯示*/
      fwrite(out, sizeof(short), out_len, stdout);
      count++;
   }
   speex_resampler_destroy(st);

//free函數(shù)接受一個(gè)指針,然后將指針指向的地址還給系統(tǒng)。(但它不會(huì)改變指針的指向,所以一般在free之后還要將指針置
   空,不然你的這個(gè)指針就會(huì)變成野指針)
//一般來說,malloc函數(shù)應(yīng)該和free函數(shù)成對(duì)出現(xiàn),防止向系統(tǒng)要的內(nèi)存太多系統(tǒng)不高興。
   free(in);
   free(out);
   free(fin);
   free(fout);
   return 0;
}
;i++)>;i++)>

可以得知:

  • 輸入音頻的采樣率要求為96000Hz、聲道為單聲道。
  • 輸出音頻的采樣率為44100。

回聲消除功能

  • 運(yùn)行測(cè)試回聲消除的可執(zhí)行文件時(shí),需要輸入兩段音頻文件,分別為一份麥克風(fēng)的音頻、一份speaker的音頻。另外需要指定一份處理后輸出的音頻文件。采樣率都為8000Hz
  • 測(cè)試回聲消除功能的源文件為testecho.c。
    testecho.c源碼分析如下:
/* 
Speex 源碼中附帶的這個(gè)例子,只適合于串行的鏈?zhǔn)矫襟w流,當(dāng)媒體播放、媒體采集、媒體網(wǎng)
絡(luò)數(shù)據(jù)接口分屬在不同現(xiàn)成時(shí),就會(huì)存在同步問題,異步線程會(huì)導(dǎo)致信號(hào)延遲加大,回聲消除收斂效果不好。
*/

#ifdef HAVE_CONFIG_H
#include "config.h"
#endif

/*使用回聲消除器需要加#include "speex/speex_echo.h"*/
#include "speex/speex_echo.h"
/*使用預(yù)處理器需要添加#include "speex/speex_preprocess.h"*/
#include "speex/speex_preprocess.h"
#include 
//stdlib 頭文件即standard library標(biāo)準(zhǔn)庫頭文件 
#include 
// sys/types.h中文名稱為基本系統(tǒng) 數(shù)據(jù)類型。在應(yīng)用程序源文件中包含  以訪問 _LP64 和 _ILP32 的定義
#include  
//stat.h頭文件,輕松獲取文件屬性
#include  
//fcntl.h相關(guān)函數(shù) open,fcntl,shutdown,unlink,fclose
#include  

//NN是frame_size幀長(zhǎng)度,TAIL是filter_length濾波器長(zhǎng)度
#define NN 128
#define TAIL 1024 

//當(dāng)你需要程序帶參數(shù)地啟動(dòng)的時(shí)候,就用int main(int argc, char *argv[])
int main(int argc, char **argv) 
{
//FILE* 指針作為文件句柄,是文件訪問的唯一標(biāo)識(shí),它由fopen函數(shù)創(chuàng)建,fopen打開文件成功,則返回一個(gè)有效的FILE*指針,否則返回空指針NULL //[n?l]
   FILE *echo_fd, *ref_fd, *e_fd;
   short echo_buf[NN], ref_buf[NN], e_buf[NN];
   SpeexEchoState *st;
   SpeexPreprocessState *den;
//采樣率為8000.單位為hz
   int sampleRate = 8000;

   if (argc != 4)
   {
      fprintf(stderr, "testecho mic_signal.sw speaker_signal.sw output.swn");
      exit(1);
   }

// fopen函數(shù)用于打開文件
   echo_fd = fopen(argv[2], "rb");
   ref_fd  = fopen(argv[1],  "rb");
   e_fd    = fopen(argv[3], "wb");

/*
1.創(chuàng)建一個(gè)回聲消除狀態(tài):SpeexEchoState *echo_state = speex_echo_state_init(frame_size, filter_length);
前邊的語句SpeexEchoState *st;  
2.NN是frame_size幀長(zhǎng)度,TAIL是filter_length濾波器長(zhǎng)度
*/·
   st = speex_echo_state_init(NN, TAIL);
   den = speex_preprocess_state_init(NN, sampleRate);
   speex_echo_ctl(st, SPEEX_ECHO_SET_SAMPLING_RATE, &sampleRate);
/*
如果你想進(jìn)一步減少信號(hào)中的回波,你可以通過將回波消除器與預(yù)處理器相關(guān)聯(lián)來實(shí)現(xiàn).這是通過調(diào)用:
speex_preprocess_ctl(preprocess_state, SPEEX_PREPROCESS_SET_ECHO_STATE,echo_state);
*/
   speex_preprocess_ctl(den, SPEEX_PREPROCESS_SET_ECHO_STATE, st);
   while (!feof(ref_fd) && !feof(echo_fd))
   {
      fread(ref_buf, sizeof(short), NN, ref_fd);
      fread(echo_buf, sizeof(short), NN, echo_fd);
/*創(chuàng)建回聲消除器狀態(tài)后,可以通過以下方式處理音頻: 
speex_echo_cancellation(echo_state, input_frame, echo_frame, output_frame); 
其中,input_frame是麥克風(fēng)捕捉到的音頻,echo_frame是揚(yáng)聲器播放的信號(hào)(需要去除),output_frame是去除回聲的信號(hào)。
*/
      speex_echo_cancellation(st, ref_buf, echo_buf, e_buf);
      speex_preprocess_run(den, e_buf);
      fwrite(e_buf, sizeof(short), NN, e_fd);
   }
   speex_echo_state_destroy(st); 
//可以用以下方法消除回聲抵消狀態(tài):speex_echo_state_destroy(echo_state);
   speex_preprocess_state_destroy(den);
// fclose(FILE *fp) 一般地,fclose(fp)應(yīng)與fopen配對(duì)使用,特別是含有寫方式的文件,若不關(guān)閉,可能會(huì)造成文件數(shù)據(jù)丟失。
   fclose(e_fd);
   fclose(echo_fd);
   fclose(ref_fd);
   return 0;
}

預(yù)處理功能

  • 運(yùn)行測(cè)試預(yù)處理功能的可執(zhí)行文件時(shí),輸入一份音頻文件的同時(shí)需要指定處理后輸出的音頻文件。(采樣率為8000Hz)
  • 測(cè)試源文件testdenoise.c測(cè)試的是預(yù)處理功能中的噪聲抑制。

testdenoise.c源碼分析如下:

#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
//使用預(yù)處理功能先#include "speex/speex_preprocess.h"
#include "speex/speex_preprocess.h"
#include 
//定義NN為160
#define NN 160

int main()
{
   short in[NN];
   int i;
/*
然后,可以創(chuàng)建一個(gè)預(yù)處理器狀態(tài):SpeexPreprocessState *preprocess_state = speex_preprocess_state_init(frame_size,sampling_rate);
preprocess_state(預(yù)處理狀態(tài))
frame_size指的是幀長(zhǎng)度
sampling_rate指的是采樣率
*/
   SpeexPreprocessState *st;
   int count=0;
   float f;

/*frame_size(幀長(zhǎng)度)為160,采樣率為8000*/
   st = speex_preprocess_state_init(NN, 8000);

/*預(yù)處理器的行為可以通過以下方式改變:speex_preprocess_ctl(preprocess_state, request, ptr);*/

/*SPEEX_PREPROCESS_SET_DENOISE Turns denoising on(1) or off(2) (spx_int32_t)*/
   i=1; // i=1就是打開預(yù)處理器的降噪功能;i=2就是關(guān)閉降噪功能
   speex_preprocess_ctl(st, SPEEX_PREPROCESS_SET_DENOISE, &i); 

/*SPEEX_PREPROCESS_SET_AGC Turns automatic gain control (AGC) on(1) or off(2) (spx_int32_t)*/
/*AGC全稱是自動(dòng)增益控制,作用是針對(duì)不同的強(qiáng)度的信號(hào)使用不同的增益進(jìn)行放大,使得信號(hào)最終的輸出幅度維持在同一標(biāo)準(zhǔn)*/
   i=0; // 
   speex_preprocess_ctl(st, SPEEX_PREPROCESS_SET_AGC, &i);

   i=8000;
   speex_preprocess_ctl(st, SPEEX_PREPROCESS_SET_AGC_LEVEL, &i);

/*SPEEX_PREPROCESS_SET_DEREVERB Turns reverberation removal on(1) or off(2) (spx_int32_t)*/
//reverberation removal混響消除
   i=0;
   speex_preprocess_ctl(st, SPEEX_PREPROCESS_SET_DEREVERB, &i);

   f=.0;
   speex_preprocess_ctl(st, SPEEX_PREPROCESS_SET_DEREVERB_DECAY, &f);

   f=.0;
   speex_preprocess_ctl(st, SPEEX_PREPROCESS_SET_DEREVERB_LEVEL, &f);

/* while(1):這是一個(gè)死循環(huán),一直在while里循環(huán),調(diào)試代碼時(shí),為了檢測(cè)一部分代碼是否OK,可加測(cè)試點(diǎn)while(1),測(cè)試這段代碼*/
   while (1)
   {
      int vad;
      /*C 庫函數(shù) size_t fread(void *ptr, size_t size, size_t nmemb, FILE *stream) 從給定流 stream 讀取數(shù)據(jù)到 ptr 所指向的數(shù)組中。*/
      fread(in, sizeof(short), NN, stdin);
/*
feof()是檢測(cè)流上的文件結(jié)束符的函數(shù),如果文件結(jié)束,則返回非0值,否則返回0
一般在文件操作,中經(jīng)常使用feof()判斷文件是否結(jié)束。
*/
      if (feof(stdin))
         break;
/*
對(duì)于每個(gè)輸入幀,需要調(diào)用:speex_preprocess_run(preprocess_state, audio_frame);
其中audio_frame被用作輸入和輸出。
*/
//fwrite和fread是以記錄為單位的I/O函數(shù),fread和fwrite函數(shù)一般用于二進(jìn)制文件的輸入輸出。
      vad = speex_preprocess_run(st, in);
      /*fprintf (stderr, "%dn", vad);*/
      fwrite(in, sizeof(short), NN, stdout);
      count++;
   }
//預(yù)處理器狀態(tài)可以通過以下方式銷毀:speex_preprocess_state_destroy(preprocess_state);
   speex_preprocess_state_destroy(st);
   return 0;
}

抖動(dòng)緩沖功能

當(dāng)通過UDP或RTP傳輸語音(或任何相關(guān)內(nèi)容)時(shí),包可能會(huì)丟失,以不同的延遲到達(dá),甚至亂序。

1.抖動(dòng)緩沖區(qū)的目的是重新排序數(shù)據(jù)包,并緩沖足夠長(zhǎng)的時(shí)間,以便它們可以被發(fā)送以進(jìn)行解碼。

2.測(cè)試源文件testjitter.c,這個(gè)去抖動(dòng)測(cè)試需要接收來自u(píng)dp/rtp的網(wǎng)絡(luò)語音數(shù)據(jù),原生測(cè)試程序沒有做到真正意義上的測(cè)試,從程序上看是告訴用戶如何使用接口。

testjitter.c源碼分析:

#ifdef HAVE_CONFIG_H
#include "config.h"
#endif

/*jitter buffer可以通過以下方式啟用:#include */
#include "speex/speex_jitter.h"
#include 

union jbpdata {  
/*
聯(lián)合類型的聲明,union是聯(lián)合體關(guān)鍵字;聯(lián)合是一種特殊的自定義類型,該種類型定義的變量也包含一系列的成員,特征是這些成員共用同一塊空間,所以聯(lián)合體也被稱為共用體。
抖動(dòng)緩沖器是一個(gè)共享的數(shù)據(jù)區(qū)域
*/
  unsigned int idx; 
//unsigned int是整數(shù)類型 ,存儲(chǔ)大小為2 或 4 字節(jié),值范圍為0 到 65,535 或 0 到 4,294,967,295
//unsigned char的表示范圍為0~255 此處定義了一個(gè)擁有四個(gè)元素的數(shù)組
  unsigned char data[4];
};

void synthIn(JitterBufferPacket *in, int idx, int span) {
  union jbpdata d;
  d.idx = idx;

  in->data = d.data;
  in->len = sizeof(d);
  in->timestamp = idx * 10;
  in->span = span * 10;
  in->sequence = idx;
  in->user_data = 0;
}

void jitterFill(JitterBuffer *jb) {
   char buffer[65536];
   JitterBufferPacket in, out;
   int i;

   out.data = buffer;

   jitter_buffer_reset(jb);

   for(i=0;i<100;++i) {
     synthIn(&in, i, 1);
     jitter_buffer_put(jb, &in);

     out.len = 65536;

     /*
     當(dāng)解碼器準(zhǔn)備解碼數(shù)據(jù)包時(shí),需要解碼的數(shù)據(jù)包可以通過以下方式獲得:
     int start_offset;
     err = jitter_buffer_get(state, &packet, desired_span, &start_offset);
     */
    //如果從不同的線程調(diào)用jitter_buffer_put()和jitter_buffer_get(),那么需要使用互斥鎖來保護(hù)jitter緩沖區(qū)狀態(tài)。
     if (jitter_buffer_get(jb, &out, 10, NULL) != JITTER_BUFFER_OK) {
       printf("Fill test failed iteration %dn", i);
     }
     if (out.timestamp != i * 10) {
       printf("Fill test expected %d got %dn", i*10, out.timestamp);
     }
/*因?yàn)閖itter緩沖區(qū)被設(shè)計(jì)為不使用顯式計(jì)時(shí)器,所以需要顯式地告訴它時(shí)間。這是通過調(diào)用:jitter_buffer_tick(state);
*/
     jitter_buffer_tick(jb);
   }
}

/*
當(dāng)一個(gè)包到達(dá)時(shí),它需要通過以下方式插入到j(luò)itter buffer中:
JitterBufferPacket packet;
jitter_buffer_put(state, &packet);
*/
int main()
{
   char buffer[65536];
   JitterBufferPacket in, out;
   int i;

   /* 新的抖動(dòng)緩沖狀態(tài)可以通過以下方式初始化:JitterBuffer *state = jitter_buffer_init(step);
   step參數(shù)是用于調(diào)整延遲的默認(rèn)時(shí)間步長(zhǎng)還有做隱藏,step參數(shù)的值總是為1,也可以是更高的值。
   */

   JitterBuffer *jb = jitter_buffer_init(10);

   out.data = buffer;

   /* Frozen sender case */
   jitterFill(jb);
   for(i=0;i<100;++i) {
     out.len = 65536;
     jitter_buffer_get(jb, &out, 10, NULL);
     jitter_buffer_tick(jb);
   }
   synthIn(&in, 100, 1);
   jitter_buffer_put(jb, &in);
   out.len = 65536;
   if (jitter_buffer_get(jb, &out, 10, NULL) != JITTER_BUFFER_OK) {
     printf("Failed frozen sender resynchronizen");
   } else {
     printf("Frozen sender: Jitter %dn", out.timestamp - 100*10);
   }
   return 0;
}

測(cè)試步驟

編譯pc端上的測(cè)試用的可執(zhí)行程序

image.png
編譯pc端的可執(zhí)行程序:

gcc testdenoise.c -L /home/jiajiahao/Desktop/speexdsp-SpeexDSP-1.2.1/build/lib -o testdenoise -I /home/jiajiahao/Desktop/speexdsp-SpeexDSP-1.2.1/include -lm -lspeexdsp

image.png
其中:

  • gcc后面是測(cè)試用的源文件
  • -L 后指定so庫所在的文件夾
  • -l+so庫的名字(除去lib和后綴)
  • -o 后面是可執(zhí)行文件的名字,
  • -l 后面是測(cè)試用的源文件要用到的頭文件的路徑

將編譯生成的庫以及測(cè)試用的可執(zhí)行文件推送到開發(fā)板上

  • hdc工具的使用 請(qǐng)參考用hdc工具在OpenHarmony3.2 上安裝應(yīng)用中的相關(guān)內(nèi)容
  • 獲取了ohos源碼,也可以執(zhí)行./build.sh --product-name ohos-sdk編譯sdk。
    • 如果有這樣的編譯報(bào)錯(cuò),說明依賴的庫沒在linux上安裝完整。
      image.png
    • 安轉(zhuǎn)完整才能成功編譯。
sudo apt-get update 
sudo apt-get install binutils binutils-dev git git- lfs gnupg flex bison gperf build-essential zip 
curl zlib1g-dev gcc-multilib g+±m(xù)ultilib gcc-arm-linux-gnueabi libc6-dev-i386 libc6-dev-amd64 lib32ncurses5-dev x11proto-core-dev libx11-dev lib32z1-dev ccache libgl1-mesa-dev libxml2-utils 
xsltproc unzip m4 bc gnutls-bin python3.8 python3-pip ruby genext2fs device-tree-compiler make 
libffi-dev e2fsprogs pkg-config perl openssl libssl-dev libelf-dev libdwarf-dev u-boot-tools mtd-
utils cpio doxygen liblz4-tool openjdk-8-jre gcc g++ texinfo dosfstools mtools default-jre default-
jdk libncurses5 apt-utils wget scons python3.8-distutils tar rsync git-core libxml2-dev lib32z-dev 
grsync xxd libglib2.0-dev libpixman-1-dev kmod jfsutils reiserfsprogs xfsprogs squashfs-tools 
pcmciautils quota ppp libtinfo-dev libtinfo5 libncurses5-dev libncursesw5 libstdc++6 gcc-arm-none-
eabi vim ssh locales

1.通過與ohos版本匹配的hdc_std工具,將編譯生成的庫以及測(cè)試用的可執(zhí)行文件推送到開發(fā)板上

hdc_std shell               
mount -o remount,rw /	    ## 重新加載系統(tǒng)為可讀寫
mkdir speexdsp              ## 創(chuàng)建speexdsp目錄存放測(cè)試用例
exit                        ## 退出開發(fā)板系統(tǒng)

2.將壓縮包push到開發(fā)板

hdc_std file send speexdsp.tar /speexdsp

3.解壓壓縮包并將庫文件拷貝到對(duì)應(yīng)的目錄

本次移植是基于openharmony標(biāo)準(zhǔn)系統(tǒng)3.2Beta1版本,是arm64位系統(tǒng)

hdc_std shell              ## 進(jìn)入開發(fā)板系統(tǒng)
cd speexdsp
tar -xvf speexdsp.tar
cp libspeexdsp_share.z.so /system/lib64/ ## 將庫文件拷貝系統(tǒng)目錄

執(zhí)行測(cè)試程序、分析測(cè)試結(jié)果

分析測(cè)試結(jié)果需要使用到的音頻處理軟件是ocenaudio,下載地址:https://www.ocenaudio.com/en/
image.png

①執(zhí)行testresample可執(zhí)行文件
通過分析testresample.c源碼可知:執(zhí)行測(cè)試程序時(shí)輸入一份采樣率為96000Hz并且為單聲道的音頻時(shí),經(jīng)過重采樣輸出的音頻采樣率為44100Hz。
在pc端運(yùn)行
輸入的音頻為input.pcm,把它拷貝到testresample同目錄下,并且新建空白文檔命名為output.pcm。
image.png
打開終端執(zhí)行如下命令:

chmod 777 testresample
./testresample < input.pcm > output.pcm

使用重定向<符號(hào)指定輸入文件、>符號(hào)指定輸出文件
image.png

輸出的output.pcm采樣率變?yōu)?4100Hz,音頻的波形圖聲譜圖如下:

image.png

在rk3568上運(yùn)行

這里測(cè)試testresample時(shí),將一份與pc端同樣的input.pcm和output.pcm拷貝至開發(fā)板speexdsp目錄。
在開發(fā)板speexdsp目錄執(zhí)行語句如下

chmod 777 testresample                  ## 添加可執(zhí)行權(quán)限
./testresample < input.pcm > output.pcm

image.png

將開發(fā)板輸出的output.pcm拷貝至pc端

hdc_std file recv /speexdsp/output.pcm C:UsersjjhDesktop

image.png

測(cè)試結(jié)果:經(jīng)過重采樣,pc端和rk3568開發(fā)板輸出的output.pcm音頻采樣率都為44100Hz,兩者運(yùn)行測(cè)試程序testresample結(jié)果一致。

②執(zhí)行testresample2可執(zhí)行文件

通過分析testresample2.c源碼可知,執(zhí)行測(cè)試程序時(shí)需要指定一份空白的單聲道音頻文件output.pcm。

測(cè)試testresample2時(shí),需要把空白的單聲道音頻文件output.pcm拷貝至開發(fā)板speexdsp目錄。
pc端運(yùn)行
執(zhí)行語句如下:

./testresample2 > output.pcm

輸出結(jié)果如下:
終端打印信息
image.png

輸出音頻output.pcm波形圖和聲譜圖如下:
image.png

rk3568開發(fā)板上運(yùn)行
執(zhí)行語句如下:

./testresample2 > output.pcm

image.png

測(cè)試結(jié)果:輸出一份不為空的output.pcm音頻文件,并且在終端輸出文本如下:

1000 0 1024 22 -> 1024 0                  
1100 0 1024 24 -> 1024 15
1200 0 1024 26 -> 926 26
1300 926 1122 31 -> 1048 31
1400 950 1098 33 -> 1032 33
...
...
...
127600 1024 1024 2723 -> 1024 2723
...
...
127900 1024 1024 2729 -> 1024 2729
128000 1024 1024 2731 -> 1024 2730

以最后一行"128000 1024 1024 2731 -> 1024 2730“”為例,其中128000為采樣率(Hz);1024為一個(gè)編碼單元采樣點(diǎn)數(shù)(幀);1024為輸入音頻理論幀長(zhǎng);2731為輸出音頻理論幀長(zhǎng)。"->"符號(hào)后的1024為經(jīng)過重采樣處理輸入音頻實(shí)際幀長(zhǎng),2730為輸出音頻實(shí)際幀長(zhǎng)。

  • pc端和rk3568開發(fā)板運(yùn)行testresample2可執(zhí)行程序效果一致。

③執(zhí)行testecho可執(zhí)行文件

測(cè)試testecho時(shí),需要輸入兩份音頻文件,同時(shí)需要指定一份輸出的音頻文件。

輸入的兩份音頻一份為speaker.wav(麥克風(fēng)收錄的說話人語音信號(hào)+在房間多徑反射的語音),另一份為micin.wav(麥克風(fēng)收錄的房間多徑反射的語音)。

  • speaker.wav正常房間環(huán)境下收錄說話人說話聲音即可,mic2.pcm在正常環(huán)境收錄時(shí)說話人不說話即可。
  • 同時(shí)需要指定一份testecho_output.wav輸出文件。

執(zhí)行語句如下:

./testecho speaker.wav micin.wav testecho_output.wav

image.png

測(cè)試結(jié)果:對(duì)比輸入的speaker.wav和輸出testecho_output.wav的波形圖和聲譜圖,回聲已經(jīng)被消除。pc端和rk3568開發(fā)板運(yùn)行testecho可執(zhí)行程序效果一致。

image.png

④執(zhí)行testdenoise可執(zhí)行文件

通過分析testdenoise.c源碼,執(zhí)行測(cè)試程序時(shí)需要指定一份輸入的不為空的8000Hz的input.pcm音頻,并且需要指定一份空的輸出的output.pcm音頻。

rk3568上運(yùn)行
執(zhí)行語句如下:

./testdenoise < input.pcm > output.pcm

image.png

測(cè)試結(jié)果:對(duì)比輸入的input.pcm和輸出的outpu.pcm的波形圖和聲譜圖,噪聲已經(jīng)被消除。pc端和rk3568開發(fā)板運(yùn)行testdenoise可執(zhí)行程序效果一致。

image.png

⑤執(zhí)行testjitter可執(zhí)行文件

通過分析testjitter.c源碼,測(cè)試需要接收來自u(píng)dp/rtp的網(wǎng)絡(luò)語音數(shù)據(jù),原生測(cè)試程序沒有做到真正意義上的測(cè)試,從程序上看是告訴用戶如何使用接口。

執(zhí)行語句如下

./testjitter

測(cè)試結(jié)果:終端打印出語句

Frozen sender: Jitter 0

pc端和rk3568開發(fā)板運(yùn)行testjitter可執(zhí)行程序效果一致。
image.png

下期預(yù)告:OAT開源掃描和三方庫上倉基本要求

聲明:本文內(nèi)容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點(diǎn)僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場(chǎng)。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問題,請(qǐng)聯(lián)系本站處理。 舉報(bào)投訴
  • dayu200
    +關(guān)注

    關(guān)注

    1

    文章

    26

    瀏覽量

    1303
  • 潤和軟件
    +關(guān)注

    關(guān)注

    1

    文章

    288

    瀏覽量

    982
收藏 人收藏

    評(píng)論

    相關(guān)推薦

    北京迅為RK3568開發(fā)板OpenHarmony系統(tǒng)南向驅(qū)動(dòng)開發(fā)內(nèi)核HDF驅(qū)動(dòng)框架架構(gòu)

    北京迅為RK3568開發(fā)板OpenHarmony系統(tǒng)南向驅(qū)動(dòng)開發(fā)內(nèi)核HDF驅(qū)動(dòng)框架架構(gòu)
    的頭像 發(fā)表于 03-11 14:13 ?225次閱讀
    北京迅為RK3568<b class='flag-5'>開發(fā)板</b><b class='flag-5'>OpenHarmony</b><b class='flag-5'>系統(tǒng)</b>南向驅(qū)動(dòng)<b class='flag-5'>開發(fā)</b>內(nèi)核HDF驅(qū)動(dòng)框架架構(gòu)

    基于OpenHarmony標(biāo)準(zhǔn)系統(tǒng)的C++公共基礎(chǔ)類庫案例:ThreadPoll

    1、程序簡(jiǎn)介該程序是基于OpenHarmony標(biāo)準(zhǔn)系統(tǒng)的C++公共基礎(chǔ)類庫的線程池處理:ThreadPoll。本案例完成如下工作:創(chuàng)建1個(gè)線程池,設(shè)置該線程池內(nèi)部有1024個(gè)線程空間。啟動(dòng)5個(gè)線程
    的頭像 發(fā)表于 02-10 18:09 ?130次閱讀
    基于<b class='flag-5'>OpenHarmony</b><b class='flag-5'>標(biāo)準(zhǔn)系統(tǒng)</b>的C++公共基礎(chǔ)類庫案例:ThreadPoll

    dayu200 rk3568 openharmony5.0 sim卡 通話服務(wù)

    想請(qǐng)問一下有人在dayu200 rk3568上插過sim卡并且成功完成過通話服務(wù)嗎? 我現(xiàn)在在dayu200上燒錄了openHarmony release 5.0.0版本的鏡像,在上面插上了sim卡,但是仍然顯示未檢測(cè)到sim卡
    發(fā)表于 12-26 16:52

    基于ArkTS語言的OpenHarmony APP應(yīng)用開發(fā):HelloOpenharmony

    1、程序簡(jiǎn)介該程序是基于OpenHarmony標(biāo)準(zhǔn)系統(tǒng)編寫的UI應(yīng)用類:HelloOpenHarmony。本案例是基于API9接口開發(fā)。本案例已在O
    的頭像 發(fā)表于 09-15 08:09 ?573次閱讀
    基于ArkTS語言的<b class='flag-5'>OpenHarmony</b> APP應(yīng)用<b class='flag-5'>開發(fā)</b>:Hello<b class='flag-5'>Openharmony</b>

    瑞芯微RK3566鴻蒙開發(fā)板OpenHarmony標(biāo)準(zhǔn)系統(tǒng)應(yīng)用兼容性測(cè)試指導(dǎo)

    本文OpenHarmony標(biāo)準(zhǔn)系統(tǒng)應(yīng)用兼容性測(cè)試指導(dǎo),適用鴻蒙系統(tǒng)軟件開發(fā)測(cè)試的新手入門學(xué)習(xí)課程,設(shè)備為觸覺智能的瑞芯微RK3566開發(fā)板,型號(hào)Purple Pi OH。是Laval官
    的頭像 發(fā)表于 09-10 11:56 ?643次閱讀
    瑞芯微RK3566鴻蒙<b class='flag-5'>開發(fā)板</b><b class='flag-5'>OpenHarmony</b><b class='flag-5'>標(biāo)準(zhǔn)系統(tǒng)</b>應(yīng)用兼容性測(cè)試指導(dǎo)

    請(qǐng)求推薦無需NPU的OpenHarmony標(biāo)準(zhǔn)系統(tǒng)ARM開發(fā)板

    請(qǐng)教一下大佬們,目前的需求是在國產(chǎn)ARM開發(fā)板上跑OpenHarmony標(biāo)準(zhǔn)系統(tǒng),無需NPU/GPU,其它配置(CPU、RAM等)可以盡量高點(diǎn),價(jià)位在2k以內(nèi),球球推薦!感謝大佬們!
    發(fā)表于 08-16 16:25

    開鴻“龍芯+OpenHarmony開發(fā)平臺(tái)DAYU431先鋒派新品發(fā)布

    開鴻基于全新龍芯2K0300芯片平臺(tái)的重磅新品開鴻HH-SCDAYU431先鋒派開發(fā)平臺(tái)正式上市,成為開鴻DAYU系列產(chǎn)品中符合
    的頭像 發(fā)表于 08-07 14:50 ?689次閱讀
    <b class='flag-5'>潤</b>開鴻“龍芯+<b class='flag-5'>OpenHarmony</b>”<b class='flag-5'>開發(fā)</b>平臺(tái)<b class='flag-5'>DAYU</b>431先鋒派新品發(fā)布

    鴻蒙OpenHarmony南向/北向快速開發(fā)教程-迅為RK3568開發(fā)板

    大家期待已久的迅為RK3568開發(fā)板終于迎來了鴻蒙4.1系統(tǒng)的強(qiáng)勢(shì)支持!想知道如何實(shí)現(xiàn)快速開發(fā)學(xué)習(xí)嗎?跟著我們一起來探索吧! 迅為RK3568開發(fā)板: 想象一下,你手中的RK3568
    發(fā)表于 07-23 10:44

    鴻蒙OpenHarmony【基于Hi3516DV300開發(fā)板(時(shí)鐘應(yīng)用開發(fā))】

    如何快速搭建基于OpenHarmony標(biāo)準(zhǔn)系統(tǒng)(Hi3516DV300開發(fā)板)的應(yīng)用開發(fā)環(huán)境,并基于一個(gè)時(shí)鐘APP示例逐步展示應(yīng)用的創(chuàng)建、開發(fā)
    的頭像 發(fā)表于 05-08 15:27 ?1319次閱讀
    鴻蒙<b class='flag-5'>OpenHarmony</b>【基于Hi3516DV300<b class='flag-5'>開發(fā)板</b>(時(shí)鐘應(yīng)用<b class='flag-5'>開發(fā)</b>)】

    鴻蒙OpenHarmony南向:【Hi3516標(biāo)準(zhǔn)系統(tǒng)入門(命令行方式)】

    除小型系統(tǒng)外,Hi3516DV300開發(fā)板還支持標(biāo)準(zhǔn)系統(tǒng)。此章節(jié)簡(jiǎn)要介紹如何使用命令行在Hi3516DV300開發(fā)板上進(jìn)行標(biāo)準(zhǔn)系統(tǒng)
    的頭像 發(fā)表于 05-08 09:26 ?1012次閱讀
    鴻蒙<b class='flag-5'>OpenHarmony</b>南向:【Hi3516<b class='flag-5'>標(biāo)準(zhǔn)系統(tǒng)</b>入門(命令行方式)】

    鴻蒙OpenHarmony標(biāo)準(zhǔn)系統(tǒng) 運(yùn)行】(基于RK3568開發(fā)板

    燒錄完成重啟開發(fā)板后,系統(tǒng)將會(huì)自動(dòng)啟動(dòng)。開發(fā)板附帶的屏幕呈現(xiàn)以下界面,表明系統(tǒng)已運(yùn)行成功。
    的頭像 發(fā)表于 05-06 15:38 ?562次閱讀
    鴻蒙<b class='flag-5'>OpenHarmony</b>【<b class='flag-5'>標(biāo)準(zhǔn)系統(tǒng)</b> 運(yùn)行】(基于RK3568<b class='flag-5'>開發(fā)板</b>)

    鴻蒙OpenHarmony標(biāo)準(zhǔn)系統(tǒng) 運(yùn)行】 (基于RK3568開發(fā)板

    燒錄完成重啟開發(fā)板之后,系統(tǒng)將會(huì)自動(dòng)啟動(dòng)……
    的頭像 發(fā)表于 04-25 15:56 ?971次閱讀
    鴻蒙<b class='flag-5'>OpenHarmony</b>【<b class='flag-5'>標(biāo)準(zhǔn)系統(tǒng)</b> 運(yùn)行】 (基于RK3568<b class='flag-5'>開發(fā)板</b>)

    鴻蒙OpenHarmony標(biāo)準(zhǔn)系統(tǒng)編寫“Hello World”程序】 (基于RK3568開發(fā)板

    源碼],創(chuàng)建RK3568開發(fā)板的源碼工程。 示例目錄 拉取openharmony項(xiàng)目代碼,在代碼根目錄創(chuàng)建sample子系統(tǒng)文件夾,在子系統(tǒng)目錄下創(chuàng)建hello部件文件夾,hello文
    的頭像 發(fā)表于 04-24 17:32 ?1067次閱讀
    鴻蒙<b class='flag-5'>OpenHarmony</b>【<b class='flag-5'>標(biāo)準(zhǔn)系統(tǒng)</b>編寫“Hello World”程序】 (基于RK3568<b class='flag-5'>開發(fā)板</b>)

    OpenHarmony開發(fā)實(shí)例:【電話簿聯(lián)系人Contacts】

    Contacts應(yīng)用是基于OpenHarmony SDK開發(fā)的安裝在和HiSpark Taurus AI Camera(Hi3516d)開發(fā)板標(biāo)準(zhǔn)
    的頭像 發(fā)表于 04-23 09:44 ?934次閱讀
    <b class='flag-5'>OpenHarmony</b><b class='flag-5'>開發(fā)</b>實(shí)例:【電話簿聯(lián)系人Contacts】

    OpenHarmony開發(fā)實(shí)例:【 待辦事項(xiàng)TodoList】

    TodoList應(yīng)用是基于OpenHarmony SDK開發(fā)的安裝在和HiSpark Taurus AI Camera(Hi3516d)開發(fā)板標(biāo)準(zhǔn)
    的頭像 發(fā)表于 04-22 22:00 ?872次閱讀
    <b class='flag-5'>OpenHarmony</b><b class='flag-5'>開發(fā)</b>實(shí)例:【 待辦事項(xiàng)TodoList】
    主站蜘蛛池模板: 伊人色综合久久天天网 | 囯产免费久久久久久国产免费 | 99在线观看视频 | 动漫AV纯肉无码AV电影网 | 色影音先锋av资源网 | 欧美视频 亚洲视频 | av狼新人开放注册区 | 国产午夜婷婷精品无码A片 国产午夜视频在永久在线观看 | 久久精品国产福利电影网 | 在线伦理电影网 | 亚洲成片在线看 | 97国产在线观看 | 高清不卡伦理电影在线观看 | 伊人久久电影院 | 成人AV无码一二二区视频免费看 | 国产AV视频二区在线观看 | 成人国产亚洲欧美成人综合网 | 亚洲精品中文字幕制 | 暖暖视频免费观看视频 | 青青操久久 | 国产精品你懂得 | 91精选国产 | 久久久中日AB精品综合 | 亚洲AV中文字幕无码久久 | 国产中文视频无码成人精品 | 久久亚洲精品专区蓝色区 | 午夜影院老司机 | 日韩爽爽影院在线播放 | 日韩无码在线 | 亚洲一区综合图区 | 动漫美女被h动态图 | 久青草国产在视频在线观看 | jk制服喷水 | 99久久精品免费看国产一区二区 | 野花日本完整版在线观看免费高清 | 亚洲婷婷天堂综合国产剧情 | 色狠狠色综合吹潮 | 日韩做A爰片久久毛片A片毛茸茸 | 浪货嗯啊趴下NP粗口黄暴 | 国产成人拍精品视频网 | 97久久伊人精品影院 |