Developer World Spresense
English 日本語
目录

1. Audio 教程

Audio库提供各种示例sketch,包括播放和录音音频。

利用Spresense的多核特征,诸如音频编码/解码的处理在与用户应用操作的主核不同的核(以下称为DSP)中执行。 这允许用户轻松开发使用音频功能的应用程序,而无需复杂的控制。

音频教程说明如何安装DSP文件以及如何使用各种示例sketch。

1.1. 安装DSP文件

运行示例前,必须根据播放/录音的格式预先安装DSP文件。 本节介绍如何安装DSP文件。

1.1.1. DSP文件类型

表格 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.1. 将DSP文件复制并安装到microSD卡
  1. 在这里下载最新的DSP文件。

  2. 在FAT32格式的microSD卡上创建BIN目录并复制下载的文件。

arduino dsp copy cn
图表 1. DSP文件复制
  1. 运行音频示例时请将此microSD卡插入扩展板。

1.1.2.2. 使用DSP安装程序安装

为每个DSP文件都提供了DSP安装程序。

  1. 运行Arduino IDE, 选择 File→ Sketch Example→ Spresense Sketch Example Audio→ dsp_installer

    arduino dsp installer cn
    图表 2. 启动DSP安装程序
  2. 选择 Tools→ Serial Port 下的Spresense COM端口,执行写入操作。

  3. 编译和写入(上载)完成后,启动Serial monitor。

  4. 选择波特率115200 bps时,将显示如下所示的消息。

  5. 选择安装编号,然后按“发送”按钮。
    安装到microSD卡时,将FAT32格式的microSD卡插入扩展板上的microSD卡插槽。

    arduino dsp installer monitor1 cn
    图表 3. 选择DSP安装位置
  6. 如果安装成功,将显示以下消息。

    arduino dsp installer monitor2 cn
    图表 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.2. 运行环境
  • Spresense主板和扩展板

  • 播放耳机或扬声器

将耳机或有源扬声器连接到扩展板上的耳机插孔。

1.2.1.3. 操作程序
  1. 运行Arduino IDE,选择 File→ Sketch Example→ Spresense Sketch Example Audio→ application→ beep 打开示例sketch。

    arduino audio examples beep
  2. Tools→ Serial Port 中选择Spresense COM端口并写入微控制器板。

    arduino audio examples beep2
  3. 耳机输出音阶音。

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.1. 摘要

播放microSD卡上的MP3音乐文件。

1.2.2.2. 运行环境
  • Spresense主板和扩展板

  • microSD卡

  • 播放耳机或扬声器

此示例使用microSD卡和耳机。 将耳机或有源扬声器连接到扩展板上的耳机插孔。

1.2.2.3. 操作程序
  1. 在microSD卡上安装MP3解码DSP文件 MP3DEC (参见安装DSP文件)。

  2. 将要播放的MP3文件放在microSD卡的根目录中,文件名为“Sound.mp3”。

  3. 将microSD卡插入扩展板上的microSD卡插槽。

  4. 运行Arduino IDE,选择 File→ Sketch Example→ Spresense Sketch Example Audio→ application→ player 打开示例sketch。

    arduino audio examples player
  5. Tools→ Serial Port 中选择Spresense COM端口并写入微控制器板。

  6. 上传并执行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. 使用扩展板上的扬声器端子时

在使用扩展板的耳机端子作为音频输出的情况下,作为音频信号的驱动能力设置, setPlayerModesp_drv 指定为 AS_SP_DRV_MODE_LINEOUT (默认值)。

从扩展板的扬声器端子输出时,参数 sp_drv 指定为 AS_SP_DRV_MODE_4DRIVER

使用扬声器端子时,需要修改电路板。 有关详细信息,请参阅:

1.2.3. 播放WAV音乐

1.2.3.1. 摘要

播放microSD卡上的WAV音乐文件。

1.2.3.2. 运行环境
  • Spresense主板和扩展板

  • microSD 卡

  • 播放耳机或扬声器

此示例使用microSD卡和耳机。。 将耳机或有源扬声器连接到扩展板上的耳机插孔。

1.2.3.3. 操作程序
  1. 在microSD卡上安装WAV解码DSP文件 WAVDEC (参见安装DSP文件)。

  2. 将要播放的WAV文件放在microSD根目录中,名称为“Sound.wav”。

  3. 将microSD卡插入扩展板上的microSD卡插槽。

  4. 运行Arduino IDE,选择 File→ Sketch Example→ Spresense Sketch Example Audio→ application→ player_wav 打开示例sketch。

    arduino audio examples player wav

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_NORMALAS_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.1. 摘要

播放microSD卡上的高分辨率声源的WAV音乐文件。

1.2.4.2. 运行环境
  • Spresense主板和扩展板

  • microSD 卡

  • 播放耳机或扬声器

此示例使用microSD卡和耳机。。 将耳机或有源扬声器连接到扩展板上的耳机插孔。

