Audio-Play-MPG123
view release on metacpan or search on metacpan
mpg123/BENCHMARKING view on Meta::CPAN
The mp3 benchmarking lie?
-------------------------
Let's write a few notes about benchmarking the different mp3 decoders,
which are available. 'top' is NOT a benchmark, it's a simple check
how a program performs. The sad thing with 'top' is, that it has some
problems with the measurement of threaded programs of programs only
requesting short chunks of processor time. So, the only real test is
probably decoding a stream without threads with 100% CPU time and
measure the time how long your machine needs for it.
You can do this with mpg123 by doing a
time mpg123 -t mp3stream.mp3
or
time mpg123 -s mp3stream.mp3 > /dev/null
if you additionally want to measure the I/O time.
If you find a player, which claims to be 10 or even more times faster than the
current players: just don't believe it. A factor of 2 MAY BE possible.
mpg123/audio_os2.c view on Meta::CPAN
static HEV dataplayed = 0;
static ULONG resetcount;
static BOOL paused = FALSE;
static MCI_MIX_BUFFER *tobefilled, *playingbuffer = NULL, playedbuffer;
static void *pBufferplayed;
static BOOL nomoredata,nobuffermode,justflushed;
static TIB *mainthread; /* thread info to set thread priority */
ULONG keyboardtid;
static LONG APIENTRY DARTEvent(ULONG ulStatus, MCI_MIX_BUFFER *PlayedBuffer, ULONG ulFlags)
{
switch(ulFlags)
{
case MIX_STREAM_ERROR | MIX_WRITE_COMPLETE: /* error occur in device */
mpg123/audio_os2.c view on Meta::CPAN
tobefilled = ((BUFFERINFO *) playingbuffer->ulUserParm)->NextBuffer;
nomoredata = TRUE;
}
else
{
playingframe = ((BUFFERINFO *) playingbuffer->ulUserParm)->frameNum;
/* if we're about to be short of decoder's data
(2nd ahead buffer not filled), let's boost its priority! */
if(tobefilled == ( (BUFFERINFO *) ((BUFFERINFO *) playingbuffer->ulUserParm)->NextBuffer->ulUserParm)->NextBuffer)
DosSetPriority(PRTYS_THREAD,boostclass,boostdelta,mainthread->tib_ptib2->tib2_ultid);
}
/* empty the played buffer in case it doesn't get filled back */
memset(PlayedBuffer->pBuffer,0,PlayedBuffer->ulBufferLength);
DosPostEventSem(dataplayed);
mmp.pmixWrite( mmp.ulMixHandle,
PlayedBuffer /* will contain new data */,
1 );
mpg123/audio_os2.c view on Meta::CPAN
MixBuffers[i].ulFlags = 0;
MixBuffers[i].ulBufferLength = mbp.ulBufferSize;
memset(MixBuffers[i].pBuffer, 0, MixBuffers[i].ulBufferLength);
MixBuffers[i].ulUserParm = (ULONG) &bufferinfo[i];
bufferinfo[i].NextBuffer = &MixBuffers[i+1];
}
bufferinfo[i-1].NextBuffer = &MixBuffers[0];
/* Create a semaphore to know when data has been played by the DART thread */
DosCreateEventSem(NULL,&dataplayed,0,FALSE);
playingbuffer = &MixBuffers[0];
tobefilled = &MixBuffers[1];
playingframe = 0;
nomoredata = TRUE;
nobuffermode = FALSE;
justflushed = FALSE;
if(boostprio)
mpg123/audio_os2.c view on Meta::CPAN
normaldelta = atoi(temp+1);
*(temp+1) = 0;
normalclass = atoi(temp);
}
if(normalclass > 4) normaldelta = 3;
if(normaldelta > 31) normaldelta = 31;
if(normaldelta < -31) normaldelta = -31;
DosGetInfoBlocks(&mainthread,&ppib); /* ppib not needed, but makes some DOSCALLS.DLL crash */
DosSetPriority(PRTYS_THREAD,boostclass,boostdelta,mainthread->tib_ptib2->tib2_ultid);
/* Write buffers to kick off the amp mixer. see DARTEvent() */
rc = mmp.pmixWrite( mmp.ulMixHandle,
MixBuffers,
ulMCIBuffers );
return maop.usDeviceID;
}
int audio_play_samples(struct audio_info_struct *ai,unsigned char *buf,int len)
mpg123/audio_os2.c view on Meta::CPAN
{
nomoredata = FALSE;
memcpy(tobefilled->pBuffer, buf, len);
tobefilled->ulBufferLength = len;
// ((BUFFERINFO *) tobefilled->ulUserParm)->frameNum = fr->frameNum;
/* if we're out of the water (3rd ahead buffer filled),
let's reduce our priority */
if(tobefilled == ( (BUFFERINFO *) ( (BUFFERINFO *) ((BUFFERINFO *) playingbuffer->ulUserParm)->NextBuffer->ulUserParm)->NextBuffer->ulUserParm)->NextBuffer)
DosSetPriority(PRTYS_THREAD,normalclass,normaldelta,mainthread->tib_ptib2->tib2_ultid);
tobefilled = ((BUFFERINFO *) tobefilled->ulUserParm)->NextBuffer;
}
return len;
}
int audio_playing_samples(struct audio_info_struct *ai,unsigned char *buf,int len)
{
if(len > audiobufsize || !playingbuffer) return -1;
mpg123/tools/interface-and-phython view on Meta::CPAN
"""(crude) Python interface to mpg123 via the tk3play control interface
Message format is "%d %d" where the first number is one of the MSG_
codes and the second command depdendent.
"""
import popen2
import select
import string
import sys
import threading
import time
# from enum on control_tk3play.h:
MSG_CTRL = 0
MSG_BUFFER = 1
MSG_SONG = 2
MSG_QUIT = 3
MSG_NEXT = 4
MSG_RESPONSE = 5
MSG_FRAMES = 6
mpg123/tools/interface-and-phython view on Meta::CPAN
REWIND_END = 7
# Decoder modes
MODE_STOPPED = 0
MODE_PLAYING_AND_DECODING = 1
MODE_PLAYING_OLD_DECODING_NEW = 2
MODE_PLAYING_NOT_DECODING = 3
MODE_PLAYING_OLD_FINISHED_DECODING_NEW = 4
MODE_PAUSED = 5
class Status(threading.Thread):
def __init__(self, player):
threading.Thread.__init__(self)
self.setDaemon(1)
self.player = player
def run(self):
while 1:
try:
print self.player.time, self.player.frame
except AttributeError:
pass
time.sleep(1)
class MP3Player(threading.Thread):
def __init__(self):
threading.Thread.__init__(self)
# self.from_player, self.to_player = popen2.popen2("mpg123m -b 1024", 0)
self.from_player, self.to_player = popen2.popen2("mpg123m", 0)
self.resp_fileno_l = [self.from_player.fileno()]
self.running = 1
self.paused = 0
self.frame = None
self.dispatch = {}
def __del__(self):
if self.running:
( run in 1.011 second using v1.01-cache-2.11-cpan-3cd7ad12f66 )