diff options
author | marcus <marcus@df743ca5-7f9a-e211-a948-0013205c9059> | 2008-08-15 00:56:54 +0800 |
---|---|---|
committer | marcus <marcus@df743ca5-7f9a-e211-a948-0013205c9059> | 2008-08-15 00:56:54 +0800 |
commit | 9e8942be21dcc082e3307e08e5ab943934dd3c40 (patch) | |
tree | 6905d08e6f8346677cb5cf32a099d31b558da15e | |
parent | 8cfa8764590816084fcd1e866a00b92ca48de2ff (diff) | |
download | marcuscom-ports-9e8942be21dcc082e3307e08e5ab943934dd3c40.tar marcuscom-ports-9e8942be21dcc082e3307e08e5ab943934dd3c40.tar.gz marcuscom-ports-9e8942be21dcc082e3307e08e5ab943934dd3c40.tar.bz2 marcuscom-ports-9e8942be21dcc082e3307e08e5ab943934dd3c40.tar.lz marcuscom-ports-9e8942be21dcc082e3307e08e5ab943934dd3c40.tar.xz marcuscom-ports-9e8942be21dcc082e3307e08e5ab943934dd3c40.tar.zst marcuscom-ports-9e8942be21dcc082e3307e08e5ab943934dd3c40.zip |
Add the OSS sound playback module back from swfdec-0.6.8.
git-svn-id: svn://creme-brulee.marcuscom.com/ports/trunk@11287 df743ca5-7f9a-e211-a948-0013205c9059
-rw-r--r-- | graphics/swfdec/Makefile | 7 | ||||
-rw-r--r-- | graphics/swfdec/files/patch-configure | 24 | ||||
-rw-r--r-- | graphics/swfdec/files/patch-swfdec-gtk_Makefile.in | 10 | ||||
-rw-r--r-- | graphics/swfdec/files/swfdec_playback_oss.c | 265 |
4 files changed, 305 insertions, 1 deletions
diff --git a/graphics/swfdec/Makefile b/graphics/swfdec/Makefile index 3843e447e..37dd0627d 100644 --- a/graphics/swfdec/Makefile +++ b/graphics/swfdec/Makefile @@ -8,6 +8,7 @@ PORTNAME= swfdec PORTVERSION= 0.7.4 +PORTREVISION= 1 CATEGORIES= graphics MASTER_SITES= http://swfdec.freedesktop.org/download/swfdec/0.7/ @@ -21,10 +22,14 @@ USE_LDCONFIG= yes USE_GNOME= gnomehack gtk20 ltverhack USE_GSTREAMER= core good mp3 ffmpeg USE_AUTOTOOLS= libtool:15 -CONFIGURE_ARGS= --with-audio=none +CONFIGURE_ARGS= --with-audio=oss CONFIGURE_ENV= CPPFLAGS="-I${LOCALBASE}/include" \ LDFLAGS="-Wl,-Bsymbolic -L${LOCALBASE}/lib" PLIST_SUB= VERSION=${PORTVERSION:R} +post-extract: + @${CP} ${FILESDIR}/swfdec_playback_oss.c \ + ${WRKSRC}/swfdec-gtk + .include <bsd.port.mk> diff --git a/graphics/swfdec/files/patch-configure b/graphics/swfdec/files/patch-configure new file mode 100644 index 000000000..4f14187ab --- /dev/null +++ b/graphics/swfdec/files/patch-configure @@ -0,0 +1,24 @@ +--- configure.orig 2008-08-14 12:43:55.000000000 -0400 ++++ configure 2008-08-14 12:45:51.000000000 -0400 +@@ -1563,7 +1563,7 @@ Optional Packages: + both] + --with-tags[=TAGS] include additional configurations [automatic] + --with-pkg-config-path colon-separated list of pkg-config(1) dirs +- --with-audio=[auto/pulse/none] ++ --with-audio=[auto/pulse/oss/none] + audio backend to use + --with-html-dir=PATH path to installed docs + +@@ -22752,6 +22752,12 @@ echo "$as_me: WARNING: no alsa audio sup + fi + fi + ++if test "$with_audio" = "oss"; then ++ AUDIO_TYPE=oss ++ AUDIO_CFLAGS= ++ AUDIO_LIBS= ++fi ++ + if test "$with_audio" = "pulse"; then + + pkg_failed=no diff --git a/graphics/swfdec/files/patch-swfdec-gtk_Makefile.in b/graphics/swfdec/files/patch-swfdec-gtk_Makefile.in new file mode 100644 index 000000000..ddd87704a --- /dev/null +++ b/graphics/swfdec/files/patch-swfdec-gtk_Makefile.in @@ -0,0 +1,10 @@ +--- swfdec-gtk/Makefile.in.orig 2008-08-14 12:41:05.000000000 -0400 ++++ swfdec-gtk/Makefile.in 2008-08-14 12:45:58.000000000 -0400 +@@ -281,6 +282,7 @@ libswfdec_@SWFDEC_MAJORMINOR@include_HEA + + EXTRA_DIST = \ + swfdec_playback_alsa.c \ ++ swfdec_playback_oss.c \ + swfdec_playback_pulse.c \ + swfdec_playback_none.c + diff --git a/graphics/swfdec/files/swfdec_playback_oss.c b/graphics/swfdec/files/swfdec_playback_oss.c new file mode 100644 index 000000000..160f26db9 --- /dev/null +++ b/graphics/swfdec/files/swfdec_playback_oss.c @@ -0,0 +1,265 @@ +/* Swfdec + * Copyright © 2006 Benjamin Otte <otte@gnome.org> + * Copyright © 2007 Eric Anholt <eric@anholt.net> + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301 USA + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include <sys/ioctl.h> +#include <sys/soundcard.h> +#include <fcntl.h> +#include <unistd.h> +#include <stdlib.h> +#include <string.h> + +#include "swfdec_playback.h" + +/** @file Implements swfdec audio playback by opening /dev/dsp per stream + * and playing out through that. + * + * Allowing multiple access to /dev/dsp is not required by the OSS API spec, + * but FreeBSD's sound system lets you, which is what this file was written + * for. + */ + +/*** DEFINITIONS ***/ + +struct _SwfdecPlayback { + SwfdecPlayer * player; + GList * streams; /* all Stream objects */ + GMainContext * context; /* context we work in */ +}; + +typedef struct { + SwfdecPlayback * sound; /* reference to sound object */ + SwfdecAudio * audio; /* the audio we play back */ + int dsp_fd; + int fragsize; /* Audio fragment size */ + GSource * source; /* source for writing data */ + guint offset; /* offset into sound */ +} Stream; + +/* Size of one of our audio samples, in bytes */ +#define SAMPLESIZE 2 +#define CHANNELS 2 + +/*** STREAMS ***/ + +static gboolean +handle_stream (GIOChannel *source, GIOCondition cond, gpointer data) +{ + Stream *stream = data; + char *frag = malloc(stream->fragsize); + + if (frag == NULL) { + g_printerr ("Failed to allocate fragment of size %d\n", + stream->fragsize); + return FALSE; + } + + while (TRUE) { + int ret; + audio_buf_info spaceinfo; + + ret = ioctl(stream->dsp_fd, SNDCTL_DSP_GETOSPACE, &spaceinfo); + if (ret == -1) { + g_printerr ("Failed to get output buffer availability\n"); + free(frag); + return FALSE; + } + + if (spaceinfo.fragments == 0) + break; + + memset (frag, 0, stream->fragsize); + swfdec_audio_render (stream->audio, (gint16 *)frag, stream->offset, + stream->fragsize / SAMPLESIZE / CHANNELS); + + ret = write (stream->dsp_fd, frag, stream->fragsize); + if (ret != stream->fragsize) { + g_printerr ("Failed to write fragment\n"); + free(frag); + return FALSE; + } + + stream->offset += stream->fragsize / SAMPLESIZE / CHANNELS; + } + + free(frag); + + return TRUE; +} + +static void +swfdec_playback_stream_open (SwfdecPlayback *sound, SwfdecAudio *audio) +{ + GIOChannel *channel; + Stream *stream; + guint rate; + int dsp_fd, ret, format, channels, fragsize; + + dsp_fd = open("/dev/dsp", O_WRONLY); + if (dsp_fd == -1) { + g_printerr ("Failed to open /dev/dsp\n"); + return; + } + + format = AFMT_S16_LE; + ret = ioctl(dsp_fd, SNDCTL_DSP_SETFMT, &format); + if (ret == -1) { + g_printerr ("Failed to set sound format\n"); + close(dsp_fd); + return; + } + + channels = 2; + ret = ioctl(dsp_fd, SNDCTL_DSP_CHANNELS, &channels); + if (ret == -1) { + g_printerr ("Failed to set stereo\n"); + close(dsp_fd); + return; + } + + rate = 44100; + ret = ioctl(dsp_fd, SNDCTL_DSP_SPEED, &rate); + if (ret == -1) { + g_printerr ("Failed to set rate\n"); + close(dsp_fd); + return; + } + + ret = ioctl(dsp_fd, SNDCTL_DSP_GETBLKSIZE, &fragsize); + if (ret == -1) { + g_printerr ("Failed to get fragment size\n"); + close(dsp_fd); + return; + } + + stream = g_new0 (Stream, 1); + stream->sound = sound; + stream->audio = g_object_ref (audio); + stream->dsp_fd = dsp_fd; + stream->fragsize = fragsize; + sound->streams = g_list_prepend (sound->streams, stream); + + channel = g_io_channel_unix_new (stream->dsp_fd); + stream->source = g_io_create_watch (channel, G_IO_OUT); + g_source_set_priority (stream->source, G_PRIORITY_HIGH); + g_source_set_callback (stream->source, (GSourceFunc) handle_stream, stream, + NULL); + g_io_channel_unref (channel); + g_source_attach (stream->source, stream->sound->context); + + return; +} + +static void +swfdec_playback_stream_close (Stream *stream) +{ + close (stream->dsp_fd); + g_source_destroy (stream->source); + g_source_unref (stream->source); + stream->sound->streams = g_list_remove (stream->sound->streams, stream); + g_object_unref (stream->audio); + g_free (stream); +} + +/*** SOUND ***/ + +static void +advance_before (SwfdecPlayer *player, guint msecs, guint audio_samples, gpointer data) +{ + SwfdecPlayback *sound = data; + GList *walk; + + for (walk = sound->streams; walk; walk = walk->next) { + Stream *stream = walk->data; + if (audio_samples >= stream->offset) { + stream->offset = 0; + } else { + stream->offset -= audio_samples; + } + } +} + +static void +audio_added (SwfdecPlayer *player, SwfdecAudio *audio, SwfdecPlayback *sound) +{ + swfdec_playback_stream_open (sound, audio); +} + +static void +audio_removed (SwfdecPlayer *player, SwfdecAudio *audio, SwfdecPlayback *sound) +{ + GList *walk; + + for (walk = sound->streams; walk; walk = walk->next) { + Stream *stream = walk->data; + if (stream->audio == audio) { + swfdec_playback_stream_close (stream); + return; + } + } + g_assert_not_reached (); +} + +SwfdecPlayback * +swfdec_playback_open (SwfdecPlayer *player, GMainContext *context) +{ + SwfdecPlayback *sound; + const GList *walk; + + g_return_val_if_fail (SWFDEC_IS_PLAYER (player), NULL); + g_return_val_if_fail (context != NULL, NULL); + + sound = g_new0 (SwfdecPlayback, 1); + sound->player = player; + g_signal_connect (player, "advance", G_CALLBACK (advance_before), sound); + g_signal_connect (player, "audio-added", G_CALLBACK (audio_added), sound); + g_signal_connect (player, "audio-removed", G_CALLBACK (audio_removed), sound); + for (walk = swfdec_player_get_audio (player); walk; walk = walk->next) { + swfdec_playback_stream_open (sound, walk->data); + } + g_main_context_ref (context); + sound->context = context; + return sound; +} + +void +swfdec_playback_close (SwfdecPlayback *sound) +{ +#define REMOVE_HANDLER_FULL(obj,func,data,count) G_STMT_START {\ + if (g_signal_handlers_disconnect_by_func ((obj), \ + G_CALLBACK (func), (data)) != (count)) { \ + g_assert_not_reached (); \ + } \ +} G_STMT_END +#define REMOVE_HANDLER(obj,func,data) REMOVE_HANDLER_FULL (obj, func, data, 1) + + while (sound->streams) + swfdec_playback_stream_close (sound->streams->data); + REMOVE_HANDLER (sound->player, advance_before, sound); + REMOVE_HANDLER (sound->player, audio_added, sound); + REMOVE_HANDLER (sound->player, audio_removed, sound); + g_main_context_unref (sound->context); + g_free (sound); +} + + |