1.2.4.3. 操作程序
  1. 在microSD卡上安装WAV解码DSP文件 WAVDEC (参见安装DSP文件)。

  2. 将要播放的WAV文件放在microSD卡的根目录中,文件名为“HiResSound.wav”。

  3. 将microSD卡插入扩展板上的microSD卡插槽。

  4. 运行Arduino IDE,选择 File→ Sketch Example→ Spresense Sketch Example Audio→ application→ player_hires 来启动示例sketch。

    arduino audio examples player hires
  5. Tools→ Serial port 中选择Spresense COM端口并写入微控制器板。

  6. 上传并执行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.1. 摘要

此示例是使用播放列表播放音乐的示例sketch。

按顺序播放microSD卡中的多个音乐文件。 您可以执行播放,停止,下一首歌曲,返回,重复播放和随机播放等操作。

1.2.5.2. 运行环境
  • Spresense主板和扩展板

  • microSD 卡

  • 播放耳机或扬声器

此示例使用microSD卡和耳机。。 将耳机或有源扬声器连接到扩展板上的耳机插孔。

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/ 目录中安装 MP3DECWAVDEC 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
  • 音乐文件扩展名必须为.mp3或.wav。

  • 不支持包含2字节代码(如日语)的文件名。 将文件名更改为ASCII代码字符串。

  • 由于播放列表文件是以CSV格式编写的,因此请勿使用文件名,艺术家,专辑名称中包含逗号的字符串。

  1. 将microSD卡に插入扩展板上的microSD卡插槽。

  2. 运行Arduino IDE , 选择 File→ Sketch Example→ Spresense Sketch Example Audio→ application→ play_playlist 打开示例sketch。

    arduino audio examples player playlist
  3. Tools→ Serial port 中选择Spresense COM端口并写入微控制器板。

  4. 启动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.1. 摘要

同时播放microSD卡上的两个MP3音乐文件。

1.2.6.2. 运行环境
  • Spresense主板和扩展板

  • microSD 卡

  • 播放耳机或扬声器

此示例使用microSD卡和耳机。。 将耳机或有源扬声器连接到扩展板上的耳机插孔。

1.2.6.3. 操作程序
  1. 在microSD上安装MP3解码DSP文件 MP3DEC (参见安装DSP文件)。

  2. 将要播放的两个MP3文件放在microSD卡的根目录中,文件名为“Sound0.mp3”和“Sound1.mp3”。

  3. 将microSD卡插入扩展板上的microSD卡插槽。

  4. 运行Arduino IDE, 选择 文件 - >sketch示例 - > Spresensesketch示例选择Audio→ application→ dual_players 打开示例sketch。

    arduino audio examples dual players
  5. Tools→ Serial port 中选择Spresense COM端口并写入微控制器板。

  6. 编译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 调整整体音量,使用 player0player1 调整单个音量。。

1.2.7. 聆听麦克风输入的声音

1.2.7.1. 摘要

从麦克风输入的声音从耳机插孔输出。

使用音频硬件的路径设置功能,可以将来自I2S的数字音频输出到模拟通道,还可以将从麦克风的输入输出到I2S, 实现具有低功耗和非常低延迟的输出。

1.2.7.2. 运行环境
  • Spresense主板和扩展板

  • 播放耳机或扬声器

  • 录音麦克风

此示例使用耳机和麦克风。 将耳机或有源扬声器连接到扩展板上的耳机插孔。 有关麦克风连接,请参阅

在此示例中,不需要安装DSP文件。

1.2.7.3. 操作程序
  1. 运行Arduino IDE , 选择 File→ Sketch Example→ Spresense Sketch Example Audio→ application→ through 打开示例sketch。

    arduino audio examples through
  2. 示例sketch将从I2S输入的声音输出到耳机插孔。
    修改sketch以便将从麦克风输入的声音输出到耳机插孔。
    通过 File→ Save As 将其保存到可编辑的位置。

  3. setThroughMode() 函数的参数 inputAudioClass::I2sIn 更改为 AudioClass::MicIn 并保存。

  4. Tools→ Serial port 中选择Spresense COM端口并写入微控制器板。

  5. 上传并执行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.1. 摘要

录音麦克风的声音并将其作为MP3文件存储在microSD卡上。

1.2.8.2. 运行环境
  • Spresense主板和扩展板

  • microSD 卡

  • 录音麦克风

此示例使用microSD卡和麦克风。 有关麦克风连接,请参阅

1.2.8.3. 操作程序
  1. 在microSD上安装MP3编码DSP文件 MP3ENC ((参见安装DSP文件)。

  2. 运行Arduino IDE , 选择 File→ Sketch Example→ Spresense Sketch Example Audio→ application→ recorder 打开示例sketch。

    arduino audio examples recorder
  3. Tools→ Serial port 中选择Spresense COM端口并写入微控制器板。

  4. 上传并执行sketch时,录音开始并在一定时间后停止录音。

  5. 记录的数据保存在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.1. 摘要

记录麦克风的声音并将其记录为microSD卡上的WAV文件。

1.2.10.2. 运行环境
  • Spresense主板和扩展板

  • microSD 卡

  • 录音麦克风

此示例使用microSD卡和麦克风。 有关麦克风连接,请参阅

1.2.10.3. 操作程序
  1. 在microSD卡上安装用于WAV(PCM)编码的DSP文件 SRC (参见安装DSP文件)。

  2. 运行Arduino IDE , 选择 File→ Sketch Example→ Sample Spresense Audio→ application→ recorder_wav 打开示例sketch。

    arduino audio examples recorder wav
  3. 在 ` Tools→ Serial port ` 中选择Spresense COM端口并写入微控制器板。

  4. 上传并执行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)录音时,设置 fsASSAMPLINGRATE_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.1. 摘要

