SwerveBot


播放声音

<ol> <li> <p>插入USB声卡,连接扬声器 <img src="https://www.showdoc.com.cn/server/api/attachment/visitFile?sign=9e2889a353f10414d0ad67afae744694" alt="" /></p> </li> <li> <p>检查USB声卡设备</p> <pre><code class="language-bash">lsusb #加入有一条为Bus 001 Device 006: ID 0d8c:0012 C-Media Electronics, Inc. USB Audio Device #Bus 001: USB 总线编号。系统可能有多个 USB 总线(物理端口),Bus 001 表示该设备连接在第一个 USB 总线上 #Device 00x: 该总线上设备的编号。每条 USB 总线上的设备都有一个唯一的编号。这个编号是动态分配的,每次你插入设备时可能会发生变化,系统启动后设备编号也可能不同。 #ID 0d8c:0012中 #0d8c: 设备的 厂商 ID(Vendor ID) #0012: 设备的 产品 ID(Product ID) #C-Media Electronics, Inc. :制造商名称 #USB Audio Device:产品描述</code></pre> <p>正常会显示含有C-Media Electronics, Inc. USB Audio Device信息条目</p> <pre><code class="language-bash">#浏览声卡设备文件 ls /dev/snd #controlC0:内置声卡的控制接口 #pcmC0D0c:内置声卡的捕获设备(麦克风) #pcmC0D0p:内置声卡的播放设备 #controlC1:插入的USB声卡的控制接口 #pcmC1D0p:差人的USB声卡播放设备</code></pre> </li> <li> <p>使用命令行播放声音测试</p> <pre><code>#查看所有音频设备 aplay -l #使用默认设备播放 aplay /usr/share/ibus-table/data/coin9.wav #如果默认播放没有声音,可使用-D指定播放设备,hw:1,0,表示用card 1,device 0播放,与上面aplay -l 命令列表中的信息一致 aplay -D hw:1,0 /usr/share/ibus-table/data/coin9.wav #调节音量 alsamixer</code></pre> </li> <li> <p>使用python播放声音</p> <pre><code class="language-bash">mkdir -p ~/code_test/soundplay_test cd ~/code_test/soundplay_test python3 -m venv venv source ./venv/bin/activate python3 -m pip install soundplay soundfile sudo apt install portaudio19-dev</code></pre> <p>新建一个python测试文件soundplay_test.py,内容如下</p> <pre><code class="language-python">import sounddevice as sd import soundfile as sf # 读取WAV文件 data, samplerate = sf.read('/usr/share/ibus-table/data/coin9.wav') # 播放音频 sd.play(data, samplerate) # 等待播放完成 sd.wait()</code></pre> <pre><code class="language-bash">python soundplay_test.py deactivate</code></pre> </li> <li> <p>使用用C++播放声音</p> <pre><code class="language-bash">#安装依赖库 sudo apt install libasound2-dev libsndfile1-dev</code></pre> <p>新建一个python测试文件soundplay_test.cpp,内容如下</p> <pre><code class="language-cpp">#include &amp;lt;alsa/asoundlib.h&amp;gt; #include &amp;lt;sndfile.h&amp;gt; #include &amp;lt;iostream&amp;gt; int play_wav(const char *filename) { SF_INFO sfinfo; SNDFILE *infile = sf_open(&amp;quot;/tmp/test.wav&amp;quot;, SFM_READ, &amp;amp;sfinfo); if (!infile) { std::cerr &amp;lt;&amp;lt; &amp;quot;Error opening WAV file: &amp;quot; &amp;lt;&amp;lt; sf_strerror(infile) &amp;lt;&amp;lt; std::endl; return -1; } // 检查通道数 if (sfinfo.channels &amp;gt; 2) { std::cerr &amp;lt;&amp;lt; &amp;quot;Only mono and stereo are supported.&amp;quot; &amp;lt;&amp;lt; std::endl; sf_close(infile); return -1; } // 设置 ALSA 参数 snd_pcm_t *pcm_handle; snd_pcm_hw_params_t *params; unsigned int sample_rate = sfinfo.samplerate; int channels = sfinfo.channels; int dir; // 打开 PCM 设备 if (snd_pcm_open(&amp;amp;pcm_handle, &amp;quot;default&amp;quot;, SND_PCM_STREAM_PLAYBACK, 0) &amp;lt; 0) { std::cerr &amp;lt;&amp;lt; &amp;quot;Error opening PCM device &amp;quot; &amp;lt;&amp;lt; &amp;quot;default&amp;quot; &amp;lt;&amp;lt; std::endl; sf_close(infile); return -1; } // 分配参数对象 snd_pcm_hw_params_alloca(&amp;amp;params); // 填充参数对象 snd_pcm_hw_params_any(pcm_handle, params); // 设置访问类型 snd_pcm_hw_params_set_access(pcm_handle, params, SND_PCM_ACCESS_RW_INTERLEAVED); // 设置数据格式 (16位PCM) snd_pcm_hw_params_set_format(pcm_handle, params, SND_PCM_FORMAT_S16_LE); // 设置采样率 snd_pcm_hw_params_set_rate_near(pcm_handle, params, &amp;amp;sample_rate, 0); // 设置通道数 snd_pcm_hw_params_set_channels(pcm_handle, params, channels); // 设置硬件参数 if (snd_pcm_hw_params(pcm_handle, params) &amp;lt; 0) { std::cerr &amp;lt;&amp;lt; &amp;quot;Error setting PCM hardware parameters.&amp;quot; &amp;lt;&amp;lt; std::endl; sf_close(infile); snd_pcm_close(pcm_handle); return -1; } // 获取周期大小 snd_pcm_uframes_t frames; snd_pcm_hw_params_get_period_size(params, &amp;amp;frames, &amp;amp;dir); // 分配缓冲区 int16_t *buffer = new int16_t[frames * channels]; sf_count_t num_frames; // 播放音频 while ((num_frames = sf_readf_short(infile, buffer, frames)) &amp;gt; 0) if (snd_pcm_writei(pcm_handle, buffer, num_frames) &amp;lt; 0) snd_pcm_prepare(pcm_handle); // 清理 delete[] buffer; sf_close(infile); snd_pcm_drain(pcm_handle); snd_pcm_close(pcm_handle); return 0; } int main() { play_wav(&amp;quot;/usr/share/ibus-table/data/coin9.wav&amp;quot;); return 0; } //g++ -o soundplay_test ./soundplay_test.cpp -lasound -lsndfile</code></pre> <p>编译执行</p> <pre><code class="language-bash">#编译 g++ -o soundplay_test ./soundplay_test.cpp -lasound -lsndfile #执行 ./soundplay_test</code></pre> </li> <li> <p>开机提示音 创建开机启动文件</p> <pre><code class="language-bash">sudo vim /etc/systemd/system/startup_sound.service</code></pre> <p>填入下面内容</p> <pre><code class="language-bash">[Unit] Description=Play startup sound After=graphical.target [Service] Type=oneshot ExecStart=/usr/bin/aplay /usr/share/ibus-table/data/coin9.wav RemainAfterExit=true [Install] WantedBy=graphical.target</code></pre> <pre><code class="language-bash">#设为开机启动 sudo systemctl enable startup_sound.service #取消开机启动 sudo systemctl disable startup_sound.service</code></pre> </li> </ol>

页面列表

ITEM_HTML