X-Git-Url: https://scm.cri.ensmp.fr/git/Faustine.git/blobdiff_plain/1059e1cc0c2ecfa237406949aa26155b6a5b9154..66f23d4fabf89ad09adbd4dfc15ac6b5b2b7da83:/interpretor/preprocessor/faust-0.9.47mr3/architecture/audio/alsa-dsp.h diff --git a/interpretor/preprocessor/faust-0.9.47mr3/architecture/audio/alsa-dsp.h b/interpretor/preprocessor/faust-0.9.47mr3/architecture/audio/alsa-dsp.h deleted file mode 100644 index e3a4f28..0000000 --- a/interpretor/preprocessor/faust-0.9.47mr3/architecture/audio/alsa-dsp.h +++ /dev/null @@ -1,693 +0,0 @@ -/************************************************************************ - - IMPORTANT NOTE : this file contains two clearly delimited sections : - the ARCHITECTURE section (in two parts) and the USER section. Each section - is governed by its own copyright and license. Please check individually - each section for license and copyright information. -*************************************************************************/ - -/*******************BEGIN ARCHITECTURE SECTION (part 1/2)****************/ - -/************************************************************************ - FAUST Architecture File - Copyright (C) 2003-2011 GRAME, Centre National de Creation Musicale - --------------------------------------------------------------------- - This Architecture section is free software; you can redistribute it - and/or modify it under the terms of the GNU General Public License - as published by the Free Software Foundation; either version 3 of - the License, or (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; If not, see . - - EXCEPTION : As a special exception, you may create a larger work - that contains this FAUST architecture section and distribute - that work under terms of your choice, so long as this FAUST - architecture section is not modified. - - - ************************************************************************ - ************************************************************************/ - -#ifndef __alsa_dsp__ -#define __alsa_dsp__ - -#include -#include -#include -#include - -#include -#include "audio.h" -#include "dsp.h" - -/** -DEFAULT ALSA PARAMETERS CONTROLLED BY ENVIRONMENT VARIABLES - -Some default parameters of Faust's ALSA applications are controlled by the following environment variables : - - FAUST2ALSA_DEVICE = "hw:0" - FAUST2ALSA_FREQUENCY= 44100 - FAUST2ALSA_BUFFER = 1024 - FAUST2ALSA_PERIODS = 2 - -*/ - -using namespace std; - -// handle 32/64 bits int size issues - -#ifdef __x86_64__ - -#define uint32 unsigned int -#define uint64 unsigned long int - -#define int32 int -#define int64 long int - -#else - -#define uint32 unsigned int -#define uint64 unsigned long long int - -#define int32 int -#define int64 long long int -#endif - -// check 32/64 bits issues are correctly handled - -#define check_error(err) if (err) { printf("%s:%d, alsa error %d : %s\n", __FILE__, __LINE__, err, snd_strerror(err)); exit(1); } -#define check_error_msg(err,msg) if (err) { fprintf(stderr, "%s:%d, %s : %s(%d)\n", __FILE__, __LINE__, msg, snd_strerror(err), err); exit(1); } -#define display_error_msg(err,msg) if (err) { fprintf(stderr, "%s:%d, %s : %s(%d)\n", __FILE__, __LINE__, msg, snd_strerror(err), err); } - -#define max(x,y) (((x)>(y)) ? (x) : (y)) -#define min(x,y) (((x)<(y)) ? (x) : (y)) - -/** - * Used to set the priority and scheduling of the audi#include - #include -o thread - */ -static bool setRealtimePriority () -{ - struct passwd * pw; - int err; - uid_t uid; - struct sched_param param; - - uid = getuid (); - pw = getpwnam ("root"); - setuid (pw->pw_uid); - param.sched_priority = 50; /* 0 to 99 */ - err = sched_setscheduler(0, SCHED_RR, ¶m); - setuid (uid); - return (err != -1); -} - -/****************************************************************************** -******************************************************************************* - - AUDIO INTERFACE - -******************************************************************************* -*******************************************************************************/ - -enum { kRead = 1, kWrite = 2, kReadWrite = 3 }; - -/** - * A convenient class to pass parameters to AudioInterface - */ -class AudioParam -{ - public: - - const char* fCardName; - unsigned int fFrequency; - unsigned int fBuffering; - unsigned int fPeriods; - - unsigned int fSoftInputs; - unsigned int fSoftOutputs; - - public : - AudioParam() : - fCardName("hw:0"), - fFrequency(44100), - fBuffering(512), - fPeriods(2), - fSoftInputs(2), - fSoftOutputs(2) - {} - - AudioParam& cardName(const char* n) { fCardName = n; return *this; } - AudioParam& frequency(int f) { fFrequency = f; return *this; } - AudioParam& buffering(int fpb) { fBuffering = fpb; return *this; } - AudioParam& periods(int p) { fPeriods = p; return *this; } - AudioParam& inputs(int n) { fSoftInputs = n; return *this; } - AudioParam& outputs(int n) { fSoftOutputs = n; return *this; } -}; - -/** - * An ALSA audio interface - */ -class AudioInterface : public AudioParam -{ - public : - snd_pcm_t* fOutputDevice ; - snd_pcm_t* fInputDevice ; - snd_pcm_hw_params_t* fInputParams; - snd_pcm_hw_params_t* fOutputParams; - - snd_pcm_format_t fSampleFormat; - snd_pcm_access_t fSampleAccess; - - unsigned int fCardInputs; - unsigned int fCardOutputs; - - unsigned int fChanInputs; - unsigned int fChanOutputs; - - // interleaved mode audiocard buffers - void* fInputCardBuffer; - void* fOutputCardBuffer; - - // non interleaved mode audiocard buffers - void* fInputCardChannels[256]; - void* fOutputCardChannels[256]; - - // non interleaved mod, floating point software buffers - float* fInputSoftChannels[256]; - float* fOutputSoftChannels[256]; - - public : - - const char* cardName() { return fCardName; } - int frequency() { return fFrequency; } - int buffering() { return fBuffering; } - int periods() { return fPeriods; } - - float** inputSoftChannels() { return fInputSoftChannels; } - float** outputSoftChannels() { return fOutputSoftChannels; } - - - AudioInterface(const AudioParam& ap = AudioParam()) : AudioParam(ap) - { - - fInputDevice = 0; - fOutputDevice = 0; - fInputParams = 0; - fOutputParams = 0; - } - - /** - * Open the audio interface - */ - void open() - { - int err; - - // allocation d'un stream d'entree et d'un stream de sortie - err = snd_pcm_open( &fInputDevice, fCardName, SND_PCM_STREAM_CAPTURE, 0 ); check_error(err) - err = snd_pcm_open( &fOutputDevice, fCardName, SND_PCM_STREAM_PLAYBACK, 0 ); check_error(err) - - // recherche des parametres d'entree - err = snd_pcm_hw_params_malloc ( &fInputParams ); check_error(err); - setAudioParams(fInputDevice, fInputParams); - - // recherche des parametres de sortie - err = snd_pcm_hw_params_malloc ( &fOutputParams ); check_error(err) - setAudioParams(fOutputDevice, fOutputParams); - - // set the number of physical input and output channels close to what we need - fCardInputs = fSoftInputs; - fCardOutputs = fSoftOutputs; - - snd_pcm_hw_params_set_channels_near(fInputDevice, fInputParams, &fCardInputs); - snd_pcm_hw_params_set_channels_near(fOutputDevice, fOutputParams, &fCardOutputs); - - printf("inputs : %u, outputs : %u\n", fCardInputs, fCardOutputs); - - // enregistrement des parametres d'entree-sortie - - err = snd_pcm_hw_params (fInputDevice, fInputParams ); check_error (err); - err = snd_pcm_hw_params (fOutputDevice, fOutputParams ); check_error (err); - - //assert(snd_pcm_hw_params_get_period_size(fInputParams,NULL) == snd_pcm_hw_params_get_period_size(fOutputParams,NULL)); - - // allocation of alsa buffers - if (fSampleAccess == SND_PCM_ACCESS_RW_INTERLEAVED) { - fInputCardBuffer = calloc(interleavedBufferSize(fInputParams), 1); - fOutputCardBuffer = calloc(interleavedBufferSize(fOutputParams), 1); - - } else { - for (unsigned int i = 0; i < fCardInputs; i++) { - fInputCardChannels[i] = calloc(noninterleavedBufferSize(fInputParams), 1); - } - for (unsigned int i = 0; i < fCardOutputs; i++) { - fOutputCardChannels[i] = calloc(noninterleavedBufferSize(fOutputParams), 1); - } - - } - - // allocation of floating point buffers needed by the dsp code - - fChanInputs = max(fSoftInputs, fCardInputs); assert (fChanInputs < 256); - fChanOutputs = max(fSoftOutputs, fCardOutputs); assert (fChanOutputs < 256); - - for (unsigned int i = 0; i < fChanInputs; i++) { - fInputSoftChannels[i] = (float*) calloc (fBuffering, sizeof(float)); - for (unsigned int j = 0; j < fBuffering; j++) { - fInputSoftChannels[i][j] = 0.0; - } - } - - for (unsigned int i = 0; i < fChanOutputs; i++) { - fOutputSoftChannels[i] = (float*) calloc (fBuffering, sizeof(float)); - for (unsigned int j = 0; j < fBuffering; j++) { - fOutputSoftChannels[i][j] = 0.0; - } - } - } - - void setAudioParams(snd_pcm_t* stream, snd_pcm_hw_params_t* params) - { - int err; - - // set params record with initial values - err = snd_pcm_hw_params_any ( stream, params ); - check_error_msg(err, "unable to init parameters") - - // set alsa access mode (and fSampleAccess field) either to non interleaved or interleaved - - err = snd_pcm_hw_params_set_access (stream, params, SND_PCM_ACCESS_RW_NONINTERLEAVED ); - if (err) { - err = snd_pcm_hw_params_set_access (stream, params, SND_PCM_ACCESS_RW_INTERLEAVED ); - check_error_msg(err, "unable to set access mode neither to non-interleaved or to interleaved"); - } - snd_pcm_hw_params_get_access(params, &fSampleAccess); - - - // search for 32-bits or 16-bits format - err = snd_pcm_hw_params_set_format (stream, params, SND_PCM_FORMAT_S32); - if (err) { - err = snd_pcm_hw_params_set_format (stream, params, SND_PCM_FORMAT_S16); - check_error_msg(err, "unable to set format to either 32-bits or 16-bits"); - } - snd_pcm_hw_params_get_format(params, &fSampleFormat); - // set sample frequency - snd_pcm_hw_params_set_rate_near (stream, params, &fFrequency, 0); - - // set period and period size (buffering) - err = snd_pcm_hw_params_set_period_size (stream, params, fBuffering, 0); - check_error_msg(err, "period size not available"); - - err = snd_pcm_hw_params_set_periods (stream, params, fPeriods, 0); - check_error_msg(err, "number of periods not available"); - } - - ssize_t interleavedBufferSize (snd_pcm_hw_params_t* params) - { - _snd_pcm_format format; snd_pcm_hw_params_get_format(params, &format); - snd_pcm_uframes_t psize; snd_pcm_hw_params_get_period_size(params, &psize, NULL); - unsigned int channels; snd_pcm_hw_params_get_channels(params, &channels); - ssize_t bsize = snd_pcm_format_size (format, psize * channels); - return bsize; - } - - ssize_t noninterleavedBufferSize (snd_pcm_hw_params_t* params) - { - _snd_pcm_format format; snd_pcm_hw_params_get_format(params, &format); - snd_pcm_uframes_t psize; snd_pcm_hw_params_get_period_size(params, &psize, NULL); - ssize_t bsize = snd_pcm_format_size (format, psize); - return bsize; - } - - void close() - {} - - /** - * Read audio samples from the audio card. Convert samples to floats and take - * care of interleaved buffers - */ - void read() - { - if (fSampleAccess == SND_PCM_ACCESS_RW_INTERLEAVED) { - - int count = snd_pcm_readi(fInputDevice, fInputCardBuffer, fBuffering); - if (count<0) { - display_error_msg(count, "reading samples"); - int err = snd_pcm_prepare(fInputDevice); - check_error_msg(err, "preparing input stream"); - } - - if (fSampleFormat == SND_PCM_FORMAT_S16) { - - short* buffer16b = (short*) fInputCardBuffer; - for (unsigned int s = 0; s < fBuffering; s++) { - for (unsigned int c = 0; c < fCardInputs; c++) { - fInputSoftChannels[c][s] = float(buffer16b[c + s*fCardInputs])*(1.0/float(SHRT_MAX)); - } - } - - } else if (fSampleFormat == SND_PCM_FORMAT_S32) { - - int32* buffer32b = (int32*) fInputCardBuffer; - for (unsigned int s = 0; s < fBuffering; s++) { - for (unsigned int c = 0; c < fCardInputs; c++) { - fInputSoftChannels[c][s] = float(buffer32b[c + s*fCardInputs])*(1.0/float(INT_MAX)); - } - } - } else { - - printf("unrecognized input sample format : %u\n", fSampleFormat); - exit(1); - } - - } else if (fSampleAccess == SND_PCM_ACCESS_RW_NONINTERLEAVED) { - - int count = snd_pcm_readn(fInputDevice, fInputCardChannels, fBuffering); - if (count<0) { - display_error_msg(count, "reading samples"); - int err = snd_pcm_prepare(fInputDevice); - check_error_msg(err, "preparing input stream"); - } - - if (fSampleFormat == SND_PCM_FORMAT_S16) { - - for (unsigned int c = 0; c < fCardInputs; c++) { - short* chan16b = (short*) fInputCardChannels[c]; - for (unsigned int s = 0; s < fBuffering; s++) { - fInputSoftChannels[c][s] = float(chan16b[s])*(1.0/float(SHRT_MAX)); - } - } - - } else if (fSampleFormat == SND_PCM_FORMAT_S32) { - - for (unsigned int c = 0; c < fCardInputs; c++) { - int32* chan32b = (int32*) fInputCardChannels[c]; - for (unsigned int s = 0; s < fBuffering; s++) { - fInputSoftChannels[c][s] = float(chan32b[s])*(1.0/float(INT_MAX)); - } - } - } else { - - printf("unrecognized input sample format : %u\n", fSampleFormat); - exit(1); - } - - } else { - check_error_msg(-10000, "unknow access mode"); - } - } - - /** - * write the output soft channels to the audio card. Convert sample - * format and interleaves buffers when needed - */ - void write() - { - recovery : - - if (fSampleAccess == SND_PCM_ACCESS_RW_INTERLEAVED) { - - if (fSampleFormat == SND_PCM_FORMAT_S16) { - - short* buffer16b = (short*) fOutputCardBuffer; - for (unsigned int f = 0; f < fBuffering; f++) { - for (unsigned int c = 0; c < fCardOutputs; c++) { - float x = fOutputSoftChannels[c][f]; - buffer16b[c + f*fCardOutputs] = short( max(min(x,1.0),-1.0) * float(SHRT_MAX) ) ; - } - } - - } else if (fSampleFormat == SND_PCM_FORMAT_S32) { - - int32* buffer32b = (int32*) fOutputCardBuffer; - for (unsigned int f = 0; f < fBuffering; f++) { - for (unsigned int c = 0; c < fCardOutputs; c++) { - float x = fOutputSoftChannels[c][f]; - buffer32b[c + f*fCardOutputs] = int( max(min(x,1.0),-1.0) * float(INT_MAX) ) ; - } - } - } else { - - printf("unrecognized output sample format : %u\n", fSampleFormat); - exit(1); - } - - int count = snd_pcm_writei(fOutputDevice, fOutputCardBuffer, fBuffering); - if (count<0) { - display_error_msg(count, "w3"); - int err = snd_pcm_prepare(fOutputDevice); - check_error_msg(err, "preparing output stream"); - goto recovery; - } - - - } else if (fSampleAccess == SND_PCM_ACCESS_RW_NONINTERLEAVED) { - - if (fSampleFormat == SND_PCM_FORMAT_S16) { - - for (unsigned int c = 0; c < fCardOutputs; c++) { - short* chan16b = (short*) fOutputCardChannels[c]; - for (unsigned int f = 0; f < fBuffering; f++) { - float x = fOutputSoftChannels[c][f]; - chan16b[f] = short( max(min(x,1.0),-1.0) * float(SHRT_MAX) ) ; - } - } - - } else if (fSampleFormat == SND_PCM_FORMAT_S32) { - - for (unsigned int c = 0; c < fCardOutputs; c++) { - int32* chan32b = (int32*) fOutputCardChannels[c]; - for (unsigned int f = 0; f < fBuffering; f++) { - float x = fOutputSoftChannels[c][f]; - chan32b[f] = int( max(min(x,1.0),-1.0) * float(INT_MAX) ) ; - } - } - - } else { - - printf("unrecognized output sample format : %u\n", fSampleFormat); - exit(1); - } - - int count = snd_pcm_writen(fOutputDevice, fOutputCardChannels, fBuffering); - if (count<0) { - display_error_msg(count, "w3"); - int err = snd_pcm_prepare(fOutputDevice); - check_error_msg(err, "preparing output stream"); - goto recovery; - } - - } else { - check_error_msg(-10000, "unknow access mode"); - } - } - - /** - * print short information on the audio device - */ - void shortinfo() - { - int err; - snd_ctl_card_info_t* card_info; - snd_ctl_t* ctl_handle; - err = snd_ctl_open (&ctl_handle, fCardName, 0); check_error(err); - snd_ctl_card_info_alloca (&card_info); - err = snd_ctl_card_info(ctl_handle, card_info); check_error(err); - printf("%s|%d|%d|%d|%d|%s\n", - snd_ctl_card_info_get_driver(card_info), - fCardInputs, fCardOutputs, - fFrequency, fBuffering, - snd_pcm_format_name((_snd_pcm_format)fSampleFormat)); - } - - /** - * print more detailled information on the audio device - */ - void longinfo() - { - int err; - snd_ctl_card_info_t* card_info; - snd_ctl_t* ctl_handle; - - printf("Audio Interface Description :\n"); - printf("Sampling Frequency : %d, Sample Format : %s, buffering : %d\n", - fFrequency, snd_pcm_format_name((_snd_pcm_format)fSampleFormat), fBuffering); - printf("Software inputs : %2d, Software outputs : %2d\n", fSoftInputs, fSoftOutputs); - printf("Hardware inputs : %2d, Hardware outputs : %2d\n", fCardInputs, fCardOutputs); - printf("Channel inputs : %2d, Channel outputs : %2d\n", fChanInputs, fChanOutputs); - - // affichage des infos de la carte - err = snd_ctl_open (&ctl_handle, fCardName, 0); check_error(err); - snd_ctl_card_info_alloca (&card_info); - err = snd_ctl_card_info(ctl_handle, card_info); check_error(err); - printCardInfo(card_info); - - // affichage des infos liees aux streams d'entree-sortie - if (fSoftInputs > 0) printHWParams(fInputParams); - if (fSoftOutputs > 0) printHWParams(fOutputParams); - } - - void printCardInfo(snd_ctl_card_info_t* ci) - { - printf("Card info (address : %p)\n", ci); - printf("\tID = %s\n", snd_ctl_card_info_get_id(ci)); - printf("\tDriver = %s\n", snd_ctl_card_info_get_driver(ci)); - printf("\tName = %s\n", snd_ctl_card_info_get_name(ci)); - printf("\tLongName = %s\n", snd_ctl_card_info_get_longname(ci)); - printf("\tMixerName = %s\n", snd_ctl_card_info_get_mixername(ci)); - printf("\tComponents = %s\n", snd_ctl_card_info_get_components(ci)); - printf("--------------\n"); - } - - void printHWParams( snd_pcm_hw_params_t* params ) - { - printf("HW Params info (address : %p)\n", params); -#if 0 - printf("\tChannels = %d\n", snd_pcm_hw_params_get_channels(params)); - printf("\tFormat = %s\n", snd_pcm_format_name((_snd_pcm_format)snd_pcm_hw_params_get_format(params))); - printf("\tAccess = %s\n", snd_pcm_access_name((_snd_pcm_access)snd_pcm_hw_params_get_access(params))); - printf("\tRate = %d\n", snd_pcm_hw_params_get_rate(params, NULL)); - printf("\tPeriods = %d\n", snd_pcm_hw_params_get_periods(params, NULL)); - printf("\tPeriod size = %d\n", (int)snd_pcm_hw_params_get_period_size(params, NULL)); - printf("\tPeriod time = %d\n", snd_pcm_hw_params_get_period_time(params, NULL)); - printf("\tBuffer size = %d\n", (int)snd_pcm_hw_params_get_buffer_size(params)); - printf("\tBuffer time = %d\n", snd_pcm_hw_params_get_buffer_time(params, NULL)); -#endif - printf("--------------\n"); - } - -}; - -// lopt : Scan Command Line long int Arguments -long lopt(int argc, char *argv[], const char* longname, const char* shortname, long def) -{ - for (int i=2; igetNumInputs()) - .outputs(DSP->getNumOutputs())); - } - virtual ~alsaaudio() { stop(); delete fAudio; } - - virtual bool init(const char */*name*/, dsp* DSP) { - AVOIDDENORMALS; - fAudio->open(); - DSP->init(fAudio->frequency()); - return true; - } - - virtual bool start() { - fRunning = true; - if (pthread_create( &fAudioThread, 0, __run, this)) - fRunning = false; - return fRunning; - } - - virtual void stop() { - if (fRunning) { - fRunning = false; - pthread_join (fAudioThread, 0); - } - } - - virtual void run() { - bool rt = setRealtimePriority(); - printf(rt ? "RT : ":"NRT: "); fAudio->shortinfo(); - fAudio->write(); - fAudio->write(); - while(fRunning) { - fAudio->read(); - fDSP->compute(fAudio->buffering(), fAudio->inputSoftChannels(), fAudio->outputSoftChannels()); - fAudio->write(); - } - } -}; - -void* __run (void* ptr) -{ - alsaaudio * alsa = (alsaaudio*)ptr; - alsa->run(); - return 0; -} - -#endif - -/********************END ARCHITECTURE SECTION (part 2/2)****************/ -