diff options
author | Gonzalo Odiard <godiard@gmail.com> | 2013-05-02 21:07:23 (GMT) |
---|---|---|
committer | Gonzalo Odiard <godiard@gmail.com> | 2013-05-02 21:07:23 (GMT) |
commit | 9e987a46e1365bdc82a9d8516740f43ce9c32fb9 (patch) | |
tree | 67635703e02edf63e0f701fe094f4930aed0ac4c /common/Util/Clooper/aclient.cpp | |
parent | b1e39bb668516e55128b6c8e3264f4267df0db68 (diff) |
Output to ALSA directly from csound
TamTam sound is crackly on some setups (e.g. XO-1.5 and newer with
dmix running at 48000Hz).
Clooper seems to implement its own ALSA sample rate resampling,
as well as upsampling of the period rate to overcome any differences
in csound period size and ALSA period size. This code is the cause
of the crackles.
Switch to csound's internal ALSA backend, which works well, and does
not have these problems. Tested on XO-1, XO-1.5, XO-1.75 and XO-4.
Signed-off-by: Daniel Drake <dsd@laptop.org>
Diffstat (limited to 'common/Util/Clooper/aclient.cpp')
-rw-r--r-- | common/Util/Clooper/aclient.cpp | 127 |
1 files changed, 13 insertions, 114 deletions
diff --git a/common/Util/Clooper/aclient.cpp b/common/Util/Clooper/aclient.cpp index f238c36..e68b8cb 100644 --- a/common/Util/Clooper/aclient.cpp +++ b/common/Util/Clooper/aclient.cpp @@ -12,20 +12,8 @@ #include <cmath> #include <csound/csound.h> -#include <alsa/asoundlib.h> -static double pytime(const struct timeval * tv) -{ - struct timeval t; - if (!tv) - { - tv = &t; - gettimeofday(&t, NULL); - } - return (double) tv->tv_sec + (double) tv->tv_usec / 1000000.0; -} #include "log.cpp" -#include "audio.cpp" int VERBOSE = 3; @@ -510,52 +498,31 @@ struct TamTamSound MYFLT tick_total; /** the upsampling ratio from csound */ - unsigned int csound_ksmps; - snd_pcm_uframes_t csound_frame_rate; - snd_pcm_uframes_t csound_period_size; - snd_pcm_uframes_t period0; - unsigned int period_per_buffer; //should be 2 - int up_ratio; //if the hardware only supports a small integer multiple of our effective samplerate, do a real-time conversion + int csound_frame_rate; + long csound_period_size; log_t * ll; - SystemStuff * sys_stuff; - TamTamSound(log_t * ll, char * orc, snd_pcm_uframes_t period0, unsigned int ppb, int ksmps, int framerate ) + TamTamSound(log_t * ll, char * orc, int framerate ) : ThreadID(NULL), PERF_STATUS(STOP), csound(NULL), music(), ticks_per_period(0.0), tick_adjustment(0.0), tick_total(0.0), - csound_ksmps(ksmps), //must agree with the orchestra file csound_frame_rate(framerate), //must agree with the orchestra file - period0(period0), - period_per_buffer(ppb), - up_ratio(1), - ll( ll ), - sys_stuff(NULL) + ll( ll ) { - sys_stuff = new SystemStuff(ll); - if (0 > sys_stuff->open(csound_frame_rate, 4, period0, period_per_buffer)) - { - return; - } - sys_stuff->close(0); - up_ratio = sys_stuff->rate / csound_frame_rate; - csound_period_size = (sys_stuff->period_size % up_ratio == 0) - ? sys_stuff->period_size / up_ratio - : csound_ksmps * 4; - csound = csoundCreate(NULL); - int argc=3; + int argc=4; const char **argv = (const char**)malloc(argc*sizeof(char*)); argv[0] = "csound"; argv[1] = "-m0"; - argv[2] = orc; + argv[2] = "-+rtaudio=alsa"; + argv[3] = orc; ll->printf(1, "loading csound orchestra file %s\n", orc); //csoundInitialize(&argc, &argv, 0); csoundPreCompile(csound); - csoundSetHostImplementedAudioIO(csound, 1, csound_period_size); int result = csoundCompile(csound, argc, (char**)argv); if (result) { @@ -563,6 +530,8 @@ struct TamTamSound ll->printf( "ERROR: csoundCompile of orchestra %s failed with code %i\n", orc, result); } free(argv); + csound_period_size = csoundGetOutputBufferSize(csound); + csound_period_size /= 2; /* channels */ setTickDuration(0.05); } ~TamTamSound() @@ -574,7 +543,6 @@ struct TamTamSound csoundDestroy(csound); } ll->printf(2, "TamTamSound destroyed\n"); - if (sys_stuff) delete sys_stuff; delete ll; } bool good() @@ -586,76 +554,10 @@ struct TamTamSound { assert(csound); - const int nchannels = 2; - int nloops = 0; - long int csound_nsamples = csoundGetOutputBufferSize(csound); - long int csound_nframes = csound_nsamples / nchannels; - - ll->printf(2, "INFO: nsamples = %li nframes = %li\n", csound_nsamples, csound_nframes); - - if (0 > sys_stuff->open(csound_frame_rate, 4, period0, period_per_buffer)) - { - ll->printf( "ERROR: failed to open alsa device, thread abort\n"); - return 1; - } - - assert(up_ratio == (signed)(sys_stuff->rate / csound_frame_rate)); - - bool do_upsample = (signed)sys_stuff->period_size != csound_nframes; - short *upbuf = new short[ sys_stuff->period_size * nchannels ]; - int cbuf_pos = csound_nframes; // trigger a call to csoundPerformBuffer immediately - float *cbuf = NULL; - int up_pos = 0; - int ratio_pos = 0; - tick_total = 0.0f; - while (PERF_STATUS == CONTINUE) { - if ( do_upsample ) //fill one period of audio buffer data by 0 or more calls to csound - { - up_pos = 0; - int messed = 0; - short cursample[2]={0,0}; - while(!messed) - { - if (cbuf_pos == csound_nframes) - { - cbuf_pos = 0; - if (csoundPerformBuffer(csound)) { messed = 1;break;} - cbuf = csoundGetOutputBuffer(csound); - cursample[0] = (signed short int) (cbuf[cbuf_pos*2+0] * (1<<15)); - cursample[1] = (signed short int) (cbuf[cbuf_pos*2+1] * (1<<15)); - - } - upbuf[2*up_pos+0] = cursample[0]; - upbuf[2*up_pos+1] = cursample[1]; - if (++ratio_pos == up_ratio) - { - ratio_pos = 0; - ++cbuf_pos; - cursample[0] = (signed short int) (cbuf[cbuf_pos*2+0] * (1<<15)); - cursample[1] = (signed short int) (cbuf[cbuf_pos*2+1] * (1<<15)); - } - - if (++up_pos == (signed)sys_stuff->period_size) break; - } - if (messed || (up_pos != (signed)sys_stuff->period_size)) break; - - if (0 > sys_stuff->writebuf(sys_stuff->period_size, upbuf)) break; - } - else //fill one period of audio directly from csound - { - if (csoundPerformBuffer(csound)) break; - cbuf = csoundGetOutputBuffer(csound); - for (int i = 0; i < csound_nframes * nchannels; ++i) - { - cbuf[i] *= (float) ((1<<15)-100.0f); - upbuf[i] = (signed short int) cbuf[i]; - } - if (0 > sys_stuff->writebuf(csound_nframes,upbuf)) break; - } - + if (csoundPerformBuffer(csound)) break; if (tick_adjustment > - ticks_per_period) { MYFLT tick_inc = ticks_per_period + tick_adjustment; @@ -667,11 +569,8 @@ struct TamTamSound { tick_adjustment += ticks_per_period; } - ++nloops; } - sys_stuff->close(1); - delete [] upbuf; ll->printf(2, "INFO: performance thread returning 0\n"); return 0; } @@ -820,8 +719,8 @@ DECL(sc_initialize) //(char * csd) { char * str; char * log_file; - int period, ppb, ksmps, framerate; - if (!PyArg_ParseTuple(args, "ssiiiii", &str, &log_file, &period, &ppb, &VERBOSE, &ksmps, &framerate )) + int framerate; + if (!PyArg_ParseTuple(args, "ssii", &str, &log_file, &VERBOSE, &framerate )) { return NULL; } @@ -840,7 +739,7 @@ DECL(sc_initialize) //(char * csd) fprintf(stderr, "Logging disabled on purpose\n"); } g_log = new log_t(_debug, VERBOSE); - g_tt = new TamTamSound(g_log, str, period, ppb, ksmps, framerate); + g_tt = new TamTamSound(g_log, str, framerate); g_music = & g_tt->music; atexit(&cleanup); if (g_tt->good()) |