如何在Linux上用C语言制作声音



我需要一种在Linux上的C程序中播放某些音符的方法。当使用窗口时,可以使用#include <dos.h>并使用直接的函数,如sound(note/frequency)delay(time in ms)和自我解释的nosound()。Linux上有类似的东西吗?感谢

我喜欢上面关于libao的提示-我只是尝试了一下,它运行得很好。这里有一个类似的复杂程度,使用OpenAL合成PCM格式的原始音频缓冲区,然后渲染为音频

// sudo apt-get install libopenal-dev
// gcc -o openal_play_monday   openal_play_monday.c  -lopenal -lm
#include <stdio.h>
#include <stdlib.h>    // gives malloc
#include <math.h>

#ifdef __APPLE__
#include <OpenAL/al.h>
#include <OpenAL/alc.h>
#elif __linux
#include <AL/al.h>
#include <AL/alc.h>
#include <unistd.h>
#endif
ALCdevice  * openal_output_device;
ALCcontext * openal_output_context;
ALuint internal_buffer;
ALuint streaming_source[1];
int al_check_error(const char * given_label) {
    ALenum al_error;
    al_error = alGetError();
    if(AL_NO_ERROR != al_error) {
        printf("ERROR - %s  (%s)n", alGetString(al_error), given_label);
        return al_error;
    }
    return 0;
}
void MM_init_al() {
    const char * defname = alcGetString(NULL, ALC_DEFAULT_DEVICE_SPECIFIER);
    openal_output_device  = alcOpenDevice(defname);
    openal_output_context = alcCreateContext(openal_output_device, NULL);
    alcMakeContextCurrent(openal_output_context);
    // setup buffer and source
    alGenBuffers(1, & internal_buffer);
    al_check_error("failed call to alGenBuffers");
}
void MM_exit_al() {
    ALenum errorCode = 0;
    // Stop the sources
    alSourceStopv(1, & streaming_source[0]);        //      streaming_source
    int ii;
    for (ii = 0; ii < 1; ++ii) {
        alSourcei(streaming_source[ii], AL_BUFFER, 0);
    }
    // Clean-up
    alDeleteSources(1, &streaming_source[0]);
    alDeleteBuffers(16, &streaming_source[0]);
    errorCode = alGetError();
    alcMakeContextCurrent(NULL);
    errorCode = alGetError();
    alcDestroyContext(openal_output_context);
    alcCloseDevice(openal_output_device);
}
void MM_render_one_buffer() {
    /* Fill buffer with Sine-Wave */
    // float freq = 440.f;
    float freq = 100.f;
    float incr_freq = 0.1f;
    int seconds = 4;
    // unsigned sample_rate = 22050;
    unsigned sample_rate = 44100;
    double my_pi = 3.14159;
    size_t buf_size = seconds * sample_rate;
    // allocate PCM audio buffer        
    short * samples = malloc(sizeof(short) * buf_size);
   printf("nhere is freq %fn", freq);
    int i=0;
    for(; i<buf_size; ++i) {
        samples[i] = 32760 * sin( (2.f * my_pi * freq)/sample_rate * i );
        freq += incr_freq;  //  change freq just to make things interesting
        if (100.0 > freq || freq > 5000.0) {
            incr_freq *= -1.0f;  // toggle direction of freq increment
        }
    }
    /* upload buffer to OpenAL */
    alBufferData( internal_buffer, AL_FORMAT_MONO16, samples, buf_size, sample_rate);
    al_check_error("populating alBufferData");
    free(samples);
    /* Set-up sound source and play buffer */
    // ALuint src = 0;
    // alGenSources(1, &src);
    // alSourcei(src, AL_BUFFER, internal_buffer);
    alGenSources(1, & streaming_source[0]);
    alSourcei(streaming_source[0], AL_BUFFER, internal_buffer);
    // alSourcePlay(src);
    alSourcePlay(streaming_source[0]);
    // ---------------------
    ALenum current_playing_state;
    alGetSourcei(streaming_source[0], AL_SOURCE_STATE, & current_playing_state);
    al_check_error("alGetSourcei AL_SOURCE_STATE");
    while (AL_PLAYING == current_playing_state) {
        printf("still playing ... so sleepn");
        sleep(1);   // should use a thread sleep NOT sleep() for a more responsive finish
        alGetSourcei(streaming_source[0], AL_SOURCE_STATE, & current_playing_state);
        al_check_error("alGetSourcei AL_SOURCE_STATE");
    }
    printf("end of playingn");
    /* Dealloc OpenAL */
    MM_exit_al();
}   //  MM_render_one_buffer
int main() {
    MM_init_al();
    MM_render_one_buffer();
}

如果你想进一步推动OpenAL。。。看看这个

https://github.com/scottstensland/render-audio-openal

开箱即用的OpenAL播放PCM音频缓冲区很好。。。然而,它留下了播放流的能力作为练习。在github repo中,我使用OpenAL编写了一个音频服务器,它实现了播放流音频。。。享受

Windows使用自己的唯一声音架构,因此您可以访问sound()例程。

根据安装的软件包,不同的linux机器可能需要不同的方法。也许实用程序beep(在stackexchange上没有这个问题)可以引导您走向正确的方向

单向

包括#include<conio.h>和在side main()或您想使用调用打印("\a")的位置

printf("a");

第二路

包括头文件

#include <windows.h>

和调用函数Beep(500, 500);

Beep(freq, dur);,其中freq=嘟嘟声频率,该频率为int,也为int 中的dutation