c++ audio generator wave sine

C++-Reproduce un tono generado a partir de una onda sinusoidal



audio generator (3)

Tendrá que pasar por el sistema operativo para reproducir los sonidos. No es tan sencillo como crees. En OSX, necesitarás pasar por CoreAudio.

Un mejor enfoque sería usar una biblioteca de envoltura como PortAudio (http://www.portaudio.com/) que hará que su código sea más portátil y le ahorrará algunos de los parámetros necesarios para obtener sonido de su programa.

Hola a todos, actualmente estoy tratando de descubrir cómo reproducir un tono que he generado usando una onda sinusoidal.

Aquí está mi código:

#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; }

Obviamente, no hace nada en este momento, ya que no tengo idea de cómo jugar el búfer. No quiero generar un archivo wav, ni quiero cargar uno. Solo quiero reproducir el buffer que he generado.

Actualmente estoy trabajando en Mac OS X, y he intentado usar métodos OpenAL. Sin embargo, he descubierto que alut y alu ya no son parte de él y, si intento usarlo, resulta que está depredado de todos modos. También intenté incluir QAudioOutput, pero por alguna razón no parece estar en ninguna parte de mi Mac.

Solo quiero una reproducción simple del tono que he creado. ¿Alguien tiene algo a lo que puedan dirigirme?

¡¡¡Montones de gracias!!!


He escrito un ejemplo exactamente para esto. Funciona bien con OpenAL bajo MacOSX y reproduce senos suaves. Eche un vistazo aquí: http://ioctl.eu/blog/2011/03/16/openal-sine-synth/

El código es bastante corto, supongo que puedo agregarlo aquí también para completar:

#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; }

Actualización : He descubierto que OpenAL es demasiado limitado para mis necesidades, como que tengo algunos problemas con la reproducción de baja latencia, ya que parece que este no es el dominio principal de OpenAL. En cambio, encontré el muy convincente PortAudio: http://www.portaudio.com/. Admite todas las plataformas principales (Mac, Win, Unix / ALSA) y se ve muy bien. Hay un ejemplo de reproducción sinusoidal que es mucho más sofisticado, pero bastante simple. Solo descarga la última versión y encuentra la muestra de reproducción sinusoidal en test / patest_sine.c


Pruebe esto (este programa utiliza el concepto de transformación Z , un ejemplo completo que genera tonos dtmf usando ALSA y compilable en LINUX están disponibles aquí ):

/* * 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; }