the Fink project is an effort to port
popular Unix programs to Mac OS X
Package: mpg123
Version: pre0.59s
Revision: 8
Maintainer: None
Conflicts: mpg321
Replaces: mpg321
Source: http://www.%n.de/%n/%n-%v.tar.gz
Source-MD5: a63675b0ea7990d4a7d7e7e14f23a3e4
SourceDirectory: %n
TarFilesRename: JUKEBOX:JUKEBOX.txt
PatchScript: sed 's|@FINKPREFIX@|%i|g' <%a/%n.patch | patch -p1
CompileScript: make macosx
DocFiles: BENCHMARKING BUGS CHANGES COPYING JUKEBOX.txt README TODO
Description: Real time MPEG Audio Player for Layer 1,2 and Layer3
DescDetail: <<
Mpg123 is a fast, free and portable MPEG audio player for Unix. It
supports MPEG 1.0/2.0 layers 1, 2 and 3. For full CD quality playback
(44 kHz, 16 bit, stereo) a Pentium, SPARCstation10, DEC Alpha or similar
CPU is required. Mono and/or reduced quality playback (22 kHz or 11 kHz) is
even possible on 486 CPUs. This version of mpg123 has both coreaudio and
IPv6 support.
<<
DescPort: <<
Uses Guillaume Outters coreaudio driver for mpg123, available from
http://sourceforge.net/projects/mosx-mpg123. The patch used for IPv6
support is available from http://www.bugfactory.org/~gav/ipv6.
<<
DescPackaging: <<
Previous versions by Justin F. Hallet and Matt Stephenson.
<<
License: Restrictive/Distributable
Homepage: http://www.mpg123.de
diff -ru mpg123/Makefile mpg123-patched/Makefile
--- mpg123/Makefile Tue Jan 23 11:00:46 2001
+++ mpg123-patched/Makefile Wed Sep 12 15:53:51 2001
@@ -4,9 +4,9 @@
# Where to install binary and manpage on "make install":
-PREFIX=/usr/local
+PREFIX=@FINKPREFIX@
BINDIR=$(PREFIX)/bin
-MANDIR=$(PREFIX)/man
+MANDIR=$(PREFIX)/share/man
SECTION=1
########################################################
@@ -54,6 +54,7 @@
@echo "make netbsd NetBSD"
@echo "make openbsd OpenBSD"
@echo "make mint MiNT on Atari"
+ @echo "make macosx MacOSX"
@echo "make generic try this one if your system isn't listed above"
@echo ""
@echo "Please read the file INSTALL for additional information."
@@ -736,6 +737,12 @@
-finline-functions -ffast-math \
-DREAL_IS_FLOAT -DMINT -DNOXFERMEM' \
AUDIO_LIB='-lsocket' \
+ mpg123-make
+
+macosx:
+ $(MAKE) CC=cc LDFLAGS='$(LDFLAGS)' AUDIO_LIB='-framework CoreAudio' \
+ OBJECTS='decode.o dct64.o audio_macosx.o term.o' \
+ CFLAGS='$(CFLAGS) -DINET6 -DTERM_CONTROL -DMAC_OS_X -Wall -O2 -DPPC_ENDIAN' \
mpg123-make
# maybe you need the additonal options LDFLAGS='-lnsl -lsocket' when linking (see solaris:)
--- mpg123/audio_macosx.c Thu Jan 2 17:10:57 2003
+++ mpg123-patched/audio_macosx.c Thu Jan 2 17:00:35 2003
@@ -0,0 +1,337 @@
+/*- This is a 80 chars line, to have pretty formatted comments ---------------*/
+
+/* audio_macosx.c, originally written by Guillaume Outters
+ * to contact the author, please mail to: guillaume.outters@free.fr
+ *
+ * This file is some quick pre-alpha patch to allow me to have some music for my
+ * long working days, and it does it well. But it surely isn't a final version;
+ * as Mac OS X requires at least a G3, I'm not sure it will be useful to
+ * implement downsampling.
+ *
+ * Mac OS X audio works by asking you to fill its buffer, and, to complicate a
+ * bit, you must provide it with floats. In order not to patch too much mpg123,
+ * we'll accept signed short (mpg123 "approved" format) and transform them into
+ * floats as soon as received. Let's say this way calculations are faster.
+ *
+ * As we don't have some /dev/audio device with blocking write, we'll have to
+ * stop mpg123 before it does too much work, while we are waiting our dump proc
+ * to be called. I wanted to use semaphores, but they still need an
+ * implementation from Apple before I can do anything. So we'll block using a
+ * sleep and wake up on SIGUSR2.
+ * Version 0.2: now I use named semaphores (which are implemented AND work).
+ * Preprocessor flag MOSX_USES_SEM (defined at the beginning of this file)
+ * enables this behaviour.
+ *
+ * In order always to have a ready buffer to be dumped when the routine gets
+ * called, we have a "buffer loop" of NUMBER_BUFFERS buffers. mpg123 fills it
+ * on one extremity ('to'), playProc reads it on another point ('from'). 'to'
+ * blocks when it arrives on 'from' (having filled the whole circle of buffers)
+ * and 'from' blocks when no data is available. As soon as it has emptied a
+ * buffer, if mpg123 is sleeping, it awakes it quite brutaly (SIGUSR2) to tell
+ * it to fill the buffer. */
+
+#ifndef MOSX_USES_SEM
+#define MOSX_USES_SEM 1 /* Semaphores or sleep()/kill()? I would say semaphores, but this is just my advice, after all */
+#endif
+#ifndef MOSX_SEM_V2
+#define MOSX_SEM_V2 1
+#endif
+
+#include "mpg123.h"
+#include
+#include
+#include
+#include
+#if MOSX_USES_SEM
+#include
+#endif
+
+struct aBuffer
+{
+ float * buffer;
+ long size;
+
+ float * ptr; /* Where in the buffer are we? */
+ long remaining;
+
+ struct aBuffer * next;
+};
+typedef struct aBuffer aBuffer;
+
+struct anEnv
+{
+ long size;
+ short * debut;
+ short * ptr;
+ AudioDeviceID device;
+ char play;
+
+ /* Intermediate buffers */
+
+ #if MOSX_USES_SEM
+ sem_t * semaphore;
+ #else
+ char wait; /* mpg123 is waiting (due to the semaphore) to show the world its power; let's free him! */
+ pid_t pid;
+ #endif
+ aBuffer * from; /* Current buffers */
+ aBuffer * to;
+};
+
+static struct anEnv env;
+
+#define ENV ((struct anEnv *)inClientData)
+#define NUMBER_BUFFERS 16 /* Tried with 3 buffers, but then any little window move is sufficient to stop the sound. Here we have 1.5 seconds music buffered */
+
+void destroyBuffers()
+{
+ aBuffer * ptr;
+ aBuffer * ptr2;
+
+ ptr = env.to->next;
+ env.to->next = NULL;
+ while(ptr)
+ {
+ ptr2 = ptr->next;
+ if(ptr->buffer) free(ptr->buffer);
+ free(ptr);
+ ptr = ptr2;
+ }
+}
+
+void initBuffers()
+{
+ long m;
+ aBuffer ** ptrptr;
+
+ ptrptr = &env.to;
+ for(m = 0; m < NUMBER_BUFFERS; m++)
+ {
+ *ptrptr = malloc(sizeof(aBuffer));
+ (*ptrptr)->size = 0;
+ (*ptrptr)->remaining = 0;
+ (*ptrptr)->buffer = NULL;
+ ptrptr = &(*ptrptr)->next;
+ #if MOSX_USES_SEM
+ sem_post(env.semaphore); /* This buffer is ready for filling (of course, it is empty!) */
+ #endif
+ }
+ *ptrptr = env.from = env.to;
+}
+
+int fillBuffer(aBuffer * b, short * source, long size)
+{
+ float * dest;
+
+ if(b->remaining) /* Non empty buffer, must still be playing */
+ return(-1);
+ if(b->size != size) /* Hey! What's that? Coudn't this buffer size be fixed once (well, perhaps we just didn't allocate it yet) */
+ {
+ if(b->buffer) free(b->buffer);
+ b->buffer = malloc(size * sizeof(float));
+ b->size = size;
+ }
+
+ dest = b->buffer;
+ while(size--)
+ //*dest++ = ((*source++) + 32768) / 65536.0;
+ *dest++ = (*source++) / 32768.0;
+
+ b->ptr = b->buffer;
+ b->remaining = b->size; /* Do this at last; we shouldn't show the buffer is full before it is effectively */
+
+ #ifdef DEBUG_MOSX
+ printf("."); fflush(stdout);
+ #endif
+
+ return(0);
+}
+
+OSStatus playProc(AudioDeviceID inDevice, const AudioTimeStamp * inNow, const AudioBufferList * inInputData, const AudioTimeStamp * inInputTime, AudioBufferList * outOutputData, const AudioTimeStamp * inOutputTime, void * inClientData)
+{
+ long m, n, o;
+ float * dest;
+
+ for(o = 0; o < outOutputData->mNumberBuffers; o++)
+ {
+ m = outOutputData->mBuffers[o].mDataByteSize / sizeof(float); /* What we have to fill */
+ dest = outOutputData->mBuffers[o].mData;
+
+ while(m > 0)
+ {
+ if( (n = ENV->from->remaining) <= 0 ) /* No more bytes in the current read buffer! */
+ {
+ while( (n = ENV->from->remaining) <= 0)
+ usleep(2000); /* Let's wait a bit for the results... */
+ }
+
+ /* We dump what we can */
+
+ if(n > m) n = m; /* In fact, just the necessary should be sufficient (I think) */
+
+ memcpy(dest, ENV->from->ptr, n * sizeof(float));
+
+ /* Let's remember all done work */
+
+ m -= n;
+ ENV->from->ptr += n;
+ if( (ENV->from->remaining -= n) <= 0) /* ... and tell mpg123 there's a buffer to fill */
+ {
+ #if MOSX_USES_SEM
+ sem_post(ENV->semaphore);
+ #else
+ if(ENV->wait)
+ {
+ kill(ENV->pid, SIGUSR2);
+ ENV->wait = 0;
+ }
+ #endif
+ ENV->from = ENV->from->next;
+ }
+ }
+ }
+
+ return (0);
+}
+
+#if ! MOSX_USES_SEM
+void start(int n)
+{
+ signal(SIGUSR2, start);
+}
+#endif
+
+int audio_open(struct audio_info_struct *ai)
+{
+ long size;
+ AudioStreamBasicDescription format;
+ #if MOSX_USES_SEM
+ char s[10];
+ long m;
+ #endif
+ /*float vol;
+ OSStatus e;*/
+
+ /* Where did that default audio output go? */
+
+ size = sizeof(env.device);
+ if(AudioHardwareGetProperty(kAudioHardwarePropertyDefaultOutputDevice, &size, &env.device)) return(-1);
+
+ /* Hmmm, let's choose PCM format */
+
+ size = sizeof(format);
+ if(AudioDeviceGetProperty(env.device, 0, 0, kAudioDevicePropertyStreamFormat, &size, &format)) return(-1);
+ if(format.mFormatID != kAudioFormatLinearPCM) return(-1);
+
+ /* Let's test volume, which doesn't seem to work (but this is only an alpha, remember?) */
+
+ /*vol = 0.5;
+ size = sizeof(vol);
+ if(e = AudioDeviceSetProperty(env.device, NULL, 0, 0, 'volm', size, &vol)) { printf("Didn't your mother ever tell you not to hear music so loudly?\n"); return(-1); } */
+
+ /* Let's init our environment */
+
+ env.size = 0;
+ env.debut = NULL;
+ env.ptr = NULL;
+ env.play = 0;
+
+ #if MOSX_USES_SEM
+ strcpy(s, "/mpg123-0000");
+ do
+ {
+ for(m = 10;; m--)
+ if( (s[m]++) <= '9')
+ break;
+ else
+ s[m] = '0';
+ } while( (env.semaphore = sem_open(s, O_CREAT | O_EXCL, 0644, 0)) == (sem_t *)SEM_FAILED);
+ #else
+ env.pid = getpid();
+ env.wait = 0;
+ signal(SIGUSR2, start);
+ #endif
+
+ initBuffers();
+
+ /* And prepare audio launching */
+
+ if(AudioDeviceAddIOProc(env.device, playProc, &env)) return(-1);
+
+ return(0);
+}
+
+int audio_reset_parameters(struct audio_info_struct *ai)
+{
+ return 0;
+}
+
+int audio_rate_best_match(struct audio_info_struct *ai)
+{
+ return 0;
+}
+
+int audio_set_rate(struct audio_info_struct *ai)
+{
+ return 0;
+}
+
+int audio_set_channels(struct audio_info_struct *ai)
+{
+ return 0;
+}
+
+int audio_set_format(struct audio_info_struct *ai)
+{
+ return 0;
+}
+
+int audio_get_formats(struct audio_info_struct *ai)
+{
+ return AUDIO_FORMAT_SIGNED_16;
+}
+
+int audio_play_samples(struct audio_info_struct *ai,unsigned char *buf,int len)
+{
+ /* We have to calm down mpg123, else he wouldn't hesitate to drop us another buffer (which would be the same, in fact) */
+
+ #if MOSX_USES_SEM && MOSX_SEM_V2 /* Suddenly, I have some kind of doubt: HOW COULD IT WORK??? */
+ while(sem_wait(env.semaphore)){} /* We just have to wait a buffer fill request */
+ fillBuffer(env.to, (short *)buf, len / sizeof(short));
+ #else
+ while(fillBuffer(env.to, (short *)buf, len / sizeof(short)) < 0) /* While the next buffer to write is not empty, we wait a bit... */
+ {
+ #ifdef DEBUG_MOSX
+ printf("|"); fflush(stdout);
+ #endif
+ #if MOSX_USES_SEM
+ sem_wait(env.semaphore); /* This is a bug. I should wait for the semaphore once per empty buffer (and not each time fillBuffers() returns -1). See MOSX_SEM_V2; this was a too quickly modified part when I implemented MOSX_USES_SEM. */
+ #else
+ env.wait = 1;
+ sleep(3600); /* This should be sufficient, shouldn't it? */
+ #endif
+ }
+ #endif
+ env.to = env.to->next;
+
+ /* And we lauch action if not already done */
+
+ if(!env.play)
+ {
+ if(AudioDeviceStart(env.device, playProc)) return(-1);
+ env.play = 1;
+ }
+
+ return len;
+}
+
+int audio_close(struct audio_info_struct *ai)
+{
+ AudioDeviceStop(env.device, playProc); /* No matter the error code, we want to close it (by brute force if necessary) */
+ AudioDeviceRemoveIOProc(env.device, playProc);
+ destroyBuffers();
+ #if MOSX_USES_SEM
+ sem_close(env.semaphore);
+ #endif
+ return 0;
+}
--- mpg123/common.c Thu May 17 02:56:56 2001
+++ mpg123-patched/common.c Sun Jan 19 17:37:04 2003
@@ -140,7 +140,7 @@
* -1: giving up
* 1: synched
*/
-#define MAX_INPUT_FRAMESIZE 1920
+#define MAX_INPUT_FRAMESIZE 4096
#define SYNC_HEAD_MASK 0xffff0000
#define SYNC_HEAD_MASK_FF 0x0000f000
#define LOOK_AHEAD_NUM 3
--- mpg123/httpget.c Mon Oct 30 12:45:12 2000
+++ mpg123-patched/httpget.c Thu Nov 8 12:42:43 2001
@@ -233,8 +233,10 @@
int relocate, numrelocs = 0;
FILE *myfile;
#ifdef INET6
- struct addrinfo hints, *res, *res0;
- int error;
+// struct addrinfo hints, *res, *res0;
+// int error;
+ struct hostent *hp;
+ struct sockaddr_in6 sin;
#else
struct hostent *hp;
struct sockaddr_in sin;
@@ -345,7 +347,7 @@
strcat (request, ACCEPT_HEAD);
#ifdef INET6
- memset(&hints, 0, sizeof(hints));
+/* memset(&hints, 0, sizeof(hints));
hints.ai_socktype = SOCK_STREAM;
error = getaddrinfo(host, (char *)myport, &hints, &res0);
if (error) {
@@ -366,7 +368,28 @@
break;
}
- freeaddrinfo(res0);
+ freeaddrinfo(res0);*/
+
+ sock = -1;
+ hp = gethostbyname2(host,AF_INET6);
+ if (!hp)
+ goto fail;
+ if (hp->h_length != sizeof(sin.sin6_addr))
+ goto fail;
+ sock = socket(AF_INET6, SOCK_STREAM, IPPROTO_TCP);
+ if (sock < 0)
+ goto fail;
+ memset(&sin, 0, sizeof(sin));
+ sin.sin6_family = AF_INET6;
+ /* sin.sin_len = sizeof(struct sockaddr_in); */
+ memcpy(&sin.sin6_addr, hp->h_addr, hp->h_length);
+ sin.sin6_port = htons(atoi( (char *) myport));
+ if (connect(sock, (struct sockaddr *)&sin, sizeof(struct sockaddr_in6) ) < 0) {
+ perror("connect");
+ close(sock);
+ sock = -1;
+ }
+fail:
#else
sock = -1;
hp = gethostbyname(host);
Package: mpg123
Version: 0.61
Revision: 1
Epoch: 1
Maintainer: Nicholas Humfrey
Source: mirror:sourceforge:%n/%n-%v.tar.bz2
Source-MD5: 13b505ec04e5afb10399c89f24e99f0e
Conflicts: mpg321
Replaces: mpg321
ConfigureParams: --with-audio=macosx --mandir=%p/share/man --disable-dependency-tracking
InstallScript: make install DESTDIR=%d
DocFiles: <<
AUTHORS COPYING NEWS README
doc/BENCHMARKING doc/BUGS doc/CONTACT doc/LICENSE
doc/PATENTS doc/README.gain doc/README.remote
doc/THANKS doc/TODO
<<
Description: Real time MPEG Audio Player
DescDetail: <<
mpg123 is a fast, free and portable MPEG audio player for Unix. It
supports MPEG 1.0/2.0 layers 1, 2 and 3.
<<
License: LGPL
Homepage: http://www.mpg123.org/