<div dir="ltr">Thanks Daniel.<div style>Two questions:</div><div style>when was the change done? I mean, what sugar version should we mark as compatible</div><div style>with a activity with this change?</div><div style><br>
</div><div style>The second is, if you already have the binaries compiled for every xo,</div><div style>if you can send me the binaries, I don't need do it again.</div><div style><br></div><div style>Gonzalo</div></div>
<div class="gmail_extra"><br><br><div class="gmail_quote">On Wed, May 1, 2013 at 12:25 PM, Daniel Drake <span dir="ltr"><<a href="mailto:dsd@laptop.org" target="_blank">dsd@laptop.org</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
<div class="im">TamTam sound is crackly on some setups (e.g. XO-1.5 and newer with<br>
dmix running at 48000Hz).<br>
<br>
</div><div class="im">Clooper seems to implement its own ALSA sample rate resampling,<br>
as well as upsampling of the period rate to overcome any differences<br>
in csound period size and ALSA period size. This code is the cause of<br>
the crackles.<br>
<br>
Switch to csound's internal ALSA backend, which works well, and does<br>
not have these problems. Tested on XO-1, XO-1.5, XO-1.75 and XO-4.<br>
---<br>
 common/Config.py                |   5 -<br>
 common/Resources/tamtamorc.csd  |   2 +-<br>
 common/Util/CSoundClient.py     |   4 +-<br>
</div> common/Util/Clooper/Makefile    |   4 +-<br>
 common/Util/Clooper/aclient.cpp | 127 +++------------------<br>
 common/Util/Clooper/audio.cpp   | 237 ----------------------------------------<br>
 6 files changed, 17 insertions(+), 362 deletions(-)<br>
 delete mode 100644 common/Util/Clooper/audio.cpp<br>
<br>
v2: totally remove dependency on ALSA header and library<br>
<div><div class="h5"><br>
diff --git a/common/Config.py b/common/Config.py<br>
index b1c1318..bb9c3ff 100644<br>
--- a/common/Config.py<br>
+++ b/common/Config.py<br>
@@ -55,13 +55,8 @@ for i in (INSTANCE_DIR, DATA_DIR, SNDS_INFO_DIR, TMP_DIR):<br>
 PLUGIN_DEBUG = os.getenv("CSOUND_LOGFILE", "")<br>
 PLUGIN_VERBOSE = DEBUG<br>
 PLUGIN_UNIVORC = join(FILES_DIR, "tamtamorc.csd")<br>
-PLUGIN_KSMPS = 64<br>
 PLUGIN_RATE = 16000<br>
<br>
-## PLUGIN ALSA PARAMETERS:<br>
-PLUGIN_PERIOD = 1024<br>
-PLUGIN_NPERIODS = 2<br>
-<br>
 try:<br>
     from sugar3.graphics.toolbarbox import ToolbarBox, ToolbarButton<br>
     HAVE_TOOLBOX = True<br>
diff --git a/common/Resources/tamtamorc.csd b/common/Resources/tamtamorc.csd<br>
index f0a63f1..3adf81b 100644<br>
--- a/common/Resources/tamtamorc.csd<br>
+++ b/common/Resources/tamtamorc.csd<br>
@@ -1,6 +1,6 @@<br>
 <CsoundSynthesizer><br>
 <CsOptions><br>
--n -m0 -W -s -d<br>
+-n -odac -m0 -W -s -d<br>
 </CsOptions><br>
 <CsInstruments><br>
 sr=16000<br>
diff --git a/common/Util/CSoundClient.py b/common/Util/CSoundClient.py<br>
index 3cf6794..c082137 100644<br>
--- a/common/Util/CSoundClient.py<br>
+++ b/common/Util/CSoundClient.py<br>
@@ -47,9 +47,7 @@ class _CSoundClientPlugin:<br>
<br>
     def __init__(self):<br>
         sc_initialize( Config.PLUGIN_UNIVORC, Config.PLUGIN_DEBUG,<br>
-                Config.PLUGIN_PERIOD, Config.PLUGIN_NPERIODS,<br>
-                Config.PLUGIN_VERBOSE,<br>
-                Config.PLUGIN_KSMPS, Config.PLUGIN_RATE)<br>
+                Config.PLUGIN_VERBOSE, Config.PLUGIN_RATE)<br>
         self.on = False<br>
         #self.masterVolume = 100.0<br>
         self.periods_per_buffer = 2<br>
