- More remnants deleted of old portaudio-v19

They have done a major re-org of their directory structure



git-svn-id: svn+ssh://svn.code.sf.net/p/wsjt/wsjt/trunk@254 ab8295b8-cf94-4d9e-aec4-7959e3be5d79
This commit is contained in:
Diane Bruce 2006-08-09 21:26:22 +00:00
parent 0981dc4123
commit fe4de879ac
11 changed files with 0 additions and 3154 deletions

View File

@ -1,186 +0,0 @@
# Generated automatically from Makefile.in by configure.
#
# PortAudio V19 Makefile.in
#
# Dominic Mazzoni
#
PREFIX = /usr/local
CC = cc
CFLAGS = -g -O2 -Wall -pedantic -pipe -fPIC -DPA_LITTLE_ENDIAN -I/usr/local/include -Ipa_common -DSIZEOF_SHORT=2 -DSIZEOF_INT=4 -DSIZEOF_LONG=4 -DHAVE_LIBPTHREAD=1 -DPA_USE_JACK=1 -DPA_USE_OSS=1
LIBS = -lpthread -pthread -L/usr/local/lib -ljack -lm -lpthread
AR = /usr/bin/ar
RANLIB = ranlib
INSTALL = /usr/bin/install -c -o root -g wheel
SHARED_FLAGS = -shared -fPIC
DLL_LIBS = -pthread -L/usr/local/lib -ljack
CXXFLAGS = -O2 -pipe
NASM =
NASMOPT =
OTHER_OBJS = pa_jack/pa_jack.o pa_unix_oss/pa_unix_oss.o pa_unix/pa_unix_hostapis.o pa_unix/pa_unix_util.o
PALIB = libportaudio.a
PADLL = libportaudio.so
PADLLV = $(PADLL).0.0.19
PAINC = pa_common/portaudio.h
COMMON_OBJS = \
pa_common/pa_allocation.o \
pa_common/pa_converters.o \
pa_common/pa_cpuload.o \
pa_common/pa_dither.o \
pa_common/pa_front.o \
pa_common/pa_process.o \
pa_common/pa_skeleton.o \
pa_common/pa_stream.o \
pa_common/pa_trace.o
TESTS = \
bin/paqa_devs \
bin/paqa_errs \
bin/patest1 \
bin/patest_buffer \
bin/patest_callbackstop \
bin/patest_clip \
bin/patest_dither \
bin/patest_hang \
bin/patest_in_overflow \
bin/patest_latency \
bin/patest_leftright \
bin/patest_longsine \
bin/patest_many \
bin/patest_maxsines \
bin/patest_multi_sine \
bin/patest_out_underflow \
bin/patest_pink \
bin/patest_prime \
bin/patest_read_record \
bin/patest_record \
bin/patest_ringmix \
bin/patest_saw \
bin/patest_sine8 \
bin/patest_sine \
bin/patest_sine_formats \
bin/patest_sine_time \
bin/patest_start_stop \
bin/patest_stop \
bin/patest_sync \
bin/patest_toomanysines \
bin/patest_underflow \
bin/patest_wire \
bin/patest_write_sine \
bin/pa_devs \
bin/pa_fuzz \
bin/pa_minlat
# Most of these don't compile yet. Put them in TESTS, above, if
# you want to try to compile them...
ALL_TESTS = \
bin/debug_convert \
bin/debug_dither_calc \
bin/debug_dual \
bin/debug_multi_in \
bin/debug_multi_out \
bin/debug_record \
bin/debug_record_reuse \
bin/debug_sine_amp \
bin/debug_sine \
bin/debug_sine_formats \
bin/debug_srate \
bin/debug_test1 \
bin/pa_devs \
bin/pa_fuzz \
bin/pa_minlat \
bin/paqa_devs \
bin/paqa_errs \
bin/patest1 \
bin/patest_buffer \
bin/patest_clip \
bin/patest_dither \
bin/patest_hang \
bin/patest_in_overflow \
bin/patest_latency \
bin/patest_leftright \
bin/patest_longsine \
bin/patest_many \
bin/patest_maxsines \
bin/patest_multi_sine \
bin/patest_out_underflow \
bin/patest_pink \
bin/patest_read_record \
bin/patest_record \
bin/patest_ringmix \
bin/patest_saw \
bin/patest_sine8 \
bin/patest_sine \
bin/patest_sine_formats \
bin/patest_sine_time \
bin/patest_start_stop \
bin/patest_stop \
bin/patest_sync \
bin/patest_toomanysines \
bin/patest_underflow \
bin/patest_wire \
bin/patest_write_sine
OBJS = $(COMMON_OBJS) $(OTHER_OBJS)
all: lib/$(PALIB) lib/$(PADLLV)
tests: bin/ $(TESTS)
lib/$(PALIB): lib/ $(OBJS) Makefile $(PAINC)
$(AR) ruv lib/$(PALIB) $(OBJS)
$(RANLIB) lib/$(PALIB)
lib/$(PADLLV): lib/ $(OBJS) Makefile $(PAINC)
$(CC) $(SHARED_FLAGS) -o lib/$(PADLLV) $(OBJS) $(DLL_LIBS)
$(TESTS): bin/%: lib/$(PALIB) Makefile $(PAINC) pa_tests/%.c
$(CC) -o $@ $(CFLAGS) pa_tests/$*.c lib/$(PALIB) $(LIBS)
install: lib/$(PALIB) lib/$(PADLLV)
$(INSTALL) -d $(PREFIX)/lib
$(INSTALL) -m 644 lib/$(PADLLV) $(PREFIX)/lib/$(PADLLV)
$(INSTALL) -m 644 lib/$(PALIB) $(PREFIX)/lib/$(PALIB)
cd $(PREFIX)/lib && rm -f $(PADLL) && ln -s $(PADLLV) $(PADLL)
$(INSTALL) -d $(PREFIX)/include
$(INSTALL) -m 644 pa_common/portaudio.h $(PREFIX)/include/portaudio.h
@echo ""
@echo "------------------------------------------------------------"
@echo "PortAudio was successfully installed."
@echo ""
@echo "On some systems (e.g. Linux) you should run 'ldconfig' now"
@echo "to make the shared object available. You may also need to"
@echo "modify your LD_LIBRARY_PATH environment variable to include"
@echo "the directory $(PREFIX)/lib"
@echo "------------------------------------------------------------"
@echo ""
uninstall:
rm -f $(PREFIX)/lib/$(PADLLV)
rm -f $(PREFIX)/lib/$(PALIB)
rm -f $(PREFIX)/lib/$(PADLL)
rm -f $(PREFIX)/include/portaudio.h
clean:
rm -f $(OBJS) $(TESTS) lib/$(PALIB) lib/$(PADLLV)
%.o: %.c Makefile $(PAINC)
$(CC) -c $(CFLAGS) $< -o $@
%.o: %.cpp Makefile $(PAINC)
$(CXX) -c $(CXXFLAGS) $< -o $@
%.o: %.asm
$(NASM) $(NASMOPT) -o $@ $<
bin:
mkdir bin
lib:
mkdir lib

View File

@ -1,198 +0,0 @@
import os.path, copy, sys
def checkSymbol(conf, header, library=None, symbol=None, autoadd=True, critical=False, pkgName=None):
env = conf.env
if library is None:
library = "c" # Standard library
autoadd = False
if pkgName is not None:
origLibPath = copy.copy(env.get("LIBPATH", None))
origLibs = copy.copy(env.get("LIBS", None))
origLinkFlags = copy.copy(env.get("LINKFLAGS", None))
origCppFlags = copy.copy(env.get("CPPFLAGS", None))
origCppPath = copy.copy(env.get("CPPPATH", None))
origCcFlags = copy.copy(env.get("CCFLAGS", None))
origAsFlags = copy.copy(env.get("ASFLAGS", None))
try: env.ParseConfig("pkg-config --silence-errors %s --cflags --libs" % pkgName)
except: pass
else:
# I see no other way of checking that the parsing succeeded, if it did add no more linking parameters
if env["LIBS"] != origLibs:
autoadd = False
try:
if not conf.CheckCHeader(header, include_quotes="<>"):
raise ConfigurationError("missing header %s" % header)
if symbol is not None and not conf.CheckLib(library, symbol, language="C", autoadd=autoadd):
raise ConfigurationError("missing symbol %s in library %s" % (symbol, library))
except ConfigurationError:
if pkgName is not None:
# Restore any changes made by ParseConfig
if origLibPath is not None:
env["LIBPATH"] = origLibPath
if origLibs is not None:
env["LIBS"] = origLibs
if origLinkFlags is not None:
env["LINKFLAGS"] = origLinkFlags
if origCppFlags is not None:
env["CPPFLAGS"] = origCppFlags
if origCppPath is not None:
env["CPPPATH"] = origCppPath
if origCcFlags is not None:
env["CCFLAGS"] = origCcFlags
if origAsFlags is not None:
env["ASFLAGS"] = origAsFlags
if not critical:
return False
raise
return True
Import("env", "Platform", "Posix", "ConfigurationError")
# Store all signatures in one file, otherwise .sconsign files will get installed along with our own files
env.SConsignFile()
neededLibs = []
optionalImpls = {}
if Platform in Posix:
neededLibs += [("pthread", "pthread.h", "pthread_create"), ("m", "math.h", "sin")]
if env["useALSA"]:
optionalImpls["ALSA"] = ("asound", "alsa/asoundlib.h", "snd_pcm_open")
if env["useJACK"]:
optionalImpls["JACK"] = ("jack", "jack/jack.h", "jack_client_new")
if env["useOSS"]:
# TODO: It looks like the prefix for soundcard.h depends on the platform
optionalImpls["OSS"] = ("oss", "sys/soundcard.h", None)
else:
raise ConfigurationError("unknown platform %s" % Platform)
if Platform == "darwin":
env.Append(LINKFLAGS=["-framework CoreAudio", "-framework AudioToolBox"])
env.Append(CPPDEFINES=["PA_USE_COREAUDIO"])
elif Platform == "cygwin":
env.Append(LIBS=["winmm"])
elif Platform == "irix":
neededLibs += [("audio", "dmedia/audio.h", "alOpenPort"), ("dmedia", "dmedia/dmedia.h", "dmGetUST")]
env.Append(CPPDEFINES=["PA_USE_SGI"])
def CheckCTypeSize(context, tp):
context.Message("Checking the size of C type %s..." % tp)
ret = context.TryRun("""
#include <stdio.h>
int main() {
printf("%%d", sizeof(%s));
return 0;
}
""" % tp, ".c")
if not ret[0]:
context.Result(" Couldn't obtain size of type %s!" % tp)
return None
assert ret[1]
sz = int(ret[1])
context.Result("%d" % sz)
return sz
if sys.byteorder == "little":
env.Append(CPPDEFINES=["PA_LITTLE_ENDIAN"])
elif sys.byteorder == "big":
env.Append(CPPDEFINES=["PA_BIG_ENDIAN"])
else:
raise ConfigurationError("unknown byte order: %s" % sys.byteorder)
if env["enableDebugOutput"]:
env.Append(CPPDEFINES=["PA_ENABLE_DEBUG_OUTPUT"])
# Start configuration
conf = env.Configure(log_file="sconf.log", custom_tests={"CheckCTypeSize": CheckCTypeSize})
env.Append(CPPDEFINES=["SIZEOF_SHORT=%d" % conf.CheckCTypeSize("short")])
env.Append(CPPDEFINES=["SIZEOF_INT=%d" % conf.CheckCTypeSize("int")])
env.Append(CPPDEFINES=["SIZEOF_LONG=%d" % conf.CheckCTypeSize("long")])
if checkSymbol(conf, "time.h", "rt", "clock_gettime"):
env.Append(CPPDEFINES=["HAVE_CLOCK_GETTIME"])
if checkSymbol(conf, "time.h", "nanosleep"):
env.Append(CPPDEFINES=["HAVE_NANOSLEEP"])
for lib, hdr, sym in neededLibs:
checkSymbol(conf, hdr, lib, sym, critical=True)
for name, val in optionalImpls.items():
lib, hdr, sym = val
if checkSymbol(conf, hdr, lib, sym, critical=False, pkgName=name.lower()):
env.Append(CPPDEFINES=["PA_USE_%s=1" % name.upper()])
# Configuration finished
env = conf.Finish()
CommonSources = [os.path.join("pa_common", f) for f in "pa_allocation.c pa_converters.c pa_cpuload.c pa_dither.c pa_front.c \
pa_process.c pa_skeleton.c pa_stream.c pa_trace.c".split()]
ImplSources = []
if Platform in Posix:
env.AppendUnique(LINKFLAGS=["-pthread"])
BaseCFlags = "-Wall -pedantic -pipe -pthread"
DebugCFlags = "-g"
OptCFlags = "-O2"
ImplSources += [os.path.join("pa_unix", f) for f in "pa_unix_hostapis.c pa_unix_util.c".split()]
if "ALSA" in optionalImpls:
ImplSources.append(os.path.join("pa_linux_alsa", "pa_linux_alsa.c"))
if "JACK" in optionalImpls:
ImplSources.append(os.path.join("pa_jack", "pa_jack.c"))
if "OSS" in optionalImpls:
ImplSources.append(os.path.join("pa_unix_oss", "pa_unix_oss.c"))
env["CCFLAGS"] = BaseCFlags
if env["enableDebug"]:
env["CCFLAGS"] += " " + DebugCFlags
if env["enableOptimize"]:
env["CCFLAGS"] += " " + OptCFlags
if not env["enableAsserts"]:
env.Append(CPPDEFINES=["-DNDEBUG"])
if env["customCFlags"]:
env["CCFLAGS"] += " " + env["customCFlags"]
sources = CommonSources + ImplSources
if env["enableShared"]:
sharedLib = env.SharedLibrary(target="portaudio", source=sources)
else:
sharedLib = None
staticLib = env.StaticLibrary(target="portaudio", source=sources)
if Platform in Posix:
prefix = env["prefix"]
env.Alias("install", env.Install(os.path.join(prefix, "include"), os.path.join("pa_common", "portaudio.h")))
if env["enableStatic"]:
env.Alias("install", env.Install(os.path.join(prefix, "lib"), staticLib))
def symlink(env, target, source):
trgt = str(target[0])
src = str(source[0])
print trgt, src
if os.path.exists(trgt):
os.remove(trgt)
os.symlink("libportaudio.so.0.0.19", trgt)
if env["enableShared"]:
env.Alias("install", env.InstallAs(target=os.path.join(prefix, "lib", "%s.0.0.19") % sharedLib[0], source=sharedLib))
env.Alias("install", env.Command(os.path.join(prefix, "lib", "libportaudio.so"), sharedLib, symlink))
testNames = ["patest_sine", "paqa_devs", "paqa_errs", "patest1", "patest_buffer", "patest_callbackstop", "patest_clip", \
"patest_dither", "patest_hang", "patest_in_overflow", "patest_latency", "patest_leftright", "patest_longsine", \
"patest_many", "patest_maxsines", "patest_multi_sine", "patest_out_underflow", "patest_pink", "patest_prime", \
"patest_read_record", "patest_record", "patest_ringmix", "patest_saw", "patest_sine8", "patest_sine", \
"patest_sine_time", "patest_start_stop", "patest_stop", "patest_sync", \
"patest_toomanysines", "patest_underflow", "patest_wire", "patest_write_sine", "pa_devs", "pa_fuzz", "pa_minlat"]
# The test directory ("bin") should be in the top-level PA directory, the calling script should ensure that SCons doesn't
# switch current directory by calling SConscriptChdir(False). Specifying an absolute directory for each target means it won't
# be relative to the build directory
tests = [env.Program(target=os.path.join(os.getcwd(), "bin", name), source=[os.path.join("pa_tests", name + ".c"), staticLib]) for name in testNames]
Return("sources", "sharedLib", "staticLib")

