How to make sound in C on Linux?

I need a way to play certain musical notes in my C program on Linux. When using windows, it is possible to #include <dos.h> and use direct functions such as sound(note/frequency) , delay(time in ms) , and self-learning nosound() . Is there something parallel in Linux? Thanks

+7
source share
3 answers

I like the advice above regarding libao - I just tried it and it works great. Here's a similar level of difficulty using OpenAL to render audio

 // 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> #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; // incr_freq += incr_freq; // freq *= factor_freq; if (100.0 > freq || freq > 5000.0) { incr_freq *= -1.0f; } } /* 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(); } 

If you want to push OpenAL further ...

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

Out of the box, OpenAL perfectly reproduces the PCM audio buffer ... however, as an exercise, it leaves the ability to play the stream. In this GitHub repository, I wrote an audio server using OpenAL, which implements playback of streaming audio ...

+5
source

Windows uses its own sound architecture, so you can access the sound() routine.

Different Linux machines, depending on the installed packages, may require different approaches. Perhaps the beep utility (from this stackexchange question ) may lead you in the right direction

+1
source

one way

including #include<conio.h> and in the side main () or where you want to use call printing ("\ a")

printf("\a");

Second way

including header file

 #include <windows.h> 

and the calling Beep(500, 500); function Beep(500, 500);

Beep(freq, dur); where freq = signal frequency, which is int and dutation, also int

+1
source

Source: https://habr.com/ru/post/977287/


All Articles