Summary: | artsd fails at using a modern alsa setup: pcm.default not used | ||
---|---|---|---|
Product: | [Unmaintained] arts | Reporter: | Moritz Moeller-Herrmann <moritz-kdebugs> |
Component: | artsd | Assignee: | Stefan Westerfeld <stefan> |
Status: | RESOLVED FIXED | ||
Severity: | grave | CC: | bitblt, jarkko.haapalainen, kde-multimedia, rdieter, sami.nieminen |
Priority: | NOR | ||
Version: | 1.2 | ||
Target Milestone: | --- | ||
Platform: | Debian testing | ||
OS: | Linux | ||
Latest Commit: | Version Fixed In: | ||
Sentry Crash Report: |
Description
Moritz Moeller-Herrmann
2003-12-19 03:48:01 UTC
I second this bug report. Apparently, aRts can use only real ALSA devices (such as hw:0,0) but not devices which work via user-space plugins (such as "dmix"). When using aRts via a dmix device (with artsd' -d argument), it's simply silent, not playing anything (but not emiting errors either). BACKGROUND ========== You may ask: If aRts does user-space software mixing already, why do you use "dmix" at all? Answer: Because: 1. Pure ALSA applications can be easily made to use dmix. 2. Sometimes I prefer dmix over aRts for sake of lower latencies. 3. When a single machine runs multiple KDE desktops on different VTs, the multiple aRts servers, belonging to differnet users, will compete over the sound device. dmix allows them to share it. P.S. Unlike what's said in the previous comment, dmix is pure user-space software mixing. I was going to report this but fortunately found this bug report. I too would like to see artsd having support for dmix feature of ALSA. Would it be possible to have some simple passthrough feature for artsd that would pass the audio to dmix if enabled. Also a way to specify the device would be nice (you can specify it in e.g. mplayer and xmms). Indeed, since it should be possible to use one linux box as a multi-user desktop system, reason (3) of comment #1 should be enough reason to fix aRts straight away. Having a way to mix (dmix) should be used to enable multi-user mixing for as many alsa clients as possible, including artsd. Does anyone care for arts?! If alsa wouldn't be so crappy I guess somebody would want to fix it. Someone has writen a way to workaround the problem. Look at bottom of <http://alsa.opensrc.org/index.php?page=DmixPlugin> I added a new bug-report (it's my mistake of course) with a hint, how can be the current code fixed. See http://bugs.kde.org/show_bug.cgi?id=76413 Unfortunately, it seems that arts development is somehow stopped or very slow, so I guess we have to solve this bug ourselves, altough our capacity (ALSA team) is limited. CVS commit by carewolf: After venting my fury I calmed down and looked at the dmix-code. It seems it is really more borken than broken, and nothing we can't work around. - Make aRts work with dmix. Two important changes: 1. Dmix uses read-events to signify write-events, so we need to autodetect what kind of crack ALSA is smoking today. 2. Dmix needs to be started like a recorder even if this is contrary to the ALSA API documentation. If everything works like expected I will backport and close bugs 76413 and 70802. CCMAIL: 76413@bugs.kde.org CCMAIL: 70802@bugs.kde.org M +110 -48 audioioalsa9.cc 1.6 Works for me. Thanks a lot. However, artsd is using about 80 % of the CPU (1 GHz). Yes, there seems to be too many IO-events now. I am working on filtering them a bit. I tried with the patch, but I am getting "Sound server fatal error: cpu overload, aborting" errors, and my laptop hangs for about 10 secs every time I try to play a sound. Hardware: P4-2800 SI7012 (intel8x0) Software: linux-2.6.3 (with alsa-driver 1.0.2c) arts-1.2.1 with the patch applied CVS commit by carewolf: Avoid infinite loops when playing through DMix. CCMAIL: 70802@bugs.kde.org M +45 -25 audioioalsa9.cc 1.7 --- arts/flow/audioioalsa9.cc #1.6:1.7 @@ -72,5 +72,7 @@ protected: int m_period_size, m_periods; bool inProgress; + bool restartIOHandling; + void startIO(); int poll2iomanager(int pollTypes); int setPcmParams(snd_pcm_t *pcm); @@ -118,4 +120,6 @@ AudioIOALSA::AudioIOALSA() m_pcm_capture = NULL; inProgress = false; + restartIOHandling = false; + audio_read_fd = audio_write_fd = -1; } @@ -196,14 +200,6 @@ bool AudioIOALSA::open() (float)(2.0 * _samplingRate * _channels)*1000.0); - /* watch PCM file descriptor(s) */ - Dispatcher::the()->ioManager()->remove(this, IOType::all); - audio_read_fd = audio_write_fd = -1; - if (_direction & directionWrite) { - audio_write_fd = watchDescriptor(m_pcm_playback); - } - if (_direction & directionRead) { - audio_read_fd = watchDescriptor(m_pcm_capture); - } + startIO(); /* restore the format value */ switch (m_format) { @@ -311,4 +307,16 @@ int AudioIOALSA::getParam(AudioParam p) } +void AudioIOALSA::startIO() +{ + /* watch PCM file descriptor(s) */ + if (m_pcm_playback) { + audio_write_fd = watchDescriptor(m_pcm_playback); + } + if (m_pcm_capture) { + audio_read_fd = watchDescriptor(m_pcm_capture); + } + +} + int AudioIOALSA::poll2iomanager(int pollTypes) { @@ -352,5 +360,4 @@ int AudioIOALSA::xrun(snd_pcm_t *pcm) if ((err = snd_pcm_prepare(pcm)) < 0) return err; - if (pcm == m_pcm_capture) snd_pcm_start(pcm); // ignore error here.. return 0; @@ -367,5 +374,4 @@ int AudioIOALSA::resume(snd_pcm_t *pcm) if ((err = snd_pcm_prepare(pcm)) < 0) return err; - if (pcm == m_pcm_capture) snd_pcm_start(pcm); // ignore error here.. } @@ -395,4 +401,8 @@ int AudioIOALSA::read(void *buffer, int int AudioIOALSA::write(void *buffer, int size) { + // DMix has an annoying habit of returning instantantly on the returned + // poll-descriptor. So we block here to avoid an infinity loop. + while(snd_pcm_wait(m_pcm_playback, 1) == 0); + int frames = snd_pcm_bytes_to_frames(m_pcm_playback, size); int length; @@ -416,5 +426,13 @@ void AudioIOALSA::notifyIO(int fd, int t int todo = 0; - if (inProgress) return; + if(inProgress) + { + if(!restartIOHandling) + { + Dispatcher::the()->ioManager()->remove(this,IOType::all); + restartIOHandling = true; + } + return; + } // We can't trust the type as ALSA might have read-type events, @@ -425,8 +443,10 @@ void AudioIOALSA::notifyIO(int fd, int t if (type & IOType::except) todo |= AudioSubSystem::ioExcept; + restartIOHandling = false; inProgress = true; AudioSubSystem::the()->handleIO(todo); inProgress = false; + if (restartIOHandling) startIO(); } CVS commit by carewolf: Dmix seems to work this time with no adverse effects. CCMAIL:70802-done@bugs.kde.org M +141 -56 audioioalsa9.cc 1.4.2.2 |