View File

@ -1,30 +0,0 @@
# This file is a shell script that caches the results of configure
# tests run on this system so they can be shared between configure
# scripts and configure runs. It is not useful on other systems.
# If it contains results you don't want to keep, you may remove or edit it.
#
# By default, configure uses ./config.cache as the cache file,
# creating it if it does not exist already. You can give configure
# the --cache-file=FILE option to use a different cache file; that is
# what configure does when it calls configure scripts in
# subdirectories, so they share the cache.
# Giving --cache-file=/dev/null disables caching, for debugging configure.
# config.status only pays attention to the cache file if you give it the
# --recheck option to rerun configure.
#
ac_cv_c_bigendian=${ac_cv_c_bigendian=no}
ac_cv_lib_asound_snd_pcm_open=${ac_cv_lib_asound_snd_pcm_open=no}
ac_cv_lib_pthread_pthread_create=${ac_cv_lib_pthread_pthread_create=yes}
ac_cv_path_AR=${ac_cv_path_AR=/usr/bin/ar}
ac_cv_path_PKG_CONFIG=${ac_cv_path_PKG_CONFIG=/usr/local/bin/pkg-config}
ac_cv_path_install=${ac_cv_path_install='/usr/bin/install -c'}
ac_cv_prog_CC=${ac_cv_prog_CC=cc}
ac_cv_prog_RANLIB=${ac_cv_prog_RANLIB=ranlib}
ac_cv_prog_cc_cross=${ac_cv_prog_cc_cross=no}
ac_cv_prog_cc_g=${ac_cv_prog_cc_g=yes}
ac_cv_prog_cc_works=${ac_cv_prog_cc_works=yes}
ac_cv_prog_gcc=${ac_cv_prog_gcc=yes}
ac_cv_sizeof_int=${ac_cv_sizeof_int=4}
ac_cv_sizeof_long=${ac_cv_sizeof_long=4}
ac_cv_sizeof_short=${ac_cv_sizeof_short=2}
lt_cv_sys_max_cmd_len=${lt_cv_sys_max_cmd_len=262144}

View File

