initial commit with some toy code
This commit is contained in:
commit
030b4acd4a
7 changed files with 282 additions and 0 deletions
1
.gitignore
vendored
Normal file
1
.gitignore
vendored
Normal file
|
@ -0,0 +1 @@
|
||||||
|
*.swp
|
21
LICENSE
Normal file
21
LICENSE
Normal 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
2
Makefile
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
|
||||||
|
default: test
|
3
README
Normal file
3
README
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
This is a Julia interface to PortAudio.
|
||||||
|
|
||||||
|
More info to come...
|
49
deps/src/Makefile
vendored
Normal file
49
deps/src/Makefile
vendored
Normal 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
110
deps/src/shim.c
vendored
Normal 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
96
src/portaudio.jl
Normal 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
|
Loading…
Reference in a new issue