【问题标题】:How to use PC speaker in linux?如何在 Linux 中使用 PC 扬声器?
【发布时间】:2011-05-25 17:35:54
【问题描述】:

如何在 linux 中使用 PC 扬声器进行 c/c++ 编程? 我可以控制哔声的时间和频率吗?

【问题讨论】:

  • 不到 10 美元就能买到声卡。在 PC 扬声器附近,您再也没有生意可做。
  • @Ignacio:如果它已经存在,为什么不使用它?
  • @sheepsimulator:对于简单的任务,有时这更合适。我的房间里有一个无头 SVN 服务器,我将它配置为每次有人提交某事时都会发出哔哔声(这种情况很少见)——这是一个很好的功能。就我而言,我使用了外部命令来发出哔哔声,但在某些情况下,从程序中使用它也可能是一种选择(使用第三方音频库是一种过大的杀伤力)。
  • 两个陷阱:a) 在大多数发行版中默认禁用它,因此您需要使用 sudo modprobe -v pcspkr b) 重新启用它您需要以 root 身份运行它,否则它将因“权限被拒绝”而失败

标签: c++ linux audio


【解决方案1】:

取自here

#include <sys/ioctl.h>
#include <unistd.h>
#include <linux/kd.h>
int main(void)
{
    int freq[] = { /* C   D    E    F    G    A    B    C */
                    523, 587, 659, 698, 784, 880, 988, 1046 };
    int i;

    for (i=0; i<8; i++)
    {
            ioctl(STDOUT_FILENO, KIOCSOUND, 1193180/freq[i]);
            usleep(500000);
    }
    ioctl(STDOUT_FILENO, KIOCSOUND, 0); /*Stop silly sound*/
    return 0;
}

【讨论】:

    【解决方案2】:

    是的,打开一个控制台设备(例如 /dev/console 或 /dev/tty0),然后向它发出 KIOCSOUND ioctl,如 console_ioctl(4) 手册页中所述。

    这很糟糕,而且是特定于 Linux 的,但我认为它回答了你的问题。


    编辑:令人难以置信的是,ALSA 内核中有一个 PC 扬声器驱动程序,它可以让您在 PC 扬声器中播放数字声音。它的音质会很差,但会占用大量 CPU :)

    【讨论】:

      【解决方案3】:

      如果您真的想要这样做,请查看 beep 命令的源代码: http://www.johnath.com/beep/beep.c

      【讨论】:

        【解决方案4】:

        大概如果芯片组中仍然有一个 8253 等效物连接到类似于扬声器的东西,您可以根据数据表寄存器或古老的 PC 指南访问它(我很欣慰地承认我不再有这些信息) 来自内核模块或在以 root 身份调用 ioperm() 之后。

        从前还有一个用于 PC 扬声器的内核 PWM“模拟”音频驱动程序。我相信那是我第一次编译内核。这是在内核模块出现之前的日子,或者至少在它们进入流行发行版之前。

        【讨论】:

        • 在标准内核中实际上有一个设备驱动程序(它可能没有被加载)。为什么不使用它?
        • 是的,如果它可用或可用的话,最好使用它。
        【解决方案5】:

        在我使用 Ubuntu 16.04 的情况下,“ioctl”功能不起作用。

        所以,最后,以下代码在不安装任何额外库的情况下运行良好。

        /* This outputs a tone to the speaker */
        
        #include <alsa/asoundlib.h>
        #include <math.h>
        
        #define RATE 44100 // PCM rate [Hz]
        #define FREQ 440 // Tone frequence [Hz]
        #define DURATION 5 // Tone duration [s]
        
        void info_format(snd_pcm_format_t format);
        
        int main(void)
        {
            snd_pcm_t *handle;
            unsigned char buffer[RATE * DURATION];
        
            for (int i = 0; i < sizeof(buffer); i++)
            {
                buffer[i] = 0xFF * sin(2 * M_PI * FREQ * i / RATE);
            }
        
            snd_pcm_open(&handle, "default", SND_PCM_STREAM_PLAYBACK, 0 /* blocked mode */);
        
            snd_pcm_set_params(handle, SND_PCM_FORMAT_U8, SND_PCM_ACCESS_RW_INTERLEAVED, 1 /* channels */, RATE /* rate [Hz] */, 1 /* soft resample */, 500000 /* latency [us] */);
        
            snd_pcm_writei(handle, buffer, sizeof(buffer));
        
            snd_pcm_close(handle);
        
            return 0;
        }
        

        如果代码的文件名是'beep.c',可以编译如下:

        gcc beep.c -lasound -lm -o beep

        并且可以如下执行:

        ./哔声

        【讨论】:

          猜你喜欢
          • 2012-09-29
          • 2020-05-03
          • 1970-01-01
          • 1970-01-01
          • 2020-06-30
          • 1970-01-01
          • 1970-01-01
          • 2016-04-02
          • 1970-01-01
          相关资源
          最近更新 更多