簡體   English   中英

如何在 Linux 上用 C 產生聲音?

[英]How to produce sound in C on Linux?

我需要一種在 Linux 上的 C 程序中播放某些音符的方法。 使用 Windows 時,可以#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 %f\n", 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 sleep\n");

        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 playing\n");

    /* 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 存儲庫中,我使用 OpenAL 編寫了一個音頻服務器,它實現了播放流音頻......享受

Windows 使用自己唯一的聲音架構,因此您可以訪問sound()例程。

不同的 linux 機器,根據安裝的軟件包,可能需要不同的方法。 也許實用程序beep在 stackexchange 上這個問題之外)可以引導您走向正確的方向

單程

包括#include<conio.h>和 side main() 或您想使用 call print("\\a") 的地方

printf("\\a");

第二種方式

包括頭文件

#include <windows.h>

並調用函數Beep(500, 500);

Beep(freq, dur); 其中 freq = 蜂鳴頻率,它是 int 並且也是 int

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM