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
和WAVDEC
DSP二进制文件(参见安装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。