[Debian GNUstep maintainers] RFH: ALSA output bundle for cynthiune.app
Yavor Doganov
yavor at gnu.org
Tue Feb 9 16:19:53 UTC 2010
[ CCing my local GUG, someone might have an idea what's going on. ]
Modern (Debian) kernels disable OSS support by default; this was done
in other distros long time ago. I noticed a release goal [1] for
getting rid of apps that use /dev/dsp by default; Cynthiune is among
them.
[1] http://wiki.debian.org/ReleaseGoals/NoLinuxDevDsp
Furthermore, it is not entirely clear to me that the current
dependencies are right; I asked on mentors a few days ago [2] about
this but got no reply.
[2] http://article.gmane.org/gmane.linux.debian.devel.mentors/41523
Regardless of the current (potential and likely) dependency problem,
it is clear that an ALSA bundle is needed on the long term, to be the
default on all GNU/Linux archs. I wrote one fairly quickly, but I
experience severe memory clobbering problems, especially at work,
where my workstation is a a dual-core Pentium IV. It is very hard to
reproduce the crashes on an old scruffy machine such as my main
workstation at home (running gNewSense, but it shouldn't matter much;
it's hard to reproduce on my single-core Debian sid machine as well).
Initially I thought there's a severe bug in the way I use the
libasound API, but the aRts output bundle (the only one which is
threaded; OSS and Esound are not) has exactly the same problem. I
spent more than a week in trying various approaches (using
NSLock/NSRecursiveLock in critical places, dynamic memory allocation,
copying the buffer before passing it to parentPlayer's
[readNextChunk:withSize:] (which calls the corresponding method in the
relevant format bundle), etc. No success.
I feel there's something very fishy here, possibly fairly trivial and
fundamental, but I already feel helpless :-(
What am I doing wrong?
The patch is attached, just apply it against the patched source
cynthiune.app 0.9.5-9 source. As the pkg-gnustep list strips
attachments, I uploaded it here [3]. For your convenience, a binary
package built with noopt and nostrip for squeeze (so that it's almost
guaranteed to work on sid) is available there [4] as well.
[3] http://www.fsa-bg.org/~yavorescu/alsa.patch
[4] http://www.fsa-bg.org/~yavorescu/cynthiune.app_0.9.5-9_i386.deb
sha1sum: 1578db1f37f2f1fa360b6a4cb3df8f8555d12f47
-------------- next part --------------
--- cynthiune.app-0.9.5.orig/Bundles/ALSA/ALSA.h
+++ cynthiune.app-0.9.5/Bundles/ALSA/ALSA.h
@@ -0,0 +1,41 @@
+/* ALSA.h - this file is part of Cynthiune -*-objc-*-
+ *
+ * Copyright (C) 2010 Free Software Foundation, Inc.
+ *
+ * Author: Yavor Doganov <yavor at gnu.org>
+ *
+ * Cynthiune is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * Cynthiune is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef ALSA_H
+#define ALSA_H
+
+ at interface ALSA : NSObject <CynthiuneBundle, Output>
+{
+ id parentPlayer;
+ snd_pcm_t *pcm_handle;
+
+ BOOL stopRequested;
+
+ unsigned int channels;
+ unsigned long rate;
+
+ unsigned char buffer[DEFAULT_BUFFER_SIZE];
+}
+
+ at end
+
+#endif /* ALSA_H */
--- cynthiune.app-0.9.5.orig/Bundles/ALSA/ALSA.m
+++ cynthiune.app-0.9.5/Bundles/ALSA/ALSA.m
@@ -0,0 +1,183 @@
+/* ALSA.m - this file is part of Cynthiune
+ *
+ * Copyright (C) 2010 Free Software Foundation, Inc.
+ *
+ * Author: Yavor Doganov <yavor at gnu.org>
+ *
+ * Cynthiune is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * Cynthiune is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef _REENTRANT
+#define _REENTRANT 1
+#endif
+
+#import <AppKit/AppKit.h>
+
+#import <Cynthiune/CynthiuneBundle.h>
+#import <Cynthiune/Output.h>
+#import <Cynthiune/utils.h>
+
+#include <alsa/asoundlib.h>
+
+#import "ALSA.h"
+
+#define LOCALIZED(X) _b ([ALSA class], X)
+
+static char *device = "default";
+
+
+ at implementation ALSA
+
++ (NSString *) bundleDescription
+{
+ return LOCALIZED (@"Output plug-in for ALSA");
+}
+
+
++ (NSArray *) bundleCopyrightStrings
+{
+ return [NSArray arrayWithObjects:
+ LOCALIZED (@"Copyright (C) 2010 Free Software Foundation,"
+ @" Inc."),
+ nil];
+}
+
+
++ (BOOL) isThreaded
+{
+ return YES;
+}
+
+
+- (void) setParentPlayer: (id) aPlayer;
+{
+ parentPlayer = aPlayer;
+}
+
+
+- (id) init
+{
+ if ((self = [super init]))
+ {
+ parentPlayer = nil;
+ pcm_handle = NULL;
+ channels = 0;
+ rate = 0;
+ stopRequested = NO;
+ }
+
+ return self;
+}
+
+
+- (BOOL) openDevice
+{
+ int err;
+ BOOL result = NO;
+
+ if ((err = snd_pcm_open (&pcm_handle, device, SND_PCM_STREAM_PLAYBACK, 0))
+ < 0)
+ NSRunAlertPanel (LOCALIZED (@"Error"), LOCALIZED (@"Failed to open the "
+ @"ALSA device:\n%s"),
+ LOCALIZED (@"OK"), NULL, NULL, snd_strerror (err));
+ else if ((err = snd_pcm_set_params (pcm_handle, SND_PCM_FORMAT_S16,
+ SND_PCM_ACCESS_RW_INTERLEAVED,
+ channels, rate, 1, 5000000)) < 0)
+ NSRunAlertPanel (LOCALIZED (@"Error"), LOCALIZED (@"Failed to set device"
+ @"parameters:\n%s"),
+ LOCALIZED (@"OK"), NULL, NULL, snd_strerror (err));
+ else if ((err = snd_pcm_prepare (pcm_handle)) < 0)
+ NSRunAlertPanel (LOCALIZED (@"Error"), LOCALIZED (@"Failed to prepare the "
+ @"ALSA device for "
+ @"playing:\n%s"),
+ LOCALIZED (@"OK"), NULL, NULL, snd_strerror (err));
+ else
+ result = YES;
+
+ return result;
+}
+
+
+- (BOOL) prepareDeviceWithChannels: (unsigned int) numberOfChannels
+ andRate: (unsigned long) sampleRate
+{
+ channels = numberOfChannels;
+ rate = sampleRate;
+
+ return YES;
+}
+
+
+- (void) closeDevice
+{
+ while (stopRequested)
+ [NSThread sleepUntilDate: [NSDate dateWithTimeIntervalSinceNow: 0.1]];
+ snd_pcm_close (pcm_handle);
+}
+
+
+- (void) threadLoop
+{
+ NSAutoreleasePool *pool = [NSAutoreleasePool new];
+
+ while (!stopRequested)
+ {
+ snd_pcm_sframes_t written;
+ snd_pcm_uframes_t frames;
+ int bufferSize;
+
+ bufferSize = [parentPlayer readNextChunk: buffer
+ withSize: DEFAULT_BUFFER_SIZE];
+
+ if (bufferSize > 0)
+ {
+ frames = snd_pcm_bytes_to_frames (pcm_handle, bufferSize);
+ written = snd_pcm_writei (pcm_handle, buffer, frames);
+ }
+
+ if (written < 0)
+ {
+ NSLog (LOCALIZED (@"Failure writing to the ALSA device:\n"
+ @"%s, trying to recover.\n"),
+ snd_strerror (written));
+ snd_pcm_recover (pcm_handle, written, 0);
+ }
+
+ if ([pool autoreleaseCount] > 50)
+ [pool emptyPool];
+ }
+
+ stopRequested = NO;
+ [pool release];
+}
+
+
+- (BOOL) startThread
+{
+ [NSThread detachNewThreadSelector: @selector (threadLoop)
+ toTarget: self
+ withObject: nil];
+
+ return YES;
+}
+
+
+- (void) stopThread
+{
+ stopRequested = YES;
+}
+
+ at end
--- cynthiune.app-0.9.5.orig/Bundles/ALSA/GNUmakefile
+++ cynthiune.app-0.9.5/Bundles/ALSA/GNUmakefile
@@ -0,0 +1,44 @@
+# GNUmakefile - this file is part of Cynthiune
+#
+# Copyright (C) 2010 Free Software Foundation, Inc.
+#
+# Author: Yavor Doganov <yavor at gnu.org>
+#
+# Cynthiune is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2, or (at your option)
+# any later version.
+#
+# Cynthiune is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; see the file COPYING. If not, write to
+# the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
+# Boston, MA 02110-1301, USA.
+
+include $(GNUSTEP_MAKEFILES)/common.make
+
+PACKAGE_NAME = ALSA
+BUNDLE_NAME = ALSA
+BUNDLE_EXTENSION = .output
+BUNDLE_INSTALL_DIR = $(GNUSTEP_LIBRARY)/Cynthiune
+ALSA_PRINCIPAL_CLASS = ALSA
+
+ALSA_HEADERS = ALSA.h
+
+ALSA_OBJC_FILES = ALSA.m
+
+ADDITIONAL_INCLUDE_DIRS += -I../../Frameworks
+
+FRAMEWORKS_DIRS = ../../Frameworks/Cynthiune
+FRAMEWORKS = Cynthiune
+
+include ../../frameworks.make
+
+-include GNUmakefile.preamble
+-include GNUmakefile.local
+include $(GNUSTEP_MAKEFILES)/bundle.make
+-include GNUmakefile.postamble
--- cynthiune.app-0.9.5.orig/Bundles/ALSA/GNUmakefile.preamble
+++ cynthiune.app-0.9.5/Bundles/ALSA/GNUmakefile.preamble
@@ -0,0 +1,31 @@
+# GNUmakefile.preamble - this file is part of Cynthiune -*-makefile-gmake-*-
+#
+# Copyright (C) 2010 Free Software Foundation, Inc.
+#
+# Author: Yavor Doganov <yavor at gnu.org>
+#
+# Cynthiune is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2, or (at your option)
+# any later version.
+#
+# Cynthiune is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; see the file COPYING. If not, write to
+# the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
+# Boston, MA 02110-1301, USA.
+
+ALSA_CFLAGS := $(shell pkg-config --cflags alsa)
+ALSA_LIBS := $(shell pkg-config --libs alsa)
+
+ADDITIONAL_INCLUDE_DIRS += $(ALSA_CFLAGS)
+BUNDLE_LIBS += $(ALSA_LIBS)
+ADDITIONAL_OBJCFLAGS += -Wall -Wno-import
+
+ifeq ($(debug), yes)
+ADDITIONAL_LDFLAGS += -lmcheck
+endif
--- cynthiune.app-0.9.5.orig/GNUmakefile
+++ cynthiune.app-0.9.5/GNUmakefile
@@ -94,6 +94,14 @@ endif
else
+ifeq (linux-gnu,$(GNUSTEP_TARGET_OS))
+
+ifneq (yes,$(disable-alsa))
+BUNDLES += ALSA
+endif
+
+endif
+
ifneq (yes,$(disable-oss))
BUNDLES += OSS
endif
More information about the pkg-GNUstep-maintainers
mailing list