@ -1,538 +0,0 @@
/*
* $Id: PlaybackNode.cc,v 1.1.1.1 2002/01/22 00:52:07 phil Exp $
* PortAudio Portable Real-Time Audio Library
* Latest Version at: http://www.portaudio.com
* BeOS Media Kit Implementation by Joshua Haberman
*
* Copyright (c) 2001 Joshua Haberman <joshua@haberman.com>
*
* 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,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* Any person wishing to distribute modifications to the Software is
* requested to send the modifications to the original developer so that
* they can be incorporated into the canonical version.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR
* ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
* CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
* ---
*
* Significant portions of this file are based on sample code from Be. The
* Be Sample Code Licence follows:
*
* Copyright 1991-1999, Be Incorporated.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions, and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions, and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR "AS IS" AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF TITLE, NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
* TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <stdio.h>
#include <be/media/BufferGroup.h>
#include <be/media/Buffer.h>
#include <be/media/TimeSource.h>
#include "PlaybackNode.h"
#define PRINT(x) { printf x; fflush(stdout); }
#ifdef DEBUG
#define DBUG(x) PRINT(x)
#else
#define DBUG(x)
#endif
PaPlaybackNode::PaPlaybackNode(uint32 channels, float frame_rate, uint32 frames_per_buffer,
PortAudioCallback* callback, void *user_data) :
BMediaNode("PortAudio input node"),
BBufferProducer(B_MEDIA_RAW_AUDIO),
BMediaEventLooper(),
mAborted(false),
mRunning(false),
mBufferGroup(NULL),
mDownstreamLatency(0),
mStartTime(0),
mCallback(callback),
mUserData(user_data),
mFramesPerBuffer(frames_per_buffer)
{
DBUG(("Constructor called.\n"));
mPreferredFormat.type = B_MEDIA_RAW_AUDIO;
mPreferredFormat.u.raw_audio.channel_count = channels;
mPreferredFormat.u.raw_audio.frame_rate = frame_rate;
mPreferredFormat.u.raw_audio.byte_order =
(B_HOST_IS_BENDIAN) ? B_MEDIA_BIG_ENDIAN : B_MEDIA_LITTLE_ENDIAN;
mPreferredFormat.u.raw_audio.buffer_size =
media_raw_audio_format::wildcard.buffer_size;
mOutput.destination = media_destination::null;
mOutput.format = mPreferredFormat;
/* The amount of time it takes for this node to produce a buffer when
* asked. Essentially, it is how long the user's callback takes to run.
* We set this to be the length of the sound data each buffer of the
* requested size can hold. */
//mInternalLatency = (bigtime_t)(1000000 * frames_per_buffer / frame_rate);
/* ACK! it seems that the mixer (at least on my machine) demands that IT
* specify the buffer size, so for now I'll just make a generic guess here */
mInternalLatency = 1000000 / 20;
}
PaPlaybackNode::~PaPlaybackNode()
{
DBUG(("Destructor called.\n"));
Quit(); /* Stop the BMediaEventLooper thread */
}
/*************************
*
* Local methods
*
*/
bool PaPlaybackNode::IsRunning()
{
return mRunning;
}
PaTimestamp PaPlaybackNode::GetStreamTime()
{
BTimeSource *timeSource = TimeSource();
PaTimestamp time = (timeSource->Now() - mStartTime) *
mPreferredFormat.u.raw_audio.frame_rate / 1000000;
return time;
}
void PaPlaybackNode::SetSampleFormat(PaSampleFormat inFormat,
PaSampleFormat outFormat)
{
uint32 beOutFormat;
switch(outFormat)
{
case paFloat32:
beOutFormat = media_raw_audio_format::B_AUDIO_FLOAT;
mOutputSampleWidth = 4;
break;
case paInt16:
beOutFormat = media_raw_audio_format::B_AUDIO_SHORT;
mOutputSampleWidth = 2;
break;
case paInt32:
beOutFormat = media_raw_audio_format::B_AUDIO_INT;
mOutputSampleWidth = 4;
break;
case paInt8:
beOutFormat = media_raw_audio_format::B_AUDIO_CHAR;
mOutputSampleWidth = 1;
break;
case paUInt8:
beOutFormat = media_raw_audio_format::B_AUDIO_UCHAR;
mOutputSampleWidth = 1;
break;
case paInt24:
case paPackedInt24:
case paCustomFormat:
DBUG(("Unsupported output format: %x\n", outFormat));
break;
default:
DBUG(("Unknown output format: %x\n", outFormat));
}
mPreferredFormat.u.raw_audio.format = beOutFormat;
mFramesPerBuffer * mPreferredFormat.u.raw_audio.channel_count * mOutputSampleWidth;
}
BBuffer *PaPlaybackNode::FillNextBuffer(bigtime_t time)
{
/* Get a buffer from the buffer group */
BBuffer *buf = mBufferGroup->RequestBuffer(
mOutput.format.u.raw_audio.buffer_size, BufferDuration());
unsigned long frames = mOutput.format.u.raw_audio.buffer_size /
mOutputSampleWidth / mOutput.format.u.raw_audio.channel_count;
bigtime_t start_time;
int ret;
if( !buf )
{
DBUG(("Unable to allocate a buffer\n"));
return NULL;
}
start_time = mStartTime +
(bigtime_t)((double)mSamplesSent /
(double)mOutput.format.u.raw_audio.frame_rate /
(double)mOutput.format.u.raw_audio.channel_count *
1000000.0);
/* Now call the user callback to get the data */
ret = mCallback(NULL, /* Input buffer */
buf->Data(), /* Output buffer */
frames, /* Frames per buffer */
mSamplesSent / mOutput.format.u.raw_audio.channel_count, /* timestamp */
mUserData);
if( ret )
mAborted = true;
media_header *hdr = buf->Header();
hdr->type = B_MEDIA_RAW_AUDIO;
hdr->size_used = mOutput.format.u.raw_audio.buffer_size;
hdr->time_source = TimeSource()->ID();
hdr->start_time = start_time;
return buf;
}
/*************************
*
* BMediaNode methods
*
*/
BMediaAddOn *PaPlaybackNode::AddOn( int32 * ) const
{
DBUG(("AddOn() called.\n"));
return NULL; /* we don't provide service to outside applications */
}
status_t PaPlaybackNode::HandleMessage( int32 message, const void *data,
size_t size )
{
DBUG(("HandleMessage() called.\n"));
return B_ERROR; /* we don't define any custom messages */
}
/*************************
*
* BMediaEventLooper methods
*
*/
void PaPlaybackNode::NodeRegistered()
{
DBUG(("NodeRegistered() called.\n"));
/* Start the BMediaEventLooper thread */
SetPriority(B_REAL_TIME_PRIORITY);
Run();
/* set up as much information about our output as we can */
mOutput.source.port = ControlPort();
mOutput.source.id = 0;
mOutput.node = Node();
::strcpy(mOutput.name, "PortAudio Playback");
}
void PaPlaybackNode::HandleEvent( const media_timed_event *event,
bigtime_t lateness, bool realTimeEvent )
{
// DBUG(("HandleEvent() called.\n"));
status_t err;
switch(event->type)
{
case BTimedEventQueue::B_START:
DBUG((" Handling a B_START event\n"));
if( RunState() != B_STARTED )
{
mStartTime = event->event_time + EventLatency();
mSamplesSent = 0;
mAborted = false;
mRunning = true;
media_timed_event firstEvent( mStartTime,
BTimedEventQueue::B_HANDLE_BUFFER );
EventQueue()->AddEvent( firstEvent );
}
break;
case BTimedEventQueue::B_STOP:
DBUG((" Handling a B_STOP event\n"));
mRunning = false;
EventQueue()->FlushEvents( 0, BTimedEventQueue::B_ALWAYS, true,
BTimedEventQueue::B_HANDLE_BUFFER );
break;
case BTimedEventQueue::B_HANDLE_BUFFER:
//DBUG((" Handling a B_HANDLE_BUFFER event\n"));
/* make sure we're started and connected */
if( RunState() != BMediaEventLooper::B_STARTED ||
mOutput.destination == media_destination::null )
break;
BBuffer *buffer = FillNextBuffer(event->event_time);
/* make sure we weren't aborted while this routine was running.
* this can happen in one of two ways: either the callback returned
* nonzero (in which case mAborted is set in FillNextBuffer() ) or
* the client called AbortStream */
if( mAborted )
{
if( buffer )
buffer->Recycle();
Stop(0, true);
break;
}
if( buffer )
{
err = SendBuffer(buffer, mOutput.destination);
if( err != B_OK )
buffer->Recycle();
}
mSamplesSent += mOutput.format.u.raw_audio.buffer_size / mOutputSampleWidth;
/* Now schedule the next buffer event, so we can send another
* buffer when this one runs out. We calculate when it should
* happen by calculating when the data we just sent will finish
* playing.
*
* NOTE, however, that the event will actually get generated
* earlier than we specify, to account for the latency it will
* take to produce the buffer. It uses the latency value we
* specified in SetEventLatency() to determine just how early
* to generate it. */
/* totalPerformanceTime includes the time represented by the buffer
* we just sent */
bigtime_t totalPerformanceTime = (bigtime_t)((double)mSamplesSent /
(double)mOutput.format.u.raw_audio.channel_count /
(double)mOutput.format.u.raw_audio.frame_rate * 1000000.0);
bigtime_t nextEventTime = mStartTime + totalPerformanceTime;
media_timed_event nextBufferEvent(nextEventTime,
BTimedEventQueue::B_HANDLE_BUFFER);
EventQueue()->AddEvent(nextBufferEvent);
break;
}
}
/*************************
*
* BBufferProducer methods
*
*/
status_t PaPlaybackNode::FormatSuggestionRequested( media_type type,
int32 /*quality*/, media_format* format )
{
/* the caller wants to know this node's preferred format and provides
* a suggestion, asking if we support it */
DBUG(("FormatSuggestionRequested() called.\n"));
if(!format)
return B_BAD_VALUE;
*format = mPreferredFormat;
/* we only support raw audio (a wildcard is okay too) */
if ( type == B_MEDIA_UNKNOWN_TYPE || type == B_MEDIA_RAW_AUDIO )
return B_OK;
else
return B_MEDIA_BAD_FORMAT;
}
status_t PaPlaybackNode::FormatProposal( const media_source& output,
media_format* format )
{
/* This is similar to FormatSuggestionRequested(), but it is actually part
* of the negotiation process. We're given the opportunity to specify any
* properties that are wildcards (ie. properties that the other node doesn't
* care one way or another about) */
DBUG(("FormatProposal() called.\n"));
/* Make sure this proposal really applies to our output */
if( output != mOutput.source )
return B_MEDIA_BAD_SOURCE;
/* We return two things: whether we support the proposed format, and our own
* preferred format */
*format = mPreferredFormat;
if( format->type == B_MEDIA_UNKNOWN_TYPE || format->type == B_MEDIA_RAW_AUDIO )
return B_OK;
else
return B_MEDIA_BAD_FORMAT;
}
status_t PaPlaybackNode::FormatChangeRequested( const media_source& source,
const media_destination& destination, media_format* io_format, int32* )
{
/* we refuse to change formats, supporting only 1 */
DBUG(("FormatChangeRequested() called.\n"));
return B_ERROR;
}
status_t PaPlaybackNode::GetNextOutput( int32* cookie, media_output* out_output )
{
/* this is where we allow other to enumerate our outputs -- the cookie is
* an integer we can use to keep track of where we are in enumeration. */
DBUG(("GetNextOutput() called.\n"));
if( *cookie == 0 )
{
*out_output = mOutput;
*cookie = 1;
return B_OK;
}
return B_BAD_INDEX;
}
status_t PaPlaybackNode::DisposeOutputCookie( int32 cookie )
{
DBUG(("DisposeOutputCookie() called.\n"));
return B_OK;
}
void PaPlaybackNode::LateNoticeReceived( const media_source& what,
bigtime_t how_much, bigtime_t performance_time )
{
/* This function is called as notification that a buffer we sent wasn't
* received by the time we stamped it with -- it got there late. Basically,
* it means we underestimated our own latency, so we should increase it */
DBUG(("LateNoticeReceived() called.\n"));
if( what != mOutput.source )
return;
if( RunMode() == B_INCREASE_LATENCY )
{
mInternalLatency += how_much;
SetEventLatency( mDownstreamLatency + mInternalLatency );
DBUG(("Increasing latency to %Ld\n", mDownstreamLatency + mInternalLatency));
}
else
DBUG(("I don't know what to do with this notice!"));
}
void PaPlaybackNode::EnableOutput( const media_source& what, bool enabled,
int32* )
{
DBUG(("EnableOutput() called.\n"));
/* stub -- we don't support this yet */
}
status_t PaPlaybackNode::PrepareToConnect( const media_source& what,
const media_destination& where, media_format* format,
media_source* out_source, char* out_name )
{
/* the final stage of format negotiations. here we _must_ make specific any
* remaining wildcards */
DBUG(("PrepareToConnect() called.\n"));
/* make sure this really refers to our source */
if( what != mOutput.source )
return B_MEDIA_BAD_SOURCE;
/* make sure we're not already connected */
if( mOutput.destination != media_destination::null )
return B_MEDIA_ALREADY_CONNECTED;
if( format->type != B_MEDIA_RAW_AUDIO )
return B_MEDIA_BAD_FORMAT;
if( format->u.raw_audio.format != mPreferredFormat.u.raw_audio.format )
return B_MEDIA_BAD_FORMAT;
if( format->u.raw_audio.buffer_size ==
media_raw_audio_format::wildcard.buffer_size )
{
DBUG(("We were left to decide buffer size: choosing 2048"));
format->u.raw_audio.buffer_size = 2048;
}
else
DBUG(("Using consumer specified buffer size of %lu.\n",
format->u.raw_audio.buffer_size));
/* Reserve the connection, return the information */
mOutput.destination = where;
mOutput.format = *format;
*out_source = mOutput.source;
strncpy( out_name, mOutput.name, B_MEDIA_NAME_LENGTH );
return B_OK;
}
void PaPlaybackNode::Connect(status_t error, const media_source& source,
const media_destination& destination, const media_format& format, char* io_name)
{
DBUG(("Connect() called.\n"));

View File

@ -1,108 +0,0 @@
/*
* $Id$
* PortAudio Portable Real-Time Audio Library
* Latest Version at: http://www.portaudio.com
* BeOS Media Kit Implementation by Joshua Haberman
*
* Copyright (c) 2001 Joshua Haberman <joshua@haberman.com>
*
* 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,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* Any person wishing to distribute modifications to the Software is
* requested to send the modifications to the original developer so that
* they can be incorporated into the canonical version.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR
* ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
* CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*/
#include <be/media/MediaRoster.h>
#include <be/media/MediaEventLooper.h>
#include <be/media/BufferProducer.h>
#include "portaudio.h"
class PaPlaybackNode :
public BBufferProducer,
public BMediaEventLooper
{
public:
PaPlaybackNode( uint32 channels, float frame_rate, uint32 frames_per_buffer,
PortAudioCallback *callback, void *user_data );
~PaPlaybackNode();
/* Local methods ******************************************/
BBuffer *FillNextBuffer(bigtime_t time);
void SetSampleFormat(PaSampleFormat inFormat, PaSampleFormat outFormat);
bool IsRunning();
PaTimestamp GetStreamTime();
/* BMediaNode methods *************************************/
BMediaAddOn* AddOn( int32 * ) const;
status_t HandleMessage( int32 message, const void *data, size_t size );
/* BMediaEventLooper methods ******************************/
void HandleEvent( const media_timed_event *event, bigtime_t lateness,
bool realTimeEvent );
void NodeRegistered();
/* BBufferProducer methods ********************************/
status_t FormatSuggestionRequested( media_type type, int32 quality,
media_format* format );
status_t FormatProposal( const media_source& output, media_format* format );
status_t FormatChangeRequested( const media_source& source,
const media_destination& destination, media_format* io_format, int32* );
status_t GetNextOutput( int32* cookie, media_output* out_output );
status_t DisposeOutputCookie( int32 cookie );
void LateNoticeReceived( const media_source& what, bigtime_t how_much,
bigtime_t performance_time );
void EnableOutput( const media_source& what, bool enabled, int32* _deprecated_ );
status_t PrepareToConnect( const media_source& what,
const media_destination& where, media_format* format,
media_source* out_source, char* out_name );
void Connect(status_t error, const media_source& source,
const media_destination& destination, const media_format& format,
char* io_name);
void Disconnect(const media_source& what, const media_destination& where);
status_t SetBufferGroup(const media_source& for_source, BBufferGroup* newGroup);
bool mAborted;
private:
media_output mOutput;
media_format mPreferredFormat;
uint32 mOutputSampleWidth, mFramesPerBuffer;
BBufferGroup *mBufferGroup;
bigtime_t mDownstreamLatency, mInternalLatency, mStartTime;
uint64 mSamplesSent;
PortAudioCallback *mCallback;
void *mUserData;
bool mRunning;
};

View File

@ -1,441 +0,0 @@
/*
* $Id: pa_beos_mk.cc,v 1.1.1.1 2002/01/22 00:52:09 phil Exp $
* PortAudio Portable Real-Time Audio Library
* Latest Version at: http://www.portaudio.com
* BeOS Media Kit Implementation by Joshua Haberman
*
* Copyright (c) 2001 Joshua Haberman <joshua@haberman.com>
*
* 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,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* Any person wishing to distribute modifications to the Software is
* requested to send the modifications to the original developer so that
* they can be incorporated into the canonical version.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR
* ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
* CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*/
#include <be/app/Application.h>
#include <be/kernel/OS.h>
#include <be/media/RealtimeAlloc.h>
#include <be/media/MediaRoster.h>
#include <be/media/TimeSource.h>
#include <stdio.h>
#include <string.h>
#include "portaudio.h"
#include "pa_host.h"
#include "PlaybackNode.h"
#define PRINT(x) { printf x; fflush(stdout); }
#ifdef DEBUG
#define DBUG(x) PRINT(x)
#else
#define DBUG(x)
#endif
typedef struct PaHostSoundControl
{
/* These members are common to all modes of operation */
media_node pahsc_TimeSource; /* the sound card's DAC. */
media_format pahsc_Format;
/* These methods are specific to playing mode */
media_node pahsc_OutputNode; /* output to the mixer */
media_node pahsc_InputNode; /* reads data from user callback -- PA specific */
media_input pahsc_MixerInput; /* input jack on the soundcard's mixer. */
media_output pahsc_PaOutput; /* output jack from the PA node */
PaPlaybackNode *pahsc_InputNodeInstance;
}
PaHostSoundControl;
/*************************************************************************/
PaDeviceID Pa_GetDefaultOutputDeviceID( void )
{
/* stub */
return 0;
}
/*************************************************************************/
PaDeviceID Pa_GetDefaultInputDeviceID( void )
{
/* stub */
return 0;
}
/*************************************************************************/
const PaDeviceInfo* Pa_GetDeviceInfo( PaDeviceID id )
{
/* stub */
return NULL;
}
/*************************************************************************/
int Pa_CountDevices()
{
/* stub */
return 1;
}
/*************************************************************************/
PaError PaHost_Init( void )
{
/* we have to create this in order to use BMediaRoster. I hope it doesn't
* cause problems */
be_app = new BApplication("application/x-vnd.portaudio-app");
return paNoError;
}
PaError PaHost_Term( void )
{
delete be_app;
return paNoError;
}
/*************************************************************************/
PaError PaHost_StreamActive( internalPortAudioStream *past )
{
PaHostSoundControl *pahsc = (PaHostSoundControl *)past->past_DeviceData;
DBUG(("IsRunning returning: %s\n",
pahsc->pahsc_InputNodeInstance->IsRunning() ? "true" : "false"));
return (PaError)pahsc->pahsc_InputNodeInstance->IsRunning();
}
PaError PaHost_StartOutput( internalPortAudioStream *past )
{
return paNoError;
}
/*************************************************************************/
PaError PaHost_StartInput( internalPortAudioStream *past )
{
return paNoError;
}
/*************************************************************************/
PaError PaHost_StopInput( internalPortAudioStream *past, int abort )
{
return paNoError;
}
/*************************************************************************/
PaError PaHost_StopOutput( internalPortAudioStream *past, int abort )
{
return paNoError;
}
/*************************************************************************/
PaError PaHost_StartEngine( internalPortAudioStream *past )
{
bigtime_t very_soon, start_latency;
status_t err;
BMediaRoster *roster = BMediaRoster::Roster(&err);
PaHostSoundControl *pahsc = (PaHostSoundControl *)past->past_DeviceData;
/* for some reason, err indicates an error (though nothing it wrong)
* when the DBUG macro in pa_lib.c is enabled. It's reproducably
* linked. Weird. */
if( !roster /* || err != B_OK */ )
{
DBUG(("No media server! err=%d, roster=%x\n", err, roster));
return paHostError;
}
/* tell the node when to start -- since there aren't any other nodes
* starting that we have to wait for, just tell it to start now
*/
BTimeSource *timeSource = roster->MakeTimeSourceFor(pahsc->pahsc_TimeSource);
very_soon = timeSource->PerformanceTimeFor( BTimeSource::RealTime() );
timeSource->Release();
/* Add the latency of starting the network of nodes */
err = roster->GetStartLatencyFor( pahsc->pahsc_TimeSource, &start_latency );
very_soon += start_latency;
err = roster->StartNode( pahsc->pahsc_InputNode, very_soon );
/* No need to start the mixer -- it's always running */
return paNoError;
}
/*************************************************************************/
PaError PaHost_StopEngine( internalPortAudioStream *past, int abort )
{
PaHostSoundControl *pahsc = (PaHostSoundControl *)past->past_DeviceData;
BMediaRoster *roster = BMediaRoster::Roster();
if( !roster )
{
DBUG(("No media roster!\n"));
return paHostError;
}
if( !pahsc )
return paHostError;
/* this crashes, and I don't know why yet */
// if( abort )
// pahsc->pahsc_InputNodeInstance->mAborted = true;
roster->StopNode(pahsc->pahsc_InputNode, 0, /* immediate = */ true);
return paNoError;
}
/*************************************************************************/
PaError PaHost_OpenStream( internalPortAudioStream *past )
{
status_t err;
BMediaRoster *roster = BMediaRoster::Roster(&err);
PaHostSoundControl *pahsc;
/* Allocate and initialize host data. */
pahsc = (PaHostSoundControl *) PaHost_AllocateFastMemory(sizeof(PaHostSoundControl));
if( pahsc == NULL )
{
goto error;
}
memset( pahsc, 0, sizeof(PaHostSoundControl) );
past->past_DeviceData = (void *) pahsc;
if( !roster /* || err != B_OK */ )
{
/* no media server! */
DBUG(("No media server.\n"));
goto error;
}
if ( past->past_NumInputChannels > 0 && past->past_NumOutputChannels > 0 )
{
/* filter -- not implemented yet */
goto error;
}
else if ( past->past_NumInputChannels > 0 )
{
/* recorder -- not implemented yet */
goto error;
}
else
{
/* player ****************************************************************/
status_t err;
int32 num;
/* First we need to create the three components (like components in a stereo
* system). The mixer component is our interface to the sound card, data
* we write there will get played. The BePA_InputNode component is the node
* which represents communication with the PA client (it is what calls the
* client's callbacks). The time source component is the sound card's DAC,
* which allows us to slave the other components to it instead of the system
* clock. */
err = roster->GetAudioMixer( &pahsc->pahsc_OutputNode );
if( err != B_OK )
{
DBUG(("Couldn't get default mixer.\n"));
goto error;
}
err = roster->GetTimeSource( &pahsc->pahsc_TimeSource );
if( err != B_OK )
{
DBUG(("Couldn't get time source.\n"));
goto error;
}
pahsc->pahsc_InputNodeInstance = new PaPlaybackNode(2, 44100,
past->past_FramesPerUserBuffer, past->past_Callback, past->past_UserData );
pahsc->pahsc_InputNodeInstance->SetSampleFormat(0,
past->past_OutputSampleFormat);
err = roster->RegisterNode( pahsc->pahsc_InputNodeInstance );
if( err != B_OK )
{
DBUG(("Unable to register node.\n"));
goto error;
}
roster->GetNodeFor( pahsc->pahsc_InputNodeInstance->Node().node,
&pahsc->pahsc_InputNode );
if( err != B_OK )
{
DBUG(("Unable to get input node.\n"));
goto error;
}
/* Now we have three components (nodes) sitting next to each other. The
* next step is to look at them and find their inputs and outputs so we can
* wire them together. */
err = roster->GetFreeInputsFor( pahsc->pahsc_OutputNode,
&pahsc->pahsc_MixerInput, 1, &num, B_MEDIA_RAW_AUDIO );
if( err != B_OK || num < 1 )
{
DBUG(("Couldn't get the mixer input.\n"));
goto error;
}
err = roster->GetFreeOutputsFor( pahsc->pahsc_InputNode,
&pahsc->pahsc_PaOutput, 1, &num, B_MEDIA_RAW_AUDIO );
if( err != B_OK || num < 1 )
{
DBUG(("Couldn't get PortAudio output.\n"));
goto error;
}
/* We've found the input and output -- the final step is to run a wire
* between them so they are connected. */
/* try to make the mixer input adapt to what PA sends it */
pahsc->pahsc_Format = pahsc->pahsc_PaOutput.format;
roster->Connect( pahsc->pahsc_PaOutput.source,
pahsc->pahsc_MixerInput.destination, &pahsc->pahsc_Format,
&pahsc->pahsc_PaOutput, &pahsc->pahsc_MixerInput );
/* Actually, there's one final step -- tell them all to sync to the
* sound card's DAC */
roster->SetTimeSourceFor( pahsc->pahsc_InputNode.node,
pahsc->pahsc_TimeSource.node );
roster->SetTimeSourceFor( pahsc->pahsc_OutputNode.node,
pahsc->pahsc_TimeSource.node );
}
return paNoError;
error:
PaHost_CloseStream( past );
return paHostError;
}
/*************************************************************************/
PaError PaHost_CloseStream( internalPortAudioStream *past )
{
PaHostSoundControl *pahsc = (PaHostSoundControl *)past->past_DeviceData;
status_t err;
BMediaRoster *roster = BMediaRoster::Roster(&err);
if( !roster )
{
DBUG(("Couldn't get media roster\n"));
return paHostError;
}
if( !pahsc )
return paHostError;
/* Disconnect all the connections we made when opening the stream */
roster->Disconnect(pahsc->pahsc_InputNode.node, pahsc->pahsc_PaOutput.source,
pahsc->pahsc_OutputNode.node, pahsc->pahsc_MixerInput.destination);
DBUG(("Calling ReleaseNode()"));
roster->ReleaseNode(pahsc->pahsc_InputNode);
/* deleting the node shouldn't be necessary -- it is reference counted, and will
* delete itself when its references drop to zero. the call to ReleaseNode()
* above should decrease its reference count */
pahsc->pahsc_InputNodeInstance = NULL;
return paNoError;
}
/*************************************************************************/
PaTimestamp Pa_StreamTime( PortAudioStream *stream )
{
internalPortAudioStream *past = (internalPortAudioStream *) stream;
PaHostSoundControl *pahsc = (PaHostSoundControl *)past->past_DeviceData;
return pahsc->pahsc_InputNodeInstance->GetStreamTime();
}
/*************************************************************************/
void Pa_Sleep( long msec )
{
/* snooze() takes microseconds */
snooze( msec * 1000 );
}
/*************************************************************************
* Allocate memory that can be accessed in real-time.
* This may need to be held in physical memory so that it is not
* paged to virtual memory.
* This call MUST be balanced with a call to PaHost_FreeFastMemory().
* Memory will be set to zero.
*/
void *PaHost_AllocateFastMemory( long numBytes )
{
/* BeOS supports non-pagable memory through pools -- a pool is an area
* of physical memory that is locked. It would be best to pre-allocate
* that pool and then hand out memory from it, but we don't know in
* advance how much we'll need. So for now, we'll allocate a pool
* for every request we get, storing a pointer to the pool at the
* beginning of the allocated memory */
rtm_pool *pool;
void *addr;
long size = numBytes + sizeof(rtm_pool *);
static int counter = 0;
char pool_name[100];
/* Every pool needs a unique name. */
sprintf(pool_name, "PaPoolNumber%d", counter++);
if( rtm_create_pool( &pool, size, pool_name ) != B_OK )
return 0;
addr = rtm_alloc( pool, size );
if( addr == NULL )
return 0;
memset( addr, 0, numBytes );
*((rtm_pool **)addr) = pool; // store the pointer to the pool
addr = (rtm_pool **)addr + 1; // and return the next location in memory
return addr;
}
/*************************************************************************
* Free memory that could be accessed in real-time.
* This call MUST be balanced with a call to PaHost_AllocateFastMemory().
*/
void PaHost_FreeFastMemory( void *addr, long numBytes )
{
rtm_pool *pool;
if( addr == NULL )
return;
addr = (rtm_pool **)addr - 1;
pool = *((rtm_pool **)addr);
rtm_free( addr );
rtm_delete_pool( pool );
}

View File

@ -1,184 +0,0 @@
/*
* PortAudio Portable Real-Time Audio Library
* PortAudio DLL Header File
* Latest version available at: http://www.audiomulch.com/portaudio/
*
* Copyright (c) 1999-2000 Ross Bencina and 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,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* Any person wishing to distribute modifications to the Software is
* requested to send the modifications to the original developer so that
* they can be incorporated into the canonical version.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR
* ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
* CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*/
// changed by zplane.developement in order to generate a DLL
#ifndef __PADLLENTRY_HEADER_INCLUDED__
#define __PADLLENTRY_HEADER_INCLUDED__
typedef int PaError;
typedef enum {
paNoError = 0,
paHostError = -10000,
paInvalidChannelCount,
paInvalidSampleRate,
paInvalidDeviceId,
paInvalidFlag,
paSampleFormatNotSupported,
paBadIODeviceCombination,
paInsufficientMemory,
paBufferTooBig,
paBufferTooSmall,
paNullCallback,
paBadStreamPtr,
paTimedOut,
paInternalError
} PaErrorNum;
typedef unsigned long PaSampleFormat;
#define paFloat32 ((PaSampleFormat) (1<<0)) /*always available*/
#define paInt16 ((PaSampleFormat) (1<<1)) /*always available*/
#define paInt32 ((PaSampleFormat) (1<<2)) /*always available*/
#define paInt24 ((PaSampleFormat) (1<<3))
#define paPackedInt24 ((PaSampleFormat) (1<<4))
#define paInt8 ((PaSampleFormat) (1<<5))
#define paUInt8 ((PaSampleFormat) (1<<6)) /* unsigned 8 bit, 128 is "ground" */
#define paCustomFormat ((PaSampleFormat) (1<<16))
typedef int PaDeviceID;
#define paNoDevice -1
typedef struct
{
int structVersion;
const char *name;
int maxInputChannels;
int maxOutputChannels;
/* Number of discrete rates, or -1 if range supported. */
int numSampleRates;
/* Array of supported sample rates, or {min,max} if range supported. */
const double *sampleRates;
PaSampleFormat nativeSampleFormats;
}
PaDeviceInfo;
typedef double PaTimestamp;
typedef int (PortAudioCallback)(
void *inputBuffer, void *outputBuffer,
unsigned long framesPerBuffer,
PaTimestamp outTime, void *userData );
#define paNoFlag (0)
#define paClipOff (1<<0) /* disable default clipping of out of range samples */
#define paDitherOff (1<<1) /* disable default dithering */
#define paPlatformSpecificFlags (0x00010000)
typedef unsigned long PaStreamFlags;
typedef void PortAudioStream;
#define PaStream PortAudioStream
extern PaError (__cdecl* Pa_Initialize)( void );
extern PaError (__cdecl* Pa_Terminate)( void );
extern long (__cdecl* Pa_GetHostError)( void );
extern const char* (__cdecl* Pa_GetErrorText)( PaError );
extern int (__cdecl* Pa_CountDevices)(void);
extern PaDeviceID (__cdecl* Pa_GetDefaultInputDeviceID)( void );
extern PaDeviceID (__cdecl* Pa_GetDefaultOutputDeviceID)( void );
extern const PaDeviceInfo* (__cdecl* Pa_GetDeviceInfo)( PaDeviceID);
extern PaError (__cdecl* Pa_OpenStream)(
PortAudioStream ** ,
PaDeviceID ,
int ,
PaSampleFormat ,
void *,
PaDeviceID ,
int ,
PaSampleFormat ,
void *,
double ,
unsigned long ,
unsigned long ,
unsigned long ,
PortAudioCallback *,
void * );
extern PaError (__cdecl* Pa_OpenDefaultStream)( PortAudioStream** stream,
int numInputChannels,
int numOutputChannels,
PaSampleFormat sampleFormat,
double sampleRate,
unsigned long framesPerBuffer,
unsigned long numberOfBuffers,
PortAudioCallback *callback,
void *userData );
extern PaError (__cdecl* Pa_CloseStream)( PortAudioStream* );
extern PaError (__cdecl* Pa_StartStream)( PortAudioStream *stream );
extern PaError (__cdecl* Pa_StopStream)( PortAudioStream *stream );
extern PaError (__cdecl* Pa_AbortStream)( PortAudioStream *stream );
extern PaError (__cdecl* Pa_StreamActive)( PortAudioStream *stream );
extern PaTimestamp (__cdecl* Pa_StreamTime)( PortAudioStream *stream );
extern double (__cdecl* Pa_GetCPULoad)( PortAudioStream* stream );
extern int (__cdecl* Pa_GetMinNumBuffers)( int framesPerBuffer, double sampleRate );
extern void (__cdecl* Pa_Sleep)( long msec );
extern PaError (__cdecl* Pa_GetSampleSize)( PaSampleFormat format );
#endif // __PADLLENTRY_HEADER_INCLUDED__

View File

@ -1,203 +0,0 @@
//////////////////////////////////////////////////////////////////////////
HINSTANCE pPaDll;
/*
the function pointers to the PortAudio DLLs
*/
PaError (__cdecl* Pa_Initialize)( void );
PaError (__cdecl* Pa_Terminate)( void );
long (__cdecl* Pa_GetHostError)( void );
const char* (__cdecl* Pa_GetErrorText)( PaError );
int (__cdecl* Pa_CountDevices)(void);
PaDeviceID (__cdecl* Pa_GetDefaultInputDeviceID)( void );
PaDeviceID (__cdecl* Pa_GetDefaultOutputDeviceID)( void );
const PaDeviceInfo* (__cdecl* Pa_GetDeviceInfo)( PaDeviceID);
PaError (__cdecl* Pa_OpenStream)(
PortAudioStream ** ,
PaDeviceID ,
int ,
PaSampleFormat ,
void *,
PaDeviceID ,
int ,
PaSampleFormat ,
void *,
double ,
unsigned long ,
unsigned long ,
unsigned long ,
PortAudioCallback *,
void * );
PaError (__cdecl* Pa_OpenDefaultStream)( PortAudioStream** stream,
int numInputChannels,
int numOutputChannels,
PaSampleFormat sampleFormat,
double sampleRate,
unsigned long framesPerBuffer,
unsigned long numberOfBuffers,
PortAudioCallback *callback,
void *userData );
PaError (__cdecl* Pa_CloseStream)( PortAudioStream* );
PaError (__cdecl* Pa_StartStream)( PortAudioStream *stream );
PaError (__cdecl* Pa_StopStream)( PortAudioStream *stream );
PaError (__cdecl* Pa_AbortStream)( PortAudioStream *stream );
PaError (__cdecl* Pa_StreamActive)( PortAudioStream *stream );
PaTimestamp (__cdecl* Pa_StreamTime)( PortAudioStream *stream );
double (__cdecl* Pa_GetCPULoad)( PortAudioStream* stream );
int (__cdecl* Pa_GetMinNumBuffers)( int framesPerBuffer, double sampleRate );
void (__cdecl* Pa_Sleep)( long msec );
PaError (__cdecl* Pa_GetSampleSize)( PaSampleFormat format );
//////////////////////////////////////////////////////////////////////////
...
ZERROR AudioEngine::DirectXSupport(ZBOOL bSupDX)
{
if (bSupDX)
if (CheckForDirectXSupport())
bSupportDirectX = _TRUE;
else
return _NO_SOUND;
else
bSupportDirectX = _FALSE;
return _NO_ERROR;
}
ZBOOL AudioEngine::CheckForDirectXSupport()
{
HMODULE pTestDXLib;
FARPROC pFunctionality;
pTestDXLib=LoadLibrary("DSOUND");
if (pTestDXLib!=NULL) // check if there is a DirectSound
{
pFunctionality = GetProcAddress(pTestDXLib, (char*) 7);
if (pFunctionality!=NULL)
{
FreeLibrary(pTestDXLib);
return _TRUE;
}
else
{
FreeLibrary(pTestDXLib);
return _FALSE;
}
}
else
return _FALSE;
}
ZERROR AudioEngine::LoadPALib()
{
#ifdef _DEBUG
if (bSupportDirectX)
pPaDll = LoadLibrary("PA_DXD");
else
pPaDll = LoadLibrary("PA_MMED");
#else
if (bSupportDirectX)
pPaDll = LoadLibrary("PA_DX");
else
pPaDll = LoadLibrary("PA_MME");
#endif
if (pPaDll!=NULL)
{
Pa_Initialize = (int (__cdecl*)(void))GetProcAddress(pPaDll,"Pa_Initialize");
Pa_Terminate = (int (__cdecl*)(void))GetProcAddress(pPaDll,"Pa_Terminate");
Pa_GetHostError = (long (__cdecl* )( void )) GetProcAddress(pPaDll,"Pa_GetHostError");
Pa_GetErrorText = (const char* (__cdecl* )( PaError )) GetProcAddress(pPaDll,"Pa_GetErrorText");
Pa_CountDevices = (int (__cdecl*)(void))GetProcAddress(pPaDll,"Pa_CountDevices");
Pa_GetDefaultInputDeviceID = (int (__cdecl*)(void))GetProcAddress(pPaDll,"Pa_GetDefaultInputDeviceID");
Pa_GetDefaultOutputDeviceID = (int (__cdecl*)(void))GetProcAddress(pPaDll,"Pa_GetDefaultOutputDeviceID");
Pa_GetDeviceInfo = (const PaDeviceInfo* (__cdecl* )( PaDeviceID)) GetProcAddress(pPaDll,"Pa_GetDeviceInfo");
Pa_OpenStream = ( PaError (__cdecl* )(
PortAudioStream ** ,
PaDeviceID ,
int ,
PaSampleFormat ,
void *,
PaDeviceID ,
int ,
PaSampleFormat ,
void *,
double ,
unsigned long ,
unsigned long ,
unsigned long ,
PortAudioCallback *,
void * )) GetProcAddress(pPaDll,"Pa_OpenStream");
Pa_OpenDefaultStream = (PaError (__cdecl* )( PortAudioStream** ,
int ,
int ,
PaSampleFormat ,
double ,
unsigned long ,
unsigned long ,
PortAudioCallback *,
void * )) GetProcAddress(pPaDll,"Pa_OpenDefaultStream");
Pa_CloseStream = (PaError (__cdecl* )( PortAudioStream* )) GetProcAddress(pPaDll,"Pa_CloseStream");
Pa_StartStream = (PaError (__cdecl* )( PortAudioStream* )) GetProcAddress(pPaDll,"Pa_StartStream");
Pa_StopStream = (PaError (__cdecl* )( PortAudioStream* ))GetProcAddress(pPaDll,"Pa_StopStream");
Pa_AbortStream = (PaError (__cdecl* )( PortAudioStream* )) GetProcAddress(pPaDll,"Pa_AbortStream");
Pa_StreamActive = (PaError (__cdecl* )( PortAudioStream* )) GetProcAddress(pPaDll,"Pa_StreamActive");
Pa_StreamTime = (PaTimestamp (__cdecl* )( PortAudioStream *))GetProcAddress(pPaDll,"Pa_StreamTime");
Pa_GetCPULoad = (double (__cdecl* )( PortAudioStream* ))GetProcAddress(pPaDll,"Pa_GetCPULoad");
Pa_GetMinNumBuffers = (int (__cdecl* )( int , double )) GetProcAddress(pPaDll,"Pa_GetMinNumBuffers");
Pa_Sleep = (void (__cdecl* )( long )) GetProcAddress(pPaDll,"Pa_Sleep");
Pa_GetSampleSize = (PaError (__cdecl* )( PaSampleFormat )) GetProcAddress(pPaDll,"Pa_GetSampleSize");
return _NO_ERROR;
}
else
return _DLL_NOT_FOUND;
}
ZERROR AudioEngine::UnLoadPALib()
{
if (pPaDll!=NULL)
FreeLibrary(pPaDll);
return _NO_ERROR;
}
...

View File

@ -1,827 +0,0 @@
/*
* Portable Audio I/O Library
* Host Independant Layer
*
* Based on the Open Source API proposed by Ross Bencina
* Copyright (c) 1999-2000 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,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* Any person wishing to distribute modifications to the Software is
* requested to send the modifications to the original developer so that
* they can be incorporated into the canonical version.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR
* ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
* CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*/
/* Modification History:
PLB20010422 - apply Mike Berry's changes for CodeWarrior on PC
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
/* PLB20010422 - "memory.h" doesn't work on CodeWarrior for PC. Thanks Mike Berry for the mod. */
#ifdef _WIN32
#ifndef __MWERKS__
#include <memory.h>
#endif /* __MWERKS__ */
#else /* !_WIN32 */
#include <memory.h>
#endif /* _WIN32 */
#include "portaudio.h"
#include "pa_host.h"
#include "pa_trace.h"
/* The reason we might NOT want to validate the rate before opening the stream
* is because many DirectSound drivers lie about the rates they actually support.
*/
#define PA_VALIDATE_RATE (0) /* If true validate sample rate against driver info. */
/*
O- maybe not allocate past_InputBuffer and past_OutputBuffer if not needed for conversion
*/
#ifndef FALSE
#define FALSE (0)
#define TRUE (!FALSE)
#endif
#define PRINT(x) { printf x; fflush(stdout); }
#define ERR_RPT(x) PRINT(x)
#define DBUG(x) /* PRINT(x) */
#define DBUGX(x) /* PRINT(x) */
static int gInitCount = 0; /* Count number of times Pa_Initialize() called to allow nesting and overlapping. */
static PaError Pa_KillStream( PortAudioStream *stream, int abort );
/***********************************************************************/
int PaHost_FindClosestTableEntry( double allowableError, const double *rateTable, int numRates, double frameRate )
{
double err, minErr = allowableError;
int i, bestFit = -1;
for( i=0; i<numRates; i++ )
{
err = fabs( frameRate - rateTable[i] );
if( err < minErr )
{
minErr = err;
bestFit = i;
}
}
return bestFit;
}
/**************************************************************************
** Make sure sample rate is legal and also convert to enumeration for driver.
*/
PaError PaHost_ValidateSampleRate( PaDeviceID id, double requestedFrameRate,
double *closestFrameRatePtr )
{
long bestRateIndex;
const PaDeviceInfo *pdi;
pdi = Pa_GetDeviceInfo( id );
if( pdi == NULL ) return paInvalidDeviceId;
if( pdi->numSampleRates == -1 )
{
/* Is it out of range? */
if( (requestedFrameRate < pdi->sampleRates[0]) ||
(requestedFrameRate > pdi->sampleRates[1]) )
{
return paInvalidSampleRate;
}
*closestFrameRatePtr = requestedFrameRate;
}
else
{
bestRateIndex = PaHost_FindClosestTableEntry( 1.0, pdi->sampleRates, pdi->numSampleRates, requestedFrameRate );
if( bestRateIndex < 0 ) return paInvalidSampleRate;
*closestFrameRatePtr = pdi->sampleRates[bestRateIndex];
}
return paNoError;
}
/*************************************************************************/
DLL_API PaError Pa_OpenStream(
PortAudioStream** streamPtrPtr,
PaDeviceID inputDeviceID,
int numInputChannels,
PaSampleFormat inputSampleFormat,
void *inputDriverInfo,
PaDeviceID outputDeviceID,
int numOutputChannels,
PaSampleFormat outputSampleFormat,
void *outputDriverInfo,
double sampleRate,
unsigned long framesPerBuffer,
unsigned long numberOfBuffers,
unsigned long streamFlags,
PortAudioCallback *callback,
void *userData )
{
internalPortAudioStream *past = NULL;
PaError result = paNoError;
int bitsPerInputSample;
int bitsPerOutputSample;
/* Print passed parameters. */
DBUG(("Pa_OpenStream( %p, %d, %d, %d, %p, /* input */ \n",
streamPtrPtr, inputDeviceID, numInputChannels,
inputSampleFormat, inputDriverInfo ));
DBUG((" %d, %d, %d, %p, /* output */\n",
outputDeviceID, numOutputChannels,
outputSampleFormat, outputDriverInfo ));
DBUG((" %g, %d, %d, 0x%x, , %p )\n",
sampleRate, framesPerBuffer, numberOfBuffers,
streamFlags, userData ));
/* Check for parameter errors. */
if( (streamFlags & ~(paClipOff | paDitherOff)) != 0 ) return paInvalidFlag;
if( streamPtrPtr == NULL ) return paBadStreamPtr;
if( inputDriverInfo != NULL ) return paHostError; /* REVIEW */
if( outputDriverInfo != NULL ) return paHostError; /* REVIEW */
if( (inputDeviceID < 0) && ( outputDeviceID < 0) ) return paInvalidDeviceId;
if( (outputDeviceID >= Pa_CountDevices()) || (inputDeviceID >= Pa_CountDevices()) ) return paInvalidDeviceId;
if( (numInputChannels <= 0) && ( numOutputChannels <= 0) ) return paInvalidChannelCount;
#if SUPPORT_AUDIO_CAPTURE
if( inputDeviceID >= 0 )
{
PaError size = Pa_GetSampleSize( inputSampleFormat );
if( size < 0 ) return size;
bitsPerInputSample = 8 * size;
if( (numInputChannels <= 0) ) return paInvalidChannelCount;
}
#else
if( inputDeviceID >= 0 )
{
return paInvalidChannelCount;
}
#endif /* SUPPORT_AUDIO_CAPTURE */
else
{
if( numInputChannels > 0 ) return paInvalidChannelCount;
bitsPerInputSample = 0;
}
if( outputDeviceID >= 0 )
{
PaError size = Pa_GetSampleSize( outputSampleFormat );
if( size < 0 ) return size;
bitsPerOutputSample = 8 * size;
if( (numOutputChannels <= 0) ) return paInvalidChannelCount;
}
else
{
if( numOutputChannels > 0 ) return paInvalidChannelCount;
bitsPerOutputSample = 0;
}
if( callback == NULL ) return paNullCallback;
/* Allocate and clear stream structure. */
past = (internalPortAudioStream *) PaHost_AllocateFastMemory( sizeof(internalPortAudioStream) );
if( past == NULL ) return paInsufficientMemory;
memset( past, 0, sizeof(internalPortAudioStream) );
AddTraceMessage("Pa_OpenStream: past", (long) past );
past->past_Magic = PA_MAGIC; /* Set ID to catch bugs. */
past->past_FramesPerUserBuffer = framesPerBuffer;
past->past_NumUserBuffers = numberOfBuffers; /* NOTE - PaHost_OpenStream() NMUST CHECK FOR ZERO! */
past->past_Callback = callback;
past->past_UserData = userData;
past->past_OutputSampleFormat = outputSampleFormat;
past->past_InputSampleFormat = inputSampleFormat;
past->past_OutputDeviceID = outputDeviceID;
past->past_InputDeviceID = inputDeviceID;
past->past_NumInputChannels = numInputChannels;
past->past_NumOutputChannels = numOutputChannels;
past->past_Flags = streamFlags;
/* Check for absurd sample rates. */
if( (sampleRate < 1000.0) || (sampleRate > 200000.0) )
{
result = paInvalidSampleRate;
goto cleanup;
}
/* Allocate buffers that may be used for format conversion from user to native buffers. */
if( numInputChannels > 0 )
{
#if PA_VALIDATE_RATE
result = PaHost_ValidateSampleRate( inputDeviceID, sampleRate, &past->past_SampleRate );
if( result < 0 )
{
goto cleanup;
}
#else
past->past_SampleRate = sampleRate;
#endif
/* Allocate single Input buffer. */
past->past_InputBufferSize = framesPerBuffer * numInputChannels * ((bitsPerInputSample+7) / 8);
past->past_InputBuffer = PaHost_AllocateFastMemory(past->past_InputBufferSize);
if( past->past_InputBuffer == NULL )
{
result = paInsufficientMemory;
goto cleanup;
}
}
else
{
past->past_InputBuffer = NULL;
}
/* Allocate single Output buffer. */
if( numOutputChannels > 0 )
{
#if PA_VALIDATE_RATE
result = PaHost_ValidateSampleRate( outputDeviceID, sampleRate, &past->past_SampleRate );
if( result < 0 )
{
goto cleanup;
}
#else
past->past_SampleRate = sampleRate;
#endif
past->past_OutputBufferSize = framesPerBuffer * numOutputChannels * ((bitsPerOutputSample+7) / 8);
past->past_OutputBuffer = PaHost_AllocateFastMemory(past->past_OutputBufferSize);
if( past->past_OutputBuffer == NULL )
{
result = paInsufficientMemory;
goto cleanup;
}
}
else
{
past->past_OutputBuffer = NULL;
}
result = PaHost_OpenStream( past );
if( result < 0 ) goto cleanup;
*streamPtrPtr = (void *) past;
return result;
cleanup:
if( past != NULL ) Pa_CloseStream( past );
*streamPtrPtr = NULL;
return result;
}
/*************************************************************************/
DLL_API PaError Pa_OpenDefaultStream( PortAudioStream** stream,
int numInputChannels,
int numOutputChannels,
PaSampleFormat sampleFormat,
double sampleRate,
unsigned long framesPerBuffer,
unsigned long numberOfBuffers,
PortAudioCallback *callback,
void *userData )
{
return Pa_OpenStream(
stream,
((numInputChannels > 0) ? Pa_GetDefaultInputDeviceID() : paNoDevice),
numInputChannels, sampleFormat, NULL,
((numOutputChannels > 0) ? Pa_GetDefaultOutputDeviceID() : paNoDevice),
numOutputChannels, sampleFormat, NULL,
sampleRate, framesPerBuffer, numberOfBuffers, paNoFlag, callback, userData );
}
/*************************************************************************/
DLL_API PaError Pa_CloseStream( PortAudioStream* stream)
{
PaError result;
internalPortAudioStream *past;
DBUG(("Pa_CloseStream()\n"));
if( stream == NULL ) return paBadStreamPtr;
past = (internalPortAudioStream *) stream;
Pa_AbortStream( past );
result = PaHost_CloseStream( past );
if( past->past_InputBuffer ) PaHost_FreeFastMemory( past->past_InputBuffer, past->past_InputBufferSize );
if( past->past_OutputBuffer ) PaHost_FreeFastMemory( past->past_OutputBuffer, past->past_OutputBufferSize );
PaHost_FreeFastMemory( past, sizeof(internalPortAudioStream) );
return result;
}
/*************************************************************************/
DLL_API PaError Pa_StartStream( PortAudioStream *stream )
{
PaError result = paHostError;
internalPortAudioStream *past;
if( stream == NULL ) return paBadStreamPtr;
past = (internalPortAudioStream *) stream;
past->past_FrameCount = 0.0;
if( past->past_NumInputChannels > 0 )
{
result = PaHost_StartInput( past );
DBUG(("Pa_StartStream: PaHost_StartInput returned = 0x%X.\n", result));
if( result < 0 ) goto error;
}
if( past->past_NumOutputChannels > 0 )
{
result = PaHost_StartOutput( past );
DBUG(("Pa_StartStream: PaHost_StartOutput returned = 0x%X.\n", result));
if( result < 0 ) goto error;
}
result = PaHost_StartEngine( past );
DBUG(("Pa_StartStream: PaHost_StartEngine returned = 0x%X.\n", result));
if( result < 0 ) goto error;
return paNoError;
error:
return result;
}
/*************************************************************************/
DLL_API PaError Pa_StopStream( PortAudioStream *stream )
{
return Pa_KillStream( stream, 0 );
}
/*************************************************************************/
DLL_API PaError Pa_AbortStream( PortAudioStream *stream )
{
return Pa_KillStream( stream, 1 );
}
/*************************************************************************/
static PaError Pa_KillStream( PortAudioStream *stream, int abort )
{
PaError result = paNoError;
internalPortAudioStream *past;
DBUG(("Pa_StopStream().\n"));
if( stream == NULL ) return paBadStreamPtr;
past = (internalPortAudioStream *) stream;
if( (past->past_NumInputChannels > 0) || (past->past_NumOutputChannels > 0) )
{
result = PaHost_StopEngine( past, abort );
DBUG(("Pa_StopStream: PaHost_StopEngine returned = 0x%X.\n", result));
if( result < 0 ) goto error;
}
if( past->past_NumInputChannels > 0 )
{
result = PaHost_StopInput( past, abort );
DBUG(("Pa_StopStream: PaHost_StopInput returned = 0x%X.\n", result));
if( result != paNoError ) goto error;
}
if( past->past_NumOutputChannels > 0 )
{
result = PaHost_StopOutput( past, abort );
DBUG(("Pa_StopStream: PaHost_StopOutput returned = 0x%X.\n", result));
if( result != paNoError ) goto error;
}
error:
past->past_Usage = 0;
past->past_IfLastExitValid = 0;
return result;
}
/*************************************************************************/
DLL_API PaError Pa_StreamActive( PortAudioStream *stream )
{
internalPortAudioStream *past;
if( stream == NULL ) return paBadStreamPtr;
past = (internalPortAudioStream *) stream;
return PaHost_StreamActive( past );
}
/*************************************************************************/
DLL_API const char *Pa_GetErrorText( PaError errnum )
{
const char *msg;
switch(errnum)
{
case paNoError: msg = "Success"; break;
case paHostError: msg = "Host error."; break;
case paInvalidChannelCount: msg = "Invalid number of channels."; break;
case paInvalidSampleRate: msg = "Invalid sample rate."; break;
case paInvalidDeviceId: msg = "Invalid device ID."; break;
case paInvalidFlag: msg = "Invalid flag."; break;
case paSampleFormatNotSupported: msg = "Sample format not supported"; break;
case paBadIODeviceCombination: msg = "Illegal combination of I/O devices."; break;
case paInsufficientMemory: msg = "Insufficient memory."; break;
case paBufferTooBig: msg = "Buffer too big."; break;
case paBufferTooSmall: msg = "Buffer too small."; break;
case paNullCallback: msg = "No callback routine specified."; break;
case paBadStreamPtr: msg = "Invalid stream pointer."; break;
case paTimedOut : msg = "Wait Timed Out."; break;
case paInternalError: msg = "Internal PortAudio Error."; break;
default: msg = "Illegal error number."; break;
}
return msg;
}
/*
Get CPU Load as a fraction of total CPU time.
A value of 0.5 would imply that PortAudio and the sound generating
callback was consuming roughly 50% of the available CPU time.
The amount may vary depending on CPU load.
This function may be called from the callback function.
*/
DLL_API double Pa_GetCPULoad( PortAudioStream* stream)
{
internalPortAudioStream *past;
if( stream == NULL ) return (double) paBadStreamPtr;
past = (internalPortAudioStream *) stream;
return past->past_Usage;
}
/*************************************************************
** Calculate 2 LSB dither signal with a triangular distribution.
** Ranged properly for adding to a 32 bit integer prior to >>15.
*/
#define DITHER_BITS (15)
#define DITHER_SCALE (1.0f / ((1<<DITHER_BITS)-1))
static long Pa_TriangularDither( void )
{
static unsigned long previous = 0;
static unsigned long randSeed1 = 22222;
static unsigned long randSeed2 = 5555555;
long current, highPass;
/* Generate two random numbers. */
randSeed1 = (randSeed1 * 196314165) + 907633515;
randSeed2 = (randSeed2 * 196314165) + 907633515;
/* Generate triangular distribution about 0. */
current = (((long)randSeed1)>>(32-DITHER_BITS)) + (((long)randSeed2)>>(32-DITHER_BITS));
/* High pass filter to reduce audibility. */
highPass = current - previous;
previous = current;
return highPass;
}
/*************************************************************************
** Called by host code.
** Convert input from Int16, call user code, then convert output
** to Int16 format for native use.
** Assumes host native format is paInt16.
** Returns result from user callback.
*/
long Pa_CallConvertInt16( internalPortAudioStream *past,
short *nativeInputBuffer,
short *nativeOutputBuffer )
{
long temp;
long bytesEmpty = 0;
long bytesFilled = 0;
int userResult;
unsigned int i;
void *inputBuffer = NULL;
void *outputBuffer = NULL;
#if SUPPORT_AUDIO_CAPTURE
/* Get native data from DirectSound. */
if( (past->past_NumInputChannels > 0) && (nativeInputBuffer != NULL) )
{
/* Convert from native format to PA format. */
unsigned int samplesPerBuffer = past->past_FramesPerUserBuffer * past->past_NumInputChannels;
switch(past->past_InputSampleFormat)
{
case paFloat32:
{
float *inBufPtr = (float *) past->past_InputBuffer;
inputBuffer = past->past_InputBuffer;
for( i=0; i<samplesPerBuffer; i++ )
{
inBufPtr[i] = nativeInputBuffer[i] * (1.0f / 32767.0f);
}
break;
}
case paInt32:
{
/* Convert 16 bit data to 32 bit integers */
int *inBufPtr = (int *) past->past_InputBuffer;
inputBuffer = past->past_InputBuffer;
for( i=0; i<samplesPerBuffer; i++ )
{
inBufPtr[i] = nativeInputBuffer[i] << 16;
}
break;
}
case paInt16:
{
/* Already in correct format so don't copy. */
inputBuffer = nativeInputBuffer;
break;
}
case paInt8:
{
/* Convert 16 bit data to 8 bit chars */
char *inBufPtr = (char *) past->past_InputBuffer;
inputBuffer = past->past_InputBuffer;
if( past->past_Flags & paDitherOff )
{
for( i=0; i<samplesPerBuffer; i++ )
{
inBufPtr[i] = (char)(nativeInputBuffer[i] >> 8);
}
}
else
{
for( i=0; i<samplesPerBuffer; i++ )
{
temp = nativeInputBuffer[i];
temp += Pa_TriangularDither() >> 7;
temp = ((temp < -0x8000) ? -0x8000 : ((temp > 0x7FFF) ? 0x7FFF : temp));
inBufPtr[i] = (char)(temp >> 8);
}
}
break;
}
case paUInt8:
{
/* Convert 16 bit data to 8 bit unsigned chars */
unsigned char *inBufPtr = (unsigned char *) past->past_InputBuffer;
inputBuffer = past->past_InputBuffer;
if( past->past_Flags & paDitherOff )
{
for( i=0; i<samplesPerBuffer; i++ )
{
inBufPtr[i] = ((unsigned char)(nativeInputBuffer[i] >> 8)) + 0x80;
}
}
else
{
/* If you dither then you have to clip because dithering could push the signal out of range! */
for( i=0; i<samplesPerBuffer; i++ )
{
temp = nativeInputBuffer[i];
temp += Pa_TriangularDither() >> 7;
temp = ((temp < -0x8000) ? -0x8000 : ((temp > 0x7FFF) ? 0x7FFF : temp));
inBufPtr[i] = (unsigned char)(temp + 0x80);
}
}
break;
}
default:
break;
}
}
#endif /* SUPPORT_AUDIO_CAPTURE */
/* Are we doing output time? */
if( (past->past_NumOutputChannels > 0) && (nativeOutputBuffer != NULL) )
{
/* May already be in native format so just write directly to native buffer. */
outputBuffer = (past->past_OutputSampleFormat == paInt16) ?
nativeOutputBuffer : past->past_OutputBuffer;
}
/*
AddTraceMessage("Pa_CallConvertInt16: inputBuffer = ", (int) inputBuffer );
AddTraceMessage("Pa_CallConvertInt16: outputBuffer = ", (int) outputBuffer );
*/
/* Call user callback routine. */
userResult = past->past_Callback(
inputBuffer,
outputBuffer,
past->past_FramesPerUserBuffer,
past->past_FrameCount,
past->past_UserData );
past->past_FrameCount += (PaTimestamp) past->past_FramesPerUserBuffer;
/* Convert to native format if necessary. */
if( outputBuffer != NULL )
{
unsigned int samplesPerBuffer = past->past_FramesPerUserBuffer * past->past_NumOutputChannels;
switch(past->past_OutputSampleFormat)
{
case paFloat32:
{
float *outBufPtr = (float *) past->past_OutputBuffer;
if( past->past_Flags & paDitherOff )
{
if( past->past_Flags & paClipOff ) /* NOTHING */
{
for( i=0; i<samplesPerBuffer; i++ )
{
*nativeOutputBuffer++ = (short) (outBufPtr[i] * (32767.0f));
}
}
else /* CLIP */
{
for( i=0; i<samplesPerBuffer; i++ )
{
temp = (long)(outBufPtr[i] * 32767.0f);
*nativeOutputBuffer++ = (short)((temp < -0x8000) ? -0x8000 : ((temp > 0x7FFF) ? 0x7FFF : temp));
}
}
}
else
{
/* If you dither then you have to clip because dithering could push the signal out of range! */
for( i=0; i<samplesPerBuffer; i++ )
{
float dither = Pa_TriangularDither()*DITHER_SCALE;
float dithered = (outBufPtr[i] * (32767.0f)) + dither;
temp = (long) (dithered);
*nativeOutputBuffer++ = (short)((temp < -0x8000) ? -0x8000 : ((temp > 0x7FFF) ? 0x7FFF : temp));
}
}
break;
}
case paInt32:
{
int *outBufPtr = (int *) past->past_OutputBuffer;
if( past->past_Flags & paDitherOff )
{
for( i=0; i<samplesPerBuffer; i++ )
{
*nativeOutputBuffer++ = (short) (outBufPtr[i] >> 16 );
}
}
else
{
for( i=0; i<samplesPerBuffer; i++ )
{
/* Shift one bit down before dithering so that we have room for overflow from add. */
temp = (outBufPtr[i] >> 1) + Pa_TriangularDither();
temp = temp >> 15;
*nativeOutputBuffer++ = (short)((temp < -0x8000) ? -0x8000 : ((temp > 0x7FFF) ? 0x7FFF : temp));
}
}
break;
}
case paInt8:
{
char *outBufPtr = (char *) past->past_OutputBuffer;
for( i=0; i<samplesPerBuffer; i++ )
{
*nativeOutputBuffer++ = ((short)outBufPtr[i]) << 8;
}
break;
}
case paUInt8:
{
unsigned char *outBufPtr = (unsigned char *) past->past_OutputBuffer;
for( i=0; i<samplesPerBuffer; i++ )
{
*nativeOutputBuffer++ = ((short)(outBufPtr[i] - 0x80)) << 8;
}
break;
}
default:
break;
}
}
return userResult;
}
/*************************************************************************
** Called by host code.
** Convert input from Float32, call user code, then convert output
** to Float32 format for native use.
** Assumes host native format is Float32.
** Returns result from user callback.
** FIXME - Unimplemented for formats other than paFloat32!!!!
*/
long Pa_CallConvertFloat32( internalPortAudioStream *past,
float *nativeInputBuffer,
float *nativeOutputBuffer )
{
long bytesEmpty = 0;
long bytesFilled = 0;
int userResult;
void *inputBuffer = NULL;
void *outputBuffer = NULL;
/* Get native data from DirectSound. */
if( (past->past_NumInputChannels > 0) && (nativeInputBuffer != NULL) )
{
inputBuffer = nativeInputBuffer; // FIXME
}
/* Are we doing output time? */
if( (past->past_NumOutputChannels > 0) && (nativeOutputBuffer != NULL) )
{
/* May already be in native format so just write directly to native buffer. */
outputBuffer = (past->past_OutputSampleFormat == paFloat32) ?
nativeOutputBuffer : past->past_OutputBuffer;
}
/*
AddTraceMessage("Pa_CallConvertInt16: inputBuffer = ", (int) inputBuffer );
AddTraceMessage("Pa_CallConvertInt16: outputBuffer = ", (int) outputBuffer );
*/
/* Call user callback routine. */
userResult = past->past_Callback(
inputBuffer,
outputBuffer,
past->past_FramesPerUserBuffer,
past->past_FrameCount,
past->past_UserData );
past->past_FrameCount += (PaTimestamp) past->past_FramesPerUserBuffer;
/* Convert to native format if necessary. */ // FIXME
return userResult;
}
/*************************************************************************/
DLL_API PaError Pa_Initialize( void )
{
if( gInitCount++ > 0 ) return paNoError;
ResetTraceMessages();
return PaHost_Init();
}
DLL_API PaError Pa_Terminate( void )
{
PaError result = paNoError;
if( gInitCount == 0 ) return paNoError;
else if( --gInitCount == 0 )
{
result = PaHost_Term();
DumpTraceMessages();
}
return result;
}
/*************************************************************************/
DLL_API PaError Pa_GetSampleSize( PaSampleFormat format )
{
int size;
switch(format )
{
case paUInt8:
case paInt8:
size = 1;
break;
case paInt16:
size = 2;
break;
case paPackedInt24:
size = 3;
break;
case paFloat32:
case paInt32:
case paInt24:
size = 4;
break;
default:
size = paSampleFormatNotSupported;
break;
}
return (PaError) size;
}

View File

@ -1,439 +0,0 @@
#ifndef PORT_AUDIO_H
#define PORT_AUDIO_H
#ifdef __cplusplus
extern "C"
{
#endif /* __cplusplus */
/*
* PortAudio Portable Real-Time Audio Library
* PortAudio API Header File
* Latest version available at: http://www.audiomulch.com/portaudio/
*
* Copyright (c) 1999-2000 Ross Bencina and 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,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* Any person wishing to distribute modifications to the Software is
* requested to send the modifications to the original developer so that
* they can be incorporated into the canonical version.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR
* ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
* CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*/
// added by zplane.developement in order to generate a DLL
#if defined(PA_MME_EXPORTS) || defined(PA_DX_EXPORTS)
#define DLL_API __declspec( dllexport )
#elif defined(_LIB) || defined(_STATIC_LINK) || defined(_STATIC_APP)
#define DLL_API
#else
#define DLL_API __declspec(dllexport)
#endif
typedef int PaError;
typedef enum {
paNoError = 0,
paHostError = -10000,
paInvalidChannelCount,
paInvalidSampleRate,
paInvalidDeviceId,
paInvalidFlag,
paSampleFormatNotSupported,
paBadIODeviceCombination,
paInsufficientMemory,
paBufferTooBig,
paBufferTooSmall,
paNullCallback,
paBadStreamPtr,
paTimedOut,
paInternalError
} PaErrorNum;
/*
Pa_Initialize() is the library initialisation function - call this before
using the library.
*/
DLL_API PaError Pa_Initialize( void );
/*
Pa_Terminate() is the library termination function - call this after
using the library.
*/
DLL_API PaError Pa_Terminate( void );
/*
Return host specific error.
This can be called after receiving a paHostError.
*/
DLL_API long Pa_GetHostError( void );
/*
Translate the error number into a human readable message.
*/
DLL_API const char *Pa_GetErrorText( PaError errnum );
/*
Sample formats
These are formats used to pass sound data between the callback and the
stream. Each device has a "native" format which may be used when optimum
efficiency or control over conversion is required.
Formats marked "always available" are supported (emulated) by all devices.
The floating point representation uses +1.0 and -1.0 as the respective
maximum and minimum.
*/
typedef unsigned long PaSampleFormat;
#define paFloat32 ((PaSampleFormat) (1<<0)) /*always available*/
#define paInt16 ((PaSampleFormat) (1<<1)) /*always available*/
#define paInt32 ((PaSampleFormat) (1<<2)) /*always available*/
#define paInt24 ((PaSampleFormat) (1<<3))
#define paPackedInt24 ((PaSampleFormat) (1<<4))
#define paInt8 ((PaSampleFormat) (1<<5))
#define paUInt8 ((PaSampleFormat) (1<<6)) /* unsigned 8 bit, 128 is "ground" */
#define paCustomFormat ((PaSampleFormat) (1<<16))
/*
Device enumeration mechanism.
Device ids range from 0 to Pa_CountDevices()-1.
Devices may support input, output or both. Device 0 is always the "default"
device and should support at least stereo in and out if that is available
on the taget platform _even_ if this involves kludging an input/output
device on platforms that usually separate input from output. Other platform
specific devices are specified by positive device ids.
*/
typedef int PaDeviceID;
#define paNoDevice -1
typedef struct
{
int structVersion;
const char *name;
int maxInputChannels;
int maxOutputChannels;
/* Number of discrete rates, or -1 if range supported. */
int numSampleRates;
/* Array of supported sample rates, or {min,max} if range supported. */
const double *sampleRates;
PaSampleFormat nativeSampleFormats;
}
PaDeviceInfo;
DLL_API int Pa_CountDevices();
/*
Pa_GetDefaultInputDeviceID(), Pa_GetDefaultOutputDeviceID()
Return the default device ID or paNoDevice if there is no devices.
The result can be passed to Pa_OpenStream().
On the PC, the user can specify a default device by
setting an environment variable. For example, to use device #1.
set PA_RECOMMENDED_OUTPUT_DEVICE=1
The user should first determine the available device ID by using
the supplied application "pa_devs".
*/
DLL_API PaDeviceID Pa_GetDefaultInputDeviceID( void );
DLL_API PaDeviceID Pa_GetDefaultOutputDeviceID( void );
/*
PaTimestamp is used to represent a continuous sample clock with arbitrary
start time useful for syncronisation. The type is used in the outTime
argument to the callback function and the result of Pa_StreamTime()
*/
typedef double PaTimestamp;
/*
Pa_GetDeviceInfo() returns a pointer to an immutable PaDeviceInfo structure
referring to the device specified by id.
If id is out of range the function returns NULL.
The returned structure is owned by the PortAudio implementation and must
not be manipulated or freed. The pointer is guaranteed to be valid until
between calls to Pa_Initialize() and Pa_Terminate().
*/
DLL_API const PaDeviceInfo* Pa_GetDeviceInfo( PaDeviceID id );
/*
PortAudioCallback is implemented by clients of the portable audio api.
inputBuffer and outputBuffer are arrays of interleaved samples,
the format, packing and number of channels used by the buffers are
determined by parameters to Pa_OpenStream() (see below).
framesPerBuffer is the number of sample frames to be processed by the callback.
outTime is the time in samples when the buffer(s) processed by
this callback will begin being played at the audio output.
See also Pa_StreamTime()
userData is the value of a user supplied pointer passed to Pa_OpenStream()
intended for storing synthesis data etc.
return value:
The callback can return a nonzero value to stop the stream. This may be
useful in applications such as soundfile players where a specific duration
of output is required. However, it is not necessary to utilise this mechanism
as StopStream() will also terminate the stream. A callback returning a
nonzero value must fill the entire outputBuffer.
NOTE: None of the other stream functions may be called from within the
callback function except for Pa_GetCPULoad().
*/
typedef int (PortAudioCallback)(
void *inputBuffer, void *outputBuffer,
unsigned long framesPerBuffer,
PaTimestamp outTime, void *userData );
/*
Stream flags
These flags may be supplied (ored together) in the streamFlags argument to
the Pa_OpenStream() function.
[ suggestions? ]
*/
#define paNoFlag (0)
#define paClipOff (1<<0) /* disable defult clipping of out of range samples */
#define paDitherOff (1<<1) /* disable default dithering */
#define paPlatformSpecificFlags (0x00010000)
typedef unsigned long PaStreamFlags;
/*
A single PortAudioStream provides multiple channels of real-time
input and output audio streaming to a client application.
Pointers to PortAudioStream objects are passed between PortAudio functions.
*/
typedef void PortAudioStream;
#define PaStream PortAudioStream
/*
Pa_OpenStream() opens a stream for either input, output or both.
stream is the address of a PortAudioStream pointer which will receive
a pointer to the newly opened stream.
inputDevice is the id of the device used for input (see PaDeviceID above.)
inputDevice may be paNoDevice to indicate that an input device is not required.
numInputChannels is the number of channels of sound to be delivered to the
callback. It can range from 1 to the value of maxInputChannels in the
device input record for the device specified in the inputDevice parameter.
If inputDevice is paNoDevice numInputChannels is ignored.
inputSampleFormat is the format of inputBuffer provided to the callback
function. inputSampleFormat may be any of the formats described by the
PaSampleFormat enumeration (see above). PortAudio guarantees support for
the sound devices native formats (nativeSampleFormats in the device info
record) and additionally 16 and 32 bit integer and 32 bit floating point
formats. Support for other formats is implementation defined.
inputDriverInfo is a pointer to an optional driver specific data structure
containing additional information for device setup or stream processing.
inputDriverInfo is never required for correct operation. If not used
inputDriverInfo should be NULL.
outputDevice is the id of the device used for output (see PaDeviceID above.)
outputDevice may be paNoDevice to indicate that an output device is not required.
numOutputChannels is the number of channels of sound to be supplied by the
callback. See the definition of numInputChannels above for more details.
outputSampleFormat is the sample format of the outputBuffer filled by the
callback function. See the definition of inputSampleFormat above for more
details.
outputDriverInfo is a pointer to an optional driver specific data structure
containing additional information for device setup or stream processing.
outputDriverInfo is never required for correct operation. If not used
outputDriverInfo should be NULL.
sampleRate is the desired sampleRate for input and output
framesPerBuffer is the length in sample frames of all internal sample buffers
used for communication with platform specific audio routines. Wherever
possible this corresponds to the framesPerBuffer parameter passed to the
callback function.
numberOfBuffers is the number of buffers used for multibuffered
communication with the platform specific audio routines. This parameter is
provided only as a guide - and does not imply that an implementation must
use multibuffered i/o when reliable double buffering is available (such as
SndPlayDoubleBuffer() on the Macintosh.)
streamFlags may contain a combination of flags ORed together.
These flags modify the behavior of the
streaming process. Some flags may only be relevant to certain buffer formats.
callback is a pointer to a client supplied function that is responsible
for processing and filling input and output buffers (see above for details.)
userData is a client supplied pointer which is passed to the callback
function. It could for example, contain a pointer to instance data necessary
for processing the audio buffers.
return value:
Apon success Pa_OpenStream() returns PaNoError and places a pointer to a
valid PortAudioStream in the stream argument. The stream is inactive (stopped).
If a call to Pa_OpenStream() fails a nonzero error code is returned (see
PAError above) and the value of stream is invalid.
*/
DLL_API PaError Pa_OpenStream( PortAudioStream** stream,
PaDeviceID inputDevice,
int numInputChannels,
PaSampleFormat inputSampleFormat,
void *inputDriverInfo,
PaDeviceID outputDevice,
int numOutputChannels,
PaSampleFormat outputSampleFormat,
void *outputDriverInfo,
double sampleRate,
unsigned long framesPerBuffer,
unsigned long numberOfBuffers,
PaStreamFlags streamFlags,
PortAudioCallback *callback,
void *userData );
/*
Pa_OpenDefaultStream() is a simplified version of Pa_OpenStream() that
opens the default input and/or ouput devices. Most parameters have
identical meaning to their Pa_OpenStream() counterparts, with the following
exceptions:
If either numInputChannels or numOutputChannels is 0 the respective device
is not opened (same as passing paNoDevice in the device arguments to Pa_OpenStream() )
sampleFormat applies to both the input and output buffers.
*/
DLL_API PaError Pa_OpenDefaultStream( PortAudioStream** stream,
int numInputChannels,
int numOutputChannels,
PaSampleFormat sampleFormat,
double sampleRate,
unsigned long framesPerBuffer,
unsigned long numberOfBuffers,
PortAudioCallback *callback,
void *userData );
/*
Pa_CloseStream() closes an audio stream, flushing any pending buffers.
*/
DLL_API PaError Pa_CloseStream( PortAudioStream* );
/*
Pa_StartStream() and Pa_StopStream() begin and terminate audio processing.
When Pa_StopStream() returns, all pending audio buffers have been played.
Pa_AbortStream() stops playing immediately without waiting for pending
buffers to complete.
*/
DLL_API PaError Pa_StartStream( PortAudioStream *stream );
DLL_API PaError Pa_StopStream( PortAudioStream *stream );
DLL_API PaError Pa_AbortStream( PortAudioStream *stream );
/*
Pa_StreamActive() returns one when the stream is playing audio,
zero when not playing, or a negative error number if the
stream is invalid.
The stream is active between calls to Pa_StartStream() and Pa_StopStream(),
but may also become inactive if the callback returns a non-zero value.
In the latter case, the stream is considered inactive after the last
buffer has finished playing.
*/
DLL_API PaError Pa_StreamActive( PortAudioStream *stream );
/*
Pa_StreamTime() returns the current output time for the stream in samples.
This time may be used as a time reference (for example syncronising audio to
MIDI).
*/
DLL_API PaTimestamp Pa_StreamTime( PortAudioStream *stream );
/*
The "CPU Load" is a fraction of total CPU time consumed by the
stream's audio processing.
A value of 0.5 would imply that PortAudio and the sound generating
callback was consuming roughly 50% of the available CPU time.
This function may be called from the callback function or the application.
*/
DLL_API double Pa_GetCPULoad( PortAudioStream* stream );
/*
Use Pa_GetMinNumBuffers() to determine minimum number of buffers required for
the current host based on minimum latency.
On the PC, for the DirectSound implementation, latency can be optionally set
by user by setting an environment variable.
For example, to set latency to 200 msec, put:
set PA_MIN_LATENCY_MSEC=200
in the AUTOEXEC.BAT file and reboot.
If the environment variable is not set, then the latency will be determined
based on the OS. Windows NT has higher latency than Win95.
*/
DLL_API int Pa_GetMinNumBuffers( int framesPerBuffer, double sampleRate );
/*
Sleep for at least 'msec' milliseconds.
You may sleep longer than the requested time so don't rely
on this for accurate musical timing.
*/
DLL_API void Pa_Sleep( long msec );
/*
Return size in bytes of a single sample in a given PaSampleFormat
or paSampleFormatNotSupported.
*/
DLL_API PaError Pa_GetSampleSize( PaSampleFormat format );
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif /* PORT_AUDIO_H */