linux - 带有libasound的USB声卡无法播放声音。 (C++)

标签 linux audio alsa soundcard libasound

我目前正在学习使用alsa api(libasound)开发。
我想把pcm声音发送到我的usb声卡。
我运行以下代码:

#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);
  }

注:buf是在hellopi.h中声明的包含声波的数组。
当我使用snd_pcm_open(&playback_handle,“hw:1,0”,snd_pcm_stream_playback,0)和hw:0,0时,可以使用笔记本电脑的内部声卡。但是,如果我使用hw:1,0,使用usb声卡,什么都没有发生(甚至没有错误!)是的。
如果我在终端运行:
aplay -l

我有以下结果:
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

你好
我知道USB卡没问题,因为我有声音:
speaker-test -Dhw:1,0 -c2 -twav

我不知道为什么我的代码是用hw:1,0发出声音的音符…
我希望你们中的一些人能帮助我!
谢谢,
Maxime。

最佳答案

我找到一个解决方案,使用示例中提供的代码和asound库。

/*
 *  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;
}

它可以工作,但我仍然要找出第一个代码不好的原因。
再见,
Maxime。

本文翻译自 https://stackoverflow.com/questions/38672296/

网站遵循 CC BY-SA 4.0 协议,转载或引用请注明出处。


相关文章:

python - 没有密码验证的Sendmail(Python 2.4)

java - android实时获取声音频率?

c++ - 使用ALSA的函数snd_pcm_writei可以立即释放样品缓冲区吗?

java - 如何使用Java和相反的格式将音频文件(mp3文件)转换为二进制文件?

linux - Linux音频应用程序:希望低延迟播放(并停止)

c - ALSA snd_pcm_sw_params_set_stop_threshold()值较低会导致欠载

python - 在Linux openSUSE 13.1中安装主管时出错

linux - 无法使用hdfs dfs命令在hdfs中复制数据

regex - sed命令删除文本,直到找到csv的每一行都匹配

iphone - 您如何反转AVAudioPlayer的播放?