[英]Can't play sound in USB sound card with libasound. (C++)
I'm currently learning to develop using alsa API (libasound). 我目前正在学习使用alsa API(libasound)进行开发。 I want to send PCM sound to my usb sound card. 我想将PCM声音发送到我的USB声卡。
I run this code : 我运行这段代码:
#include <stdio.h>
#include <stdlib.h>
#include <alsa/asoundlib.h>
#include "helloPi.h"
int main(int argc, char *argv[]) {
int i;
int err;
snd_pcm_t *playback_handle;
snd_pcm_hw_params_t *hw_params;
if ((err = snd_pcm_open(&playback_handle, "hw:1,0", SND_PCM_STREAM_PLAYBACK,
0)) < 0) {
fprintf(stderr, "cannot open audio device %s (%s)\n", argv[1],
snd_strerror(err));
exit(1);
}
if ((err = snd_pcm_hw_params_malloc(&hw_params)) < 0) {
fprintf(stderr, "cannot allocate hardware parameter structure (%s)\n",
snd_strerror(err));
exit(1);
}
if ((err = snd_pcm_hw_params_any(playback_handle, hw_params)) < 0){
fprintf(stderr, "cannot initialize hardware parameter structure (%s)\n",
snd_strerror(err));
exit(1);
}
if ((err = snd_pcm_hw_params_set_access(playback_handle, hw_params,
SND_PCM_ACCESS_RW_INTERLEAVED)) < 0) {
fprintf(stderr, "cannot set access type (%s)\n", snd_strerror(err));
exit(1);
}
if ((err = snd_pcm_hw_params_set_format(playback_handle, hw_params,
SND_PCM_FORMAT_S16_LE)) < 0) {
fprintf(stderr, "cannot set sample format (%s)\n", snd_strerror(err));
exit(1);
}
unsigned int freq = 44100;
if ((err = snd_pcm_hw_params_set_rate_near(playback_handle, hw_params,
&freq, 0)) < 0) {
fprintf(stderr, "cannot set sample rate (%s)\n", snd_strerror(err));
exit(1);
}
if ((err = snd_pcm_hw_params_set_channels(playback_handle, hw_params, 2))
< 0) {
fprintf(stderr, "cannot set channel count (%s)\n", snd_strerror(err));
exit(1);
}
if ((err = snd_pcm_hw_params(playback_handle, hw_params)) < 0) {
fprintf(stderr, "cannot set parameters (%s)\n", snd_strerror(err));
exit(1);
}
snd_pcm_hw_params_free(hw_params);
if ((err = snd_pcm_prepare(playback_handle)) < 0) {
fprintf(stderr, "cannot prepare audio interface for use (%s)\n",
snd_strerror(err));
exit(1);
}
for (i = 0; i < 100; ++i) {
if ((err = snd_pcm_writei(playback_handle, buf, 2048)) < 0) {
fprintf(stderr, "write to audio interface failed (%s)\n",
snd_strerror(err));
exit(1);
}
}
snd_pcm_close(playback_handle);
exit(0);
}
Nota : buf is an array declared in HelloPi.h containing a sound wave. 注意: buf是在HelloPi.h中声明的包含声波的数组。
When I use snd_pcm_open(&playback_handle, "hw:1,0", SND_PCM_STREAM_PLAYBACK,0) with hw:0,0 , is work fine with the internal sound card of my laptop. 当我用hw:0,0使用snd_pcm_open(&playback_handle,“hw:1,0”,SND_PCM_STREAM_PLAYBACK,0)时,我的笔记本电脑的内部声卡工作正常。 But, if I use hw:1,0 , to use the usb sound card, nothing happened (not even an error !). 但是,如果我使用hw:1,0 ,使用usb声卡,什么也没发生(甚至没有错误!)。
If I run in a terminal : 如果我在终端中运行:
aplay -l
I have the following result : 我有以下结果:
carte 0: PCH [HDA Intel PCH], périphérique 0: ALC283 Analog [ALC283 Analog]
Sous-périphériques: 1/1
Sous-périphérique #0: subdevice #0
carte 0: PCH [HDA Intel PCH], périphérique 3: HDMI 0 [HDMI 0]
Sous-périphériques: 1/1
Sous-périphérique #0: subdevice #0
carte 1: Set [C-Media USB Headphone Set], périphérique 0: USB Audio [USB Audio]
Sous-périphériques: 1/1
Sous-périphérique #0: subdevice #0
Hello 你好
I know that the usb card is OK because I have sound with : 我知道usb卡是可以的,因为我有声音:
speaker-test -Dhw:1,0 -c2 -twav
I don't know why my code is note producing sound with hw:1,0... 我不知道为什么我的代码是用hw生成声音的注释:1,0 ...
I hope some of you will help me ! 我希望你们中的一些人能帮助我! Thanks, 谢谢,
Maxime. 马克西姆。
I find a solution, I use the code provided in the xample with the asound lib. 我找到了一个解决方案,我使用xample中提供的代码和asound lib。
/*
* This extra small demo sends a random samples to your speakers.
*/
#include <alsa/asoundlib.h>
static char *device = "hw:1,0"; /* playback device */
snd_output_t *output = NULL;
unsigned char buffer[16*1024]; /* some random data */
int main(void)
{
int err;
unsigned int i;
snd_pcm_t *handle;
snd_pcm_sframes_t frames;
for (i = 0; i < sizeof(buffer); i++)
buffer[i] = random() & 0xff;
if ((err = snd_pcm_open(&handle, device, SND_PCM_STREAM_PLAYBACK, 0)) < 0) {
printf("Playback1 open error: %s\n", snd_strerror(err));
exit(EXIT_FAILURE);
}
if ((err = snd_pcm_set_params(handle,
SND_PCM_FORMAT_S16,
SND_PCM_ACCESS_RW_INTERLEAVED,
2,
44100,
0,
50000)) < 0) { /* 0.5sec */
printf("Playback2 open error: %s\n", snd_strerror(err));
exit(EXIT_FAILURE);
}
for (i = 0; i < 16; i++) {
frames = snd_pcm_writei(handle, buffer, sizeof(buffer));
if (frames < 0)
frames = snd_pcm_recover(handle, frames, 0);
if (frames < 0) {
printf("snd_pcm_writei failed: %s\n", snd_strerror(frames));
break;
}
if (frames > 0 && frames < (long)sizeof(buffer))
printf("Short write (expected %li, wrote %li)\n", (long)sizeof(buffer), frames);
}
snd_pcm_close(handle);
return 0;
}
It work but I still have to find out why the first code wasn't good. 它工作,但我仍然需要找出为什么第一个代码不好。
Bye, Maxime. 再见,马克西姆。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.