C ++ - Reproduction of a tone generated by a sine wave

Hi everyone, I'm trying to figure out how to reproduce the tone that I created using a sine wave.

Here is my code:

#include <iostream> #include <OpenAL/al.h> #include <OpenAL/alc.h> #include <Math.h> using namespace std; int main (int argc, char * const argv[]) { int number = 0; int i, size; double const Pi=4*atan(1); cout << "Enter number of seconds:" << endl; scanf("%d", &number); size = 44100*number; unsigned char buffer [size]; //buffer array for(i = 0; i < size; i++){ buffer[i] = (char)sin((2*Pi*440)/(44100*i))*127; } return 0; } 

Obviously, this is not doing anything at the moment, since I have no idea how to play the buffer. I do not want to generate a wav file and do not want to download it. I just want to play the buffer I created.

I am currently working on Mac OS X and tried using the OpenAL methods, however I found that alut and alu are no longer part of this, and if I try to use it, it turns out that it all worked. I also tried to enable QAudioOutput, but for some reason it seems to be nowhere on my Mac.

I just need to just reproduce the tone that I created. Does anyone have something they can punish me with?

Thanks heaps !!!

+4
source share
3 answers

I wrote an example for just that. Works well with OpenAL under MacOSX and plays smooth sines. Take a look here: http://ioctl.eu/blog/2011/03/16/openal-sine-synth/

The code is quite short, I think I can add it here for completeness:

 #include <cstdio> #include <cstdlib> #include <cmath> #include <iostream> #include <OpenAL/al.h> #include <OpenAL/alc.h> #define CASE_RETURN(err) case (err): return "##err" const char* al_err_str(ALenum err) { switch(err) { CASE_RETURN(AL_NO_ERROR); CASE_RETURN(AL_INVALID_NAME); CASE_RETURN(AL_INVALID_ENUM); CASE_RETURN(AL_INVALID_VALUE); CASE_RETURN(AL_INVALID_OPERATION); CASE_RETURN(AL_OUT_OF_MEMORY); } return "unknown"; } #undef CASE_RETURN #define __al_check_error(file,line) \ do { \ ALenum err = alGetError(); \ for(; err!=AL_NO_ERROR; err=alGetError()) { \ std::cerr << "AL Error " << al_err_str(err) << " at " << file << ":" << line << std::endl; \ } \ }while(0) #define al_check_error() \ __al_check_error(__FILE__, __LINE__) void init_al() { ALCdevice *dev = NULL; ALCcontext *ctx = NULL; const char *defname = alcGetString(NULL, ALC_DEFAULT_DEVICE_SPECIFIER); std::cout << "Default device: " << defname << std::endl; dev = alcOpenDevice(defname); ctx = alcCreateContext(dev, NULL); alcMakeContextCurrent(ctx); } void exit_al() { ALCdevice *dev = NULL; ALCcontext *ctx = NULL; ctx = alcGetCurrentContext(); dev = alcGetContextsDevice(ctx); alcMakeContextCurrent(NULL); alcDestroyContext(ctx); alcCloseDevice(dev); } int main(int argc, char* argv[]) { /* initialize OpenAL */ init_al(); /* Create buffer to store samples */ ALuint buf; alGenBuffers(1, &buf); al_check_error(); /* Fill buffer with Sine-Wave */ float freq = 440.f; int seconds = 4; unsigned sample_rate = 22050; size_t buf_size = seconds * sample_rate; short *samples; samples = new short[buf_size]; for(int i=0; i<buf_size; ++i) { samples[i] = 32760 * sin( (2.f*float(M_PI)*freq)/sample_rate * i ); } /* Download buffer to OpenAL */ alBufferData(buf, AL_FORMAT_MONO16, samples, buf_size, sample_rate); al_check_error(); /* Set-up sound source and play buffer */ ALuint src = 0; alGenSources(1, &src); alSourcei(src, AL_BUFFER, buf); alSourcePlay(src); /* While sound is playing, sleep */ al_check_error(); sleep(seconds); /* Dealloc OpenAL */ exit_al(); al_check_error(); return 0; } 

Update . I found that OpenAL is too limiting my needs, for example, I have some problems with low-latency playback, as this does not seem to be the main OpenAL domain. Instead, I found a very compelling PortAudio: http://www.portaudio.com/ It supports all major platforms (Mac, Win, Unix / ALSA) and looks very good. There is an example for reproducing a sine, which is much more complicated, but quite simple. Just download the latest version and find a sample sine reproduction in test / patest_sine.c

+9
source

You will need to go through the OS to play sounds. It is not as easy as you think. On OSX, you will need to go through CoreAudio.

A better approach would be to use a wrapper library such as PortAudio (http://www.portaudio.com/), which will make your code more portable and save you part of the template needed to receive sound from your program.

0
source

Try it (this program uses the Z-Transformation Concept , a complete example is available that generates dtmf tones using ALSA and compiled on LINUX here ):

 /* * Cosine Samples Generator * * Autor: Volnei Klehm * Data: 04/01/2014 */ #include <math.h> #include <stdio.h> #define S_FREQ 8000 /*Sample frequency, should be greater thar 2*sineFrequency If using audio output it has to be the same saple frequency Used there*/ const float frequency_in_Hertz = 697; /*set output frequency*/ const float generatorContant1 = cosf(2*M_PI*(frequency_in_Hertz/S_FREQ)); const float generatorContant2 = sinf(2*M_PI*(frequency_in_Hertz/S_FREQ)); float GenerateSignal(){ static float Register[2]={1,0}; static float FeedBack; FeedBack=2*generatorContant1*Register[0]-Register[1]; Register[1]=Register[0]; Register[0]=FeedBack; return (generatorContant2*Register[1]); } int main(void) { /*generate 300 samples*/ for (int NumberOfSamples = 300; NumberOfSamples > 0; NumberOfSamples--) printf("\n%f", GenerateSignal()); return 0; } 
0
source

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


All Articles