Web   ·   Wiki   ·   Activities   ·   Blog   ·   Lists   ·   Chat   ·   Meeting   ·   Bugs   ·   Git   ·   Translate   ·   Archive   ·   People   ·   Donate
summaryrefslogtreecommitdiffstats
path: root/Util/Clooper
diff options
context:
space:
mode:
authorJames <james@mackie.(none)>2007-06-28 19:50:38 (GMT)
committer James <james@mackie.(none)>2007-06-28 19:50:38 (GMT)
commit95307822c2634e4b97c20b8d183340778f6d54a9 (patch)
treea906b1a01e335e1ded015d049e45bd823f3e6607 /Util/Clooper
parent25cdff4c6adb135dfdaa020d8f04c24a44d34998 (diff)
prog
Diffstat (limited to 'Util/Clooper')
-rw-r--r--Util/Clooper/aclient.cpp208
-rw-r--r--Util/Clooper/audio.cpp219
-rw-r--r--Util/Clooper/log.cpp12
3 files changed, 243 insertions, 196 deletions
diff --git a/Util/Clooper/aclient.cpp b/Util/Clooper/aclient.cpp
index 52edaa2..f6d39a7 100644
--- a/Util/Clooper/aclient.cpp
+++ b/Util/Clooper/aclient.cpp
@@ -14,6 +14,16 @@
#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"
@@ -26,16 +36,6 @@
int VERBOSE = 3;
FILE * _debug = NULL;
-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;
-}
struct ev_t
{
@@ -121,187 +121,6 @@ struct ev_t
csoundScoreEvent(csound, type, &param[0], param.size());
}
};
-struct SystemStuff
-{
- static void setscheduler(void)
- {
- struct sched_param sched_param;
-
- if (sched_getparam(0, &sched_param) < 0) {
- printf("Scheduler getparam failed...\n");
- return;
- }
- sched_param.sched_priority = sched_get_priority_max(SCHED_RR);
-
- if (sched_setscheduler(0, SCHED_RR, &sched_param))
- {
- if (_debug && (VERBOSE > 2)) printf("WARNING: Scheduler set to Round Robin with priority %i failed!\n", sched_param.sched_priority);
- }
- else
- {
- if (_debug && (VERBOSE > 2)) printf("INFO: Scheduler set to Round Robin with priority %i.\n", sched_param.sched_priority);
- }
- }
-
- /** the currently opened pcm hande */
- snd_pcm_t * pcm;
- snd_pcm_uframes_t period_size;
- unsigned int rate;
-
- SystemStuff() : pcm(NULL), period_size(0), rate(0)
- {
- }
- ~SystemStuff()
- {
- if (pcm) close(0);
- }
-
- int open(unsigned int rate0, int upsample_max, snd_pcm_uframes_t period0, unsigned int p_per_buff)
- {
- snd_pcm_hw_params_t *hw;
-
- if (pcm)
- {
- IF_DEBUG(0) fprintf(_debug, "ERROR: open called twice! First close the sound device\n");
- return -1;
- }
-
- if ( 0 > snd_pcm_open(&pcm, "default", SND_PCM_STREAM_PLAYBACK, 0)) { ERROR_HERE; return -1; }
- if ( 0 > snd_pcm_hw_params_malloc(&hw)) { ERROR_HERE; snd_pcm_close(pcm); pcm = NULL; return -1; }
-
- //now we can be a bit flexible with the buffer size and the sample-rate...
-
- int upsample;
- for (upsample = 1; upsample < upsample_max; ++upsample)
- {
- rate = rate0 * upsample;
-
- if ( 0 > snd_pcm_hw_params_any(pcm, hw)) { ERROR_HERE; goto open_error;}
-
- //first do the compulsory steps... interleaved float, 2 channel
- if ( 0 > snd_pcm_hw_params_set_rate_resample(pcm, hw, 0)) { ERROR_HERE; goto open_error;}
- if ( 0 > snd_pcm_hw_params_test_access(pcm, hw, SND_PCM_ACCESS_RW_INTERLEAVED)){ ERROR_HERE; goto open_error;}
- if ( 0 > snd_pcm_hw_params_set_access(pcm, hw, SND_PCM_ACCESS_RW_INTERLEAVED)){ ERROR_HERE; goto open_error;}
- if ( 0 > snd_pcm_hw_params_test_format(pcm, hw, SND_PCM_FORMAT_FLOAT)) { ERROR_HERE; goto open_error;}
- if ( 0 > snd_pcm_hw_params_set_format(pcm, hw, SND_PCM_FORMAT_FLOAT)) { ERROR_HERE; goto open_error;}
- if ( 0 > snd_pcm_hw_params_set_channels(pcm, hw, 2)) { ERROR_HERE; goto open_error;}
-
- IF_DEBUG(1) fprintf(_debug, "testing rate : %i\t", rate);
- if ( snd_pcm_hw_params_test_rate(pcm, hw, rate, 0))
- {
- fprintf(_debug, "failed.\n");
- continue;
- }
- else
- {
- IF_DEBUG(1) fprintf(_debug, "success! setting rate : %i\n", rate);
- if (0 > snd_pcm_hw_params_set_rate(pcm, hw, rate, 0)) { ERROR_HERE; goto open_error;}
-
- snd_pcm_uframes_t minb=0, maxb= 0;
- int mind=0, maxd=0;
- snd_pcm_hw_params_get_period_size_min(hw, &minb,&mind);
- snd_pcm_hw_params_get_period_size_max(hw, &maxb,&maxd);
- IF_DEBUG(1) fprintf(_debug, "FYI: period size range is [%li/%i,%li/%i]\n", minb,mind, maxb, maxd);
-
- assert(mind == 0); //rate_resample 0 makes this true right?
- assert(maxd == 0); //rate_resample 0 makes this true right?
-
- if (period0 < minb)
- {
- IF_DEBUG(1) fprintf(_debug, "requested period size (%li) < min (%li), adjusting to min\n", period_size, minb);
- period_size = minb;
- }
- else if (period0 > maxb)
- {
- IF_DEBUG(1) fprintf(_debug, "requested period size (%li) < max (%li), adjusting to min\n", period_size, maxb);
- period_size = maxb;
- }
- else
- {
- period_size = period0;
- }
-
- IF_DEBUG(1) fprintf(_debug, "testing period size : %li\n", period_size);
- if ( 0 > snd_pcm_hw_params_test_period_size(pcm, hw, period_size, 0)){ ERROR_HERE; goto open_error;}
-
-
- IF_DEBUG(1) fprintf(_debug, "setting period size : %li\n", period_size);
- if ( 0 > snd_pcm_hw_params_set_period_size(pcm, hw, period_size, 0)){ ERROR_HERE; goto open_error;}
-
- IF_DEBUG(1) fprintf(_debug, "setting buffer size : %i * %li = %li\n", p_per_buff, period_size, p_per_buff * period_size);
- if ( 0 > snd_pcm_hw_params_set_buffer_size(pcm, hw, p_per_buff*period_size)) { ERROR_HERE; goto open_error;}
-
- break;
- }
- }
-
- if (upsample_max == upsample) { ERROR_HERE; goto open_error; }
-
- if (0 > snd_pcm_hw_params(pcm, hw)) { ERROR_HERE; goto open_error; }
-
- snd_pcm_hw_params_free (hw);
- return 0;
-
-open_error:
- snd_pcm_hw_params_free (hw);
- snd_pcm_close(pcm);
- pcm = NULL;
- return -1;
- }
- void close(int drain = 0)
- {
- if (!pcm)
- {
- IF_DEBUG(2) fprintf(_debug, "WARNING: attempt to close already-closed pcm\n");
- return;
- }
- IF_DEBUG(1) fprintf(_debug, "INFO: closing pcm device\n");
- if (drain) snd_pcm_drain(pcm);
- snd_pcm_close(pcm);
- pcm = NULL;
- }
- void prepare()
- {
- if (!pcm)
- {
- IF_DEBUG(0) fprintf(_debug, "ERROR: attempt to prepare a closed pcm\n");
- return;
- }
- if (0 > snd_pcm_prepare(pcm)) { ERROR_HERE; }
- }
- int writebuf(snd_pcm_uframes_t frame_count, float * frame_data)
- {
- if (!pcm)
- {
- IF_DEBUG(0) fprintf(_debug, "ERROR: attempt to write a closed pcm\n");
- return -1;
- }
- int err;
- err = snd_pcm_writei (pcm, frame_data, frame_count );
- if (err == (signed)frame_count) return 0; //success
-
- assert(err < 0);
-
- const char * msg = NULL;
- snd_pcm_state_t state = snd_pcm_state(pcm);
- 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;
- }
- if (_debug && (VERBOSE > 1)) fprintf (_debug, "WARNING: write failed (%s)\tstate = %s\ttime=%lf\n", snd_strerror (err), msg, pytime(NULL));
- if (0 > snd_pcm_recover(pcm, err, 0)) { ERROR_HERE; return err;}
- if (0 > snd_pcm_prepare(pcm)) { ERROR_HERE; return err;}
- return 1; //warning
- }
-};
struct TamTamSound
{
/** the id of an running sound-rendering thread, or NULL */
@@ -542,11 +361,7 @@ struct TamTamSound
period_per_buffer(ppb),
up_ratio(0),
ll( new log_t(_debug, VERBOSE) ),
-#if NEWAUDIO
sys_stuff(NULL)
-#else
- sys_stuff(new SystemStuff())
-#endif
{
#if NEWAUDIO
sys_stuff = new AlsaStuff( "default", "default", SND_PCM_FORMAT_FLOAT, 2, csound_frame_rate, period0, 4, ll);
@@ -558,6 +373,7 @@ struct TamTamSound
delete sys_stuff;
sys_stuff=NULL;
#else
+ sys_stuff = new SystemStuff(ll);
if (0 > sys_stuff->open(csound_frame_rate, 4, period0, period_per_buffer))
{
return;
@@ -654,7 +470,7 @@ struct TamTamSound
if (0 > sys_stuff->writebuf(csound_nframes,csoundGetOutputBuffer(csound))) break;
#endif
}
- else
+ else //fill one period of audio buffer data by 0 or more calls to csound
{
up_pos = 0;
int messed = 0;
diff --git a/Util/Clooper/audio.cpp b/Util/Clooper/audio.cpp
index e55cc23..0ee6620 100644
--- a/Util/Clooper/audio.cpp
+++ b/Util/Clooper/audio.cpp
@@ -36,6 +36,225 @@
#include <string>
#include <alsa/asoundlib.h>
+#define ERROR_HERE ll->printf("ERROR_HERE: %s %i\n", __FILE__, __LINE__);
+
+struct SystemStuff
+{
+ log_t * ll;
+
+ snd_pcm_t *phandle, *chandle;
+ snd_pcm_uframes_t period_size;
+ unsigned int rate;
+
+ SystemStuff(log_t * ll) : ll(ll), phandle(NULL), chandle(NULL), period_size(0), rate(0)
+ {
+ }
+ ~SystemStuff()
+ {
+ if (phandle) close(0);
+ }
+
+ void setscheduler(void)
+ {
+ struct sched_param sched_param;
+
+ if (sched_getparam(0, &sched_param) < 0) {
+ 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)) {
+ ll->printf( "Scheduler set to Round Robin with priority %i...\n", sched_param.sched_priority);
+ return;
+ }
+ ll->printf( "!!!Scheduler set to Round Robin with priority %i FAILED!!!\n", sched_param.sched_priority);
+ }
+
+ int open(unsigned int rate0, int upsample_max, snd_pcm_uframes_t period0, unsigned int p_per_buff)
+ {
+ snd_pcm_hw_params_t *hw;
+
+ if (phandle)
+ {
+ ll->printf( "ERROR: open called twice! First close the sound device\n");
+ return -1;
+ }
+
+ if ( 0 > snd_pcm_open(&phandle, "default", SND_PCM_STREAM_PLAYBACK, 0)) { ERROR_HERE; return -1; }
+ if ( 0 > snd_pcm_open(&chandle, "default", SND_PCM_STREAM_CAPTURE, 0)) { ERROR_HERE; return -1; }
+ if ( 0 > snd_pcm_hw_params_malloc(&hw)) { ERROR_HERE; snd_pcm_close(phandle); phandle = NULL; return -1; }
+
+ //now we can be a bit flexible with the buffer size and the sample-rate...
+
+ int upsample;
+ for (upsample = 1; upsample < upsample_max; ++upsample)
+ {
+ rate = rate0 * upsample;
+
+ if ( 0 > snd_pcm_hw_params_any(phandle, hw)) { ERROR_HERE; goto open_error;}
+
+ //first do the compulsory steps... interleaved float, 2 channel
+ if ( 0 > snd_pcm_hw_params_set_rate_resample(phandle, hw, 0)) { ERROR_HERE; goto open_error;}
+ if ( 0 > snd_pcm_hw_params_test_access(phandle, hw, SND_PCM_ACCESS_RW_INTERLEAVED)){ ERROR_HERE; goto open_error;}
+ if ( 0 > snd_pcm_hw_params_set_access(phandle, hw, SND_PCM_ACCESS_RW_INTERLEAVED)){ ERROR_HERE; goto open_error;}
+ if ( 0 > snd_pcm_hw_params_test_format(phandle, hw, SND_PCM_FORMAT_FLOAT)) { ERROR_HERE; goto open_error;}
+ if ( 0 > snd_pcm_hw_params_set_format(phandle, hw, SND_PCM_FORMAT_FLOAT)) { ERROR_HERE; goto open_error;}
+ if ( 0 > snd_pcm_hw_params_set_channels(phandle, hw, 2)) { ERROR_HERE; goto open_error;}
+
+ if ( snd_pcm_hw_params_test_rate(phandle, hw, rate, 0))
+ {
+ ll->printf("test_rate failed( %i\n", rate);
+ continue;
+ }
+ else
+ {
+ ll->printf(1, "success! setting rate : %i\n", rate);
+ if (0 > snd_pcm_hw_params_set_rate(phandle, hw, rate, 0)) { ERROR_HERE; goto open_error;}
+
+ snd_pcm_uframes_t minb=0, maxb= 0;
+ int mind=0, maxd=0;
+ snd_pcm_hw_params_get_period_size_min(hw, &minb,&mind);
+ snd_pcm_hw_params_get_period_size_max(hw, &maxb,&maxd);
+ ll->printf(2, "FYI: period size range is [%li/%i,%li/%i]\n", minb,mind, maxb, maxd);
+
+ assert(mind == 0); //rate_resample 0 makes this true right?
+ assert(maxd == 0); //rate_resample 0 makes this true right?
+
+ if (period0 < minb)
+ {
+ ll->printf(1, "requested period size (%li) < min (%li), adjusting to min\n", period_size, minb);
+ period_size = minb;
+ }
+ else if (period0 > maxb)
+ {
+ ll->printf(2, "requested period size (%li) < max (%li), adjusting to min\n", period_size, maxb);
+ period_size = maxb;
+ }
+ else
+ {
+ period_size = period0;
+ }
+
+ ll->printf(1, "testing period size : %li\n", period_size);
+ if ( 0 > snd_pcm_hw_params_test_period_size(phandle, hw, period_size, 0)){ ERROR_HERE; goto open_error;}
+
+
+ ll->printf(1, "setting period size : %li\n", period_size);
+ if ( 0 > snd_pcm_hw_params_set_period_size(phandle, hw, period_size, 0)){ ERROR_HERE; goto open_error;}
+
+ ll->printf(1, "setting buffer size : %i * %li = %li\n", p_per_buff, period_size, p_per_buff * period_size);
+ if ( 0 > snd_pcm_hw_params_set_buffer_size(phandle, hw, p_per_buff*period_size)) { ERROR_HERE; goto open_error;}
+
+ break;
+ }
+ }
+
+ if (upsample_max == upsample) { ERROR_HERE; goto open_error; }
+
+ if (0 > snd_pcm_hw_params(phandle, hw)) { ERROR_HERE; goto open_error; }
+ if (0 > snd_pcm_hw_params(chandle, hw)) { ERROR_HERE; goto open_error; }
+
+ snd_pcm_hw_params_free (hw);
+ return 0;
+
+open_error:
+ snd_pcm_hw_params_free (hw);
+ snd_pcm_close(phandle);
+ phandle = NULL;
+ return -1;
+ }
+ void close(int drain = 0)
+ {
+ if (!phandle)
+ {
+ ll->printf(0, "WARNING: attempt to close already-closed pcm\n");
+ return;
+ }
+ ll->printf(1, "INFO: closing phandle device\n");
+ if (drain) snd_pcm_drain(phandle);
+ snd_pcm_close(phandle);
+ snd_pcm_close(chandle);
+ phandle = NULL;
+ chandle = NULL;
+ }
+ void prepare()
+ {
+ if (!phandle)
+ {
+ ll->printf(0, "ERROR: attempt to prepare a closed pcm\n");
+ return;
+ }
+ if (0 > snd_pcm_prepare(phandle)) { ERROR_HERE; }
+ }
+ int writebuf(snd_pcm_uframes_t frame_count, float * frame_data)
+ {
+ readbuf(frame_count, frame_data);
+ if (!phandle)
+ {
+ ll->printf(0, "ERROR: attempt to write a closed phandle\n");
+ return -1;
+ }
+ int err;
+ err = snd_pcm_writei (phandle, frame_data, frame_count );
+ if (err == (signed)frame_count) return 0; //success
+
+ assert(err < 0);
+
+ 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(1, "WARNING: write failed (%s)\tstate = %s\ttime=%lf\n", snd_strerror (err), msg, pytime(NULL));
+ if (0 > snd_pcm_recover(phandle, err, 0)) { ERROR_HERE; return err;}
+ if (0 > snd_pcm_prepare(phandle)) { ERROR_HERE; return err;}
+ return 1; //warning
+ }
+ int readbuf(snd_pcm_uframes_t frame_count, float * frame_data)
+ {
+ int err;
+ err = snd_pcm_readi (chandle, frame_data, frame_count );
+ if (err < 0)
+ {
+ const char * msg = NULL;
+ snd_pcm_state_t state = snd_pcm_state(chandle);
+ 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(1, "WARNING: write failed (%s)\tstate = %s\ttime=%lf\n", snd_strerror (err), msg, pytime(NULL));
+ if (0 > snd_pcm_recover(chandle, err, 0)) { ERROR_HERE; return err;}
+ if (0 > snd_pcm_prepare(chandle)) { ERROR_HERE; return err;}
+ }
+ float a = 0.0;
+ for (unsigned i = 0; i < frame_count; ++i)
+ {
+ a = a + frame_data[i] * frame_data[i];
+ }
+ fprintf(stderr, "%lf %i\n", a, err);
+ if (err == (signed)frame_count) return 0; //success
+ return -1;
+ }
+};
+#undef ERROR_HERE
+
struct AlsaStuff
{
bool good_to_go;
diff --git a/Util/Clooper/log.cpp b/Util/Clooper/log.cpp
index 2985fca..1749721 100644
--- a/Util/Clooper/log.cpp
+++ b/Util/Clooper/log.cpp
@@ -32,4 +32,16 @@ struct log_t
va_end(ap);
fflush(_file);
}
+ void printf( int level, const char * fmt, ... ) __attribute__(( format (printf, 3,4)))
+ {
+ if (level <= _level)
+ {
+ if (!_file) return;
+ va_list ap;
+ va_start(ap,fmt);
+ ::vfprintf(_file, fmt, ap);
+ va_end(ap);
+ fflush(_file);
+ }
+ }
};