initial commit with some toy code

This commit is contained in:
Spencer Russell 2013-12-11 20:18:36 -05:00
commit 030b4acd4a
7 changed files with 282 additions and 0 deletions

1
.gitignore vendored Normal file
View file

@ -0,0 +1 @@
*.swp

21
LICENSE Normal file
View file

@ -0,0 +1,21 @@
The MIT License (MIT)
Copyright (c) 2013 Spencer Russell
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.
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.

2
Makefile Normal file
View file

@ -0,0 +1,2 @@
default: test

3
README Normal file
View file

@ -0,0 +1,3 @@
This is a Julia interface to PortAudio.
More info to come...

49
deps/src/Makefile vendored Normal file
View file

@ -0,0 +1,49 @@
# Makefile lifted from Clang.jl
all: default
ifeq (exists, $(shell [ -e Make.user ] && echo exists ))
include Make.user
endif
.PHONY: all clean check-env default
#check-env:
#ifndef JULIA_ROOT
# $(error Environment variable JULIA_ROOT is not set.)
#endif
INC =-I"$(JULIA_ROOT)/usr/include"
FLAGS =-Wall -Wno-strict-aliasing -fno-omit-frame-pointer -fPIC
CFLAGS =-g
LIBS =
OBJS = shim.o
# libm can be removed later, it's just for the sin function used in testing
LIBS += -lportaudio -lm
# Figure out OS and architecture
OS = $(shell uname)
ifeq ($(OS), MINGW32_NT-6.1)
OS=WINNT
endif
# file extensions
ifeq ($(OS), WINNT)
SHLIB_EXT = dll
else ifeq ($(OS), Darwin)
SHLIB_EXT = dylib
else
SHLIB_EXT = so
endif
default: portaudio_shim.$(SHLIB_EXT)
%.o: %.c
$(CC) $< -fPIC -c -o $@ $(INC) $(CFLAGS) $(FLAGS)
portaudio_shim.$(SHLIB_EXT): $(OBJS)
$(CC) $(OBJS) -rdynamic -shared -o $@ $(LDFLAGS) $(LIBS)
clean:
rm -f *.o *.$(SHLIB_EXT)

110
deps/src/shim.c vendored Normal file
View file

@ -0,0 +1,110 @@
#include <portaudio.h>
#include <math.h>
#include <stdio.h>
#define SAMPLE_RATE 44100
static int patestCallback(const void *inputBuffer, void *outputBuffer,
unsigned long framesPerBuffer,
const PaStreamCallbackTimeInfo* timeInfo,
PaStreamCallbackFlags statusFlags,
void *userData);
static PaStream *sin_stream;
PaError play_sin(void)
{
PaError err;
// PaDeviceInfo *info;
// int numDevices;
// printf("Found Devices:\n");
// numDevices = Pa_GetDeviceCount();
// for(i = 0; i < numDevices; ++i)
// {
// info = Pa_GetDeviceInfo(i);
// printf("%s\n", info->name);
// }
err = Pa_OpenDefaultStream(&sin_stream,
0, /* no input channels */
2, /* stereo output */
paFloat32, /* 32 bit floating point output */
SAMPLE_RATE,
1024, /* frames per buffer, i.e. the number of sample frames
that PortAudio will request from the callback. Many
apps may want to use paFramesPerBufferUnspecified,
which tells PortAudio to pick the best, possibly
changing, buffer size.*/
patestCallback, /* this is your callback function */
NULL); /*This is a pointer that will be passed to your callback*/
if(err != paNoError)
{
return err;
}
err = Pa_StartStream(sin_stream);
if(err != paNoError)
{
return err;
}
return paNoError;
}
PaError stop_sin(void)
{
PaError err;
err = Pa_StopStream(sin_stream);
if(err != paNoError)
{
return err;
}
err = Pa_CloseStream(sin_stream);
if( err != paNoError )
{
return err;
}
return paNoError;
}
/*
* This routine will be called by the PortAudio engine when audio is needed.
* It may called at interrupt level on some machines so don't do anything that
* could mess up the system like calling malloc() or free().
*/
static int patestCallback(const void *inputBuffer, void *outputBuffer,
unsigned long framesPerBuffer,
const PaStreamCallbackTimeInfo* timeInfo,
PaStreamCallbackFlags statusFlags,
void *userData)
{
float freq_l = 100;
float freq_r = 150;
static float phase_l = 0;
static float phase_r = 0;
float *out = (float*)outputBuffer;
unsigned int i;
for(i=0; i<framesPerBuffer; i++)
{
/* should modulo by 2PI */
phase_l += (2 * M_PI * freq_l / SAMPLE_RATE);
if(phase_l > 2 * M_PI)
{
phase_l -= 2 * M_PI;
}
phase_r += (2 * M_PI * freq_r / SAMPLE_RATE);
if(phase_r > 2 * M_PI)
{
phase_r -= 2 * M_PI;
}
out[2*i] = sin(phase_l);
out[2*i + 1] = sin(phase_r);
}
return 0;
}

96
src/portaudio.jl Normal file
View file

@ -0,0 +1,96 @@
# thanks to Gustavo Goretkin for the start on this
module PortAudio
typealias PaTime Cdouble
typealias PaError Cint
typealias PaSampleFormat Culong
typealias PaStream Void
const PA_NO_ERROR::PaError = 0
function handle_status(err::PaError)
if err != PA_NO_ERROR
msg = ccall((:Pa_GetErrorText, "libportaudio"),
Ptr{Cchar}, (PaError,), err)
error(bytestring(msg))
end
end
function init()
err = ccall((:Pa_Initialize, "libportaudio"), PaError, ())
handle_status(err)
end
function deinit()
err = ccall((:Pa_Terminate, "libportaudio"), PaError, ())
handle_status(err)
end
function play_sin()
end
function stop_sin()
end
end # module PortAudio
type PaStreamCallbackTimeInfo
inputBufferAdcTime::PaTime
currentTime::PaTime
outputBufferDacTime::PaTime
end
typealias PaStreamCallbackFlags Culong
function stream_callback{T}( input_::Ptr{T},
output_::Ptr{T},
frame_count::Culong,
time_info::Ptr{PaStreamCallbackTimeInfo},
status_flags::PaStreamCallbackFlags,
user_data::Ptr{Void})
println("stfl:$status_flags \tframe_count:$frame_count")
ret = 0
return convert(Cint,ret)::Cint #continue stream
end
T=Float32
stream_callback_c = cfunction(stream_callback,Cint,
(Ptr{T},Ptr{T},Culong,Ptr{PaStreamCallbackTimeInfo},PaStreamCallbackFlags,Ptr{Void})
)
stream_obj = Array(Ptr{PaStream},1)
pa_err = ccall(
(:Pa_Initialize,"libportaudio"),
PaError,
(),
)
println(get_error_text(pa_err))
pa_err = ccall(
(:Pa_OpenDefaultStream,"libportaudio"),
PaError,
(Ptr{Ptr{PaStream}},Cint,Cint,PaSampleFormat,Cdouble,Culong,Ptr{Void},Any),
stream_obj,0,1,0x1,8000.0,4096,stream_callback_c,None
)
println(get_error_text(pa_err))
function start_stream(stream)
pa_err = ccall(
(:Pa_StartStream,"libportaudio"),
PaError,
(Ptr{PaStream},),
stream
)
println(get_error_text(pa_err))
end
end #module