捕获从麦克风输入的PCM数据。

在该示例中,仅显示PCM数据最前部,但是通过改进,可以执行诸如PCM原始数据的频率分析和各种滤波器等信号分析。。

1.2.11.2. 运行环境
  • Spresense主板和扩展板

  • 录音麦克风

此示例使用麦克风。 有关麦克风连接,请参阅

在此示例中,不需要安装DSP文件。

1.2.11.3. 操作程序
  1. 运行Arduino IDE , 选择 File→ Sketch Example→ Spresense Sketch Example Audio→ application→ pcm_capture 打开示例sketch。

    arduino audio examples pcm capture
  2. 示例sketch从麦克风中提取语音输入作为PCM数据。

  3. Tools→ Serial port 中选择Spresense COM端口并写入微控制器板。

  4. 启动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.1. 摘要

重复从耳机播放麦克风输入的声音的操作。

1.2.12.2. 运行环境
  • Spresense主板和扩展板

  • microSD 卡

  • 播放耳机或扬声器

  • 录音麦克风

此示例使用microSD卡和耳机。。 将耳机或有源扬声器连接到扩展板上的耳机插孔。 有关麦克风连接,请参阅

1.2.12.3. 操作程序
  1. 在microSD卡上安装MP3解码DSP文件 MP3ENCMP3DEC (参见安装DSP文件)。

  2. 将microSD卡插入扩展板上的microSD卡插槽。

  3. 运行Arduino IDE , 选择 File→ Sketch Example→ Spresense Sketch Example Audio→ application→ rec_play 打开示例sketch。

    arduino audio examples rec play
  4. Tools→ Serial port 中选择Spresense COM端口并写入微控制器板。

  5. 加载并执行示例程序后、大约以20秒的周期、记录来自麦克风的音频、播放记录的数据。
    循环录音和播放5次后停止。

1.2.12.4. 程序解说
  • 关于录音和播放功能、和其它的示例程序一样。

  • setRecorderMode(), setReadyMode(), setPlayerMode() 调用这些函数来切换模式、从而动态切换录音和播放操作。

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.2. 操作环境
  • Spresense 主板&扩展板

  • microSD 卡

  • 播放用耳机 or 扬声器

本示例、使用microSD 卡和耳机。 将耳机或有扬声器连接到扩展板上的耳机插孔。

1.3.3.3. 操作步骤
  1. 将要播放的音频PCM的RAW文件放置在microSD卡的根目录中,文件名为“ Sound0.raw”,“ Sound1.raw”和“ Sound2.raw”。

    RAW文件是没有头文件(例如WAV头文件)的PCM文件。如果位长为16位,则通道数据将每16位交织一次。仅支持16位或以下。
    基本上,从SD卡读取的速度是此样本的速率确定速率、现状、仅支持16位或以下。
    如果不可避免地要使用24位数据,请通过对齐每32位,用数据填充低24位并插入通道来创建24位RAW。
  2. 将microSD 卡插入扩展板的 microSD 卡插槽。

  3. Arduino IDE 上选择打开 File→ Sketch Example→ Spresense Sketch Example Audio → application → rendering_objif

  4. 工具 → 串口 用来选择 Spresense 的 COM 端口、烧写微机板。

  5. 示例被烧写执行后、串口监视器会进入输入等待状态。此时、"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) {      :size0
          pcm_param.size = READSIZE;
          pcm_param.sample = pcm_param.size / BYTEWIDTH / CHNUM;
          memset(pcm_param.mh.getPa(), 0, pcm_param.size);  : 0
        }
1.3.3.5. 关于帧大小和缓冲区大小

在此示例中,帧大小设置为“ READSAMPLE(240)”。 如果小于此值,则音频系统中的处理可能会延迟。 同样,增加它会增加延迟量。
缓冲区大小为、`BridgeBuffer`内の`m_buf[30 * READSIZE];`30帧。请相应调整。

由于无需任何内部信号处理即可播放信号以减少延迟,因此该通道为立体声,采样率仅为48kHz。

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.4.5. 关于写入事的信号处理

写入时、调用 signal_process(uint32_t size)、可以加工写入数据、 但如果是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. 关于录音机缓存
1.3.5.5. 关于写入时的信号处理

写入时、调用`signal_process(uint32_t size)`、来加工写入数据。 数字麦克风录音时想要提高Gain、请根据所需供应进行信号处理。

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. 关于缓存大小
1.3.6.5. 关于写入时的信号处理

通过以`signal_process(uint32_t size)` 对获取的音频数据执行信号处理(频率分析,AI等) 可以执行所需的感应处理。

2. GPS 教程