diff --git a/common/Util/Clooper/Makefile b/common/Util/Clooper/Makefile<br>
</div></div>index 0f28366..4fddb2e 100644<br>
--- a/common/Util/Clooper/Makefile<br>
+++ b/common/Util/Clooper/Makefile<br>
@@ -15,7 +15,7 @@ LIB_NAME = $(CSOUND_ARCH)_$(CSOUND_VERSION)<br>
 CXXFLAGS = $(shell python-config --cflags) \<br>
                   -Wall -Werror -fPIC -O2 -finline<br>
 LDFLAGS+=  $(python-config --libs) \<br>
-                  -lasound -lcsound<br>
+                  -lcsound<br>
<br>
 all : aclient.so<br>
        rm -rf $(LIB_NAME)<br>
<div class="im">@@ -23,7 +23,7 @@ all : aclient.so<br>
        mv aclient.so $(LIB_NAME)/<br>
        touch $(LIB_NAME)/__init__.py<br>
<br>
-aclient.so : aclient.cpp audio.cpp<br>
+aclient.so : aclient.cpp<br>
        g++ $(CXXFLAGS) -shared -o $@ $< $(LDFLAGS)<br>
<br>
 clean :<br>
diff --git a/common/Util/Clooper/aclient.cpp b/common/Util/Clooper/aclient.cpp<br>
</div>index f238c36..e68b8cb 100644<br>
--- a/common/Util/Clooper/aclient.cpp<br>
+++ b/common/Util/Clooper/aclient.cpp<br>
@@ -12,20 +12,8 @@<br>
 #include <cmath><br>
<br>
 #include <csound/csound.h><br>
-#include <alsa/asoundlib.h><br>
<div class="im"><br>
-static double pytime(const struct timeval * tv)<br>
-{<br>
-    struct timeval t;<br>
-    if (!tv)<br>
-    {<br>
-        tv = &t;<br>
-        gettimeofday(&t, NULL);<br>
-    }<br>
-    return (double) tv->tv_sec + (double) tv->tv_usec / 1000000.0;<br>
-}<br>
 #include "log.cpp"<br>
-#include "audio.cpp"<br>
<br>
<br>
 int VERBOSE = 3;<br>
</div>@@ -510,52 +498,31 @@ struct TamTamSound<br>
<div class="im">     MYFLT tick_total;<br>
<br>
     /** the upsampling ratio from csound */<br>
-    unsigned int csound_ksmps;<br>
</div>-    snd_pcm_uframes_t csound_frame_rate;<br>
-    snd_pcm_uframes_t csound_period_size;<br>
<div class="im">-    snd_pcm_uframes_t period0;<br>
-    unsigned int period_per_buffer; //should be 2<br>
-    int up_ratio;  //if the hardware only supports a small integer multiple of our effective samplerate, do a real-time conversion<br>
</div>+    int csound_frame_rate;<br>
+    long csound_period_size;<br>
<div><div class="h5"><br>
     log_t * ll;<br>
-    SystemStuff * sys_stuff;<br>
<br>
-    TamTamSound(log_t * ll, char * orc, snd_pcm_uframes_t period0, unsigned int ppb, int ksmps, int framerate )<br>
+    TamTamSound(log_t * ll, char * orc, int framerate )<br>
         : ThreadID(NULL), PERF_STATUS(STOP), csound(NULL),<br>
         music(),<br>
         ticks_per_period(0.0),<br>
         tick_adjustment(0.0),<br>
         tick_total(0.0),<br>
-        csound_ksmps(ksmps),                    //must agree with the orchestra file<br>
         csound_frame_rate(framerate),           //must agree with the orchestra file<br>
