[PD-cvs] pd/portaudio/src/hostapi/oss low_latency_tip.txt, NONE, 1.1 pa_unix_oss.c, NONE, 1.1 recplay.c, NONE, 1.1
Miller Puckette
millerpuckette at users.sourceforge.net
Sun Aug 19 01:49:35 CEST 2007
- Previous message: [PD-cvs] pd/portaudio/src/hostapi/jack pa_jack.c,NONE,1.1
- Next message: [PD-cvs] pd/portaudio/include pa_asio.h, NONE, 1.1 pa_jack.h, NONE, 1.1 pa_linux_alsa.h, NONE, 1.1 pa_mac_core.h, NONE, 1.1 pa_win_wmme.h, NONE, 1.1 portaudio.h, NONE, 1.1
- Messages sorted by:
[ date ]
[ thread ]
[ subject ]
[ author ]
Update of /cvsroot/pure-data/pd/portaudio/src/hostapi/oss
In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv19525/portaudio/src/hostapi/oss
Added Files:
low_latency_tip.txt pa_unix_oss.c recplay.c
Log Message:
CVS upload mistakes
--- NEW FILE: recplay.c ---
/*
* recplay.c
* Phil Burk
* Minimal record and playback test.
*
*/
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#ifndef __STDC__
/* #include <getopt.h> */
#endif /* __STDC__ */
#include <fcntl.h>
#ifdef __STDC__
#include <string.h>
#else /* __STDC__ */
#include <strings.h>
#endif /* __STDC__ */
#include <sys/soundcard.h>
#define NUM_BYTES (64*1024)
#define BLOCK_SIZE (4*1024)
#define AUDIO "/dev/dsp"
char buffer[NUM_BYTES];
int audioDev = 0;
main (int argc, char *argv[])
{
int numLeft;
char *ptr;
int num;
int samplesize;
/********** RECORD ********************/
/* Open audio device. */
audioDev = open (AUDIO, O_RDONLY, 0);
if (audioDev == -1)
{
perror (AUDIO);
exit (-1);
}
/* Set to 16 bit samples. */
samplesize = 16;
ioctl(audioDev, SNDCTL_DSP_SAMPLESIZE, &samplesize);
if (samplesize != 16)
{
perror("Unable to set the sample size.");
exit(-1);
}
/* Record in blocks */
printf("Begin recording.\n");
numLeft = NUM_BYTES;
ptr = buffer;
while( numLeft >= BLOCK_SIZE )
{
if ( (num = read (audioDev, ptr, BLOCK_SIZE)) < 0 )
{
perror (AUDIO);
exit (-1);
}
else
{
printf("Read %d bytes\n", num);
ptr += num;
numLeft -= num;
}
}
close( audioDev );
/********** PLAYBACK ********************/
/* Open audio device for writing. */
audioDev = open (AUDIO, O_WRONLY, 0);
if (audioDev == -1)
{
perror (AUDIO);
exit (-1);
}
/* Set to 16 bit samples. */
samplesize = 16;
ioctl(audioDev, SNDCTL_DSP_SAMPLESIZE, &samplesize);
if (samplesize != 16)
{
perror("Unable to set the sample size.");
exit(-1);
}
/* Play in blocks */
printf("Begin playing.\n");
numLeft = NUM_BYTES;
ptr = buffer;
while( numLeft >= BLOCK_SIZE )
{
if ( (num = write (audioDev, ptr, BLOCK_SIZE)) < 0 )
{
perror (AUDIO);
exit (-1);
}
else
{
printf("Wrote %d bytes\n", num);
ptr += num;
numLeft -= num;
}
}
close( audioDev );
}
--- NEW FILE: pa_unix_oss.c ---
/*
* $Id: pa_unix_oss.c,v 1.1 2007/08/18 23:49:33 millerpuckette Exp $
* PortAudio Portable Real-Time Audio Library
* Latest Version at: http://www.portaudio.com
* OSS implementation by:
* Douglas Repetto
* Phil Burk
* Dominic Mazzoni
* Arve Knudsen
*
* Based on the Open Source API proposed by Ross Bencina
* Copyright (c) 1999-2002 Ross Bencina, Phil Burk
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files
* (the "Software"), to deal in the Software without restriction,
* including without limitation the rights to use, copy, modify, merge,
* publish, distribute, sublicense, and/or sell copies of the Software,
* and to permit persons to whom the Software is furnished to do so,
[...1907 lines suppressed...]
audio_buf_info info;
if( ioctl( stream->capture->fd, SNDCTL_DSP_GETISPACE, &info ) < 0 )
return paUnanticipatedHostError;
return info.fragments * stream->capture->hostFrames;
}
/* TODO: Compute number of allocated bytes somewhere else, can we use ODELAY with capture */
static signed long GetStreamWriteAvailable( PaStream* s )
{
PaOssStream *stream = (PaOssStream*)s;
int delay = 0;
if( ioctl( stream->playback->fd, SNDCTL_DSP_GETODELAY, &delay ) < 0 )
return paUnanticipatedHostError;
return (PaOssStreamComponent_BufferSize( stream->playback ) - delay) / PaOssStreamComponent_FrameSize( stream->playback );
}
--- NEW FILE: low_latency_tip.txt ---
From: "Benno Senoner" <sbenno at gardena.net>
To: <music-dsp at shoko.calarts.edu>
Subject: Re: [music-dsp] coding realtime guitar efx on a "pc"
Date: Saturday, June 30, 2001 8:19 AM
Andrè,
you are solving your problem the wrong way:
you need to use a single threaded solution which does this:
- set the audio I/O parameters to fragnum=4 fragsize=128 bytes (=32samples) if
you use stereo or fragsize=64 bytes (=32 samples) if you use mono.
(do not forget to activate fulltuplex with using the _TRIGGER_ stuff)
(you need to frist deactivate audio and then start the trigger after the DAC is
prefilled (see below))
This will give you a total input to output latency of 4x32 samples
= 128 samples which at 44.1kHz correspond to 2.9msec latency.
now set your process to SCHED_FIFO (see man sched_setscheduler)
after the initialization your code should do more than less this:
- write() 4 x 32 samples to the audio fd in order to prefill the DAC.
Without this you will get dropouts.
while(1) {
read() 32 samples from ADC
perform_dsp_stuff() on the 32 samples
write() 32 samples to DAC
}
If you use a low latency kernel and pay attention to all the stuff above, then
you will get rock solid 3msec latencies (plus eventual converter latencies but
these are in the 1-2msec range AFAIK).
Using multiple threads , pipes etc, only complicates your life and often makes
it impossible to achieve these low latences.
Realtime/audio programming is not an easy task , this is why people often
fail to get the desired results even if their hardware is low-latency capable.
The problem is that the final latency depends on the hardware you use,
the application and the operating system.
cheers,
Benno.
http://www.linuxaudiodev.org The Home of Linux Audio Development
On Sat, 30 Jun 2001, you wrote:
> On 2001-06-29 21:38 +0200, Benno Senoner wrote:
>
> > OSS/Free refuses to use a low # of frags ?
> >
> > That's a myth.
>
> I hope it is. :-)
>
> The fact is that ioctl(SNDCTL_DSP_SETFRAGMENT) succeeds with
> values as low a 0x10007 (one 128-B fragment) but the latency is
> still high enough to be clearly noticeable, which suggests that
> it's *way* above 2/3 ms. This is on an otherwise idle machine
> equipped with a SB PCI 128.
>
> But maybe it's me who's doing something wrong. I've been careful
> to flush stdio buffers or use unbuffered I/O (write(2)) but I
> may have let something else through.
>
> For example, since the signal processing and the I/O are done by
> two different vanilla processes communicating via pipes, it may
> be a scheduling granularity problem (E.G. the kernel giving the
> I/O process a time slice every 20 ms).
>
> --
> André Majorel <amajorel at teaser.fr>
> http://www.teaser.fr/~amajorel/
>
> dupswapdrop -- the music-dsp mailing list and website: subscription info,
> FAQ, source code archive, list archive, book reviews, dsp links
> http://shoko.calarts.edu/musicdsp/
--
dupswapdrop -- the music-dsp mailing list and website: subscription info,
FAQ, source code archive, list archive, book reviews, dsp links
http://shoko.calarts.edu/musicdsp/
- Previous message: [PD-cvs] pd/portaudio/src/hostapi/jack pa_jack.c,NONE,1.1
- Next message: [PD-cvs] pd/portaudio/include pa_asio.h, NONE, 1.1 pa_jack.h, NONE, 1.1 pa_linux_alsa.h, NONE, 1.1 pa_mac_core.h, NONE, 1.1 pa_win_wmme.h, NONE, 1.1 portaudio.h, NONE, 1.1
- Messages sorted by:
[ date ]
[ thread ]
[ subject ]
[ author ]
More information about the Pd-cvs
mailing list