在本教程中,我们将基于示例草图,使用Spresense GPS功能的简单应用程序, 并了解如何自定义示例以添加和扩展功能。

2.1. GPS 示例草图

2.1.1. 简介

了解基于GNSS库示例草图gnss.ino的GNSS库的基本功能。

2.1.2. 操作环境

下面是操作此草图所需的环境。
主板上装有GPS芯片天线,只需主板即可移动GPS功能。

  • Spresense 主板

2.1.3. 操作说明

从 Arduino IDE 菜单中,打开 File → Examples → GNSS → gnss

gnss example1
gnss example2

将此示例写入Spresense板。

gnss example3

打开串行监视器时,将显示定位信息。在定位过程中,LED0每隔一秒闪烁一次。

gnss example4
  • 时间从初始时间 1980/01/06 00:00:00 开始计数。
    从卫星获取精确时间后,切换到当前 UTC 时间显示。

  • numSat:表示找到的卫星数

  • 在非定位状态下,将显示"无修复,无位置"。
    定位后,显示"修复"和"Lat=纬度、Lon=经度"。
    此外,获得位置信息后,LED1会亮起。

gnss example5

每分钟显示有关卫星的详细信息。

  • 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.2. 操作环境

下面是操作此草图所需的环境。

  • Spresense主板

  • Spresense扩展板

  • microSD卡

2.2.3. 操作说明

连接Spresense主板和扩展板,并将microSD卡插入扩展板。
从Arduino IDE菜单中,打开 File → Examples → GNSS → gnss_tracker

gnss tracker1
gnss tracker2

将此示例写入Spresense板。

gnss tracker3

打开串行监视器时,首先打印应用程序的配置信息,然后开始输出定位结果。

gnss tracker4

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
    GPS

    SatelliteSystem=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处理。如果源数据被划分为多个文本文件,请将该文件合并为一个文件。

    1. 打开 https://www.h-schmidt.net/NMEA/

    2. 通过" 选择文件 " 指定输入文件,然后按" 发送 "按钮

    3. 下载转换为KML的文件

      gnss nmea2kml1
      gnss nmea2kml2
      另外, 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.2. 操作环境

下面是操作此示例所需的环境。

  • Spresense 主板

2.3.3. 代码修改

打开gnss_tracker.ino示例。

gnss tracker1
gnss tracker2

从Arduino IDE的菜单,选择 File → Save as…​ 将示例保存到任何文件夹。复制示例以进行编辑。

gnss tracker5

打开gnss_file.cpp并进行修改。

  • 添加#include <Flash.h>这行

  • 删除 “ SDClass theSD; "这行

  • 替换 " theSD " → " Flash "

    • 更改为使用Flash。由于Flash库具有与SD相同的接口配置,因此只需更改对象名称即可。

    • 参考下面修改的示例。

      gnss tracker7

2.3.4. 操作说明

操作过程与 SD 相同。将刚刚编辑的示例写入Spresense板并运行。

2.3.5. GPS 数据验证步骤

有几种方法可以检索存储在Flash内存中的结果。(除了这里介绍的方法外,您还可以使用 Add-on 等通过网络传输文件)。

  • 转存文件方法

    GPS记录器数据存储在Flash中作为文本文件。将内容转储到串行终端,并将显示结果另存为文件。 这是一个非常原始的方法,但快速和容易。

    由于 Arduino IDE 的串行监视器无法将串行显示结果保存到文件中,因此建议使用其他终端(如 TeraTerm 或 minicom)。
    1. 下载示例 nuttx_shell

      写入并运行草图时,串行终端将显示" NuttShell nsh> "提示。

    2. 使用命令 ls 查看Flash中的文件列表。

      nsh> ls -l /mnt/spif
      gnss tracker8
    3. 使用 cat 命令显示目标日志文件。 将日志结果设置为在运行命令之前保存到文件中。

      nsh> cat /mnt/spif/00000003.txt
      gnss tracker9

      能够搜索GPS记录器数据。
      如果不再需要Flash中的文件,可以使用 rm 命令将其删除。

      nsh> rm /mnt/spif/00000003.txt
  • Flash → microSD 复制方法

    如果有扩展板,则可以使用扩展板从Flash复制到microSD并检索文件

    1. 而且使用示例 nuttx_shell

      写入并运行示例时,串行终端将显示" NuttShell nsh> " 提示。

    2. ls 命令查看Flash上的文件列表。

      nsh> ls -l /mnt/spif
      gnss tracker8
    3. cp 命令复制目标日志文件到microSD。

      nsh> cp /mnt/spif/00000003.txt /mnt/sd0
      gnss trackerA

      通过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.1. 简介

将GPS接收器中常用的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(1000)) {
    /* Get NavData. */
    Gnss.getNavData(&NavData);

    /* Output NMEA */
    Gnss.getPositionData(PositionData);
    NMEA_Output(&(((GnssPositionData*)PositionData)->Data));
  }
}
1 可以通过NMEA_SetMask()函数输出NMEA语句。 例如,如果仅输出 GGA 或 GSA,请指定 0x5。 有关 NMEA 掩码值的详细信息,请参阅下文。

运行此示例时,NMEA数据将输出到串行监视器。