-        period0(period0),<br>
-        period_per_buffer(ppb),<br>
-        up_ratio(1),<br>
-        ll( ll ),<br>
-        sys_stuff(NULL)<br>
+        ll( ll )<br>
     {<br>
-        sys_stuff = new SystemStuff(ll);<br>
-        if (0 > sys_stuff->open(csound_frame_rate, 4, period0, period_per_buffer))<br>
-        {<br>
-            return;<br>
-        }<br>
-        sys_stuff->close(0);<br>
-        up_ratio = sys_stuff->rate / csound_frame_rate;<br>
-        csound_period_size = (sys_stuff->period_size % up_ratio == 0)<br>
-                  ? sys_stuff->period_size / up_ratio<br>
-                  : csound_ksmps * 4;<br>
-<br>
         csound = csoundCreate(NULL);<br>
-        int argc=3;<br>
+        int argc=4;<br>
         const char  **argv = (const char**)malloc(argc*sizeof(char*));<br>
         argv[0] = "csound";<br>
         argv[1] = "-m0";<br>
-        argv[2] = orc;<br>
+        argv[2] = "-+rtaudio=alsa";<br>
+        argv[3] = orc;<br>
<br>
         ll->printf(1,  "loading csound orchestra file %s\n", orc);<br>
         //csoundInitialize(&argc, &argv, 0);<br>
         csoundPreCompile(csound);<br>
-        csoundSetHostImplementedAudioIO(csound, 1, csound_period_size);<br>
         int result = csoundCompile(csound, argc, (char**)argv);<br>
         if (result)<br>
         {<br>
</div></div>@@ -563,6 +530,8 @@ struct TamTamSound<br>
<div class="im">             ll->printf( "ERROR: csoundCompile of orchestra %s failed with code %i\n", orc, result);<br>
         }<br>
         free(argv);<br>
+        csound_period_size = csoundGetOutputBufferSize(csound);<br>
+        csound_period_size /= 2; /* channels */<br>
         setTickDuration(0.05);<br>
     }<br>
     ~TamTamSound()<br>
</div>@@ -574,7 +543,6 @@ struct TamTamSound<br>
<div class="im">             csoundDestroy(csound);<br>
         }<br>
         ll->printf(2, "TamTamSound destroyed\n");<br>
-        if (sys_stuff) delete sys_stuff;<br>
         delete ll;<br>
     }<br>
     bool good()<br>
