diff options
author | Nat <natcl@hotmail.com> | 2007-06-28 19:21:09 (GMT) |
---|---|---|
committer | Nat <natcl@hotmail.com> | 2007-06-28 19:21:09 (GMT) |
commit | 96e2433f750c47eed78413d96115877bcf6d6add (patch) | |
tree | 43cc7befd883e6ec6beaa5c8475c8b576c43f6d3 /Util | |
parent | 881f6fabeb1e93d8df53156c1cdad7aabd919a8e (diff) | |
parent | 25cdff4c6adb135dfdaa020d8f04c24a44d34998 (diff) |
Merge branch 'master' of git+ssh://natcl@dev.laptop.org/git/projects/tamtam
Diffstat (limited to 'Util')
-rw-r--r-- | Util/Clooper/aclient.cpp | 89 | ||||
-rw-r--r-- | Util/Clooper/audio.cpp | 85 | ||||
-rw-r--r-- | Util/Clooper/log.cpp | 35 |
3 files changed, 163 insertions, 46 deletions
diff --git a/Util/Clooper/aclient.cpp b/Util/Clooper/aclient.cpp index 187a65e..52edaa2 100644 --- a/Util/Clooper/aclient.cpp +++ b/Util/Clooper/aclient.cpp @@ -14,13 +14,16 @@ #include <csound/csound.h> #include <alsa/asoundlib.h> +#include "log.cpp" #include "audio.cpp" #define ERROR_HERE if (_debug && (VERBOSE > 0)) fprintf(_debug, "ERROR: %s:%i\n", __FILE__, __LINE__) #define IF_DEBUG(N) if (_debug && (VERBOSE > N)) -int VERBOSE = 2; +#define NEWAUDIO 0 + +int VERBOSE = 3; FILE * _debug = NULL; static double pytime(const struct timeval * tv) @@ -147,7 +150,6 @@ struct SystemStuff SystemStuff() : pcm(NULL), period_size(0), rate(0) { - assert(!"deprecated"); } ~SystemStuff() { @@ -267,7 +269,7 @@ open_error: } if (0 > snd_pcm_prepare(pcm)) { ERROR_HERE; } } - int write(snd_pcm_uframes_t frame_count, float * frame_data) + int writebuf(snd_pcm_uframes_t frame_count, float * frame_data) { if (!pcm) { @@ -524,7 +526,12 @@ struct TamTamSound unsigned int period_per_buffer; int up_ratio; + log_t * ll; +#if NEWAUDIO AlsaStuff * sys_stuff; +#else + SystemStuff * sys_stuff; +#endif TamTamSound(char * orc, snd_pcm_uframes_t period0, unsigned int ppb) : ThreadID(NULL), PERF_STATUS(STOP), csound(NULL), @@ -534,9 +541,15 @@ struct TamTamSound period0(period0), period_per_buffer(ppb), up_ratio(0), + ll( new log_t(_debug, VERBOSE) ), +#if NEWAUDIO sys_stuff(NULL) +#else + sys_stuff(new SystemStuff()) +#endif { - sys_stuff = new AlsaStuff( "default", "default", SND_PCM_FORMAT_FLOAT, 2, csound_frame_rate, period0, 4, stderr); +#if NEWAUDIO + sys_stuff = new AlsaStuff( "default", "default", SND_PCM_FORMAT_FLOAT, 2, csound_frame_rate, period0, 4, ll); if (! sys_stuff->good_to_go ) return; up_ratio = sys_stuff->rate / csound_frame_rate; csound_period_size = (sys_stuff->period_size % up_ratio == 0) @@ -544,6 +557,18 @@ struct TamTamSound : csound_ksmps * 4; delete sys_stuff; sys_stuff=NULL; +#else + 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; + +#endif csound = csoundCreate(NULL); int argc=3; @@ -578,6 +603,8 @@ struct TamTamSound csoundDestroy(csound); } if (_debug && (VERBOSE > 2)) fprintf(_debug, "TamTam aclient destroyed\n"); + if (sys_stuff) delete sys_stuff; + delete ll; } uintptr_t thread_fn() { @@ -590,10 +617,24 @@ struct TamTamSound if (_debug && (VERBOSE > 2)) fprintf(_debug, "INFO: nsamples = %li nframes = %li\n", csound_nsamples, csound_nframes); - sys_stuff = new AlsaStuff( "default", "default", SND_PCM_FORMAT_FLOAT, 2, csound_frame_rate, period0, 4, stderr); - if (!sys_stuff->good_to_go) return 1; +#if NEWAUDIO + sys_stuff = new AlsaStuff( "default", "default", SND_PCM_FORMAT_FLOAT, 2, csound_frame_rate, period0, 4, ll); + if (!sys_stuff->good_to_go) + { + delete sys_stuff; + return 1; + } assert(up_ratio = sys_stuff->rate / csound_frame_rate); +#else + if (0 > sys_stuff->open(csound_frame_rate, 4, period0, period_per_buffer)) + { + IF_DEBUG(0) fprintf(_debug, "ERROR: failed to open alsa device, thread abort\n"); + return 1; + } + + assert(up_ratio = sys_stuff->rate / csound_frame_rate); +#endif float *upbuf = new float[ sys_stuff->period_size * nchannels ]; //2 channels int cbuf_pos = csound_nframes; @@ -603,11 +644,15 @@ struct TamTamSound while (PERF_STATUS == CONTINUE) { - if (sys_stuff->period_size == csound_nframes ) + if ((signed)sys_stuff->period_size == csound_nframes ) { - if (0 > sys_stuff->readbuf((char*)csoundGetInputBuffer(csound))) break; + //if (0 > sys_stuff->readbuf((char*)csoundGetInputBuffer(csound))) break; if (csoundPerformBuffer(csound)) break; +#if NEWAUDIO if (0 > sys_stuff->writebuf((char*)csoundGetOutputBuffer(csound))) break; +#else + if (0 > sys_stuff->writebuf(csound_nframes,csoundGetOutputBuffer(csound))) break; +#endif } else { @@ -630,11 +675,15 @@ struct TamTamSound ++cbuf_pos; } - if (++up_pos == sys_stuff->period_size) break; + if (++up_pos == (signed)sys_stuff->period_size) break; } - if (messed || (up_pos != sys_stuff->period_size)) break; + if (messed || (up_pos != (signed)sys_stuff->period_size)) break; +#if NEWAUDIO if (0 > sys_stuff->writebuf((char*)upbuf)) break; +#else + if (0 > sys_stuff->writebuf(csound_nframes,csoundGetOutputBuffer(csound))) break; +#endif } if (thread_playloop) @@ -644,7 +693,13 @@ struct TamTamSound ++nloops; } +#if NEWAUDIO delete sys_stuff; + sys_stuff = NULL; +#else + sys_stuff->close(1); +#endif + delete [] upbuf; if (_debug && (VERBOSE > 2)) fprintf(_debug, "INFO: returning from performance thread\n"); return 0; } @@ -662,8 +717,10 @@ struct TamTamSound { PERF_STATUS = CONTINUE; ThreadID = csoundCreateThread(csThread, (void*)this); + ll->printf( "INFO(%s:%i) aclient launching performance thread (%p)\n", __FILE__, __LINE__, ThreadID ); return 0; } + ll->printf( "INFO(%s:%i) skipping duplicate request to launch a thread\n", __FILE__, __LINE__ ); return 1; } int stop() @@ -675,10 +732,10 @@ struct TamTamSound if (ThreadID) { PERF_STATUS = STOP; - if (_debug && (VERBOSE > 2)) fprintf(_debug, "INFO: aclient joining performance thread\n"); + ll->printf( "INFO(%s:%i) aclient joining performance thread\n", __FILE__, __LINE__ ); uintptr_t rval = csoundJoinThread(ThreadID); - if (rval) - if (_debug && (VERBOSE > 0)) fprintf(_debug, "WARNING: thread returned %zu\n", rval); + ll->printf( "INFO(%s:%i) ... joined\n", __FILE__, __LINE__ ); + if (rval) ll->printf( "WARNING: thread returned %zu\n", rval); ThreadID = NULL; return 0; } @@ -852,9 +909,15 @@ DECL(sc_initialize) //(char * csd) return NULL; } if ( log_file[0] ) + { _debug = fopen(log_file,"w"); + if (_debug==NULL) fprintf(stderr, "Logging disabled due to error in fopen(%s) \n", log_file); + } else + { _debug = NULL; + fprintf(stderr, "Logging disabled on purpose\n"); + } sc_tt = new TamTamSound(str, period, ppb); atexit(&cleanup); if (sc_tt->good()) diff --git a/Util/Clooper/audio.cpp b/Util/Clooper/audio.cpp index 838bc52..e55cc23 100644 --- a/Util/Clooper/audio.cpp +++ b/Util/Clooper/audio.cpp @@ -47,7 +47,7 @@ struct AlsaStuff int period_size; snd_output_t *output; snd_pcm_t *phandle, *chandle; - FILE * log; + log_t *ll; int frame_bytes; int allow_resample; int streams_linked; @@ -56,7 +56,7 @@ struct AlsaStuff snd_pcm_hw_params_t *p_params, *c_params; snd_pcm_sw_params_t *p_swparams, *c_swparams; - AlsaStuff( const char * pdev, const char * cdev, snd_pcm_format_t fmt, int chnl, int r0, int p0, int upsample_max, FILE * logfile) + AlsaStuff( const char * pdev, const char * cdev, snd_pcm_format_t fmt, int chnl, int r0, int p0, int upsample_max, log_t * ll) : good_to_go(false), pdevice(pdev), cdevice(cdev), @@ -66,7 +66,7 @@ struct AlsaStuff buffer_size(0), period_size(0), phandle(NULL), chandle(NULL), - log(logfile), + ll(ll), frame_bytes((snd_pcm_format_width(format) / 8) * channels), allow_resample(0) { @@ -82,19 +82,19 @@ struct AlsaStuff snd_pcm_sw_params_alloca(&c_swparams); - if ((err = snd_output_stdio_attach(&output, logfile, 0)) < 0) { - fprintf(log, "Output failed: %s\n", snd_strerror(err)); + if ((err = snd_output_stdio_attach(&output, ll->_file, 0)) < 0) { + ll->printf("Output failed: %s\n", snd_strerror(err)); return; } setscheduler(); if ((err = snd_pcm_open(&phandle, pdevice.c_str(), SND_PCM_STREAM_PLAYBACK, 0 )) < 0) { - fprintf(log, "Playback open error: %s\n", snd_strerror(err)); + ll->printf("Playback open error: %s\n", snd_strerror(err)); return; } if ((err = snd_pcm_open(&chandle, cdevice.c_str(), SND_PCM_STREAM_CAPTURE, 0 )) < 0) { - fprintf(log, "Record open error: %s\n", snd_strerror(err)); + ll->printf("Record open error: %s\n", snd_strerror(err)); return; } @@ -108,11 +108,11 @@ struct AlsaStuff // set stream params if ((err = setparams_stream(phandle, pt_params, "playback")) < 0) { - fprintf(log, "Unable to set parameters for playback stream: %s\n", snd_strerror(err)); + ll->printf( "Unable to set parameters for playback stream: %s\n", snd_strerror(err)); continue; } if ((err = setparams_stream(chandle, ct_params, "capture")) < 0) { - fprintf(log, "Unable to set parameters for playback stream: %s\n", snd_strerror(err)); + ll->printf("Unable to set parameters for playback stream: %s\n", snd_strerror(err)); continue; } @@ -127,26 +127,19 @@ struct AlsaStuff continue; } - fprintf(stderr, "%s:%i\n", __FILE__, __LINE__); snd_pcm_hw_params_get_period_size(p_params, &p_psize, NULL); - fprintf(stderr, "\t%i %i\n", (int)p_psize, period_size); if (p_psize < (unsigned int)period_size) continue; - fprintf(stderr, "%s:%i\n", __FILE__, __LINE__); - snd_pcm_hw_params_get_period_size(c_params, &c_psize, NULL); if (c_psize < (unsigned int)period_size) continue; - fprintf(stderr, "%s:%i\n", __FILE__, __LINE__); snd_pcm_hw_params_get_period_time(p_params, &p_time, NULL); snd_pcm_hw_params_get_period_time(c_params, &c_time, NULL); if (p_time != c_time) continue; - fprintf(stderr, "%s:%i\n", __FILE__, __LINE__); snd_pcm_hw_params_get_buffer_size(p_params, &p_size); if (p_psize * 2 < p_size) continue; - fprintf(stderr, "%s:%i\n", __FILE__, __LINE__); snd_pcm_hw_params_get_buffer_size(c_params, &c_size); if (c_psize * 2 < c_size) continue; @@ -163,6 +156,7 @@ struct AlsaStuff if (upsample == upsample_max) return; + ll->printf("Preparing audio devices\n"); if ((err = snd_pcm_prepare(phandle)) < 0) { printf("Prepare playback error: %s\n", snd_strerror(err)); return; @@ -176,24 +170,25 @@ struct AlsaStuff snd_pcm_dump(chandle, output); char * silence = (char*)malloc(period_size * frame_bytes); if (snd_pcm_format_set_silence(format, silence, period_size*channels) < 0) { - fprintf(log, "silence error\n"); + ll->printf( "silence error\n"); } if (writebuf(silence) < 0) { - fprintf(log, "write error\n"); + ll->printf( "write error\n"); good_to_go=false; } if (writebuf(silence) < 0) { - fprintf(log, "write error\n"); + ll->printf( "write error\n"); good_to_go=false; } free(silence); + ll->printf("Starting audio devices\n"); if ((err = snd_pcm_start(chandle)) < 0) { - fprintf(log, "Go capture error: %s\n", snd_strerror(err)); + ll->printf( "Go capture error: %s\n", snd_strerror(err)); good_to_go=false; return; } if ((err = snd_pcm_start(phandle)) < 0) { - fprintf(log, "Go playback error: %s\n", snd_strerror(err)); + ll->printf( "Go playback error: %s\n", snd_strerror(err)); good_to_go=false; return; } @@ -213,28 +208,32 @@ struct AlsaStuff struct sched_param sched_param; if (sched_getparam(0, &sched_param) < 0) { - fprintf(log, "Scheduler getparam failed...\n"); + ll->printf( "Scheduler getparam failed...\n"); return; } sched_param.sched_priority = sched_get_priority_max(SCHED_RR); if (!sched_setscheduler(0, SCHED_RR, &sched_param)) { - fprintf(log, "Scheduler set to Round Robin with priority %i...\n", sched_param.sched_priority); + ll->printf( "Scheduler set to Round Robin with priority %i...\n", sched_param.sched_priority); return; } - fprintf(log, "!!!Scheduler set to Round Robin with priority %i FAILED!!!\n", sched_param.sched_priority); + ll->printf( "!!!Scheduler set to Round Robin with priority %i FAILED!!!\n", sched_param.sched_priority); } long readbuf(char *buf) { + return 0; if (!good_to_go) return -1; long frames = period_size; while( frames ) { - fprintf(stderr, "reading a buf\n"); + ll->printf( "reading %li\n", frames); long r = snd_pcm_readi(chandle, buf, frames); - if (r < 0) return r; + if (r < 0) + { + ll->printf( "error in snd_pcm_readi(): %s\n", snd_strerror(r)); + return r; + } buf += r * frame_bytes; frames -= r; - fprintf(stderr, "... done\n"); } return 0; } @@ -243,14 +242,34 @@ struct AlsaStuff long frames = period_size; if (!good_to_go) return -1; while ( frames ) { - fprintf(stderr, "before a buf\n"); + ll->printf("snd_pcm_writei ! (%li)\n", frames); long r = snd_pcm_writei(phandle, buf, frames); - fprintf(stderr, "after buf\n"); - if ( r == -EAGAIN ) continue; - if ( r < 0 ) return r; - buf += r * frame_bytes; - frames -= r; + if (r == frames) break; + if (r >= 0) + { + ll->printf("snd_pcm_writei wrote only some of the frames! (%li)\n", r); + break; + } + const char * msg = NULL; + snd_pcm_state_t state = snd_pcm_state(phandle); + switch (state) + { + case SND_PCM_STATE_OPEN: msg = "open"; break; + case SND_PCM_STATE_SETUP: msg = "setup"; break; + case SND_PCM_STATE_PREPARED:msg = "prepared"; break; + case SND_PCM_STATE_RUNNING: msg = "running"; break; + case SND_PCM_STATE_XRUN: msg = "xrun"; break; + case SND_PCM_STATE_DRAINING: msg = "draining"; break; + case SND_PCM_STATE_PAUSED: msg = "paused"; break; + case SND_PCM_STATE_SUSPENDED: msg = "suspended"; break; + case SND_PCM_STATE_DISCONNECTED: msg = "disconnected"; break; + } + ll->printf( "WARNING: write failed (%s)\tstate = %s\t\n", snd_strerror (r), msg); + if (0 > snd_pcm_recover(phandle, r, 0)) { ll->printf( "fuck\n"); return r;} + ll->printf( "made it end of recover... looping\n"); + if (0 > snd_pcm_prepare(phandle)) { ll->printf( "fuck\n"); return r;} + ll->printf( "made it end of writebuf... looping\n"); } return 0; } diff --git a/Util/Clooper/log.cpp b/Util/Clooper/log.cpp new file mode 100644 index 0000000..2985fca --- /dev/null +++ b/Util/Clooper/log.cpp @@ -0,0 +1,35 @@ + +#include <stdarg.h> +#include <stdio.h> + +struct log_t +{ + FILE * _file; + int _level; + int _close; + + log_t(const char * logpath, int level = 0) : _file(NULL), _level(level), _close(1) + { + _file = fopen(logpath, "w"); + if (!_file) + { + fprintf(stderr, "Failed to open log file for writing: %s\n", logpath); + } + } + log_t(FILE * file, int level = 0): _file(file), _level(level), _close(0) + { + } + ~log_t() + { + if (_close && _file) fclose(_file); + } + void printf( const char * fmt, ... ) __attribute__(( format (printf, 2,3))) + { + if (!_file) return; + va_list ap; + va_start(ap,fmt); + ::vfprintf(_file, fmt, ap); + va_end(ap); + fflush(_file); + } +}; |