gnss nmea log

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端口并启动它。

gnss nmea monitor com ja

除了纬度和经度信息之外,您还可以看到许多信息,如海拔和天空图,如下所示。

gnss nmea monitor ja

2.6. GPS 移动时钟

2.6.1. 简介

在RTC库的Examples下,应用移动示例rtc_gnss.ino。
本示例将来自GNSS的时间信息设置为内置Spresense 的RTC(实时时钟)。

2.6.2. 操作环境

下面是操作此草图所需的环境。
主板上装有GPS芯片天线,只需主板即可移动GPS功能。

  • Spresense 主板

2.6.3. 操作说明

在Arduino IDE, 选择菜单 File → Examples → RTC → rtc_gnss

rtc gnss1
rtc gnss2

将此示例写入Spresense板。

rtc gnss3

打开串行监视器时,打印时间信息。

rtc gnss4

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.1. 概要

根据GNSS库中的示例gnss.ino来输出1PPS信号。 1PPS是根据卫星获取的时间来准确输出1秒周期信号。

2.7.2. 运行环境

操作此示例所需的环境如下所示。
在主板上安装GPS芯片天线。 1PPS信号从扩展板的D02引脚输出。

  • Spresense 主板

  • Spresense 扩展板

2.7.3. 操作步骤

有关操作步骤は、请参照GPS 示例草图

2.7.4. 程序说明

  /* Start 1PSS output to PIN_D02 */
  Gnss.start1PPS(); (1)
1 在gnss.ino示例的setup()函数中将注释掉的start1PPS()函数生效。 在获取GPS时间的同时,将开始向PIN_D02引脚输出1PPS信号。

3. Camera 教程

3.1. Camera 简单示例

3.1.1. 简介

将使用Spresense相机拍摄的JPEG图像保存到microSD卡。

像延时相机一样,大约每秒钟关闭一次快门,并拍摄100张JPEG图像的照片。

3.1.2. 操作环境

  • Spresense主板和扩展板

  • Spresense相机板

  • microSD卡

将Spresense主板连接到相机板,请参考 如何连接Spresense 主板和Spresense 相机板

相机功能无需扩展板即可工作,但此示例使用扩展板将相机拍摄的照片保存到microSD卡。

3.1.3. 操作说明

  1. 将卡插入扩展板上的microSD卡插槽。

  2. 在Arduino IDE中,选择菜单 File → Examples for Spresense Camera → camera

    arduino camera examples1
    arduino camera examples2
  3. Tools → Serioal Port 中选择Spresense COM端口以写入微控制器板。

    arduino camera examples3
  4. 刻录完成后,程序将工作并开始拍照。
    打开串行监视器时,将显示预览图像的日志信息,以及拍摄静止图像时的日志。

    arduino camera examples4
  5. microSD 卡上保存 ”PICT00.JPG" ~ "PICT099.JPG" 文件。
    请尝试从microSD卡中取出JPEG图像。

3.1.4. 程序说明

详细的注释位于开发指南 示例代码说明 示例代码中。

3.2. LCD 上显示 Camera 预览图像

3.2.1. 简介

更改之前的camera示例草图,以便在LCD上显示预览图像。

预览图像的大小为QVGA(320 x 240)。

LCD 使用配备ILI9341的2.2英寸LCD模块。

3.2.2. 操作环境

  • Spresense 主板和扩展板

  • Spresense 相机板

  • microSD 卡

  • LCD 板(ILI9341 2.2 英寸LCD模块)

3.2.2.1. LCD 和扩展板连接

下面是与ILI9341 2.2英寸LCD模块的连接示例。

connect ili9341
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)。

  • RESETDC/RS 引脚使用D8、D9作为GPIO。
    参考 LCDSP001板 也具有相同的引脚分配, 可以按原样使用本教程中的代码。

3.2.2.2. 安装 Adafruit ILI9341 库

演示如何安装Adafruit ILI9341的Arduino库。

  1. 下载下面两个库的zip文件。

  2. 选择Arduino IDE中 Sketch → Include Library → Add .ZIP Library 菜单。

    arduino camera examples5
  3. 使用下载的 zip 文件进行安装。

  4. 如果安装成功,将显示以下消息:
    (请分别安装 Adafruit-GFX-库和 Adafruit_ILI9341)

    arduino camera examples6

3.2.3. 操作顺序

  1. 选择Arduino IDE上 Files → Examples → Examples for Spresense Camera → camera 菜单。

  2. 当编辑示例之后,选择 File → Save AS 来保存示例文件。

  3. 将以下代码添加到草图

    1. 将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 生成对象。
    2. setup()函数中初始化tft。

      void setup(void) {
          :
        tft.begin(40000000); (1)
        tft.setRotation(3);  (2)
          :
      1 使用40 MHz的SPI通信速率初始化tft。
      2 将LCD显示屏旋转270度。
    3. 通过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图像。
  4. Tools → Serial Port 中选择Spresense COM端口以写入微控制器板。

  5. 上传并运行草图后,在拍摄照片时,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示例

自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。

例如, 下图显示了常用代码的存储位置。

diag b936c6b05e866fd235bbb90a0fb0c932
图表 5. MyCounter代码存储位置示例

以上是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));
}

