mirror of
https://github.com/overte-org/overte.git
synced 2025-04-20 01:24:03 +02:00
swap echo for forevermore sample, phase delay with gyro
This commit is contained in:
parent
d6d66fa6a9
commit
5fd300a91a
4 changed files with 100 additions and 23 deletions
BIN
Resources/audio/love.raw
Normal file
BIN
Resources/audio/love.raw
Normal file
Binary file not shown.
|
@ -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.
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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 */
|
||||
|
|
Loading…
Reference in a new issue