swap echo for forevermore sample, phase delay with gyro

This commit is contained in:
Stephen Birarda 2013-01-24 11:15:58 -08:00
parent d6d66fa6a9
commit 5fd300a91a
4 changed files with 100 additions and 23 deletions

BIN
Resources/audio/love.raw Normal file

Binary file not shown.

View file

@ -6,6 +6,8 @@
// Copyright (c) 2013 Rosedale Lab. All rights reserved.
//
#include <iostream>
#include <fstream>
#include "audio.h"
bool Audio::initialized;
@ -42,16 +44,51 @@ int audioCallback (const void *inputBuffer,
void *userData)
{
Audio::AudioData *data = (Audio::AudioData *) userData;
int16_t *input = (int16_t *) inputBuffer;
int16_t *output = (int16_t *) outputBuffer;
// check if we have input data
if (input != NULL) {
memcpy(data->buffer, input, data->bufferLength * 2);
int16_t *outputLeft = ((int16_t **) outputBuffer)[0];
int16_t *outputRight = ((int16_t **) outputBuffer)[1];
float yawRatio = data->linkedHead != NULL
? data->linkedHead->getYaw() / 90.0
: 0;
int numSamplesDelay = abs(floor(yawRatio * PHASE_DELAY_AT_90));
if (numSamplesDelay > PHASE_DELAY_AT_90) {
numSamplesDelay = PHASE_DELAY_AT_90;
}
int16_t *leadingBuffer = yawRatio > 0 ? outputLeft : outputRight;
int16_t *trailingBuffer = yawRatio > 0 ? outputRight : outputLeft;
int wrapAroundSamples = (BUFFER_LENGTH_BYTES / sizeof(int16_t)) - (data->fileSamples - data->samplePointer);
int16_t *samplesToQueue;
if (wrapAroundSamples < 0) {
samplesToQueue = data->fileBuffer + data->samplePointer;
data->samplePointer += (BUFFER_LENGTH_BYTES / sizeof(int16_t));
} else {
samplesToQueue = new int16_t[BUFFER_LENGTH_BYTES];
memcpy(samplesToQueue, data->fileBuffer + data->samplePointer, (data->fileSamples - data->samplePointer) * sizeof(int16_t));
memcpy(samplesToQueue, data->fileBuffer, wrapAroundSamples * sizeof(int16_t));
data->samplePointer = wrapAroundSamples;
}
memcpy(output, data->buffer, data->bufferLength * 2);
memcpy(leadingBuffer, samplesToQueue, BUFFER_LENGTH_BYTES);
int offsetBytes = numSamplesDelay * sizeof(int16_t);
memcpy(trailingBuffer, data->delayBuffer + (PHASE_DELAY_AT_90 - numSamplesDelay), offsetBytes);
memcpy(trailingBuffer + numSamplesDelay, samplesToQueue, BUFFER_LENGTH_BYTES - offsetBytes);
if (wrapAroundSamples > 0) {
delete[] samplesToQueue;
}
// copy PHASE_DELAY_AT_90 samples to delayBuffer in case we need it next go around
memcpy(data->delayBuffer, data->fileBuffer + data->samplePointer - PHASE_DELAY_AT_90, PHASE_DELAY_AT_90 * sizeof(int16_t));
return paContinue;
}
@ -77,10 +114,12 @@ bool Audio::init(Head* mainHead)
err = Pa_Initialize();
if (err != paNoError) goto error;
Audio::readFile();
err = Pa_OpenDefaultStream(&stream,
1, // input channels
1, // output channels
paInt16, // sample format
NULL, // input channels
2, // output channels
(paInt16 | paNonInterleaved), // sample format
22050, // sample rate (hz)
512, // frames per buffer
audioCallback, // callback function
@ -100,6 +139,24 @@ error:
return false;
}
void Audio::readFile()
{
int length;
FILE *soundFile = fopen("love.raw", "r");
// get length of file:
std::fseek(soundFile, 0, SEEK_END);
data->fileSamples = std::ftell(soundFile) / sizeof(int16_t);
std::rewind(soundFile);
data->fileBuffer = new int16_t[data->fileSamples];
std::fread(data->fileBuffer, sizeof(int16_t), data->fileSamples, soundFile);
std::fclose(soundFile);
}
/**
* Close the running audio stream, and deinitialize portaudio.
* Should be called at the end of program execution.

View file

@ -13,6 +13,9 @@
#include "portaudio.h"
#include "head.h"
#define BUFFER_LENGTH_BYTES 1024
#define PHASE_DELAY_AT_90 20
class Audio {
public:
// initializes audio I/O
@ -22,27 +25,32 @@ public:
// terminates audio I/O
static bool terminate();
private:
static void readFile();
static bool initialized;
static struct AudioData {
// struct for left/right data in audio buffer
struct BufferFrame {
int16_t left, right;
} *buffer;
Head* linkedHead;
int samplePointer;
int fileSamples;
// length in bytes of audio buffer
const static unsigned int bufferLength = 1024;
int16_t *delayBuffer;
int16_t *fileBuffer;
Head* linkedHead;
AudioData() {
// alloc memory for buffer
buffer = new BufferFrame[bufferLength];
memset(buffer, 0, sizeof(int16_t) * bufferLength * 2);
samplePointer = 0;
// alloc memory for sample delay buffer
delayBuffer = new int16_t[PHASE_DELAY_AT_90];
memset(delayBuffer, 0, sizeof(int16_t) * PHASE_DELAY_AT_90);
}
~AudioData() {
delete[] buffer;
delete[] fileBuffer;
delete[] delayBuffer;
}
} *data;

View file

@ -51,6 +51,7 @@
532C803A16AF3B1900B1A969 /* libopencv_video.2.4.3.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 532C802516AF3B1900B1A969 /* libopencv_video.2.4.3.dylib */; };
532C803B16AF3B1900B1A969 /* libopencv_videostab.2.4.3.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 532C802616AF3B1900B1A969 /* libopencv_videostab.2.4.3.dylib */; };
532C803C16AF3B1900B1A969 /* libportaudio.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 532C802816AF3B1900B1A969 /* libportaudio.a */; };
538BA8A316B1B71E000BF99C /* love.raw in CopyFiles */ = {isa = PBXBuildFile; fileRef = 538BA8A216B1B719000BF99C /* love.raw */; };
B6BDADE115F44A9D002A07DF /* CoreServices.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = B6BDADDE15F444DB002A07DF /* CoreServices.framework */; };
B6BDADE215F44AA5002A07DF /* CoreAudio.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = B6BDADD815F444C1002A07DF /* CoreAudio.framework */; };
B6BDADE315F44AB0002A07DF /* AudioToolbox.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = B6BDADDA15F444C9002A07DF /* AudioToolbox.framework */; };
@ -69,6 +70,7 @@
532C7CCC16AF301E00B1A969 /* grayson-particle.png in CopyFiles */,
532C7CCD16AF301E00B1A969 /* int-texture256-v2.png in CopyFiles */,
532C7CCE16AF301E00B1A969 /* int-texture256-v4.png in CopyFiles */,
538BA8A316B1B71E000BF99C /* love.raw in CopyFiles */,
532C7CCF16AF301E00B1A969 /* int-texture256-v5.png in CopyFiles */,
532C7CD016AF301E00B1A969 /* philip-image.png in CopyFiles */,
532C7CD116AF301E00B1A969 /* pngtest8rgba.png in CopyFiles */,
@ -500,6 +502,7 @@
532C802616AF3B1900B1A969 /* libopencv_videostab.2.4.3.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; path = libopencv_videostab.2.4.3.dylib; sourceTree = "<group>"; };
532C802816AF3B1900B1A969 /* libportaudio.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; path = libportaudio.a; sourceTree = "<group>"; };
532C802916AF3B1900B1A969 /* portaudio.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = portaudio.h; sourceTree = "<group>"; };
538BA8A216B1B719000BF99C /* love.raw */ = {isa = PBXFileReference; lastKnownFileType = file; path = love.raw; sourceTree = "<group>"; };
8DD76F6C0486A84900D96B5E /* interface */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = interface; sourceTree = BUILT_PRODUCTS_DIR; };
B6BDADD815F444C1002A07DF /* CoreAudio.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreAudio.framework; path = System/Library/Frameworks/CoreAudio.framework; sourceTree = SDKROOT; };
B6BDADDA15F444C9002A07DF /* AudioToolbox.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AudioToolbox.framework; path = System/Library/Frameworks/AudioToolbox.framework; sourceTree = SDKROOT; };
@ -584,6 +587,8 @@
children = (
5325C22916AF4DBE0051A40B /* agent.cpp */,
5325C22A16AF4DBE0051A40B /* agent.h */,
5325C26216AF4E2C0051A40B /* audio.cpp */,
5325C26316AF4E2C0051A40B /* audio.h */,
5325C22D16AF4DBE0051A40B /* cloud.cpp */,
5325C22E16AF4DBE0051A40B /* cloud.h */,
5325C22F16AF4DBE0051A40B /* cube.cpp */,
@ -617,8 +622,6 @@
5325C24D16AF4DBE0051A40B /* util.cpp */,
5325C24E16AF4DBE0051A40B /* util.h */,
5325C24F16AF4DBE0051A40B /* world.h */,
5325C26216AF4E2C0051A40B /* audio.cpp */,
5325C26316AF4E2C0051A40B /* audio.h */,
);
path = Source;
sourceTree = "<group>";
@ -642,6 +645,7 @@
532C7AC116AF298D00B1A969 /* Resources */ = {
isa = PBXGroup;
children = (
536E784516B0A1C900A2F6F3 /* audio */,
532C7AC216AF298D00B1A969 /* images */,
);
path = Resources;
@ -1276,6 +1280,14 @@
path = PortAudio;
sourceTree = "<group>";
};
536E784516B0A1C900A2F6F3 /* audio */ = {
isa = PBXGroup;
children = (
538BA8A216B1B719000BF99C /* love.raw */,
);
path = audio;
sourceTree = "<group>";
};
/* End PBXGroup section */
/* Begin PBXNativeTarget section */