并转换。

4.3. 尝试制造一种新的物理传感器

[T.B.D]

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. 初次使用多核引导示例

主要步骤

  1. 使用Arduino IDE打开示例

  2. 选择核心

  3. 编译和上传

重复任意数量的内核,以便使其正常工作。

请尝试执行以下步骤。

  • 从桌面启动 Arduino IDE
    (如果桌面上没有图标,请从 "开始" 菜单开始。)

    arduino multicore desktop
    在多核编程中启动多个 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 打开示例

      arduino multicore boot0
      arduino multicore boot1 main
    • Main.ino示例描述

      MP.begin(subid) 启动子ID参数指定的子核心。
      在这种情况下,我们将总共启动四个子核心从 SubCore1 到 SubCore4。

      arduino multicore boot4 main
    • 从Arduino IDE菜单中,选择 Tools → Core → MainCore

      arduino multicore boot2 main

      您可以在下面的状态栏中验证是否选择了 MainCore

      arduino multicore boot3 main
      在Arduino IDE 1.8.9切换菜单时,
      有一个状态栏显示不正确的问题。
    • 按下Upload按钮Compile&Upload

      arduino multicore boot5 main
      不能同时从多个窗口上传多个核心程序。
      执行上传操作,以便每个内核避免同时运行。
    • 将显示编译结果日志中使用的内存大小

      MainCore 始终使用768 KByte内存。

      arduino multicore boot6 main

      如果上传成功完成,MainCore编程就完成了。

      • 尝试在缺少SubCore程序的情况下启动串行监视器。
        由于SubCore不存在,您可以看到 MP.begin(1~4) 调用返回时出现错误。

        arduino multicore boot7 serial err

        如果打开了串行监视器,则可能无法从其他窗口正确上传。
        完成验证后,关闭串行监视器。

下面是SubCore编程。

  • SubCore编程

    • 从Arduino IDE菜单 File → Examples → Examples for Spresense → MultiCore MP → Boot → Sub1 打开示例

      arduino multicore boot0
      arduino multicore boot1 sub1
    • Sub1.ino示例说明

      在setup()中调用 MP.begnin() ,通知 MainCore 启动已完成。
      loop()中LED0日志显示由 MPLog() 和闪烁控制。

      arduino multicore boot4 sub1
    • 从Arduino IDE菜单选择 Tools → Core → SubCore 1

      arduino multicore boot2 sub1

      您可以在下面的状态栏中验证是否选择了 SubCore1

      arduino multicore boot3 sub1
      在Arduino IDE 1.8.9中切换菜单时
      有一个状态栏显示不正确的问题。
    • 按下Upload按钮Compile&Upload

      arduino multicore boot5 sub1
      不能同时从多个窗口上载多个核心程序。
      执行上传操作,以便每个内核避免同时运行。
    • 将显示编译结果日志中使用的内存大小

      您可以看到,此处使用的子酷示例草图使用128 KByte 内存。
      此大小取决于用户程序,并增加或减少。

      arduino multicore boot6 sub1

      如果上传成功完成,SubCore1的编程就完成了

  • 在SubCore2、3、4 的相同过程中,请执行Compile & Upload

    • 打开Sub2示例并选择SubCore 2,Compile & Upload

    • 打开Sub3示例并选择SubCore 3,Compile & Upload

    • 打开Sub4示例并选择SubCore 4,Compile & Upload

  • 动作检查

    • Spresense主板闪光灯上的四个绿色LEDS

    • 当您打开串行监视器时,您将看到来自每个内核的日志输出。

      arduino multicore boot7 serial
  • 总结

    • 一个简单的示例用于解释如何启动SubCore。
      将现有草图移植到多核环境时,添加对 MP.begin() 的调用。

    • 在多核环境中,基本用法,如 Arduino IDE 的Compile & Upload方法,并没有变化。 主要区别在于,核心选择菜单已添加到 Tool → Core 中。

6.2. 初次使用多核MessgeHello示例

主要步骤与多核启动示例的步骤相同。
这个示例在MainCore和SubCore(s)中使用常见的草图。

  1. 使用Arduino IDE打开示例(仅一次)

  2. 选择核心

  3. 编译和上传

重复任意数量的内核,以便使其正常工作。 此示例移动所有SubCore(共5个)。

