1. Audio 教程
Audio库提供各种示例sketch,包括播放和录音音频。
利用Spresense的多核特征,诸如音频编码/解码的处理在与用户应用操作的主核不同的核(以下称为DSP)中执行。 这允许用户轻松开发使用音频功能的应用程序,而无需复杂的控制。
音频教程说明如何安装DSP文件以及如何使用各种示例sketch。
1.1. 安装DSP文件
运行示例前,必须根据播放/录音的格式预先安装DSP文件。 本节介绍如何安装DSP文件。
1.1.1. DSP文件类型
| DSP文件名 | DSP安装程序 | 说明 |
|---|---|---|
MP3DEC |
mp3_dec_installer |
用于MP3音频播放 |
MP3ENC |
mp3_enc_installer |
用于MP3录音 |
WAVDEC |
wav_dec_installer |
用于WAV(PCM)音频播放 |
SRC |
src_installer |
用于WAV(PCM)录音 |
1.1.2. DSP安装方法
有两种方法可以安装DSP:
-
下载DSP文件并将其直接复制到microSD卡
-
使用DSP安装程序sketch
往microSD卡上安装的方法没有特别限制。 使用DSP安装程序时,除了扩展板上的microSD卡外,还可以安装到主板上的SPI-Flash。
注意:除非更新DSP文件,否则一次安装后不需要每次都执行DSP文件安装过程。
1.1.2.2. 使用DSP安装程序安装
为每个DSP文件都提供了DSP安装程序。
-
运行Arduino IDE, 选择
File→ Sketch Example→ Spresense Sketch Example Audio→ dsp_installer。
图表 2. 启动DSP安装程序 -
选择
Tools→ Serial Port下的Spresense COM端口,执行写入操作。 -
编译和写入(上载)完成后,启动Serial monitor。
-
选择波特率115200 bps时,将显示如下所示的消息。
-
选择安装编号,然后按“发送”按钮。
安装到microSD卡时,将FAT32格式的microSD卡插入扩展板上的microSD卡插槽。
图表 3. 选择DSP安装位置 -
如果安装成功,将显示以下消息。
图表 4. DSP安装执行
在音频播放/录音应用程序中,使用 initPlayer() 或 initRecorder() 函数的参数指定安装DSP文件的位置。 默认为microSD卡( /mnt/sd0/BIN )。使用SPI-Flash时,将其更改为 /mnt/spif/BIN 。
|
1.2. 高级接口层
Spresense Audio库是、
Audio库的开发指南 像这样、具有分层结构。
高级接口层是、在保持整体系统一致性的同时,以高度抽象的方式实现典型功能。
+ 下面是使用此高级接口层的示例。
1.2.1. 播放蜂鸣音
1.2.1.1. 摘要
此示例使用音频硬件的功能输出蜂鸣声。
指定频率的声音由音频库的setBeep()函数输出。 此功能与Arduino tone()功能非常相似,但不需要准备压电蜂鸣器。 声音从Spresense扩展板的耳机插孔输出。
在此示例中,不需要安装DSP文件。
1.2.1.3. 操作程序
-
运行Arduino IDE,选择
File→ Sketch Example→ Spresense Sketch Example Audio→ application→ beep打开示例sketch。
-
在
Tools→ Serial Port中选择Spresense COM端口并写入微控制器板。
-
耳机输出音阶音。
1.2.1.4. 程序说明
-
使用
setPlayerMode()函数设置播放器模式。theAudio->setPlayerMode(device, (1) player0bufsize, (2) player1bufsize); (3)1 device:选择输出设备,输出到扬声器耳机(AS_SETPLAYER_OUTPUTDEVICE_SPHP),I2S(AS_SETPLAYER_OUTPUTDEVICE_I2SOUTPUT)。
此示例使用AS_SETPLAYER_OUTPUTDEVICE_SPHP。
使用I2S时,请参阅输出到I2S。2 player0bufsize:指定播放器0的缓冲区大小。3 player1bufsize:指定播放器1的缓冲区大小。 有关详情,请参见关于播放器缓冲区大小。
如果仅输出蜂鸣声,则不使用缓冲区,因此在此示例中指定了0。 -
要输出蜂鸣声,请使用
setBeep()函数。theAudio->setBeep(enable, (1) volume, (2) frequency); (3)1 当 enable设置为1时,蜂鸣声输出开始,当enable设置为0时停止。2 volume:音量可以改变(-90到0[dB])。3 frequency:输出指定频率的声音。
1.2.2. 播放MP3音乐
1.2.2.3. 操作程序
-
在microSD卡上安装MP3解码DSP文件
MP3DEC(参见安装DSP文件)。 -
将要播放的MP3文件放在microSD卡的根目录中,文件名为“Sound.mp3”。
-
将microSD卡插入扩展板上的microSD卡插槽。
-
运行Arduino IDE,选择
File→ Sketch Example→ Spresense Sketch Example Audio→ application→ player打开示例sketch。
-
在
Tools→ Serial Port中选择Spresense COM端口并写入微控制器板。 -
上传并执行sketch时,耳机将播放放置在microSD卡上的MP3文件。
当文件播放到最后时停止。
1.2.2.4. 程序说明
-
使用
setRenderingClockMode()函数设置时钟模式。theAudio->setRenderingClockMode(mode); (1)1 mode:选择正常(AS_CLKMODE_NORMAL),高分辨率(AS_CLKMODE_HIRES)时钟模式。
MP3播放时指定“AS_CLKMODE_NORMAL”。 -
使用
setPlayerMode()函数设置播放器模式。theAudio->setPlayerMode(device, (1) sp_drv); (2)1 device:选择输出设备,输出到扬声器耳机(AS_SETPLAYER_OUTPUTDEVICE_SPHP),I2S(AS_SETPLAYER_OUTPUTDEVICE_I2SOUTPUT)。
此示例使用AS_SETPLAYER_OUTPUTDEVICE_SPHP。
使用I2S时,请参阅输出到I2S。2 sp_drv:设置输出驱动器。
在此示例中,指定“AS_SP_DRV_MODE_LINEOUT”。
有关详细信息,请参阅使用扩展板上的扬声器端子时。 -
使用
initPlayer()函数初始化播放器。theAudio->initPlayer(id, (1) codec, (2) codec_path, (3) fs, (4) channel); (5)1 id:选择播放器ID。
此示例使用AudioClass::Player0。2 codec:指定MP3(AS_CODECTYPE_MP3)作为编解码器类型。3 codec_path:指定安装DSP文件的位置。
为microSD卡指定/ mnt/sd0/BIN,为SPI-Flash指定/mnt/spif/BIN。4 fs:指定采样率。
MP3支持32kHz(AS_SAMPLINGRATE_32000),44.1kHz(AS_SAMPLINGRATE_44100),48kHz(AS_SAMPLINGRATE_48000)。 如果指定AS_SAMPLINGRATE_AUTO,则自动确定采样率。5 channel:指定单声道(AS_CHANNEL_MONO)或立体声(AS_CHANNEL_STEREO)。 -
使用
writeFrames()函数将MP3文件的内容写入解码器。theAudio->writeFrames(id, (1) myFile); (2)1 id:选择播放器ID。
此示例使用AudioClass::Player0。2 可以使用参数中指定的myFile更改播放文件。
此示例使用名为“Sound.mp3”的文件。
周期性地执行该函数以将流提供给解码器,从而不中断解码。 当函数写入文件末尾时,返回AUDIOLIB_ECODE_FILEEND作为函数的返回值。 -
使用
startPlayer()函数启动播放器。theAudio->startPlayer(id); (1)1 id:选择播放器ID。
此示例使用AudioClass::Player0。
使用writeFrames()函数写入解码器后调用该函数。 -
使用
stopPlayer()函数停止播放器。theAudio->stopPlayer(id, (1) mode); (2)1 id:选择播放器ID。
此示例使用AudioClass::Player0。2 可以选择是立即停止( AS_STOPPLAYER_NORMAL)还是等到已经提供给解码器的流完成播放(AS_STOPPLAYER_ESEND)。 如果没有指定mode,则缺省为AS_STOPPLAYER_NORMAL。 -
使用
setVolume(volume)功能调节音量。theAudio->setVolume(volume); (1)1 volume:您可以更改音量。 (-1020至120)
指定值的1/10是实际音量[dB]。 例如,当指定15时,音量为1.5 [dB]。
1.2.2.5. 关于播放器缓冲区大小
默认情况下,每个播放器用于从microSD卡读取的缓冲区大小为160kByte。 此大小是可以读取高分辨率WAV音频的大小,以及播放48 kHz MP3文件等的大小。 您可以通过设置 setPlayerMode 函数参数以减少缓冲区大小。 作为示例,当播放192kHz高分辨率WAV文件时,默认为160kByte 播放大约128kbps的MP3文件时,建议设置为大约24kByte。
注意:尺寸仅供参考。 请根据microSD卡性能,应用吞吐量等进行调整。 如果缓冲区太小,从microSD卡读取时会发生错误。 如果发生读取数据下溢,请增加缓冲区大小。
1.2.2.6. 输出到I2S
如果要将输出设备切换到I2S,请将 setPlayerMode 中的输出设备切换到 AS_SETPLAYER_OUTPUTDEVICE_I2SOUTPUT 。 I2S的工作模式仅支持从模式,I2S格式模式,48000Hz和立体声。
1.2.2.7. 使用扩展板上的扬声器端子时
在使用扩展板的耳机端子作为音频输出的情况下,作为音频信号的驱动能力设置,
setPlayerMode 的 sp_drv 指定为 AS_SP_DRV_MODE_LINEOUT (默认值)。
从扩展板的扬声器端子输出时,参数 sp_drv 指定为 AS_SP_DRV_MODE_4DRIVER 。
使用扬声器端子时,需要修改电路板。 有关详细信息,请参阅:
1.2.3. 播放WAV音乐
1.2.3.3. 操作程序
-
在microSD卡上安装WAV解码DSP文件
WAVDEC(参见安装DSP文件)。 -
将要播放的WAV文件放在microSD根目录中,名称为“Sound.wav”。
-
将microSD卡插入扩展板上的microSD卡插槽。
-
运行Arduino IDE,选择
File→ Sketch Example→ Spresense Sketch Example Audio→ application→ player_wav打开示例sketch。
在 Tools→ Serial Port 中选择Spresense COM端口并写入微控制器板。
上传并执行sketch时,将从耳机播放放置在microSD卡上的WAV文件。
当文件播放到最后时,它将停止。
1.2.3.4. 程序说明
-
使用
setRenderingClockMode()函数设置时钟模式。theAudio->setRenderingClockMode(mode); (1)1 模式:选择正常( AS_CLKMODE_NORMAL)或高分辨率(AS_CLKMODE_HIRES)时钟模式。
在这个例子中,我们将使用AS_CLKMODE_NORMAL。
只有在调用setPlayerMode()函数前或处于ReadyMode状态时才可以调用此函数。
要动态切换正常分辨率和高分辨率,请在切换AS_CLKMODE_NORMAL或AS_CLKMODE_HIRES之前调用setReadyMode()并切换到Ready状态。 -
使用
setPlayerMode()函数设置播放器模式。theAudio->setPlayerMode(device, (1) sp_drv); (2)1 device:选择输出设备,输出到扬声器耳机(AS_SETPLAYER_OUTPUTDEVICE_SPHP),I2S(AS_SETPLAYER_OUTPUTDEVICE_I2SOUTPUT)。
此示例使用AS_SETPLAYER_OUTPUTDEVICE_SPHP。
使用I2S时,请参阅输出到I2S。2 sp_drv:设置输出驱动器。
在此示例中,指定AS_SP_DRV_MODE_LINEOUT。
有关详细信息,请参阅使用扩展板上的扬声器端子时。 -
使用
initPlayer()函数初始化播放器。theAudio->initPlayer(id, (1) codec, (2) codec_path, (3) fs, (4) channel); (5)1 id:选择播放器ID。
此示例使用AudioClass::Player0。2 codec:指定MP3(AS_CODECTYPE_MP3)作为编解码器类型。3 codec_path:指定安装DSP文件的位置。
为microSD卡指定/mnt/sd0/BIN,为SPI-Flash指定/ mnt/spif/BIN。4 fs:指定采样率。
MP3支持32kHz(AS_SAMPLINGRATE_32000),44.1kHz(AS_SAMPLINGRATE_44100),48kHz(AS_SAMPLINGRATE_48000)。 如果指定AS_SAMPLINGRATE_AUTO,则自动确定采样率。5 channel:指定单声道(AS_CHANNEL_MONO)或立体声(AS_CHANNEL_STEREO)。 -
使用
writeFrames()函数将WAV文件的内容写入解码器。theAudio->writeFrames(id, (1) data, (2) write_size);1 id:选择播放器ID。
此示例使用AudioClass::Player0。2 可以通过更改从microSD卡读取的文件来更改播放文件。
在此示例中,指定了从文件“Sound.wav”读取的缓冲区。
周期性地执行该函数以将流提供给解码器,从而不中断解码。 -
使用
startPlayer()函数启动播放器。theAudio->startPlayer(id); (1)1 id:选择播放器ID。
此示例使用AudioClass::Player0。
使用writeFrames()函数写入解码器后调用该函数。 -
使用
stopPlayer()函数停止播放器。theAudio->stopPlayer(id, (1) mode); (2)1 id:选择播放器ID。
此示例使用AudioClass::Player0。2 可以选择是立即停止( AS_STOPPLAYER_NORMAL)还是等到已经提供给解码器的流完成播放(AS_STOPPLAYER_ESEND)。 如果没有指定mode,则缺省为AS_STOPPLAYER_NORMAL。 -
使用
setVolume(音量)功能调节音量。theAudio->setVolume(volume); (1)1 volume:您可以更改音量。 (-1020至120)
指定值的1/10是实际音量[dB]。 例如,当指定15时,音量为1.5 [dB] です。
1.2.4. 播放高分辨率音频
1.2.4.3. 操作程序
-
在microSD卡上安装WAV解码DSP文件
WAVDEC(参见安装DSP文件)。 -
将要播放的WAV文件放在microSD卡的根目录中,文件名为“HiResSound.wav”。
-
将microSD卡插入扩展板上的microSD卡插槽。
-
运行Arduino IDE,选择
File→ Sketch Example→ Spresense Sketch Example Audio→ application→ player_hires来启动示例sketch。
-
在
Tools→ Serial port中选择Spresense COM端口并写入微控制器板。 -
上传并执行sketch时,放置在microSD卡上的高分辨率WAV文件将从耳机播放。
文件播放结束时停止。
1.2.4.4. 程序说明
-
使用
setRenderingClockMode()函数设置时钟模式。theAudio->setRenderingClockMode(mode); (1)1 模式:选择正常( AS_CLKMODE_NORMAL)或高分辨率(AS_CLKMODE_HIRES)时钟模式。
在这个例子中,我们使用AS_CLKMODE_HIRES。
只有在调用setPlayerMode()前或处于ReadyMode状态时才可以调用此函数。
要动态切换正常分辨率和高分辨率,请在切换“AS_CLKMODE_NORMAL”或“AS_CLKMODE_HIRES”之前调用setReadyMode()并切换到Ready状态。 -
使用
setPlayerMode()函数设置播放器模式。theAudio->setPlayerMode(device, (1) sp_drv); (2)1 device:选择输出设备,输出到扬声器耳机(AS_SETPLAYER_OUTPUTDEVICE_SPHP),I2S(AS_SETPLAYER_OUTPUTDEVICE_I2SOUTPUT)。
在这个示例中,我们使用AS_SETPLAYER_OUTPUTDEVICE_SPHP。
使用I2S时,请参阅输出到I2S。2 sp_drv:设置输出驱动器。 在此示例中,指定AS_SP_DRV_MODE_LINEOUT。
有关详细信息,请参阅使用扩展板上的扬声器端子时。 -
使用
initPlayer()函数初始化播放器。theAudio->initPlayer(id, (1) codec, (2) codec_path, (3) fs, (4) bitlen, (5) channel); (6)1 id:选择播放器ID。
此示例使用AudioClass::Player0。2 codec:将编解码器类型指定为WAV(AS_CODECTYPE_WAV)。3 codec_path:指定DSP文件的安装位置。
为microSD指定/mnt/sd0/BIN,为SPI-Flash指定/mnt/spif/BIN。4 fs:指定采样率。
此示例指定96kHz(AS_SAMPLINGRATE_96000)。5 bitlen:指定位长度。
在此示例中,指定了24位(AS_BITLENGTH_24)。6 channel:指定单声道(AS_CHANNEL_MONO)或立体声(AS_CHANNEL_STEREO)。
-
调用
writeFrames()将从WAV文件读取的内容写入解码器。theAudio->writeFrames(id, (1) myFile); (2)1 id:选择播放器ID。
此示例使用AudioClass::Player0。2 您可以通过指定myFile参数来更改播放文件。
此示例使用名为“HiResSound.wav”的文件。
周期性地执行该函数以将流提供给解码器,从而不中断解码。。 当函数写入文件末尾时,返回AUDIOLIB_ECODE_FILEEND作为函数的返回值。 -
使用
startPlayer()函数启动播放器。theAudio->startPlayer(id); (1)1 id:选择播放器ID。
此示例使用AudioClass::Player0。
使用writeFrames()函数写入解码器后调用。 -
使用
stopPlayer()函数停止播放器。theAudio->stopPlayer(id, (1) mode); (2)1 id:选择播放器ID。
此示例使用AudioClass::Player0。2 可以选择是立即停止( AS_STOPPLAYER_NORMAL)还是等到已经提供给解码器的流完成播放(AS_STOPPLAYER_ESEND)。 如果没有指定mode参数,则缺省为AS_STOPPLAYER_NORMAL。 -
使用
setVolume(音量功能调节音量。theAudio->setVolume(volume); (1)1 volume: 您可以更改音量。(-102 ~ 120 [dB])
对于音量,指定一个乘以10的整数值,例如,15表示1.5 [dB]。
1.2.5. 播放播放列表
1.2.5.3. 操作程序
为了使用播放列表功能,需要在PC上预先创建播放列表文件并将其复制到microSD。 此示例sketch使用的microSD目录结构如下所示。
microSD 卡根目录
|-- BIN/
| |-- MP3DEC
| `-- WAVDEC
|-- AUDIO/
| |-- Sound1.mp3
| |-- Sound2.mp3
| |-- :
| |-- Sound1.wav
| |-- Sound2.wav
| |-- :
`-- PLAYLIST/
`-- TRACK_DB.CSV
-
在 BIN/ 目录中安装
MP3DEC和WAVDECDSP二进制文件(参见安装DSP文件)。 -
将播放列表播放的音乐文件复制到 AUDIO/ 目录。
-
将播放列表文件(
TRACK_DB.CSV)复制到 PLAYLIST/ 目录。
如何创建播放列表文件
播放列表文件 TRACK_DB.CSV 的格式如下所示。
这是CSV(逗号分隔值)格式的文本文件,其中每个文件的信息以行为单位写入。
[filename],[artist],[album],[channel number],[bit length],[sampling rate],[file format]
[filename],[artist],[album],[channel number],[bit length],[sampling rate],[file format]
[filename],[artist],[album],[channel number],[bit length],[sampling rate],[file format]
:
写入音乐文件名,艺术家姓名,专辑名称和编解码器信息(通道数,位长,采样率Hz)。
这是一个 TRACK_DB.CSV 的例子。
Sound1.mp3,Artist1,Album1,2,16,44100,mp3
Sound2.mp3,Artist1,Album1,2,16,44100,mp3
Sound1.wav,Artist2,Album2,2,16,48000,wav
Sound2.wav,Artist2,Album2,2,24,192000,wav
这里提供了一个简单的脚本工具mkplaylist.py,用于创建播放列表文件。 右键单击链接:这里 下载并使用该文件。 由于此脚本使用ffmpeg-python,请在已安装ffmpeg和ffmpeg-python的环境中使用它。
mkplaylist.py的用法如下所示。
python mkplaylist.py
usage: python mkplaylist.py dirname [dirname2] [dirname3] ...
usage: python mkplaylist.py -f filename
Generate an audio playlist file named as TRACK_DB.CSV
指定包含音乐文件的目录路径作为参数。 正常执行时,TRACK_DB.CSV文件将输出到当前目录。 如果TRACK_DB.CSV文件已存在,则将其添加到文件末尾。
python mkplaylist.py MyMusic
|
-
将microSD卡に插入扩展板上的microSD卡插槽。
-
运行Arduino IDE , 选择
File→ Sketch Example→ Spresense Sketch Example Audio→ application→ play_playlist打开示例sketch。
-
在
Tools→ Serial port中选择Spresense COM端口并写入微控制器板。 -
启动Serial monitor时,将显示以下菜单。 根据来自串口的键输入执行各种操作。
=== MENU (input key ?) ============== p: play s: stop +/-: volume up/down l: list n: next b: back r: repeat on/off R: random on/off a: auto play m,h,?: menu =====================================
| 使用EEPROM库,将诸如音量值,随机/重复/自动播放等信息保存在非易失性存储器中。 下次启动时,基于先前预设的信息运行。 创建自己的音乐播放器时请参考。 |
1.2.6. MP3双解码播放
1.2.6.3. 操作程序
-
在microSD上安装MP3解码DSP文件
MP3DEC(参见安装DSP文件)。 -
将要播放的两个MP3文件放在microSD卡的根目录中,文件名为“Sound0.mp3”和“Sound1.mp3”。
-
将microSD卡插入扩展板上的microSD卡插槽。
-
运行Arduino IDE, 选择
文件 - >sketch示例 - > Spresensesketch示例选择Audio→ application→ dual_players打开示例sketch。
-
在
Tools→ Serial port中选择Spresense COM端口并写入微控制器板。 -
编译sketch后烧写至开发板,程序运行时,microSD上的两个MP3会被混合在一起循环播放。
1.2.6.4. 程序说明
-
使用
setRenderingClockMode()函数设置时钟模式。theAudio->setRenderingClockMode(mode); (1)1 模式:选择正常( AS_CLKMODE_NORMAL)或高分辨率(AS_CLKMODE_HIRES)时钟模式。
为MP3播放指定“AS_CLKMODE_NORMAL”。 -
使用
setPlayerMode()函数设置播放器模式。theAudio->setPlayerMode(device, (1) sp_drv); (2)1 device:选择输出设备,输出到扬声器耳机(AS_SETPLAYER_OUTPUTDEVICE_SPHP),I2S(AS_SETPLAYER_OUTPUTDEVICE_I2SOUTPUT)。
こ在我们的示例中,我们使用AS_SETPLAYER_OUTPUTDEVICE_SPHP。
使用I2S时,请参阅输出到I2S。2 sp_drv:设置输出驱动器。
在此示例中,指定“AS_SP_DRV_MODE_LINEOUT”。
有关详细信息,请参阅使用扩展板上的扬声器端子时。 -
对于每个播放器0,1使用
initPlayer()函数初始化。theAudio->initPlayer(id, (1) codec, (2) codec_path, (3) fs, (4) channel); (5)1 id:选择播放器ID。
一个指定AudioClass::Player0,另一个指定AudioClass::Player1。2 codec: 指定编解码器类型MP3(AS_CODECTYPE_MP3)。3 codec_path:指定DSP文件的安装位置。
为microSD指定/mnt/sd0/BIN,为SPI-Flash指定/mnt/spif/BIN。4 fs:指定采样率。
MP3 支持32kHz (AS_SAMPLINGRATE_32000), 44.1kHz (AS_SAMPLINGRATE_44100), 48kHz (AS_SAMPLINGRATE_48000)。指定AS_SAMPLINGRATE_AUTO将自动选择采样率。5 channel:指定单声道(AS_CHANNEL_MONO)或立体声(AS_CHANNEL_STEREO)。 -
使用每个播放器0和1的
writeFrames()函数将MP3文件的内容写入解码器。theAudio->writeFrames(id, (1) myFile); (2)1 id:选择播放器ID。
一个指定AudioClass::Player0,另一个指定AudioClass::Player1。2 您可以通过指定myFile参数来更改播放文件。
此示例使用文件“Sound0.mp3”和“Sound1.mp3”。
周期性地执行该函数以将流提供给解码器,从而不中断解码。 当函数写入文件末尾时,返回AUDIOLIB_ECODE_FILEEND作为函数的返回值。 -
对于每个播放器0,1使用
startPlayer()函数。theAudio->startPlayer(id); (1)1 id:选择播放器ID。
一个指定AudioClass::Player0,另一个指定AudioClass::Player1。
使用writeFrames()函数写入解码器后调用。 -
对于每个播放器0,1使用
stopPlayer()函数停止播放器。theAudio->stopPlayer(id, (1) mode); (2)1 id:选择播放器ID。
一个指定AudioClass::Player0,另一个指定AudioClass::Player1。2 您可以选择是立即停止( AS_STOPPLAYER_NORMAL)还是等到已经提供给解码器的流完成播放(AS_STOPPLAYER_ESEND)。 如果没有指定mode参数,则缺省为AS_STOPPLAYER_NORMAL。 -
使用
setVolume(master,player0,player1)函数调整音量。theAudio->setVolume(master, (1) player0, (2) player1); (3)1 master: 更改两个播放器音量。(-1020 ~ 120)2 player0更改播放器0音量。(-1020 ~ 120)3 player1更改播放器1音量。(-1020 ~ 120)
指定值的1/10是实际音量[dB]。 例如,当指定15时,音量为1.5 [dB] 。 您可以使用master调整整体音量,使用player0,player1调整单个音量。。
1.2.7. 聆听麦克风输入的声音
1.2.7.1. 摘要
从麦克风输入的声音从耳机插孔输出。
使用音频硬件的路径设置功能,可以将来自I2S的数字音频输出到模拟通道,还可以将从麦克风的输入输出到I2S, 实现具有低功耗和非常低延迟的输出。
1.2.7.2. 运行环境
-
Spresense主板和扩展板
-
播放耳机或扬声器
-
录音麦克风
此示例使用耳机和麦克风。 将耳机或有源扬声器连接到扩展板上的耳机插孔。 有关麦克风连接,请参阅
在此示例中,不需要安装DSP文件。
1.2.7.3. 操作程序
-
运行Arduino IDE , 选择
File→ Sketch Example→ Spresense Sketch Example Audio→ application→ through打开示例sketch。
-
示例sketch将从I2S输入的声音输出到耳机插孔。
修改sketch以便将从麦克风输入的声音输出到耳机插孔。
通过File→ Save As将其保存到可编辑的位置。 -
将
setThroughMode()函数的参数input从AudioClass::I2sIn更改为AudioClass::MicIn并保存。 -
在
Tools→ Serial port中选择Spresense COM端口并写入微控制器板。 -
上传并执行sketch时,将从耳机听到麦克风输入的声音。
1.2.7.4. 程序说明
-
使用
setThroughMode()函数设置through模式。。theAudio->setThroughMode(input, (1) i2s_out, (2) sp_out, (3) input_gain, (4) sp_drv); (5)1 input选择输入系统。2 i2s_out选择要输出到I2S的信号源。3 sp_out选择是否输出到耳机扬声器。
例如,如果要将麦克风的音频输入输出到I2S,
为input指定AudioClass::MicIn,
为i2s_out指定AudioClass::Mic,
为sp_out指定false。4 input_gain设置麦克风增益。
可以为模拟麦克风设置0至21 [dB],为数字麦克风设置-78.5至0 [dB]。
模拟麦克风:对于input_gain,指定一个乘以10的整数值,例如为10 [dB]设置100。
数字麦克风:对于input_gain,指定一个乘以100的整数值,例如为-0.05 [dB]设置5。 <5>对于sp_drv,请参阅使用扩展板上的扬声器端子时。
1.2.8. 以MP3格式录音
1.2.8.3. 操作程序
-
在microSD上安装MP3编码DSP文件
MP3ENC((参见安装DSP文件)。 -
运行Arduino IDE , 选择
File→ Sketch Example→ Spresense Sketch Example Audio→ application→ recorder打开示例sketch。
-
在
Tools→ Serial port中选择Spresense COM端口并写入微控制器板。 -
上传并执行sketch时,录音开始并在一定时间后停止录音。
-
记录的数据保存在microSD卡中,文件名为“Sound.mp3”。
取出microSD卡并在PC上检查记录的数据。
1.2.9. 程序说明
-
使用
setRecorderMode()函数设置录音机模式。theAudio->setRecorderMode(input_device, (1) input_gain, (2) bufsize, (3) is_digital); (4)1 input_device:指定麦克风(AS_SETRECDR_STS_INPUTDEVICE_MIC)为输入设备。2 input_gain:设置麦克风增益。
可以为模拟麦克风设置0至21 [dB],为数字麦克风设置-78.5至0 [dB]。
模拟麦克风:对于input_gain,指定一个乘以10的整数值,例如为10 [dB]设置100。
数字麦克风:对于input_gain,指定一个乘以100的整数值,例如为-0.05 [dB]设置5。3 bufsize:指定录音机的缓冲区大小。
有关详细信息,请参阅关于录音机缓冲区大小。4 如果连接的麦克风是数字麦克风,请将参数 is_digital设置为true。 -
使用
initRecorder()函数初始化录音机。theAudio->initRecorder(codec, (1) codec_path, (2) fs, (3) channel); (4)1 codec指定编解码器类型MP3(AS_CODECTYPE_MP3)。2 codec_path指定DSP文件的安装位置。
为microSD指定/mnt/sd0/BIN,为SPI-Flash指定/mnt/spif/BIN。3 fs指定采样率。
MP3 支持32kHz (AS_SAMPLINGRATE_32000), 44.1kHz (AS_SAMPLINGRATE_44100), 48kHz (AS_SAMPLINGRATE_48000)。4 channel:指定单声道(AS_CHANNEL_MONO)或立体声(AS_CHANNEL_STEREO)。 -
使用
readFrames()函数读取MP3编码数据以记录到文件。theAudio->readFrames(myFile); (1)1 您可以通过指定myFile来更改录音文件。
此示例使用名为“Sound.mp3”的文件。
定期执行该函数以读出编码结果,以便编码缓冲区不会溢出。。 -
使用
startRecorder()函数启动录音机。 -
使用
stopRecorder()函数停止录音机。
1.2.9.1. 关于录音机缓冲区大小
写入microSD所需的缓冲区大小默认为160k字节。 这个尺寸足以读取高分辨率WAV音频,当播放48kHz MP3文件等时,将会消耗额外的内存。
默认情况下,160kByte是用于写入microSD卡的缓冲区大小。。 此大小是可以写入高分辨率WAV音频的大小,录音48 kHz MP3文件时, 通过setRecorderMode ,您可以更改要使用的缓冲区大小。 作为参考,当播放192kHz高分辨率WAV文件时,默认为160kByte, 录音48kHz MP3文件时,建议将其设置为大约8kByte。
注意: 大小仅供参考。请根据microSD卡性能,应用吞吐量等进行调整。 如果缓冲区太小,写入microSD时会出错。 如果发生溢出,请增加缓冲区大小。
注意:即使可以获取音频,由于诸如microSD的写入性能和正在运行的应用程序等因素,也可能无法写入所有数据。 对于当前的扩展板,上限为8ch / 48kHz或2ch / 192kHz。 此外,microSD的速度等级也有影响,请使用尽可能快传输速度的microSD卡。
1.2.10. 以WAV格式录音
1.2.10.3. 操作程序
-
在microSD卡上安装用于WAV(PCM)编码的DSP文件
SRC(参见安装DSP文件)。 -
运行Arduino IDE , 选择
File→ Sketch Example→ Sample Spresense Audio→ application→ recorder_wav打开示例sketch。
-
在 ` Tools→ Serial port ` 中选择Spresense COM端口并写入微控制器板。
-
上传并执行sketch时,录音开始并在一定时间后停止录音。
记录的数据保存在microSD上,文件名为“Sound.wav”。
取出microSD卡并在PC上检查记录的数据。
1.2.10.4. 程序说明
-
使用
setRecorderMode()函数设置为录音机模式。theAudio->setRecorderMode(input_device, (1) input_gain, (2) bufsize, (3) is_digital); (4)1 input_device: 指定麦克风(AS_SETRECDR_STS_INPUTDEVICE_MIC)为输入设备。2 input_gain: 您可以设置麦克风增益。
可以为模拟麦克风设置0至21 [dB],为数字麦克风设置-78.5至0 [dB]。
模拟麦克风:对于input_gain,指定一个乘以10的整数值,例如为10 [dB]设置100。
数字麦克风:对于input_gain,指定一个乘以100的整数值,例如为-0.05 [dB]设置5。3 bufsize: 指定录音机的缓冲区大小。
有关详细信息,请参阅关于录音机缓冲区大小。。4 如果连接的麦克风是数字麦克风,请将参数“is_digital”设置为“true”。
※在以高分辨率(192kHz)录音时,在调用setRecorderMode()函数之前, 您需要在setRenderingClockMode()函数中指定AS_CLKMODE_HIRES。 -
使用
initRecorder()函数初始化录音机。theAudio->initRecorder(codec, (1) codec_path, (2) fs, (3) channel); (4)1 codec指定编解码器类型为WAV(AS_CODECTYPE_WAV)。2 codec_path指定DSP文件的安装位置。
为microSD指定/mnt/sd0/BIN,为SPI-Flash指定/mnt/spif/BIN。3 fs指定采样率。4 channel指定通道数。
※以高分辨率(192kHz,24bit)录音时,设置fs为ASSAMPLINGRATE_192000,bitlen设置为AS_BITLENGTH_24 -
录音WAV文件时,在执行录音前调用
writeWavHeader()函数创建WAV header。theAudio->writeWavHeader(myFile); (1)1 指定记录的文件。
此示例使用名为“Sound.wav”的文件。 -
使用
readFrames()函数读取WAV(PCM)编码数据以记录到文件。theAudio->readFrames(myFile); (1)1 您可以通过指定myFile来更改录音文件。。
此示例使用名为“Sound.wav”的文件。
定期执行此函数以读取编码结果,以便编码缓冲区不会溢出。 -
startRecorder()开始录音。 -
stopRecorder()停止录音。
1.2.11. 获取PCM数据
1.2.11.3. 操作程序
-
运行Arduino IDE , 选择
File→ Sketch Example→ Spresense Sketch Example Audio→ application→ pcm_capture打开示例sketch。
-
示例sketch从麦克风中提取语音输入作为PCM数据。
-
在
Tools→ Serial port中选择Spresense COM端口并写入微控制器板。 -
启动Serial monitor时,将显示从麦克风输入的语音的PCM数据。
1.2.11.4. 程序说明
-
使用
initRecorder()函数初始化录音机。theAudio->initRecorder(codec, (1) codec_path, (2) fs, (3) channel); (4)1 codec编解码类型指定 PCM (AS_CODECTYPE_PCM)。2 codec_path指定DSP文件的安装位置。
为microSD指定/mnt/sd0/BIN,为SPI-Flash指定/mnt/spif/BIN。3 fs指定采样率。
对于48kHz(AS_SAMPLINGRATE_48000),没有必要安装DSP文件。4 channel指定通道数。
在此示例中,指定了AS_CHANNEL_4CH。 -
使用
readFrames()函数读取PCM数据。theAudio->readFrames(p_buffer, (1) buffer_size, (2) read_size); (3)1 将PCM数据读入 p_buffer。2 指定要读取的大小。 3 返回实际读取的大小。
定期执行此功能以读取PCM数据,以便捕获缓冲区不会溢出。
1.2.12. 重复录音和播放
1.2.12.2. 运行环境
-
Spresense主板和扩展板
-
microSD 卡
-
播放耳机或扬声器
-
录音麦克风
此示例使用microSD卡和耳机。。 将耳机或有源扬声器连接到扩展板上的耳机插孔。 有关麦克风连接,请参阅
1.2.12.3. 操作程序
-
在microSD卡上安装MP3解码DSP文件
MP3ENC和MP3DEC(参见安装DSP文件)。 -
将microSD卡插入扩展板上的microSD卡插槽。
-
运行Arduino IDE , 选择
File→ Sketch Example→ Spresense Sketch Example Audio→ application→ rec_play打开示例sketch。
-
在
Tools→ Serial port中选择Spresense COM端口并写入微控制器板。 -
加载并执行示例程序后、大约以20秒的周期、记录来自麦克风的音频、播放记录的数据。
循环录音和播放5次后停止。
1.3. 对象接口层
Spresense Audio库是、
Audio库的开发指南 像这样、具有分层结构。
对象接口层、可以实现高级接口层中无法实现的功能的组合。
以下是对象接口层的示例。
1.3.1. MP3 音乐播放
1.3.1.1. 概要
这是播放microSD 卡里的MP3 音乐的示例。
本示例是和高级接口 MP3音乐播放 功能一样的示例。
1.3.1.2. 操作环境 和 操作步骤
本示例是、Arduino IDE 上选择 file → sketch example → Spresense sketch Audio → application → player_objif 。
+ 操作环境 和 操作步骤的详情请参照、MP3音乐播放。
1.3.1.3. 程序解说
-
createStaticPools()设置共享内存的布局。initMemoryPools(); createStaticPools(no); (1)1 no: 指定布局号码。本示例是、请指定播放功能用的布局 (MEM_LAYOUT_PLAYER) 。 -
各Audio库的生成和初始化。
theMixer->activateBaseband(); (1) thePlayer->create( (2) id, (3) attention_cb); (4) theMixer->create( (5) attention_cb); (4) thePlayer->activate( (6) id, (3) mediaplayer_done_callback); (7) theMixer->activate( (8) OutputMixer0, (9) HPOutputDevice, (10) outputmixer_done_callback); (11)1 theMixer→activateBaseband
Audio硬件模块初始化并打开电源。2 thePlayer→create
Player软件模块的生成和初始化。3 id: 指定Player的ID。Spresense 、最多同时播放2个。可以指定`MediaPlayer::Player0` 或MediaPlayer::Player1。4 attention_cb: 从各个模块通知的错误・警告用的回调函数。请编写错误处理。5 theMixer→create
Mixer软件模块的生成和初始化。6 thePlayer→activate
Player播放操作模式设定7 mediaplayer_done_callback: 从各个模块通知的错误・警告用的回调函数。请编写错误处理。8 theMixer→activate
Mixer发音动作模式设置9 OutputMixer0: Mixer的ID指定。请用和Player一样的ID。10 HPOutputDevice: 设定输出目的地。 `HPOutputDevice`是模拟输出。`I2SOutputDevice`是I2S输出。11 outputmixer_done_callback: 向Mixer发出事件时结果通知用的回调函数。 -
setRenderingClockMode()函数用来设置发音的时钟模式。theMixer->setRenderingClkMode(mode); (1)1 mode: 选择通常 (OUTPUTMIXER_RNDCLK_NORMAL) 或高解析度 (OUTPUTMIXER_RNDCLK_HIRES) 时钟模式。
MP3 播放时、请指定`OUTPUTMIXER_RNDCLK_NORMAL` 。 -
Player库进行初始化。
thePlayer->initPlayer(id, (1) codec, (2) codec_path, (3) fs, (4) channel); (5)1 id: Player ID 选择。
本示例 使用AudioClass::Player0。2 codec: 编解码器类型指定 MP3 (AS_CODECTYPE_MP3) 。3 codec_path: DSP 文件指定被安装的路径。
microSD 卡的话指定 "/mnt/sd0/BIN" 、SPI-Flash 的话指定 "/mnt/spif/BIN" 。4 fs: 指定采样率。
MP3 的话、支持 32kHz (AS_SAMPLINGRATE_32000), 44.1kHz (AS_SAMPLINGRATE_44100), 48kHz (AS_SAMPLINGRATE_48000) 。 指定`AS_SAMPLINGRATE_AUTO` 的话,自动判定采样率。5 channel: 指定 单声道 (AS_CHANNEL_MONO) 或双声道 (AS_CHANNEL_STEREO) 。 -
writeFrames()函数将MP3 文件内容写入解码器。thePlayer->writeFrames(id, (1) myFile); (2)1 id: Player ID 选择。
本示例使用AudioClass::Player0。2 指定参数 myFile 、可以更改播放文件。
本示例使用 "Sound.mp3" 文件。
为了不使解码中断,定期执行测函数以提供解码器数据流。 写文件结束时函数将返回值AUDIOLIB_ECODE_FILEEND。 -
setVolume(volume)函数用来调整音量。thePlayer->setVolume(volume); (1)1 volume: 可以更改音量。(-1020 ~ 120)
指定值的 1/10 是实际的音量[dB]。例如、指定15的话音量是1.5 [dB]。 -
startPlayer()函数用来启动播放器。thePlayer->startPlayer(id, (1) mediaplayer_decode_callback (2) );1 id: Player ID 选择。
本示例使用`AudioClass::Player0` 。
writeFrames()请在写入解码器之后再调用此函数。2 mediaplayer_decode_callback: Decode帧为单位被调用的回调函数。 callback内、需要向Mixer传输数据(AsPcmDataParam)。请编写下面的代码。
theMixer->sendData(OutputMixer0, outmixer_send_callback, pcm_param);
| 此callback是、可以在传输到Mixer之前处理应输出的PCM,再发送到Mixer。 |
-
stopPlayer()函数用来停止播放器。thePlayer->stopPlayer(id, (1) mode); (2)1 id: Player ID 选择。
本示例使用AudioClass::Player0。2 mode可以选择 立即停止 (AS_STOPPLAYER_NORMAL)、或等待直到提供给解码器的流完成播放然后停止 (AS_STOPPLAYER_ESEND) 。mode参数不设置的话、默认为AS_STOPPLAYER_NORMAL。
1.3.1.4. 关于播放器缓存大小
详情请参照、MP3音乐播放 。
1.3.1.5. I2S 输出
详情请参照、MP3音乐播放 。
1.3.1.6. 扩展板的扬声器使用时
详情请参照、MP3音乐播放 。
1.3.2. MP3 双解码播放
1.3.2.1. 概要
microSD 卡里的2个MP3音乐同时播放的示例。
本サンプルはハイレベルインターフェースの MP3デュアルデコード再生 と全く同じサンプルになります。
1.3.2.2. 操作环境 和 操作步骤
本示例是、Arduino IDE 上选择 File→ Sketch Example→ Spresense Sketch Example Audio → application → dual_players_objif 。
+ 操作环境 和 操作步骤 详情请参照、MP3双解码播放 。
1.3.2.3. 程序解说
双解码是、MP3音乐播放启动2个播放器。但是、各个播放器是、每个player需要独立提供Audio ES数据、为了避免互相操作的影响、每个player在不同的线程运行。
详情请参照、MP3音乐播放。
-
设置共享内存布局。
-
各Audio库初始化。
-
设置时钟模式。
-
Player库初始化。
-
MP3 文件内容写入到解码器。
-
启动播放器。
-
停止播放器。
| 不同解析度无法发音。 |
-
setVolume(master, player0, player1)函数用来调整音量。thePlayer->setVolume(master, (1) player0, (2) player1); (3)1 master: 可以更改播放器0,1 双方音量。(-1020 ~ 120)2 player0可以更改播放器0的音量。(-1020 ~ 120)3 player1可以更改播放器1的音量。(-1020 ~ 120)
指定值的 1/10 是实际的音量[dB]。例如、指定15的话音量是1.5 [dB]。master可以调整全体音量、player0,player1个别音量。
1.3.3. 低延时播放
1.3.3.1. 概要
这是低延迟播放的示例,适用于希望以某些输入(例如开关按键声音,游戏和乐器)高速发声的情况。 以低延迟播放microSD卡上的音频文件(仅RAW填充)。
为了尝试低延迟播放,它会根据输入shell中的字符进行发音。
另外,为了获得低延迟,如果读取音频文件需要花费很长时间,则可以添加静音功能,以使播放不会停止。
1.3.3.3. 操作步骤
-
将要播放的音频PCM的RAW文件放置在microSD卡的根目录中,文件名为“ sound0.raw”,“ sound1.raw”和“ sound2.raw”。
RAW文件是没有头文件(例如WAV头文件)的PCM文件。如果位长为16位,则通道数据将每16位交织一次。仅支持16位或以下。 基本上,从SD卡读取的速度是此样本的速率确定速率、现状、仅支持16位或以下。
如果不可避免地要使用24位数据,请通过对齐每32位,用数据填充低24位并插入通道来创建24位RAW。 -
将microSD 卡插入扩展板的 microSD 卡插槽。
-
Arduino IDE 上选择打开
File→ Sketch Example→ Spresense Sketch Example Audio → application → rendering_objif。 -
工具 → 串口用来选择 Spresense 的 COM 端口、烧写微机板。 -
示例被烧写执行后、串口监视器会进入输入等待状态。此时、"p\n"输入的话"Sound0.raw"将播放、"o\n"输入的话"Sound1.raw"将播放、"i\n"输入的话"Sound2.raw"将播放。"s\n"用来停止播放。
NOTE:声音播放中时、指示播放新的曲目时会立即播放新曲目。
1.3.3.4. 程序解说
SD卡读取速度成为低延迟播放中的速度瓶颈。 因此,我们使用环形缓冲区来缓冲SD卡中的读取。 另外,为了在低延迟下具有抵抗读取延迟的健壮性,当缺少读取数据时,将插入静音,从而不会停止发音本身。
-
BridgeBuffer类用于缓冲从SD卡读取的RAW数据的类。。
writebuf(File& file, uint32_t size)用来从SD卡内的`file`对象指定文件写入到`size`大小的数据到缓存里。
readbuf(uint8_t *dst)用来将 返回值所示大小的数据读取到dst所示的地址。
clearbuf()清除缓存。 -
createStaticPools()设置共享内存布局。initMemoryPools(); createStaticPools(no); (1)1 no: 指定布局号码。本示例、请指定播放机能用的布局 (MEM_LAYOUT_PLAYER)。 -
Mixer库的生成和初始化。
theMixer->activateBaseband(); (1) theMixer->create( (2) attention_cb); (3) theMixer->activate( (4) OutputMixer0, (5) HPOutputDevice, (6) outputmixer_done_callback); (7)1 theMixer→activateBaseband
Audio硬件模块初始化以及启动电源等。2 theMixer→create
Mixer软件模块的生成和初始化。3 theMixer→activate
Mixer发音操作模式设置4 OutputMixer0: Mixer ID指定。请和Player设置同样的ID。5 HPOutputDevice: 设置输出目的地。 `HPOutputDevice`是模拟输出。`I2SOutputDevice`是I2S输出。6 outputmixer_done_callback: 向Mixer发出事件时结果通知的回调函数。 -
setRenderingClockMode()函数用来设置时钟模式。theMixer->setRenderingClkMode(mode); (1)1 mode: 选择通常 (OUTPUTMIXER_RNDCLK_NORMAL) 或高解析度 (OUTPUTMIXER_RNDCLK_HIRES) 时钟模式。
低延迟播放时、请指定`OUTPUTMIXER_RNDCLK_NORMAL` 。 -
setVolume(volume)函数用来调整音量。thePlayer->setVolume(volume); (1)1 volume: 音量を変更できます。(-1020 ~ 120)
指定值的 1/10 是实际的音量[dB]。例如、指定15的话音量是1.5 [dB]。
Mixer没有开始的特殊事件。给Mixer3以上数据(AsPcmDataParam)送信时才会开始。
|
Mixer没有结束的特殊事件。给Mixer送信的数据(AsPcmDataParam)中的 `bool is_end`设置为`ture`送信的话,这帧的发音结束后终止。+
结束时该帧搭载着Fadeout。
|
-
outmixer_send_callback内的代码 `outmixer_send_callback`会在1帧发音结束后被调用。在这里下面的代码必须给Mixer提供下一个发音帧。theMixer->sendData(OutputMixer0, outmixer_send_callback, pcm_param);这时、数据(
AsPcmDataParam pcm_param)的各个参数需要设置数据。static bool getFrame(AsPcmDataParam *pcm) {本示例、上面的函数里进行代入处理。数据结构详情请参照、SDK开发文档的API式样。
此外,在此过程中,如果无法读取数据,则将其填充为0以继续发音。
if (!getFrame(&pcm_param)) { : 在这里从Fifo读取 break; } /* Send PCM */ pcm_param.is_end = false; pcm_param.is_valid = true; if (pcm_param.size == 0) { :无法读取时,size为0 pcm_param.size = READSIZE; pcm_param.sample = pcm_param.size / BYTEWIDTH / CHNUM; memset(pcm_param.mh.getPa(), 0, pcm_param.size); : 无法读取填充为0输出 }
1.3.4. MP3 形式录音
1.3.4.1. 概要
从麦克风录制音频并在microSD卡上录制为MP3文件。
该示例具有与高级接口的 MP3形式录音 相同的功能。。
1.3.4.2. 操作环境 和 操作步骤
本示例是、Arduino IDE 上选择 File→ Sketch Example→ Spresense Sketch Example Audio → application → recorder_objif。
操作环境 和 操作步骤 の详情请参照、MP3形式で録音する 。
1.3.4.3. 程序解说
-
createStaticPools()共享内存布局设置。initMemoryPools(); createStaticPools(no); (1)1 no: 指定布局号码。本示例、请指定录音功能用的布局 (MEM_LAYOUT_RECORDER) 。 -
Recoder库生成和初始化。
theRecorder->begin( (1) attention_cb); (2) theRecorder->activate( (3) dev, (4) done_callback); (5)1 theRecorder→begin
Recorder软件模块生成。2 attention_cb: 从各个模块通知的错误・警告用的回调函数。请编写错误处理。3 theRecorder→activate
Recorder录制操作模式设置。4 dev: 设置输入设备。仅支持麦克风设备。请指定AS_SETRECDR_STS_INPUTDEVICE_MIC。5 done_callback: 向Recorder发出事件时结果通知的回调函数。 -
setCapturingClkMode()函数用来设置录音时钟模式。theRecorder->setCapturingClkMode(mode); (1)1 mode: 通常 (MEDIARECORDER_CAPCLK_NORMAL) 或高解析度 (MEDIARECORDER_CAPCLK_HIRES) 时钟模式选择。
MP3 录制时、请指定MEDIARECORDER_CAPCLK_NORMAL。 -
initRecorder()函数用来执行解码器的初始化。theRecorder->init(codec, (1) channel, (2) fs, (3) bits, (4) bitrate, (5) path); (6)1 codec指定编解码器类型MP3(AS_CODECTYPE_MP3)。2 channel: 指定频道数。可以指定 1 / 2 。3 fs: 指定采样率。
MP3的话,支持48kHz (48000) 。4 bits: 指定声音数据的位长。MP3的话请指定`16`。5 bitrare: 指定压缩产生的ES数据的比特率。这里指定96000。6 path指定DSP文件的安装位置。
指定 microSD 卡 "/mnt/sd0/BIN" 、SPI-Flash "/mnt/spif/BIN" 。 -
readFrames()函数用来读取MP3编码的数据记录到文件。theRecorder->readFrames(ptr, (1) buffer_size, (2) size); (3)1 ptr : 指定用于写入生成的音频流的缓冲区的起始地址。 2 buffer_size : 指定用于写出生成的音频流的缓冲区的大小。 3 size : 实际写出并存储数据大小。
如果size为0,则没有要写入的数据。 -
start()启动录音机函数。theRecorder->start(); -
stop()停止录音机函数。theRecorder->stop();
1.3.4.4. 关于录音机缓存
请参照 MP3形式录音 。
1.3.5. WAV 形式录音
1.3.5.1. 概要
记录来自麦克风的声音并记录为microSD卡上的WAV文件。
本示例是高级接口的 WAV_形式录音 相同功能的示例。
1.3.5.2. 操作环境 和 操作步骤
本示例是、Arduino IDE 上选择 File→ Sketch Example→ Spresense Sketch Example Audio → application → recorder_wav_objif を選択することで可能です。
+ 操作环境 和 操作步骤 の详情请参照、WAV_形式で録音する 。
1.3.5.3. 程序解说
-
createStaticPools()设置共有内存布局。initMemoryPools(); createStaticPools(no); (1)1 no: 指定布局号码。本示例、请指定录音功能用布局 (MEM_LAYOUT_RECORDER) 。 -
Recoder库生成和初始化。
theRecorder->begin( (1) attention_cb); (2) theRecorder->activate( (3) dev, (4) done_callback); (5)1 theRecorder→begin
Recorder软件模块生成。2 attention_cb: 从各个模块通知的错误・警告用的回调函数。请编写错误处理。3 theRecorder→activate
Recorder录制操作模式设置。4 dev: 设置输入设备。仅支持麦克风设备。请指定AS_SETRECDR_STS_INPUTDEVICE_MIC。5 done_callback: 向Recorder发出事件时结果通知的回调函数。 -
setCapturingClkMode()函数用来设置录音时钟模式。theRecorder->setCapturingClkMode(mode); (1)1 mode: 通常 (MEDIARECORDER_CAPCLK_NORMAL) 或高解析度 (MEDIARECORDER_CAPCLK_HIRES) 时钟模式选择。
48kHz或16kHz录音的话 请指定MEDIARECORDER_CAPCLK_NORMAL、192kHz录音的话请指定`MEDIARECORDER_CAPCLK_HIRES`。 -
initRecorder()函数用来执行解码器的初始化。theRecorder->init(codec, (1) channel, (2) fs, (3) bits, (4) bitrate, (5) path); (6)1 codec编解码器类型请指定 WAV (AS_CODECTYPE_WAV) 。2 channel: 指定通道数。1 / 2 / 4 / 8 可以指定。3 fs: 指定采样率。
MP3 的话、支持 16kHz (16000), 48kHz (48000),192kHz (192000) 。4 bits: 指定声音数据位长。请指定16`或、`24。5 bitrare: WAV的话仅支持非圧縮(PCM)比特率请忽略。6 path指定DSP文件的安装位置。
microSD 的话请指定 "/mnt/sd0/BIN" 、SPI-Flash 的话 "/mnt/spif/BIN" 。 -
readFrames()读取PCM数据以使用功能记录到文件。theRecorder->readFrames(ptr, (1) buffer_size, (2) size); (3)1 ptr : 指定用于写入PCM数据的缓冲区的起始地址。 2 buffer_size : 指定用于写入生成的音频数据的缓冲区的大小。 3 size : 实际写出并存储数据大小。
如果size为0,则没有要写入的数据。 -
start()启动录音机函数。theRecorder->start(); -
stop()停止录音机函数。theRecorder->stop();
1.3.5.4. 关于录音机缓存
请参照 WAV_形式で録音する 。
1.3.6. PCM 读取数据
1.3.6.1. 概要
捕获从麦克风输入的PCM数据。 本示例仅显示PCM数据的开始,但是通过应用此示例,您可以执行PCM原始数据的频率分析处理以及诸如各种滤波器的信号处理。 该示例具有与高级接口的PCM数据读取相同的功能。
1.3.6.2. 操作环境 和 操作步骤
本示例是、Arduino IDE 上选择 File→ Sketch Example→ Spresense Sketch Example Audio → application → pcm_capture_objif 。
+ 操作环境 和 操作步骤 の详情请参照、PCM数据读取 。
1.3.6.3. 程序解说
-
createStaticPools()设置共享内存布局。initMemoryPools(); createStaticPools(no); (1)1 no: 指定布局号码。本示例、请指定录音功能用布局 (MEM_LAYOUT_RECORDER)。 -
Recoder库生成和初始化。
theRecorder->begin( (1) attention_cb); (2) theRecorder->activate( (3) dev, (4) done_callback); (5)1 theRecorder→begin
Recorder软件模块生成。2 attention_cb: 从各个模块通知的错误・警告用的回调函数。请编写错误处理。3 theRecorder→activate
Recorder录制操作模式设置。4 dev: 设置输入设备。仅支持麦克风设备。请指定AS_SETRECDR_STS_INPUTDEVICE_MIC。5 done_callback: 向Recorder发出事件时结果通知的回调函数。 -
setCapturingClkMode()函数用来设置录音时钟模式。theRecorder->setCapturingClkMode(mode); (1)1 mode: 通常 (MEDIARECORDER_CAPCLK_NORMAL) 或高解析度 (MEDIARECORDER_CAPCLK_HIRES) 时钟模式选择。
48kHzか16kHzでの記録の場合`MEDIARECORDER_CAPCLK_NORMAL` を指定、192kHz記録の場合`MEDIARECORDER_CAPCLK_HIRES`を指定してください。 -
initRecorder()函数用来执行解码器的初始化。theRecorder->init(codec, (1) channel, (2) fs, (3) bits, (4) bitrate, (5) path); (6)1 codec编解码器类型请指定 WAV (AS_CODECTYPE_WAV) 。2 channel: 指定通道数。1 / 2 / 4 / 8 可以指定。3 fs: 指定采样率。
PCM采样、支持48kHz (48000),192kHz (192000) 。4 bits: 指定声音数据位长。请指定16`或、`24。5 bitrare: WAV的话仅支持非圧縮(PCM)比特率请忽略。6 path指定DSP文件的安装位置。
-
readFrames()读取PCM数据以记录到文件。theRecorder->readFrames(ptr, (1) buffer_size, (2) size); (3)1 ptr : 指定用于写入PCM数据的缓冲区的起始地址。 2 buffer_size : 指定用于写入生成的音频数据的缓冲区的大小。 3 size : 实际写出并存储数据大小。
如果size为0,则没有要写入的数据。 -
start()启动录音机函数。theRecorder->start(); -
stop()停止录音机函数。theRecorder->stop();
1.3.6.4. 关于缓存大小
PCM数据读取 。
2. GPS 教程
在本教程中,我们将基于示例草图,使用Spresense GPS功能的简单应用程序, 并了解如何自定义示例以添加和扩展功能。
-
GNSS库的基本用法
-
GPS跟踪器
-
NMEA输出
-
RTC时间设置
-
GPS 1PPS 执行输出
2.1. GPS 示例草图
2.1.3. 操作说明
从 Arduino IDE 菜单中,打开 File → Examples → GNSS → gnss 。
将此示例写入Spresense板。
打开串行监视器时,将显示定位信息。在定位过程中,LED0每隔一秒闪烁一次。
-
时间从初始时间 1980/01/06 00:00:00 开始计数。
从卫星获取精确时间后,切换到当前 UTC 时间显示。 -
numSat:表示找到的卫星数
-
在非定位状态下,将显示"无修复,无位置"。
定位后,显示"修复"和"Lat=纬度、Lon=经度"。
此外,获得位置信息后,LED1会亮起。
每分钟显示有关卫星的详细信息。
-
Type: 卫星类别、Id: 卫星编号、Elv: 仰角、Azm: 方位角、CN0: 信号强度。
2.1.4. 程序说明
-
使用setup()函数初始化GNSS库。
enum ParamSat { eSatGps, /**< GPS World wide coverage */ eSatGlonass, /**< GLONASS World wide coverage */ eSatGpsSbas, /**< GPS+SBAS North America */ eSatGpsGlonass, /**< GPS+Glonass World wide coverage */ eSatGpsBeidou, /**< GPS+BeiDou World wide coverage */ eSatGpsGalileo, /**< GPS+Galileo World wide coverage */ eSatGpsQz1c, /**< GPS+QZSS_L1CA East Asia & Oceania */ eSatGpsGlonassQz1c, /**< GPS+Glonass+QZSS_L1CA East Asia & Oceania */ eSatGpsBeidouQz1c, /**< GPS+BeiDou+QZSS_L1CA East Asia & Oceania */ eSatGpsGalileoQz1c, /**< GPS+Galileo+QZSS_L1CA East Asia & Oceania */ eSatGpsQz1cQz1S, /**< GPS+QZSS_L1CA+QZSS_L1S Japan */ }; /* Set this parameter depending on your current region. */ static enum ParamSat satType = eSatGps; (3) void setup() { : /* Activate GNSS device */ result = Gnss.begin(); (1) Gnss.select(XXX); (2) /* Start positioning */ result = Gnss.start(COLD_START); (4) : }1 使用Gnss.begin()函数初始化。调用此函数以加载GNSS专用固件。 如果无法正常工作,请安装最新版本的引导加载程序 arduino_set_up_zh.html 。 2 选择要用于Gnss.select()函数的卫星。 3 多个卫星的组合可用于卫星选择。 例如,如果使用QZSS Mhibhi,请将"satType"更改为"eSatGpsQz1cQz1S"。 除了GPS和QZSS,还可以添加{Glonass,BeiDou,Galileo}中的任何一个。 4 使用Gnss.start()函数开始定位。 这里会冷启动。 -
使用loop()函数定期获取 GNSS 定位结果。
void loop() { : /* Check update. */ if (Gnss.waitUpdate(-1)) (1) { /* Get NaviData. */ SpNavData NavData; Gnss.getNavData(&NavData); (2)1 在 Gnss.waitUpdate()函数中等待 GNSS 接收。 2 使用Gnss.getNavData()函数获取定位结果。根据此处获得的 NavData,使用print_pos()和print_condition()函数输出定位信息。 有关详细信息,请参阅 SpNavData 。 -
作为功能使用的示例,此示例在5分钟的周期内停止/恢复GNSS定位。
if (LoopCount >= RESTART_CYCLE) { /* Restart GNSS. */ if (Gnss.stop() != 0) (1) { Serial.println("Gnss stop error!!"); error_flag = 1; } else if (Gnss.end() != 0) (2) { Serial.println("Gnss end error!!"); error_flag = 1; } else { Serial.println("Gnss stop OK."); } if (Gnss.begin() != 0) (3) { Serial.println("Gnss begin error!!"); error_flag = 1; } else if (Gnss.start(HOT_START) != 0) (4) { Serial.println("Gnss start error!!"); error_flag = 1; } else { Serial.println("Gnss restart OK."); }1 使用Gnss.stop()函数停止定位。 2 使用Gnss.end()函数执行终止处理。 调用此函数可卸载GNSS专用固件。 3 使用Gnss.begin()函数再次初始化。 4 Gnss.start()函数使用HOT_START。通过热启动而不关闭电源,可以使用上次定位获取的时间信息、位置信息和卫星启动信息,并立即获取位置信息。
2.2. GPS 跟踪器
2.2.1. 简介
GNSS库示例中的GPS跟踪器示例草图 gnss_tracker 。+ 此草图称为GPS数据记录器, 定期从GPS获取的位置信息记录在microSD卡上。 然后,通过检索存储在microSD卡上的文件,并使用专用工具(如 PC)。 这样可以在地图上叠加移动轨迹以浏览它们。
2.2.3. 操作说明
连接Spresense主板和扩展板,并将microSD卡插入扩展板。
从Arduino IDE菜单中,打开 File → Examples → GNSS → gnss_tracker 。
将此示例写入Spresense板。
打开串行监视器时,首先打印应用程序的配置信息,然后开始输出定位结果。
2.2.4. 操作规范
电源通电后,首先读取microSD卡中的 tracker.ini 文件中写入的设置。
根据此文件中写入的设置初始化应用程序后,将启动GPS定位操作。
在操作过程中,主板上的LED表示应用程序的操作状态。
-
LED 规格
当应用程序启动时,所有四个LED指示灯仅闪烁一次。
在定位停止期间,所有LED都熄灭。 单个LED的操作规范如下:LED 说明 LED0
定位操作期间亮起/重复关闭
LED1
获取当前位置(FIX)后亮起
LED2
文件访问期间亮起
LED3
当发生某些错误(如无法访问 microSD 卡)时亮起
-
microSD 卡中的文件配置
microSD 卡中的文件配置如下所示。如果该文件不存在,则不需要提前准备该文件,因为程序将创建新文件。
文件名 说明 tracker.ini
包含应用程序设置信息的文本文件。后面将介绍每个设置。如果此文件不存在,则会创建一个具有默认设置的文件。
index.ini
包含索引号的文本文件。此数字表示GPS数据的目标文件名。例如,如果写入 "
00000018",请将GPS数据输出到文件名"0000018.txt"。重复操作时,现有此数字递增1,以避免覆盖。如果文件不存在,则会创建一个名为"00000001"的新文件。00000001.txt
00000002.txt
:要写入GPS数据的文本文件。此文件包含NMEA 0183格式的GPGGA语句。用户将此文件导入PC等,以生成GPS跟踪数据。
-
tracker.ini 设置信息
可以通过更改此处定义的设置参数来切换应用程序的行为。默认值有效,此处可以忽略。
参数 说明 参数值 SatelliteSystem
(GPS/GLONASS/SBAS/QZSS_L1CA/QZSS_L1S)
从以下选项中选择卫星系统(组合)。
GPS+GLONASS+QZSS_L1CA
GPS+BEIDOU+QZSS_L1CA
GPS+GALILEO+QZSS_L1CA
GPS+QZSS_L1CA+QZSS_L1S
GPS+QZSS_L1CA
GPS+GLONASS
GPS+BEIDOU
GPS+GALILEO
GLONASS
GPS+SBAS
GPSSatelliteSystem=GPS+GLONASS+QZSS_L1CA
NmeaOutUart
(TRUE/FALSE)
选择是否在串行监视器上显示NMEA输出。NmeaOutUart=TRUE
NmeaOutFile
(TRUE/FALSE)
选择是否将NMEA输出保存到文件中。这里是TRUE。NmeaOutFile=TRUE
BinaryOut
(TRUE/FALSE)
选择是否保存GNSS二进制数据。通常,可以保留FALSE。BinaryOut=FALSE
IntervalSec
(1-300)
设置定位间隔(秒)。IntervalSec=1
ActiveSec
(60-300)
设置定位的刷新时间(秒)。在ActiveSec中定位一秒钟后,SleepSec秒将定期重复停止定位的行为。ActiveSec=60
SleepSec
(0-240)
设置停止定位的时间段(秒)。在ActiveSec中定位一秒钟后,SleepSec秒将定期重复停止定位的行为。如果睡眠周期没有,要求始终定位,请指定0。SleepSec=240
UartDebugMessage
(NONE/ERROR/WARNING/INFO)
设置要输出到串行监视器的调试级别。UartDebugMessage=NONE
2.2.5. GPS 记录数据验证步骤
查看GPS记录数据的方法有很多种。不过,这里可以将NMEA转换为KML格式,并使用Google地球在地图上显示。
-
Google Earth 安装
从 Google Earth 下载页面 下载Google Earth并安装。
-
NMEA到KML/KMZ转换器
存储在microSD卡上的00000001.txt到9999999.txt文件的内容以NMEA格式(仅限GPGGA语句)编写。将其转换为KML/KMZ格式,可通过Google Earth处理。如果源数据被划分为多个文本文件,请将该文件合并为一个文件。
-
通过"
选择文件" 指定输入文件,然后按"发送"按钮 -
下载转换为KML的文件
另外, https://www.gpsvisualizer.com 这个网站也可以转换成Google Earth和其它格式的数据。网络上有各式各样的转换工具,在PC上运行而不通过网站转换的方式,如: NMEA to KMZ Utility 。
-
Google Earth 打开 KML 文件
移动的轨迹将在地图上映射并显示。
现在,已经了解如何使示例代码正常工作。
下面,将讨论自定义和使用GPS跟踪器的应用。
2.3. GPS 移动跟踪器
2.3.1. 简介
在上一章中,尝试应用GPS跟踪器的示例gnss_tracker.ino。此示例将GPS记录器数据存储在microSD卡上,并对其进行修改以将其保存到主板上的Flash内存中。主板只使用更小、更省电的GPS跟踪器。
2.3.3. 代码修改
打开gnss_tracker.ino示例。
从Arduino IDE的菜单,选择 File → Save as… 将示例保存到任何文件夹。复制示例以进行编辑。
打开gnss_file.cpp并进行修改。
-
添加#include <Flash.h>这行
-
删除 “
SDClass theSD;"这行 -
替换 "
theSD" → "Flash"-
更改为使用Flash。由于Flash库具有与SD相同的接口配置,因此只需更改对象名称即可。
-
参考下面修改的示例。
-
2.3.5. GPS 数据验证步骤
有几种方法可以检索存储在Flash内存中的结果。(除了这里介绍的方法外,您还可以使用 Add-on 等通过网络传输文件)。
-
转存文件方法
GPS记录器数据存储在Flash中作为文本文件。将内容转储到串行终端,并将显示结果另存为文件。 这是一个非常原始的方法,但快速和容易。
由于 Arduino IDE 的串行监视器无法将串行显示结果保存到文件中,因此建议使用其他终端(如 TeraTerm 或 minicom)。 -
下载示例 nuttx_shell 。
写入并运行草图时,串行终端将显示"
NuttShell nsh>"提示。 -
使用命令
ls查看Flash中的文件列表。nsh> ls -l /mnt/spif
-
使用
cat命令显示目标日志文件。 将日志结果设置为在运行命令之前保存到文件中。nsh> cat /mnt/spif/00000003.txt
能够搜索GPS记录器数据。
如果不再需要Flash中的文件,可以使用rm命令将其删除。nsh> rm /mnt/spif/00000003.txt
-
-
Flash → microSD 复制方法
如果有扩展板,则可以使用扩展板从Flash复制到microSD并检索文件
-
而且使用示例 nuttx_shell 。
写入并运行示例时,串行终端将显示"
NuttShell nsh>" 提示。 -
ls命令查看Flash上的文件列表。nsh> ls -l /mnt/spif
-
cp命令复制目标日志文件到microSD。nsh> cp /mnt/spif/00000003.txt /mnt/sd0
通过microSD可以检索GPS记录器数据。
如果不再需要Flash中的文件,可以使用rm命令将其删除。nsh> rm /mnt/spif/00000003.txt
-
-
Zmodem 传输文件方法
可以使用Spresense SDK环境使用Zmodem传输功能检索文件。
详细信息,请参考 Zmodem 传输文件 。
有关如何根据提取的 GPS 记录器数据在地图上映射的信息,请参考 这里 。
2.4. GPS 跟踪器节能
2.4.1. 简介
通过将LowPower库与GPS跟踪器相结合,节省能源。 即使在正常工作时,Spresense 的功能是低功耗的。如果使用LowPower库,还可以显著降低功耗。 为了延长电源/电池的使用时间,请尝试根据本教程更改源代码。
此处使用LowPower库的以下功能。 有关LowPower库的详细信息,请参考 LowPower 程序库 。
-
更改时钟模式
-
使用睡眠模式
2.4.2. 更改时钟模式
通常,将运行在156MHz下的系统范围的时钟降至32MHz可降低功耗。 GNSS定位功能在32MHz时钟操作模式下运行时也有效。 更改GPS跟踪器,如下所示:
#include <LowPower.h> (1)
void setup()
{
:
LowPower.begin(); (2)
LowPower.clockMode(CLOCK_MODE_32MHz); (3)
:
}
| 1 | 引用LowPower库。 |
| 2 | 在setup()函数中调用LowPower.begin()函数。 |
| 3 | 将时钟模式设置为32MHz。 |
只需添加对LowPower.clockMode(CLOCK_MODE_32MHz)的调用即可切换时钟模式。
2.4.3. 使用睡眠模式
当定位功能间歇性地运行时,在非定位期间将系统置于睡眠状态,从而降低待机功率。 在进入睡眠状态之前,将最终定位位置和卫星轨道信息存储在闪存中,以便在从睡眠 唤醒后通过热启动立即继续定位操作。
更改源代码以使用睡眠模式,如下所示:
#include <LowPower.h> (1)
#include <Flash.h> (2)
| 1 | 引用LowPower库。 |
| 2 | 引用Flash库。 |
void setup()
{
LowPower.begin(); (1)
bootcause_e bc = LowPower.bootCause(); (2)
if ((bc == POR_SUPPLY) || (bc == POR_NORMAL)) {
/* Remove backup file if power-on-reset */
Flash.remove("gnss_backup.bin"); (3)
}
| 1 | 在setup()函数中调用LowPower.begin()函数。 |
| 2 | 获取系统启动的因素。 可以确定是电源打开重置(如上电或按下复位开关)还是从睡眠状态唤醒。 |
| 3 | 如果启动因素(如首次启动时)是Power-On-Reset,请删除Flash上的备份文件。 当从Deep Sleep中醒来时,请使用Flash上的备份文件进行热启动定位。 |
static void SleepIn(void)
{
/* Turn off the LED. */
APP_PRINT("Sleep ");
ledOff(PIN_LED0);
/* Save backup data to flash */
Gnss.saveEphemeris(); (1)
Gnss.stop();
Gnss.end();
| 1 | 在SleepIn()函数中退出Gnss之前,将备份数据存储在Flash中。 |
void loop() {
:
/* Check state. */
if (State == eStateSleep)
{
/* Deep sleep */
Serial.print("Go to Deep sleep...");
LowPower.deepSleep(Parameter.SleepSec); (1)
| 1 | 在loop()函数中执行睡眠时调用LowPower.deepSleep()函数。 Parameter.SleepSec后,会自动从深度睡眠中唤醒。 当Deep Slep唤醒时,从setup()开始操作,其顺序与按下重置时的顺序相同。 |
2.5. NMEA 打印输出
2.5.2. 示例代码
下面是用于输出NMEA数据的示例。
#include <GNSS.h>
#include <GNSSPositionData.h>
#include <gpsutils/cxd56_gnss_nmea.h>
SpGnss Gnss;
char PositionData[sizeof(GnssPositionData)];
/* output NMEA */
static char nmea_buf[NMEA_SENTENCE_MAX_LEN];
static char *reqbuf(uint16_t size)
{
if (size > sizeof(nmea_buf)) {
return NULL;
}
return nmea_buf;
}
static void freebuf(char *buf)
{
return;
}
static int outbin(char *buf, uint32_t len)
{
return len;
}
static int outnmea(char *buf)
{
return printf("%s", buf);
}
void setup()
{
/* Initialize Serial */
Serial.begin(115200);
/* Initialize GNSS */
if (Gnss.begin()) {
Serial.println("begin error!");
}
/* select satellite system */
Gnss.select(GPS);
Gnss.select(GLONASS);
Gnss.select(QZ_L1CA);
//Gnss.select(QZ_L1S);
//Gnss.select(SBAS);
/* set interval */
Gnss.setInterval(1);
if (Gnss.start(COLD_START)) {
Serial.println("start error!");
}
/* use NMEA library */
NMEA_InitMask();
//NMEA_SetMask(0x5); // only GGA+GSA (1)
NMEA_OUTPUT_CB funcs;
funcs.bufReq = reqbuf;
funcs.out = outnmea;
funcs.outBin = outbin;
funcs.bufFree = freebuf;
NMEA_RegistOutputFunc(&funcs);
}
void loop()
{
SpNavData NavData;
/* Check update. */
if (Gnss.waitUpdate(1)) {
/* Get NavData. */
Gnss.getNavData(&NavData);
/* Output NMEA */
Gnss.getPositionData(PositionData);
NMEA_Output(&(((GnssPositionData*)PositionData)->Data));
}
}
| 1 | 可以通过NMEA_SetMask()函数输出NMEA语句。 例如,如果仅输出 GGA 或 GSA,请指定 0x5。 有关 NMEA 掩码值的详细信息,请参阅下文。 |
运行此示例时,NMEA数据将输出到串行监视器。
2.5.3. NMEA 掩码值
在NMEA 0183(ver 4.00)标准中定义的 NMEA 句子中, 输出NMEA语句是NMEA_SetMask()函数的参数,具有位掩码值。 最初,NMEA掩码设置为0xef。
| NMEA | Bit | Description |
|---|---|---|
$xxGGA |
0 |
基本信息,如时间、纬度和经度、高程、定位状态和DGPS基站编号 |
$xxGLL |
1 |
GGA的简单版本,如时间、纬度和经度、定位状态等 |
$xxGSA |
2 |
不使用每颗卫星,DOP值 |
$xxGSV |
3 |
可见卫星的卫星编号、高程、方位角和信号强度 |
$xxGNS |
4 |
时间、纬度和经度、定位状态 |
$xxRMC |
5 |
时间、纬度和经度、速度和时间偏差 |
$xxVTG |
6 |
了解有关行驶速度的详细信息 |
$xxZDA |
7 |
时间信息,包括日期 |
$QZQSM |
14 |
灾害危机管理报告服务消息(QZSS 专有语句) |
xx 表示以下内容:
-
GP:使用GPS卫星定位时
-
GL:使用GLONASS卫星进行定位时
-
GZ:使用QZS卫星定位
-
BD:使用BeiDou卫星进行定位时
-
GA:使用Galileo卫星进行定位时
-
GN:使用多个卫星系统进行定位时
2.5.4. NMEA 监视器
各种工具可用于使用NMEA数据。
这里使用 NMEA Monitor for windows 尝试实时查看解码 NMEA 数据的结果。
选择串行监视器输出的COM端口并启动它。
除了纬度和经度信息之外,您还可以看到许多信息,如海拔和天空图,如下所示。
2.6. GPS 移动时钟
2.6.3. 操作说明
在Arduino IDE, 选择菜单 File → Examples → RTC → rtc_gnss 。
将此示例写入Spresense板。
打开串行监视器时,打印时间信息。
2.6.4. 程序说明
#include <RTC.h>
#include <GNSS.h>
SpGnss Gnss;
#define MY_TIMEZONE_IN_SECONDS (9 * 60 * 60) // JST (1)
| 1 | 通过在示例上定义时差,UTC时间将转换为本地时间并输出到串行。 有关RTC库的详细信息,请参考 RTC库 。 |
2.7. GPS 1PPS 执行输出
2.7.3. 操作步骤
有关操作步骤は、请参照GPS 示例草图 。
3. Camera 教程
3.1. Camera 简单示例
3.1.2. 操作环境
-
Spresense主板和扩展板
-
Spresense相机板
-
microSD卡
将Spresense主板连接到相机板,请参考 如何连接Spresense 主板和Spresense 相机板 。
相机功能无需扩展板即可工作,但此示例使用扩展板将相机拍摄的照片保存到microSD卡。
3.1.3. 操作说明
-
将卡插入扩展板上的microSD卡插槽。
-
在Arduino IDE中,选择菜单
File → Examples for Spresense Camera → camera。
-
在
Tools → Serioal Port中选择Spresense COM端口以写入微控制器板。
-
刻录完成后,程序将工作并开始拍照。
打开串行监视器时,将显示预览图像的日志信息,以及拍摄静止图像时的日志。
-
microSD 卡上保存 ”PICT00.JPG" ~ "PICT009.JPG" 文件。
请尝试从microSD卡中取出JPEG图像。
3.1.4. 程序说明
详细的注释位于开发指南 示例代码说明 示例代码中。
3.2. LCD 上显示 Camera 预览图像
3.2.2. 操作环境
-
Spresense 主板和扩展板
-
Spresense 相机板
-
microSD 卡
-
LCD 板(ILI9341 2.2 英寸LCD模块)
3.2.2.1. LCD 和扩展板连接
下面是与ILI9341 2.2英寸LCD模块的连接示例。
| ILI9341 | CXD5602 pin name | Arduino compatible pin name |
|---|---|---|
VCC |
3.3V |
3.3V / IOREF / AREF |
GND |
GND |
GND |
CS |
SPI4_CS_X |
D10 |
RESET |
GPIO |
D8 |
DC/RS |
GPIO |
D9 |
SDI/MOSI |
SPI4_MOSI |
D11 |
SCK |
SPI4_SCK |
D13 |
LED |
3.3V |
3.3V / IOREF / AREF |
SDO/MISO |
SPI4_MISO |
D12 |
-
参考 Spresense 扩展板 ,在扩展板的JP1跳线上将I/O端子参考电压设置为3.3V。
-
为ILI9341的
VCC端子提供3.3V。 连接到Spresense的 3.3V、IOREF或AREF。
此示例始终为ILI9341的LED端子提供3.3V。 -
与ILI9341通信使用SPI(SPI4)。
-
RESET和DC/RS引脚使用D8、D9作为GPIO。
参考 LCDSP001板 也具有相同的引脚分配, 可以按原样使用本教程中的代码。
3.2.3. 操作顺序
-
选择Arduino IDE上
Files → Examples → Examples for Spresense Camera → camera菜单。 -
当编辑示例之后,选择
File → Save AS来保存示例文件。 -
将以下代码添加到草图
-
将Adafruit_ILI9341对象的定义添加到示例的开头。
#include <SPI.h> #include <Adafruit_GFX.h> #include <Adafruit_ILI9341.h> #define TFT_CS -1 (1) #define TFT_RST 8 (2) #define TFT_DC 9 (3) Adafruit_ILI9341 tft = Adafruit_ILI9341(&SPI, TFT_DC, TFT_CS, TFT_RST); (4)1 SPI CS使用硬件自动控制,需指定-1 2 RST 引脚指定8 3 DC 引脚指定9 4 tft 生成对象。 -
setup()函数中初始化tft。
void setup(void) { : tft.begin(40000000); (1) tft.setRotation(3); (2) :1 使用40 MHz的SPI通信速率初始化tft。 2 将LCD显示屏旋转270度。 -
通过CamCB()函数,在LCD上绘制预览图片。
void CamCB(CamImage img) { /* Check the img instance is available or not. */ if (img.isAvailable()) { /* If you want RGB565 data, convert image data format to RGB565 */ img.convertPixFormat(CAM_IMAGE_PIX_FMT_RGB565); tft.drawRGBBitmap(0, 0, (uint16_t *)img.getImgBuff(), 320, 240); (1) } }1 使用drawRGBBitmap()函数从坐标(0, 0)绘制QVGA大小的RGB565图像。
-
-
在
Tools → Serial Port中选择Spresense COM端口以写入微控制器板。 -
上传并运行草图后,在拍摄照片时,LCD上将显示预览图像。
3.2.4. 程序说明
有关开发指南,请参考 示例代码说明 。
4. 首次使用 Spresense 的Step Counter说明
4.1. Sensing程序库运行环境
请根据您要检测到的内容连接必要的传感器。
4.1.1. Step Counter运行环境
为了Step Counter程序库正常使用,以下是一些你需要事先准备好的事情。
| 这次提供的算法被调整为Bosch的BMI160和Rohm有限公司的传感器外接板。 SPRESENSE-SENSOR-EVK-701也可使用。 |
4.2. Sensing程序库示例
使用Step Counter (Sensing)的示例可从Arduino IDE File → Examples → Examples for Spresense Sensing → application 下获得。
4.2.1. Step Counter示例
-
传感器板
安装BMP280/BMI160连接板,有3轴加速度、3轴陀螺仪、压力和温度传感器 使用说明。
BMI160有关Arduino程序库 安装说明。
| 自v1.3.0以来,索尼算法将随引导加载程序更新一起安装。最新版本的 请更新到引导加载程序。 |
Arduino IDE上通过 File → Examples → Examples for Spresense Audio → application → step_counter 运行示例程序。
启动程序后
"-----------------------------------------------------------" +
" tempo, stride, speed, step, move-type"
继续显示。
4.2.1.1. Step Counter更改程序库中的物理传感器。
Rohm制造的传感器板 SPRESENSE-SENSOR-EVK-701 下面的示例演示如何更改。
-
安装KX122程序库
从这里 下载程序库。
「Clone or download」→「Download ZIP」并将其保存到任何文件夹。
将下载的文件解压缩到任何文件夹。
从Arduino的菜单中,单击「Sketch」→「Include Library」→「Add .ZIP Library…」从您选择和展开的文件夹中选择「KX122」文件夹。
-
修改示例
#include <BMI160Gen.h>
从
#include <Wire.h>
#include <KX122.h>
KX122 kx122(KX122_DEVICE_ADDRESS_1F);
如果要更改和初始化,
BMI160.begin(BMI160GenClass::I2C_MODE, i2c_addr);
从
Wire.begin();
kx122.init();
必须更改并获取数据
BMI160.readAccelerometerScaled(x, y, z);
从
kx122.get_val(acc);
/* acc 用 float acc[3] */
并将这些数据传递到逻辑传感器
AccelSensor.write_data(x, y, z);
从
AccelSensor.write_data(acc[0], acc[1], acc[2]);
可以更改。
| kx122设置为50Hz,即使在程序库中也是如此。 |
4.2.1.2. Step Counter首次制造专有的逻辑传感器。
如果要在不使用当前提供的索尼算法Step Counter (AESM) 情况下,实现自己的步进计数器算法, 请创建逻辑传感器客户端, 如下所示:
创建从传感器客户端继承的逻辑传感器类。
例如,在MyCounter.h实现MyCounterClass类。根据需要包括头文件。例如,SensorClient.h是必要的,但只有当您要使用步进计数器的定义时,才需要使用sensing/logical_sensor/step_counter.h中StepCounter。
例如, 下图显示了常用代码的存储位置。
以上是Windows环境的一个示例,如果是Ubuntu环境,则为 ~/Arduino ; 如果是macOS环境,则为 ~/Documents/Arduino 。
class MyCounterClass : public SensorClient
其中 MyCounterClass
bool begin(int id,
uint32_t subscriptions,
int rate,
int sample_watermark_num,
int size_per_sample));
int publish(FAR void* data,
uint32_t size_per_sample,
uint32_t freq,
uint32_t sample_watermark_num,
uint32_t timestamp);
int subscribe(sensor_command_data_mh_t& data);
在MyCounter.cpp中实现(重写)。
-
begin()执行 :通过MyCounter初始设置,您需要注册callback函数以接收publish加速度计的数据。callback函数调用MyCounter的
subcribe()并传递数据。描述示例unsigned char mycounter_cb(sensor_command_data_mh_t &data) { return MyCounter.subscribe(data); } bool MyCounterClass::begin(int id, uint32_t subscriptions, int rate, int sample_watermark_num, int size_per_sample) { return SensorClient::begin(id, subscriptions, rate, sample_watermark_num, size_per_sample, mycounter_cb); } -
subscribe()执行 :您可以通过订阅加速传感器数据创建自己的Step Counter计数器,并使用自己的算法进行处理。
使用程序库提供的
AccelSensorClass时,发送的数据50个频率50Hz的样本。在下面的示例中,x、y和z轴排列为st_accel_axis。 若要检索此数据,请在基类 (SensorClient)中调用Subscribe()。描述示例int MyCounterClass::subscribe(sensor_command_data_mh_t& data) { struct st_accel_axis { float x; float y; float z; } *accel_axis; accel_axis = static_cast<accel_axis*>(SensorClient::subscribe(data)); uint32_t timestamp = data.time; SensorResultStepCounter output; /* 实现您自己的算法。 在输出中放置一个值。 */ publish(&output, sizeof(SensorResultStepCounter), 1, /* 1Hz */ 1, /* 1sample */ timestamp); }subscribe数据已成为 sensor_command_data_mh_t。有关这个数据结构,请参阅 这里 此处。 -
publish()执行 :publish()将发出MyCounter计算的值。Stepfindreader作为读出应用程序客户端提供的数据结构,如果要按原样使用,则进行publish。SensorResultStepCounter必须发送。
如果以上述
SensorResultStepCounter类型通过,则按基类(SensorClient)进行使用publish()没有问题。
以下是 SensorResultStepCounter 类型介绍。
/*--------------------------------------------------------------------------*/
/**
* @struct StepCounterStepInfo
* @brief the structure of STEP_COUNTER results.
*/
typedef struct {
float tempo; /**< Indicates tempo of walking / jogging calculated
* from the input acceleration data.
* The unit is [Hz].
*/
float stride; /**< Indicates stride calculated
* from input acceleration data.
* The unit is [cm].
*/
float speed; /**< Indicates speed of walking / jogging calculated
* from the input acceleration data.
* The unit is [m/s].
*/
float distance; /**< Indicates cumulative travel distance calculated
* from the input acceleration data.
* The unit is [m].
*/
uint32_t step; /**< Indicates the number of steps calculated
* from the input acceleration data.
* The unit is [step].
*/
StepCounterMovementType movement_type; /**<
* Indicates the walking type calculated
* from the input acceleration data.
*/
uint64_t time_stamp; /**< Indicates latest timestamp of the
* acceleration sensor data used.
*/
} StepCounterStepInfo;
/*--------------------------------------------------------------------------*/
/**
* @struct SensorResultStepCounter
* @brief the structure of sensor result on step counter commands.
*/
typedef struct
{
SensorExecResult exec_result; /**< Execute resule. */
union
{
StepCounterStepInfo steps; /**< Step count. */
SensorAssertionInfo assert_info; /**< Assert information. */
};
} SensorResultStepCounter;
4.2.1.3. 尝试根据逻辑传感器更改数据。
当然,您可能希望根据自己的逻辑传感器更改传感器数据。在这种情况下
publish时,MyCounter会更改数据类型
int MyCounterClass::subscribe(sensor_command_data_mh_t& data)
{
..(省略)..
MyStepCounterResult output;
publish(&output,
sizeof(MyStepCounterResult),
1, /* 1Hz */
1, /* 1sample */
timestamp);
}
在读取Application上( StepCountReaderClass )
subscribe()
{
MyStepCounterResult* steps = reinterpret_cast<MyStepCounterResult*>(ApplicationSensorClass.subscribe(data));
}
并转换。
5. AI 教程
5.1. 手写识别
Arduino IDE中 Files → Examples → Examples for Spresense DNNRT → number_recognition 提供简单的数字识别示例。
有关详细信息,请参阅开发指南中的 DNNRT 程序库 。 如何使用Neural网络控制台创建学习模型,以及描述了在Spresense板上实际作为识别器运行的步骤。
其它示例也会不时添加到本教程中。
6. 初次搭建Spresense的Arduino多核环境
了解使用 Arduino IDE 的多核编程开发环境。
在 Arduino 多核环境中,使用 MultiCore MP 库。
应用程序 CPU 共有六个内核,包括一个 MainCore 和五个 SubCore 。
在典型的单核应用程序中,用户仅使用 MainCore 进行编程。
另一方面,通过使用此处描述的多核环境,用户负责包括 SubCore 在内的所有内核
您将能够编写和执行任何应用程序。
- MainCore
-
MainCore将在通电时被激活。
- SubCore(s)
-
SubCore将由MainCore控制推出。 总共有五个分核心。
在本教程中,您将移动 MultiCore MP 库附带的两个Example类型。
- 多核启动示例
-
启动四个次核心并使用多核执行L Chica。
通过使此示例工作,您可以了解启动SubCore的过程。 - 多核MessageHello示例
-
在MainCore和SubCore之间传达消息。
通过使此示例正常工作,您可以了解如何与 MainCore 和 SubCore 进行通信。
6.1. 初次使用多核引导示例
主要步骤
-
使用Arduino IDE打开示例
-
选择核心
-
编译和上传
重复任意数量的内核,以便使其正常工作。
请尝试执行以下步骤。
-
从桌面启动 Arduino IDE
(如果桌面上没有图标,请从 "开始" 菜单开始。)
在多核编程中启动多个 Arduino IDE 窗口时,需要考虑一些事项。
例如,如果从Arduino IDE 菜单创建带有File → New的新窗口,例如,如果在一个窗口中切换Core选择菜单,则设置将链接到所有窗口 它将得到反映。作为一种解决方法,当您为每个 Core打开多个Arduino IDE 窗口时,每次都从桌面上的图标启动Arduino IDE。通过这样做,菜单设置 (如Core) 选择不会链接到每个窗口 将能够独立设置 -
MainCore编程
-
从Arduino IDE菜单中,
File → Examples → Examples for Spresense → MultiCore MP → Boot → Main打开示例
-
Main.ino示例描述
MP.begin(subid)启动子ID参数指定的子核心。
在这种情况下,我们将总共启动四个子核心从 SubCore1 到 SubCore4。
-
从Arduino IDE菜单中,选择
Tools → Core → MainCore
您可以在下面的状态栏中验证是否选择了
MainCore
在Arduino IDE 1.8.9~1.8.13切换菜单时,
有一个状态栏显示不正确的问题。 -
按下Upload按钮Compile&Upload
不能同时从多个窗口上传多个核心程序。
执行上传操作,以便每个内核避免同时运行。 -
将显示编译结果日志中使用的内存大小
MainCore 始终使用768 KByte内存。
如果上传成功完成,MainCore编程就完成了。
-
尝试在缺少SubCore程序的情况下启动串行监视器。
由于SubCore不存在,您可以看到MP.begin(1~4)调用返回时出现错误。
如果打开了串行监视器,则可能无法从其他窗口正确上传。
完成验证后,关闭串行监视器。
-
-
下面是SubCore编程。
-
SubCore编程
-
从Arduino IDE菜单
File → Examples → Examples for Spresense → MultiCore MP → Boot → Sub1打开示例
-
Sub1.ino示例说明
在setup()中调用
MP.begnin(),通知 MainCore 启动已完成。
loop()中LED0日志显示由MPLog()和闪烁控制。
-
从Arduino IDE菜单选择
Tools → Core → SubCore 1
您可以在下面的状态栏中验证是否选择了
SubCore1
在Arduino IDE 1.8.9~1.8.13中切换菜单时
有一个状态栏显示不正确的问题。 -
按下Upload按钮Compile&Upload
不能同时从多个窗口上载多个核心程序。
执行上传操作,以便每个内核避免同时运行。 -
将显示编译结果日志中使用的内存大小
您可以看到,此处使用的子酷示例草图使用128 KByte 内存。
此大小取决于用户程序,并增加或减少。
如果上传成功完成,SubCore1的编程就完成了
-
-
在SubCore2、3、4 的相同过程中,请执行Compile & Upload
-
打开Sub2示例并选择SubCore 2,Compile & Upload
-
打开Sub3示例并选择SubCore 3,Compile & Upload
-
打开Sub4示例并选择SubCore 4,Compile & Upload
-
-
动作检查
-
Spresense主板闪光灯上的四个绿色LEDS
-
当您打开串行监视器时,您将看到来自每个内核的日志输出。
-
-
总结
-
一个简单的示例用于解释如何启动SubCore。
将现有草图移植到多核环境时,添加对MP.begin()的调用。 -
在多核环境中,基本用法,如 Arduino IDE 的Compile & Upload方法,并没有变化。 主要区别在于,核心选择菜单已添加到
Tool → Core中。
-
6.2. 初次使用多核MessgeHello示例
主要步骤与多核启动示例的步骤相同。
这个示例在MainCore和SubCore(s)中使用常见的草图。
-
使用Arduino IDE打开示例(仅一次)
-
选择核心
-
编译和上传
重复任意数量的内核,以便使其正常工作。 此示例移动所有SubCore(共5个)。
请尝试执行以下步骤。
-
从桌面启动Arduino IDE
(如果桌面上没有图标,请从 "开始" 菜单开始。)
在多核编程中启动多个Arduino IDE窗口时,需要考虑一些事项。
如果从Arduino IDE菜单中点击File → New菜单,例如,如果在一个窗口中切换Core选择菜单,它将与该设置一起反映在所有窗口中。作为一种解决方法,当您为每个 Core打开多个Arduino IDE窗口时,每次都从桌面上的图标启动Arduino IDE。 通过这样做,菜单设置 (如Core) 选择不会链接到每个窗口 可以独立设置。 -
MainCore编程
-
从Arduino IDE菜单中
File → Examples → MultiCore MP → Messsage → MessageHello打开示例
-
MessageHello.ino示例描述
使用示例中的
#ifdef SUBCORE~#else~#endif在主要核心和子核心实现之间切换。-
MainCore源代码
setup() 通过
MP.begin(subid),将启动五个子核心。
在setup()最后,MP.RecvTimeout(MP_RECV_POLLING)将接收设置为轮询模式。
在loop() 中,MP.Recv()接收来自各个SubCore的数据包地址,并在数据包printf()中输出消息。
-
SubCore源代码
在setup()中,调用
MP.begin(),通知 MainCore 启动已完成。
在loop()中,将"Hello"消息存储在数据包中,并使用其地址的MP.Send()到MainCore。
-
-
在Arduino IDE菜单中,选择
Tools → Core → MainCore
在下面的状态栏中验证是否选择了
MainCore
在Arduino IDE 1.8.9~1.8.13切换菜单时
有一个状态栏显示不正确的问题。 -
按下Uplod按钮Compile & Uplod
不能同时从多个窗口上载多个核心程序。
应执行上传操作,以便每个内核避免同时运行。 -
将显示编译结果日志中使用的内存大小
MainCore 始终使用768 KByte内存
如果上传成功完成,MainCore编程就完成了。
-
下面是SubCore执行
-
SubCore编程
-
在Arduino IDE菜单中,选择
Tools → Core → SubCore 1
在下面的状态栏中验证是否选择了
SubCore 1。
在Arduino IDE 1.8.9~1.8.13切换菜单时
有一个状态栏显示不正确的问题。 -
按下Upload按钮Compile & Upload
不能同时从多个窗口上载多个核心程序。
执行上传操作,以便每个内核避免同时运行。 -
将显示编译结果日志中使用的内存大小
您可以看到,此处使用的子酷示例草图使用128 KByte内存。
此大小取决于用户程序,并增加或减少。
如果上传成功完成,SubCore1的编程就完成了
-
-
按照子核心2、3、4、5 Compile & Upload的相同过程
-
选择SubCore 2,Compile & Upload
-
选择SubCore 3,Compile & Upload
-
选择SubCore 4,Compile & Upload
-
选择SubCore 5,Compile & Upload
-
-
动作检查
-
请打开串行监视器
-
每个SubCore发送的消息将由MainCore接收并显示在串行监视器上。
-
-
总结
-
讨论了如何使用示例与SubCore进行通信。
-
由于内存在内核之间共享,因此可以传递地址并与消息进行通信。
-
多核编程与共同的示例,而不分离每个核心的草图也是可能的。
-
6.3. 注意事项
-
有关
MultiCore MP的详细信息,请参阅 MultiCore MP 程序库 文档。 -
如果有一个已经上传到Spresense板上的SubCore二进制文件,并且想一次删除它们,Spresense Loader的安装 安装加载程序时,删除所有SubCore二进制文件,然后装载机安装开始。
请注意,除非从MainCore调用
MP.begin(),否则 SubCore 将无法在未经允许的情况下工作。 因此,即使旧的SubCore仍在上传,也没有问题。 -
在多核编程中,每个
Core打开多个Arduino IDE窗口时,每次都可以从桌面上的图标启动Arduino IDE。请启动 Arduino IDE。 这样,可以为每个窗口单独设置菜单设置,如Core选择 。 -
在Arduino IDE中的多个启动和Core之间切换是很麻烦的,但还可以使用命令行工具arduino-builder arduino-cli。上传也是可以使用flash_writer工具使用一个命令加载每个内核的二进制文件。命令行方法将在以后发布在文档中。
7. SignalProcessing库教程
SignalProcessing库具有FFT/IIR滤波器,并为它们提供了以下示例草图。
本文档说明了如何执行这些示例草图。
7.1. PeakDetector
7.1.1. 概要
该示例草图通过使用FFT库对麦克风输入的声音数据执行实时频率分析来实时检测峰值频率。请参阅Audio 库中的Audio功能。
此外,此示例还执行了将信号处理库转移到SubCore中。另请参见MultiCore MP 库。
7.1.2. 操作环境
-
Spresense主板和扩展板
-
录音麦克风
请参阅以下硬件指南以进行麦克风连接。
|
该示例是具有4个通道的多通道应用程序。 连接麦克风(最多4个模拟,8个数字),并在应用程序中进行调整。 |
7.1.3. 操作方法
主要操作步骤如下:
-
编译并上传SubCore进行信号处理
-
编译并上传MainCor以进行声音采集和应用处理
-
运行应用程序
| 如果首先编译并上传MainCore,它将在启动后调用SubCore,从而导致错误。 |
| 如果您已经编译并上传到SubCore,启动MainCore后,将启动已经上传的SubCore程序。 |
7.1.3.1. SubCore的编译和上传
-
在Arduino IDE中选择
File→ Sketch example→ Sketch example for Spresense SignalProcessing→ PeakDetector→ SubFFT来打开示例历程。 -
从Arduino IDE菜单中选择
Tools→ Core→ SubCore1(` Tools→ Core→ SubCore1`) 。在此示例中,选择的SubCore是SubCore1。
通过 Tools→ Serial Port 选择Spresense的COM端口,并写入微机主板。
+
NOTE: SubCore 程序在启动后等待 MainCore 的指令。
现在,SubCore上的准备工作就完成了。
7.1.4. 程序说明
-
输入音频通道的数量在MainAudio.ino中的。
/* Select mic channel number */
//const int mic_channel_num = 1;
//const int mic_channel_num = 2;
const int mic_channel_num = 4;
指定。
NOTE : 在SubCore上#define MAX_CHANNEL_NUM 4 表示最大通道数为4, 用户可以动态选择1-4个通道。
该示例调用了 FFT.begin(); ,而在SubCore中没有参数,因此,SubCore上的通道执行数量等于最大通道数。如果您不希望执行通道的数量等于最大通道的数量,请调用 FFT.begin (WindowHamming, "The number of execution channels", (FFTLEN / 2)); ,来指定执行通道的数量。
|
-
FFT Tab的数量在SubFFT.ino中的。
/* Select FFT length */
//#define FFT_LEN 32
//#define FFT_LEN 64
//#define FFT_LEN 128
//#define FFT_LEN 256
//#define FFT_LEN 512
#define FFT_LEN 1024
//#define FFT_LEN 2048
//#define FFT_LEN 4096
指定。
-
当前窗口函数和FFT重叠样本数设置为默认值。 窗口的默认值为 `Hamming window' ,重叠大小旨在将窗口移动taps/2。
如果要更改此设置,请在SubSub.ino中的
FFT.begin();
改成
FFT.begin ("您要使用的窗口功能", "执行通道数", "您要重叠的样本数");
7.2. SoundDetector
7.2.1. 概要
此示例使用FFT库对麦克风输入的声音数据进行实时频率分析,并检测在指定频率范围内是否输入了某些声压级的声音。请参阅Audio 库中的Audio 功能。
此外,此示例还执行了将信号处理库转移到SubCore的任务。另请参见MultiCore MP 库。
7.2.2. 操作环境
-
Spresense主板和扩展板
-
录音麦克风
请参阅以下硬件指南以进行麦克风连接。
|
该示例是具有4个通道的多通道应用程序。 连接麦克风(最多4个模拟,8个数字),并在应用程序中进行调整。 |
7.2.3. 操作方法
主要操作步骤如下:
-
编译并上传SubCore进行信号处理
-
编译并上传MainCor以进行声音采集和应用处理
-
运行应用程序
| 如果首先编译并上传MainCore,它将在启动后调用SubCore,从而导致错误。 |
| 如果您已经编译并上传到SubCore,启动MainCore后,将启动已经上传的SubCore程序。 |
7.2.3.1. SubCore的编译和上传
-
通过从Arduino IDE中选择
File→ Sketch example→ Sketch example for Spresense SignalProcessing→ SoundDetector → SubFFT来打开示例草图。 -
从Arduino IDE菜单中选择
Tools→ Core→ SubCore1(` Tools→ Core→ SubCore1`) 。在此示例中,选择的SubCore是SubCore1。 -
通过
Tools→ Serial Port选择Spresense的COM端口,并写入微机主板。SubCore程序在启动后等待MainCore的指令。
现在,在SubCore上的准备工作完成。
7.2.4. 程序说明
-
输入音频通道的数量在MainAudio.ino中的
/* Select mic channel number */
//const int mic_channel_num = 1;
//const int mic_channel_num = 2;
const int mic_channel_num = 4;
指定
NOTE : 在SubCore上#define MAX_CHANNEL_NUM 4表示最大通道数为4, 用户可以动态选择1-4个通道。
该示例调用了 FFT.begin(); ,而在SubCore中没有参数,因此,SubCore上的通道执行数量等于最大通道数。如果您不希望执行通道的数量等于最大通道的数量,请调用 FFT.begin (WindowHamming, "执行通道数", (FFTLEN / 2));,并指定执行通道的数量。
|
-
FFT Tab的数量在SubFFT.ino中的
/* Select FFT length */
//#define FFT_LEN 32
//#define FFT_LEN 64
//#define FFT_LEN 128
//#define FFT_LEN 256
//#define FFT_LEN 512
#define FFT_LEN 1024
//#define FFT_LEN 2048
//#define FFT_LEN 4096
指定。
-
当前窗口函数和FFT重叠样本数设置为默认值。 默认窗口是
Hamming window,重叠大小旨在将窗口移动tabs/ 2。
如果要更改此设置,请在SubSub.ino中的
FFT.begin();
改成
FFT.begin ("您要使用的窗口功能", "执行通道数", "您要重叠的样本数");
-
检测器设置如下:
#define POWER_THRESHOLD 30 // Power
#define LENGTH_THRESHOLD 30 // 20ms
#define INTERVAL_THRESHOLD 100 // 100ms
#define BOTTOM_SAMPLING_RATE 1000 // 1kHz
#define TOP_SAMPLING_RATE 1500 // 1.5kHz
-
用
BOTTOM_SAMPLING_RATE指定用于检测的频率范围的下限。 设置Hz值。 -
用
TOP_SAMPLING_RATE指定检测的频率范围上限。 设置Hz值。 -
用
POWER_THRESHOLD指定用于检测的声功率阈值。 -
如果相关频率范围内的音频继续输入超过
LENGTH_THRESHOLD时间, 则判断为检测到声音。 -
如果在开始检测到之后在
INTERVAL_THRESHOLD内重新检测到它,则认为它是先前检测到的声音的一部分。 同样,如果检测到的距离超过“ INTERVAL_THRESHOLD”,则会检测到另一种声音,并且通知会再次发出` MainCore` 。
7.3. VoiceChanger
7.3.1. 概要
该示例对麦克风输入的语音数据执行FFT/iFFT,以更改音频并重新生成语音数据。 将LP滤波器应用于数据生成,以过滤掉由于缺乏相位信息等而加入的高频噪声,然后输出。请参阅Audio 库中的Audio 功能。
此外,此示例还执行了将信号处理库转移到SubCore的任务。另请参见 MultiCore MP 库.
| 该样本作为简单的FFT/iFFT执行样本提供。 因此,作为音调转换器的话音质较差。 |
7.3.2. 操作环境
-
Spresense主板和扩展板
-
耳机或扬声器播放
-
录音麦克风
在此示例中,使用了耳机和麦克风。
请将耳机或扬声器连接到扩展板上的耳机插孔。
请参阅以下硬件指南以进行麦克风连接。
| 提供的样本用于单声道麦克风。 如果您想要更多麦克风,连接麦克风(最多4个模拟,8个数字),并在应用程序中进行调整。 |
| 音频输出只能达到立体声。 如果输入是3通道或更多,需要在输出之前执行缩混处理,转换为2通道数据。 |
7.3.3. 操作方法
主要操作步骤如下:
-
编译并上传SubCore进行信号处理
-
编译并上传MainCor以进行声音采集和应用处理
-
运行应用程序
| 如果首先编译并上传MainCore,它将在启动后调用SubCore,从而导致错误。 |
| 如果您已经编译并上传到SubCore,启动MainCore后,将启动已经上传的SubCore程序。 |
7.3.3.1. SubCore的编译和上传
-
通过从Arduino IDE中选择
File→ Sketch example→ Sketch example for Spresense SignalProcessing→ VoiceChanger→ SubFFT来打开示例。 -
从Arduino IDE菜单中选择
Tools→ Core→ SubCore1(` Tools→ Core→ SubCore1`) 。在此示例中,选择的SubCore是SubCore1。 -
通过
Tools→ Serial Port选择Spresense的COM端口,并写入微机主板。SubCore程序在启动后等待MainCore的指令。
现在,在SubCore上的准备工作完成。
7.3.4. 程序说明
-
输入音频通道的数量在
MainAudio.ino中的
/* Select mic channel number */
const int mic_channel_num = 1;
//const int mic_channel_num = 2;
指定。
在此示例中,如在SubCore上定义的 #define MAX_CHANNEL_NUM 1 一样,
它只能执行单轨通道。
|
-
FFT Tab 的数量在SubFFT.ino中的
/* Select FFT length */
//#define FFT_LEN 32
//#define FFT_LEN 64
//#define FFT_LEN 128
//#define FFT_LEN 256
//#define FFT_LEN 512
#define FFT_LEN 1024
//#define FFT_LEN 2048
//#define FFT_LEN 4096
指定。
-
此示例使用FFT/iFFT再生音频,因此它是
矩形窗口且没有重叠。
FFT.begin(WindowRectangle,MAX_CHANNEL_NUM,0);
如果要更改算法,请进行相应更改。
-
音频偏移量在下面的
MainAudio.ino中的
static int pitch_shift = 10;
指定。
可以根据FFT分辨率在正方向或负方向上移动。
即使在信号处理期间也可以更改此参数。
7.4. HighPassSound / LowPassSound
7.4.1. 概要
该示例对麦克风输入的语音数据执行FFT/iFFT,以更改音频并重新生成语音数据。 将LP滤波器应用于数据生成,以过滤掉由于缺乏相位信息等而加入的高频噪声,然后输出。请参阅Audio 库中的Audio 功能。
此外,此示例还执行了将信号处理库转移到SubCore的任务。另请参见 MultiCore MP 库.
7.4.2. 操作环境
-
Spresense主板和扩展板
-
耳机或扬声器播放
-
录音麦克风
在此示例中,使用了耳机和麦克风。
请将耳机或扬声器连接到扩展板上的耳机插孔。
请参阅以下硬件指南以进行麦克风连接。
| 提供的样本用于单轨麦克风。 如果您想要更多麦克风,连接麦克风(最多4个模拟,8个数字),并在应用程序中进行调整。 |
| 音频输出只能达到立体声。 如果输入是3通道或更多,需要在输出之前执行缩混处理,转换为2通道数据。 |
7.4.3. 操作方法
主要操作步骤如下:
-
编译并上传SubCore进行信号处理
-
编译并上传MainCor以进行声音采集和应用处理
-
运行应用程序
| 如果首先编译并上传MainCore,它将在启动后调用SubCore,从而导致错误。 |
| 如果您已经编译并上传到SubCore, 启动MainCore后,将启动已经上传的SubCore程序。 |
7.4.3.1. SubCore的编译和上传
-
通过从Arduino IDE中选择
File→ Sketch example→ Sketch example for Spresense SignalProcessing→ HighPassSound / LowPassSound→ SubFFT来打开示例草图。 -
从Arduino IDE菜单中选择`Tools→ Core→ SubCore1`(
Tools→ Core→ SubCore1)。在此示例中,选择的SubCore是SubCore1。 -
通过
Tools→ Serial Port选择Spresense的COM端口,并写入微机主板。SubCore程序在启动后等待MainCore的指令。
现在,在SubCore上的准备工作完成。
7.4.4. 程序说明
-
输入音频通道的数量在 `MainAudio.ino`中的
/* Select mic channel number */
const int mic_channel_num = 1;
//const int mic_channel_num = 2;
指定。
在此示例中,如在SubCore上定义 #define MAX_CHANNEL_NUM 1 ,
它只能执行单轨通道。
|
-
截止频率和Q值由
SubCore里的
HPF.begin(TYPE_HPF,g_channel,1000,sqrt(0.5));
或者
LPF.begin(TYPE_LPF,g_channel,1000,sqrt(0.5));
设置。 在此示例中,截止频率设置为1kHz,Q值设置为1 /√2。