</div>@@ -586,76 +554,10 @@ struct TamTamSound<br>
<div><div class="h5">     {<br>
         assert(csound);<br>
<br>
-        const int nchannels = 2;<br>
-        int nloops = 0;<br>
-        long int csound_nsamples = csoundGetOutputBufferSize(csound);<br>
-        long int csound_nframes = csound_nsamples / nchannels;<br>
-<br>
-        ll->printf(2, "INFO: nsamples = %li nframes = %li\n", csound_nsamples, csound_nframes);<br>
-<br>
-        if (0 > sys_stuff->open(csound_frame_rate, 4, period0, period_per_buffer))<br>
-        {<br>
-            ll->printf( "ERROR: failed to open alsa device, thread abort\n");<br>
-            return 1;<br>
-        }<br>
-<br>
-        assert(up_ratio == (signed)(sys_stuff->rate / csound_frame_rate));<br>
-<br>
-        bool do_upsample = (signed)sys_stuff->period_size != csound_nframes;<br>
-        short *upbuf = new short[ sys_stuff->period_size * nchannels ];<br>
-        int cbuf_pos = csound_nframes; // trigger a call to csoundPerformBuffer immediately<br>
-        float *cbuf = NULL;<br>
-        int up_pos = 0;<br>
-        int ratio_pos = 0;<br>
-<br>
         tick_total = 0.0f;<br>
-<br>
         while (PERF_STATUS == CONTINUE)<br>
         {<br>
-            if ( do_upsample ) //fill one period of audio buffer data by 0 or more calls to csound<br>
-            {<br>
-                up_pos = 0;<br>
-                int messed = 0;<br>
-                short cursample[2]={0,0};<br>
-                while(!messed)<br>
-                {<br>
-                    if (cbuf_pos == csound_nframes)<br>
-                    {<br>
-                        cbuf_pos = 0;<br>
-                        if (csoundPerformBuffer(csound)) { messed = 1;break;}<br>
-                        cbuf = csoundGetOutputBuffer(csound);<br>
-                       cursample[0] = (signed short int) (cbuf[cbuf_pos*2+0] * (1<<15));<br>
-                       cursample[1] = (signed short int) (cbuf[cbuf_pos*2+1] * (1<<15));<br>
-<br>
-                    }<br>
-                    upbuf[2*up_pos+0] = cursample[0];<br>
-                    upbuf[2*up_pos+1] = cursample[1];<br>
-                    if (++ratio_pos == up_ratio)<br>
-                    {<br>
-                        ratio_pos = 0;<br>
-                        ++cbuf_pos;<br>
-                       cursample[0] = (signed short int) (cbuf[cbuf_pos*2+0] * (1<<15));<br>
-                       cursample[1] = (signed short int) (cbuf[cbuf_pos*2+1] * (1<<15));<br>
-                    }<br>
-<br>
-                    if (++up_pos == (signed)sys_stuff->period_size) break;<br>
-                }<br>
-                if (messed || (up_pos != (signed)sys_stuff->period_size)) break;<br>
-<br>
-                if (0 > sys_stuff->writebuf(sys_stuff->period_size, upbuf)) break;<br>
-            }<br>
-            else               //fill one period of audio directly from csound<br>
-            {<br>
-                if (csoundPerformBuffer(csound)) break;<br>
-                cbuf = csoundGetOutputBuffer(csound);<br>
-                for (int i = 0; i < csound_nframes * nchannels; ++i)<br>
-                {<br>
-                    cbuf[i] *= (float) ((1<<15)-100.0f);<br>
-                    upbuf[i] = (signed short int) cbuf[i];<br>
-                }<br>
-                if (0 > sys_stuff->writebuf(csound_nframes,upbuf)) break;<br>
-            }<br>
-<br>
+            if (csoundPerformBuffer(csound)) break;<br>
             if (tick_adjustment > - ticks_per_period)<br>
             {<br>
                 MYFLT tick_inc = ticks_per_period + tick_adjustment;<br>
</div></div>@@ -667,11 +569,8 @@ struct TamTamSound<br>
<div class="im">             {<br>
                 tick_adjustment += ticks_per_period;<br>
             }<br>
-            ++nloops;<br>
         }<br>
<br>
-        sys_stuff->close(1);<br>
-        delete [] upbuf;<br>
         ll->printf(2, "INFO: performance thread returning 0\n");<br>
         return 0;<br>
     }<br>
</div>@@ -820,8 +719,8 @@ DECL(sc_initialize) //(char * csd)<br>
<div class="im"> {<br>
     char * str;<br>
     char * log_file;<br>
-    int period, ppb, ksmps, framerate;<br>
-    if (!PyArg_ParseTuple(args, "ssiiiii", &str, &log_file, &period, &ppb, &VERBOSE, &ksmps, &framerate ))<br>
+    int framerate;<br>
+    if (!PyArg_ParseTuple(args, "ssii", &str, &log_file, &VERBOSE, &framerate ))<br>
     {<br>
         return NULL;<br>
     }<br>
</div>@@ -840,7 +739,7 @@ DECL(sc_initialize) //(char * csd)<br>
<div class="HOEnZb"><div class="h5">         fprintf(stderr, "Logging disabled on purpose\n");<br>
     }<br>
     g_log = new log_t(_debug, VERBOSE);<br>
-    g_tt = new TamTamSound(g_log, str, period, ppb, ksmps, framerate);<br>
+    g_tt = new TamTamSound(g_log, str, framerate);<br>
     g_music = & g_tt->music;<br>
     atexit(&cleanup);<br>
     if (g_tt->good())<br>
diff --git a/common/Util/Clooper/audio.cpp b/common/Util/Clooper/audio.cpp<br>
deleted file mode 100644<br>
index 6f5a271..0000000<br>
--- a/common/Util/Clooper/audio.cpp<br>
+++ /dev/null<br>
@@ -1,237 +0,0 @@<br>
-#ifndef AUDIO_HXX<br>
-#define AUDIO_HXX<br>
-<br>
-/*<br>
- *  Latency test program<br>
- *<br>
- *     Author: Jaroslav Kysela <<a href="mailto:perex@suse.cz">perex@suse.cz</a>><br>
- *<br>
- *  This small demo program can be used for measuring latency between<br>
- *  capture and playback. This latency is measured from driver (diff when<br>
- *  playback and capture was started). Scheduler is set to SCHED_RR.<br>
- *<br>
- *<br>
- *   This program is free software; you can redistribute it and/or modify<br>
- *   it under the terms of the GNU General Public License as published by<br>
- *   the Free Software Foundation; either version 2 of the License, or<br>
- *   (at your option) any later version.<br>
- *<br>
- *   This program is distributed in the hope that it will be useful,<br>
- *   but WITHOUT ANY WARRANTY; without even the implied warranty of<br>
- *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the<br>
- *   GNU General Public License for more details.<br>
- *<br>
- *   You should have received a copy of the GNU General Public License<br>
- *   along with this program; if not, write to the Free Software<br>
- *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA<br>
- *<br>
- */<br>
-<br>
-#include <stdio.h><br>
-#include <stdlib.h><br>
-#include <string.h><br>
-#include <sched.h><br>
-#include <errno.h><br>
-#include <getopt.h><br>
-#include <sys/time.h><br>
-#include <math.h><br>
-<br>
-#include <string><br>
-#include <alsa/asoundlib.h><br>
-<br>
-#define ERROR_HERE ll->printf("ERROR_HERE: %s %i\n", __FILE__, __LINE__)<br>
-<br>
-struct SystemStuff<br>
-{<br>
-    log_t * ll;<br>
-<br>
-    snd_pcm_t *phandle;<br>
-    snd_pcm_uframes_t period_size;<br>
-    unsigned int      rate;<br>
-    const snd_pcm_format_t sample_format;<br>
-    SystemStuff(log_t * ll) : ll(ll), phandle(NULL), period_size(0), rate(0), sample_format(SND_PCM_FORMAT_S16)<br>
-    {<br>
-    }<br>
-    ~SystemStuff()<br>
-    {<br>
-        if (phandle) close(0);<br>
-    }<br>
-<br>
-    void setscheduler(void)<br>
-    {<br>
-        struct sched_param sched_param;<br>
-<br>
-        if (sched_getparam(0, &sched_param) < 0) {<br>
-                ll->printf( "Scheduler getparam failed...\n");<br>
-                return;<br>
-        }<br>
-        sched_param.sched_priority = sched_get_priority_max(SCHED_RR);<br>
-        if (!sched_setscheduler(0, SCHED_RR, &sched_param)) {<br>
-            ll->printf( "Scheduler set to Round Robin with priority %i...\n", sched_param.sched_priority);<br>
-            return;<br>
-        }<br>
-        ll->printf( "!!!Scheduler set to Round Robin with priority %i FAILED!!!\n", sched_param.sched_priority);<br>
-    }<br>
-<br>
-    int open(unsigned int rate0, int upsample_max, snd_pcm_uframes_t period0, unsigned int p_per_buff)<br>
-    {<br>
-        snd_pcm_hw_params_t *hw;<br>
-<br>
-        if (phandle)<br>
-        {<br>
-            ll->printf( "ERROR: open called twice! First close the sound device\n");<br>
-            return -1;<br>
-        }<br>
-<br>
-        if ( 0 > snd_pcm_open(&phandle, "default", SND_PCM_STREAM_PLAYBACK, 0)) { ERROR_HERE; return -1; }<br>
-        if ( 0 > snd_pcm_hw_params_malloc(&hw))                                 { ERROR_HERE; snd_pcm_close(phandle); phandle = NULL; return -1; }<br>
-<br>
-        //now we can be a bit flexible with the buffer size and the sample-rate...<br>
-<br>
-        int upsample;<br>
-        for (upsample = 1; upsample < upsample_max; ++upsample)<br>
-        {<br>
-            rate = rate0 * upsample;<br>
-<br>
-            if ( 0 > snd_pcm_hw_params_any(phandle, hw))                               { ERROR_HERE; goto open_error;}<br>
-<br>
-            //first do the compulsory steps... interleaved float, 2 channel<br>
-            if ( 0 > snd_pcm_hw_params_set_rate_resample(phandle, hw, 0))              { ERROR_HERE; goto open_error;}<br>
-            if ( 0 > snd_pcm_hw_params_test_access(phandle, hw, SND_PCM_ACCESS_RW_INTERLEAVED)){ ERROR_HERE; goto open_error;}<br>
-            if ( 0 > snd_pcm_hw_params_set_access(phandle, hw, SND_PCM_ACCESS_RW_INTERLEAVED)){ ERROR_HERE; goto open_error;}<br>
-            if ( 0 > snd_pcm_hw_params_test_format(phandle, hw, sample_format)) { ERROR_HERE; goto open_error;}<br>
-            if ( 0 > snd_pcm_hw_params_set_format(phandle, hw, sample_format))  { ERROR_HERE; goto open_error;}<br>
-            if ( 0 > snd_pcm_hw_params_set_channels(phandle, hw, 2))                   { ERROR_HERE; goto open_error;}<br>
-<br>
-            if ( snd_pcm_hw_params_set_rate_near(phandle, hw, &rate, 0))<br>
-            {<br>
-                ll->printf("test_rate failed( %i\n", rate);<br>
-                continue;<br>
-            }<br>
-            else<br>
-            {<br>
-                ll->printf(1, "success! setting rate :  %i\n", rate);<br>
-<br>
-                snd_pcm_uframes_t minb=0, maxb= 0;<br>
-                int mind=0, maxd=0;<br>
-                snd_pcm_hw_params_get_period_size_min(hw, &minb,&mind);<br>
-                snd_pcm_hw_params_get_period_size_max(hw, &maxb,&maxd);<br>
-                ll->printf(2, "FYI: period size range is [%li/%i,%li/%i]\n", minb,mind, maxb, maxd);<br>
-<br>
-                if ((mind != 0) || (maxd == 0))<br>
-               {<br>
-                    ll->printf(2, "watch out, mind and maxd non-zero... you didn't set rate_resample to 0 did you...\n");<br>
-               }<br>
-<br>
-                if (period0 < minb)<br>
-                {<br>
-                    ll->printf(1, "requested period size (%li) < min (%li), adjusting to min\n", period_size, minb);<br>
-                    period_size = minb;<br>
-                }<br>
-                else if (period0 > maxb)<br>
-                {<br>
-                    ll->printf(2, "requested period size (%li) < max (%li), adjusting to min\n", period_size, maxb);<br>
-                    period_size = maxb;<br>
-                }<br>
-                else<br>
-                {<br>
-                    period_size = period0;<br>
-                }<br>
-<br>
-                ll->printf(1, "testing period size :  %li\n", period_size);<br>
-                if ( 0 > snd_pcm_hw_params_test_period_size(phandle, hw, period_size, 0)){ ERROR_HERE; goto open_error;}<br>
-<br>
-<br>
-                ll->printf(1, "setting period size :  %li\n", period_size);<br>
-                if ( 0 > snd_pcm_hw_params_set_period_size_near(phandle, hw, &period_size, 0)){ ERROR_HERE; goto open_error;}<br>
-<br>
-                ll->printf(1, "setting buffer size :  %i * %li = %li\n", p_per_buff, period_size, p_per_buff * period_size);<br>
-                snd_pcm_uframes_t buff_size = p_per_buff * period_size;<br>
-                if ( 0 > snd_pcm_hw_params_set_buffer_size_near(phandle, hw, &buff_size)) { ERROR_HERE; goto open_error;}<br>
-<br>
-                break;<br>
-            }<br>
-        }<br>
-<br>
-        if (upsample_max == upsample) { ERROR_HERE; goto open_error; }<br>
-<br>
-        if (0 > snd_pcm_hw_params(phandle, hw)) { ERROR_HERE; goto open_error; }<br>
-<br>
-        snd_pcm_hw_params_free (hw);<br>
-        return 0;<br>
-<br>
-open_error:<br>
-        snd_pcm_hw_params_free (hw);<br>
-        snd_pcm_close(phandle);<br>
-        phandle = NULL;<br>
-        return -1;<br>
-    }<br>
-    void close(int drain = 0)<br>
-    {<br>
-        if (!phandle)<br>
-        {<br>
-            ll->printf(0, "WARNING: attempt to close already-closed pcm\n");<br>
-            return;<br>
-        }<br>
-        ll->printf(1, "INFO: closing phandle device\n");<br>
-        if (drain) snd_pcm_drain(phandle);<br>
-        snd_pcm_close(phandle);<br>
-        phandle = NULL;<br>
-    }<br>
-    void prepare()<br>
-    {<br>
-        if (!phandle)<br>
-        {<br>
-            ll->printf(0, "ERROR: attempt to prepare a closed pcm\n");<br>
-            return;<br>
-        }<br>
-        if (0 > snd_pcm_prepare(phandle)) { ERROR_HERE; }<br>
-    }<br>
-    int writebuf(snd_pcm_uframes_t frame_count, short int * frame_data)<br>
-    {<br>
-        if (!phandle)<br>
-        {<br>
-            ll->printf(0, "ERROR: attempt to write a closed phandle\n");<br>
-            return -1;<br>
-        }<br>
-        int err = 0;<br>
-        while (frame_count > 0) {<br>
-            err = snd_pcm_writei (phandle, frame_data, frame_count );<br>
-            if (err == (signed)frame_count) return 0; //success<br>
-            if (err == -EAGAIN)<br>
-                continue;<br>
-            if (err < 0)<br>
-                break;<br>
-            frame_data += err * 4;<br>
-            frame_count -= err;<br>
-        }<br>
-<br>
-       if (err >= 0)<br>
-       {<br>
-           ll->printf(0, "madness on line %s:%i\n", __FILE__, __LINE__);<br>
-               return -1;<br>
-       }<br>
-<br>
-        const char * msg = NULL;<br>
-        snd_pcm_state_t state = snd_pcm_state(phandle);<br>
-        switch (state)<br>
-        {<br>
-            case SND_PCM_STATE_OPEN:    msg = "open"; break;<br>
-            case SND_PCM_STATE_SETUP:   msg = "setup"; break;<br>
-            case SND_PCM_STATE_PREPARED:msg = "prepared"; break;<br>
-            case SND_PCM_STATE_RUNNING: msg = "running"; break;<br>
-            case SND_PCM_STATE_XRUN:    msg = "xrun"; break;<br>
-            case SND_PCM_STATE_DRAINING: msg = "draining"; break;<br>
-            case SND_PCM_STATE_PAUSED:  msg = "paused"; break;<br>
-            case SND_PCM_STATE_SUSPENDED: msg = "suspended"; break;<br>
-            case SND_PCM_STATE_DISCONNECTED: msg = "disconnected"; break;<br>
-        }<br>
-        ll->printf(1,  "WARNING: write failed (%s)\tstate = %s\ttime=%lf\n", snd_strerror (err), msg, pytime(NULL));<br>
-        if (0 > snd_pcm_recover(phandle, err, 0)) { ERROR_HERE; return err;}<br>
-        if (0 > snd_pcm_prepare(phandle))         { ERROR_HERE; return err;}<br>
-        return 1; //warning<br>
-    }<br>
-};<br>
-#undef ERROR_HERE<br>
-<br>
-#endif<br>
--<br>
1.8.1.4<br>
<br>
</div></div></blockquote></div><br></div>