请尝试执行以下步骤。

  • 从桌面启动Arduino IDE
    (如果桌面上没有图标,请从 "开始" 菜单开始。)

    arduino multicore desktop
    在多核编程中启动多个Arduino IDE窗口时,需要考虑一些事项。
    如果从Arduino IDE菜单中点击 File → New 菜单,例如,如果在一个窗口中切换 Core 选择菜单,它将与该设置一起反映在所有窗口中。
    作为一种解决方法,当您为每个 Core 打开多个Arduino IDE窗口时,每次都从桌面上的图标启动Arduino IDE。 通过这样做,菜单设置 (如 Core ) 选择不会链接到每个窗口 可以独立设置。
  • MainCore编程

    • 从Arduino IDE菜单中 File → Examples → MultiCore MP → Messsage → MessageHello 打开示例

      arduino multicore boot0
      arduino multicore hello1
    • MessageHello.ino示例描述

      使用示例中的 #ifdef SUBCORE ~ #else ~ #endif 在主要核心和子核心实现之间切换。

      • MainCore源代码

        setup() 通过 MP.begin(subid) ,将启动五个子核心。
        在setup()最后, MP.RecvTimeout(MP_RECV_POLLING) 将接收设置为轮询模式。
        在loop() 中,MP.Recv() 接收来自各个SubCore的数据包地址,并在数据包printf()中输出消息。

        arduino multicore hello4 main
      • SubCore源代码

        在setup()中,调用 MP.begin() ,通知 MainCore 启动已完成。
        在loop()中,将"Hello"消息存储在数据包中,并使用其地址的 MP.Send() 到MainCore。

        arduino multicore hello4 sub
    • 在Arduino IDE菜单中,选择 Tools → Core → MainCore

      arduino multicore hello2 main

      在下面的状态栏中验证是否选择了 MainCore

      arduino multicore boot3 main
      在Arduino IDE 1.8.9切换菜单时
      有一个状态栏显示不正确的问题。
    • 按下Uplod按钮Compile & Uplod

      arduino multicore hello5 main
      不能同时从多个窗口上载多个核心程序。
      应执行上传操作,以便每个内核避免同时运行。
    • 将显示编译结果日志中使用的内存大小

      MainCore 始终使用768 KByte内存

      arduino multicore boot6 main

      如果上传成功完成,MainCore编程就完成了。

下面是SubCore执行

  • SubCore编程

    • 在Arduino IDE菜单中,选择 Tools → Core → SubCore 1

      arduino multicore hello2 sub1

      在下面的状态栏中验证是否选择了 SubCore 1

      arduino multicore boot3 sub1
      在Arduino IDE 1.8.9切换菜单时
      有一个状态栏显示不正确的问题。
    • 按下Upload按钮Compile & Upload

      arduino multicore hello5 main
      不能同时从多个窗口上载多个核心程序。
      执行上传操作,以便每个内核避免同时运行。
    • 将显示编译结果日志中使用的内存大小

      您可以看到,此处使用的子酷示例草图使用128 KByte内存。
      此大小取决于用户程序,并增加或减少。

      arduino multicore boot6 sub1

      如果上传成功完成,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接收并显示在串行监视器上。

      arduino multicore hello7 serial
  • 总结

    • 讨论了如何使用示例与SubCore进行通信。

    • 由于内存在内核之间共享,因此可以传递地址并与消息进行通信。

    • 多核编程与共同的示例,而不分离每个核心的草图也是可能的。

6.3. 注意事项

  • 有关 MultiCore MP 的详细信息,请参阅 MultiCore MP 程序库 文档。

  • 如果有一个已经上传到Spresense板上的SubCore二进制文件,并且想一次删除它们,Spresense Loader的安装 安装加载程序时,删除所有SubCore二进制文件,然后装载机安装开始。

    arduino multicore remove 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. 操作方法

主要操作步骤如下:

  1. 编译并上传SubCore进行信号处理

  2. 编译并上传MainCor以进行声音采集和应用处理

  3. 运行应用程序

如果首先编译并上传MainCore,它将在启动后调用SubCore,从而导致错误。
如果您已经编译并上传到SubCore,启动MainCore后,将启动已经上传的SubCore程序。
7.1.3.1. SubCore的编译和上传
  1. 在Arduino IDE中选择 File→ Sketch example→ Sketch example for Spresense SignalProcessing→ PeakDetector→ SubFFT 来打开示例历程。

  2. 从Arduino IDE菜单中选择 Tools→ Core→ SubCore1 (` Tools→ Core→ SubCore1`) 。

    在此示例中,选择的SubCore是SubCore1。

通过 Tools→ Serial Port 选择Spresense的COM端口,并写入微机主板。

+ NOTE: SubCore 程序在启动后等待 MainCore 的指令。

现在,SubCore上的准备工作就完成了。

7.1.3.2. MainCore的编译和上传
  1. 通过从Arduino IDE中选择 File→ Sketch example→ Sketch example for Spresense SignalProcessing→ PeakDetector → MainAudio 来打开示例历程。

  2. 从Arduino IDE菜单中选择 Tools→ Core→ MainCore (` Tools→ Core→ MainCore`)

    写入微机板。

如果您选择了用于上传SubCore的串行端口,则无需再次选择它。

现在,在MainCore上进行准备也可以。

7.1.3.3. 运行应用程序
  1. 上传 MainCore 之后,打开 Tools→ Serial Monitor 并启动应用程序。

  2. 启动应用程序时,它将分析从麦克风输入的每个通道的声音频率,并在串行监视器上显示峰值频率。

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 (WindoHamming, "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. 操作方法

主要操作步骤如下:

  1. 编译并上传SubCore进行信号处理

  2. 编译并上传MainCor以进行声音采集和应用处理

  3. 运行应用程序

如果首先编译并上传MainCore,它将在启动后调用SubCore,从而导致错误。
如果您已经编译并上传到SubCore,启动MainCore后,将启动已经上传的SubCore程序。
7.2.3.1. SubCore的编译和上传
  1. 通过从Arduino IDE中选择 File→ Sketch example→ Sketch example for Spresense SignalProcessing→ SoundDetector → SubFFT 来打开示例草图。

  2. 从Arduino IDE菜单中选择 Tools→ Core→ SubCore1 (` Tools→ Core→ SubCore1`) 。

    在此示例中,选择的SubCore是SubCore1。
  3. 通过 Tools→ Serial Port 选择Spresense的COM端口,并写入微机主板。

    SubCore程序在启动后等待MainCore的指令。

现在,在SubCore上的准备工作完成。

7.2.3.2. MainCore的编译和上传
  1. 通过从Arduino IDE中选择 File→ Sketch example→ Sketch example for Spresense SignalProcessing→ SoundDetector→ MainAudio 来打开示例。

  2. 从Arduino IDE菜单中选择 Tools→ Core→ MainCore (` Tools→ Core→ MainCore`)

  3. 写入微机板。

如果您选择了用于上传SubCore的串行端口,则无需再次选择它。

现在,在MainCore上进行准备完成。

7.2.3.3. 运行应用程序
  1. 上传 MainCore 之后,打开 Tools→ Serial Monitor 并启动应用程序。

  2. 启动应用程序时,会对从麦克风输入的每个通道的声音进行频率分析,如果在指定的频率范围内输入了超过指定声功率的声音,则会显示检测和通道号,如 Found channel 0

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 (WindoHamming, "执行通道数", (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. 操作方法

主要操作步骤如下:

  1. 编译并上传SubCore进行信号处理

  2. 编译并上传MainCor以进行声音采集和应用处理

  3. 运行应用程序

如果首先编译并上传MainCore,它将在启动后调用SubCore,从而导致错误。
如果您已经编译并上传到SubCore,启动MainCore后,将启动已经上传的SubCore程序。
7.3.3.1. SubCore的编译和上传
  1. 通过从Arduino IDE中选择 File→ Sketch example→ Sketch example for Spresense SignalProcessing→ VoiceChanger→ SubFFT 来打开示例。

  2. 从Arduino IDE菜单中选择 Tools→ Core→ SubCore1 (` Tools→ Core→ SubCore1`) 。

    在此示例中,选择的SubCore是SubCore1。
  3. 通过 Tools→ Serial Port 选择Spresense的COM端口,并写入微机主板。

    SubCore程序在启动后等待MainCore的指令。

现在,在SubCore上的准备工作完成。

7.3.3.2. MainCore的编译和上传
  1. 通过选择Arduino IDE中的 File→ Sketch example→ Sketch example for Spresense SignalProcessing→ VoiceChanger → MainAudio 来打开示例。

  2. 从Arduino IDE菜单中选择 Tools→ Core→ MainCore (` Tools→ Core→ MainCore`)

    写入微机板。

    如果您选择了用于上传SubCore的串行端口,则无需再次选择它。

现在,在MainCore上的准备工作完成。

7.3.3.3. 运行应用程序
  1. 上传 MainCore 之后,打开 Tools→ Serial Monitor 并启动应用程序。

  2. 启动应用程序时,将通过FFT获得的频域数据处理为从麦克风输入的音频数据,使用iFFT重建音频变化的数据并输出。

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. 操作方法

主要操作步骤如下:

  1. 编译并上传SubCore进行信号处理

  2. 编译并上传MainCor以进行声音采集和应用处理

  3. 运行应用程序

如果首先编译并上传MainCore,它将在启动后调用SubCore,从而导致错误。
如果您已经编译并上传到SubCore, 启动MainCore后,将启动已经上传的SubCore程序。
7.4.3.1. SubCore的编译和上传
  1. 通过从Arduino IDE中选择 File→ Sketch example→ Sketch example for Spresense SignalProcessing→ HighPassSound / LowPassSound→ SubFFT 来打开示例草图。

  2. 从Arduino IDE菜单中选择`Tools→ Core→ SubCore1`(Tools→ Core→ SubCore1)。

    在此示例中,选择的SubCore是SubCore1。
  3. 通过 Tools→ Serial Port 选择Spresense的COM端口,并写入微机主板。

    SubCore 程序在启动后等待 MainCore 的指令。

现在,在SubCore上的准备工作完成。

7.4.3.2. MainCore的编译和上传
  1. 通过从Arduino IDE中选择 File→ Sketch example→ Sketch example for Spresense SignalProcessing→ HighPassSound / LowPassSound → MainAudio 打开示例。

  2. 从Arduino IDE菜单中选择`Tools→ Core→ MainCore(Tools→ Core→ MainCore

    写入微机板。

如果您选择了用于上传SubCore的串行端口,则无需再次选择它。

现在,在MainCore上的准备工作完成。

7.4.3.3. 运行应用程序
  1. 上传 MainCore 之后,打开 Tools→ Serial Monitor 并启动应用程序。

  2. 启动应用程序时,从麦克风输入的音频数据将是经过IIR处理的LPF/HPF的音频数据,并从扬声器输出。

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。