Created
September 29, 2018 19:26
-
-
Save jpcima/0b9088e39c45f52b68cbfb3212e2c3af to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
diff --git a/AudioFileSet.cpp b/AudioFileSet.cpp | |
index efa93c9..d18d748 100644 | |
--- a/AudioFileSet.cpp | |
+++ b/AudioFileSet.cpp | |
@@ -28,6 +28,10 @@ | |
// | |
#include "AudioFileSet.h" | |
+#include <soxr.h> | |
+#include <math.h> | |
+ | |
+extern unsigned int samp_rate; | |
//--------------------------------------------------------------------------- | |
// Destructor | |
@@ -125,8 +129,8 @@ int AudioFileSet::loadFileSet(string localPath) | |
cout << " Format: " << sfinfo.format << endl; | |
//warn about sampling rate incompatibility | |
- if (sfinfo.samplerate != MY_SRATE){ | |
- printf("\nWARNING: '%s' is sampled at a different rate from the current sample rate of %i\n",theFileName.c_str(),MY_SRATE); | |
+ if (sfinfo.samplerate != ::samp_rate){ | |
+ printf("\nWARNING: '%s' is sampled at a different rate from the current sample rate of %i\n",theFileName.c_str(),::samp_rate); | |
} | |
//MONO CONVERSION SET ASIDE FOR NOW... number of channels for each file is dealt with | |
@@ -177,6 +181,12 @@ int AudioFileSet::loadFileSet(string localPath) | |
} | |
} while(!empty); | |
+ | |
+ if (sfinfo.samplerate != ::samp_rate){ | |
+ printf("\nResample to %i\n",::samp_rate); | |
+ fileSet->at(fileCounter)->resampleTo(::samp_rate); | |
+ } | |
+ | |
cout << counter << endl; | |
//increment the file counter | |
fileCounter++; | |
@@ -192,10 +202,38 @@ int AudioFileSet::loadFileSet(string localPath) | |
perror (""); | |
return 1; | |
} | |
+ | |
+ return 0; | |
} | |
+void AudioFile::resampleTo(unsigned int newRate) | |
+{ | |
+ unsigned channels = this->channels; | |
+ unsigned oldFrames = frames; | |
+ unsigned oldRate = sampleRate; | |
+ SAMPLE *oldWave = wave; | |
+ unsigned newFrames = ceil((double)oldRate * newRate / oldRate); | |
+ SAMPLE *newWave = new SAMPLE[channels * newFrames]; | |
+ soxr_io_spec_t io_spec = soxr_io_spec(MY_RESAMPLER_FORMAT_I, MY_RESAMPLER_FORMAT_I); | |
+ soxr_quality_spec_t quality_spec = soxr_quality_spec(SOXR_VHQ, 0); | |
+ soxr_runtime_spec_t runtime_spec = soxr_runtime_spec(2); | |
+ size_t idone = 0; | |
+ size_t odone = 0; | |
+ soxr_error_t err = soxr_oneshot( | |
+ oldRate, newRate, channels, | |
+ oldWave, oldFrames, &idone, | |
+ newWave, newFrames, &odone, | |
+ &io_spec, &quality_spec, &runtime_spec); | |
+ if (err) | |
+ throw std::runtime_error("could not resample: libsoxr error"); | |
+ newFrames = odone; | |
+ delete[] wave; | |
+ wave = newWave; | |
+ frames = newFrames; | |
+ sampleRate = newRate; | |
+} | |
diff --git a/AudioFileSet.h b/AudioFileSet.h | |
index 55305d9..a849062 100644 | |
--- a/AudioFileSet.h | |
+++ b/AudioFileSet.h | |
@@ -50,7 +50,6 @@ struct AudioFile{ | |
this->name = myName; | |
this->path = thePath; | |
this->frames = numFrames; | |
- this->lengthSamps = numFrames * numChan; | |
this->channels = numChan; | |
this->sampleRate = srate; | |
this->wave = theWave; | |
@@ -62,12 +61,13 @@ struct AudioFile{ | |
delete [] wave; | |
} | |
} | |
- | |
+ | |
+ void resampleTo(unsigned int newRate); | |
+ | |
string name; | |
string path; | |
SAMPLE * wave; | |
unsigned long frames; | |
- unsigned long lengthSamps; | |
unsigned int channels; | |
unsigned int sampleRate; | |
}; | |
@@ -99,4 +99,4 @@ private: | |
-#endif | |
\ No newline at end of file | |
+#endif | |
diff --git a/Borderlands.cpp b/Borderlands.cpp | |
index c8d5f77..be04f4e 100644 | |
--- a/Borderlands.cpp | |
+++ b/Borderlands.cpp | |
@@ -114,9 +114,12 @@ vector<GrainClusterVis *> * grainCloudVis; | |
//cloud counter | |
unsigned int numClouds = 0; | |
+//sample rate - Hz | |
+unsigned int samp_rate = 0; | |
+ | |
//global time increment - samples per second | |
//global time is incremented in audio callback | |
-const double samp_time_sec = (double) 1.0 / (double)MY_SRATE; | |
+double samp_time_sec = 0; | |
//Initial camera movement vars | |
@@ -1566,6 +1569,36 @@ int main (int argc, char ** argv) | |
//init random number generator | |
srand(time(NULL)); | |
//start time | |
+ | |
+ //-------------Audio Configuration-----------// | |
+ | |
+ //configure RtAudio | |
+ //create the object | |
+ try { | |
+ theAudio = new MyRtAudio(1,MY_CHANNELS, &g_buffSize, MY_FORMAT,true); | |
+ } catch (RtError & err) { | |
+ err.printMessage(); | |
+ exit(1); | |
+ } | |
+ try | |
+ { | |
+ unsigned sampleRate = theAudio->getSampleRate(); | |
+ ::samp_rate = sampleRate; | |
+ ::samp_time_sec = 1.0 / sampleRate; | |
+ Stk::setSampleRate(sampleRate); | |
+ //open audio stream/assign callback | |
+ theAudio->openStream(&audioCallback); | |
+ //get new buffer size | |
+ g_buffSize = theAudio->getBufferSize(); | |
+ //report latency | |
+ theAudio->reportStreamLatency(); | |
+ | |
+ }catch (RtError & err ) | |
+ { | |
+ err.printMessage(); | |
+ cleaningFunction(); | |
+ exit(1); | |
+ } | |
//-------------Graphics Initialization--------// | |
@@ -1621,32 +1654,9 @@ int main (int argc, char ** argv) | |
- //-------------Audio Configuration-----------// | |
- | |
- //configure RtAudio | |
- //create the object | |
- try { | |
- theAudio = new MyRtAudio(1,MY_CHANNELS, MY_SRATE, &g_buffSize, MY_FORMAT,true); | |
- } catch (RtError & err) { | |
- err.printMessage(); | |
- exit(1); | |
- } | |
- try | |
- { | |
- //open audio stream/assign callback | |
- theAudio->openStream(&audioCallback); | |
- //get new buffer size | |
- g_buffSize = theAudio->getBufferSize(); | |
- //start audio stream | |
- theAudio->startStream(); | |
- //report latency | |
- theAudio->reportStreamLatency(); | |
- | |
- }catch (RtError & err ) | |
- { | |
- err.printMessage(); | |
- goto cleanup; | |
- } | |
+ | |
+ //start audio stream | |
+ theAudio->startStream(); | |
diff --git a/GrainCluster.cpp b/GrainCluster.cpp | |
index 02509c9..e1a9a3a 100644 | |
--- a/GrainCluster.cpp | |
+++ b/GrainCluster.cpp | |
@@ -28,7 +28,7 @@ | |
#include "GrainCluster.h" | |
- | |
+extern unsigned int samp_rate; | |
//Destructor | |
@@ -128,7 +128,7 @@ GrainCluster::GrainCluster(vector<AudioFile*> * soundSet, float theNumVoices) | |
// setDirection(RANDOM_DIR); | |
//initialize trigger time (samples) | |
- bang_time = duration * MY_SRATE * (double) 0.001 / overlap; | |
+ bang_time = duration * ::samp_rate * (double) 0.001 / overlap; | |
//load grains | |
for (int i = 0; i < myGrains->size(); i++){ | |
@@ -244,7 +244,7 @@ void GrainCluster::setDurationMs(float theDur) | |
//update internal grain trigger time | |
void GrainCluster::updateBangTime(){ | |
- bang_time = duration * MY_SRATE * (double) 0.001 / overlap; | |
+ bang_time = duration * ::samp_rate * (double) 0.001 / overlap; | |
//cout << "duration: " << duration << ", new bang time " << bang_time << endl; | |
} | |
diff --git a/GrainVoice.cpp b/GrainVoice.cpp | |
index e0e3def..2b6d15e 100644 | |
--- a/GrainVoice.cpp | |
+++ b/GrainVoice.cpp | |
@@ -30,6 +30,8 @@ | |
#include "GrainVoice.h" | |
+extern unsigned int samp_rate; | |
+ | |
//-------------------AUDIO----------------------------------------------------// | |
//----------------------------------------------------------------------------- | |
@@ -143,7 +145,7 @@ GrainVoice::GrainVoice(vector<AudioFile *> * soundSet,float durationMs,float the | |
winReader = 0.0; //0 idx | |
//get duration in samples (fractional) | |
- winDurationSamps = ceil(duration * MY_SRATE * (double) 0.001); | |
+ winDurationSamps = ceil(duration * ::samp_rate * (double) 0.001); | |
winInc = (double)WINDOW_LEN / winDurationSamps; | |
} | |
@@ -292,7 +294,7 @@ void GrainVoice::updateParams() | |
window = Window::Instance().getWindow(windowType); | |
//double value, but eliminate fractional component - | |
- winDurationSamps = ceil(duration * MY_SRATE * (double) 0.001); | |
+ winDurationSamps = ceil(duration * ::samp_rate * (double) 0.001); | |
//how far should we advance through windowing function each sample | |
winInc = (double)WINDOW_LEN / winDurationSamps; | |
diff --git a/MyRtAudio.cpp b/MyRtAudio.cpp | |
index ef60ac2..1a3e525 100644 | |
--- a/MyRtAudio.cpp | |
+++ b/MyRtAudio.cpp | |
@@ -40,7 +40,7 @@ MyRtAudio::~MyRtAudio() | |
//cerr << "rtaudio cleanup reached " << endl; | |
} | |
-MyRtAudio::MyRtAudio(unsigned int numIns, unsigned int numOuts, unsigned int srate, unsigned int * bufferSize, RtAudioFormat format,bool showWarnings) | |
+MyRtAudio::MyRtAudio(unsigned int numIns, unsigned int numOuts, unsigned int * bufferSize, RtAudioFormat format,bool showWarnings) | |
{ | |
//configure RtAudio | |
//create pointer to RtAudio object | |
@@ -64,6 +64,8 @@ MyRtAudio::MyRtAudio(unsigned int numIns, unsigned int numOuts, unsigned int sra | |
cout << "No Audio Devices Found!" << endl; | |
exit( 1 ); | |
} | |
+ const RtAudio::DeviceInfo &info = audio->getDeviceInfo( audio->getDefaultOutputDevice() ); | |
+ | |
//allow RtAudio to print msgs to stderr | |
audio->showWarnings( showWarnings ); | |
@@ -72,7 +74,7 @@ MyRtAudio::MyRtAudio(unsigned int numIns, unsigned int numOuts, unsigned int sra | |
myBufferSize = bufferSize; | |
//set sample rate; | |
- mySRate = srate; | |
+ mySRate = info.preferredSampleRate; | |
//set format | |
myFormat = format; | |
@@ -86,6 +88,7 @@ void MyRtAudio::openStream( RtAudioCallback callback){ | |
//create stream options | |
RtAudio::StreamOptions options; | |
+ options.streamName = "Borderlands"; | |
RtAudio::StreamParameters iParams, oParams; | |
//i/o params | |
@@ -102,6 +105,12 @@ void MyRtAudio::openStream( RtAudioCallback callback){ | |
} | |
+//report the current sample rate | |
+unsigned int MyRtAudio::getSampleRate() | |
+{ | |
+ return mySRate; | |
+} | |
+ | |
//report the current buffer size | |
unsigned int MyRtAudio::getBufferSize(){ | |
diff --git a/MyRtAudio.h b/MyRtAudio.h | |
index 01756a7..4ea58fa 100644 | |
--- a/MyRtAudio.h | |
+++ b/MyRtAudio.h | |
@@ -48,12 +48,15 @@ public: | |
virtual ~MyRtAudio(); | |
//constructor - args = | |
- MyRtAudio(unsigned int numIns, unsigned int numOuts, unsigned int srate, unsigned int * bufferSize, RtAudioFormat format,bool showWarnings); | |
+ MyRtAudio(unsigned int numIns, unsigned int numOuts, unsigned int * bufferSize, RtAudioFormat format,bool showWarnings); | |
//set the audio callback and start the audio stream | |
void openStream( RtAudioCallback callback); | |
+ //report the current sample rate | |
+ unsigned int getSampleRate(); | |
+ | |
//report the current buffer size | |
unsigned int getBufferSize(); | |
diff --git a/makefile b/makefile | |
index 8eeaab9..01fa235 100644 | |
--- a/makefile | |
+++ b/makefile | |
@@ -7,14 +7,14 @@ UNAME := $(shell uname) | |
ifeq ($(UNAME), Linux) | |
FLAGS=-D__LINUX_ALSASEQ__ -D__UNIX_JACK__ -DOSC_HOST_LITTLE_ENDIAN -c | |
-LIBS=-lasound -lpthread -ljack -lstdc++ -lglut -lGL -lGLU -lm -lsndfile | |
+LIBS=-lasound -lpthread -ljack -lstdc++ -lglut -lGL -lGLU -lm -lsndfile -lsoxr | |
endif | |
ifeq ($(UNAME), Darwin) | |
FLAGS=-D__MACOSX_CORE__ -c | |
LIBS=-framework CoreAudio -framework CoreMIDI -framework CoreFoundation \ | |
-framework IOKit -framework Carbon -framework OpenGL \ | |
-framework GLUT -framework Foundation \ | |
- -framework AppKit -lstdc++ -lm -lsndfile | |
+ -framework AppKit -lstdc++ -lm -lsndfile -lsoxr | |
endif | |
# this is needed by some oscpack sources | |
diff --git a/theglobals.h b/theglobals.h | |
index e846b0e..2494a3b 100644 | |
--- a/theglobals.h | |
+++ b/theglobals.h | |
@@ -40,8 +40,8 @@ | |
#define SAMPLE double | |
//create rtaudio format | |
#define MY_FORMAT RTAUDIO_FLOAT64 | |
-//set the sample rate | |
-#define MY_SRATE 44100 | |
+//create soxr format | |
+#define MY_RESAMPLER_FORMAT_I SOXR_FLOAT64_I | |
//number of output channels | |
#define MY_CHANNELS 2 | |
@@ -81,4 +81,4 @@ static const double globalAtten = 0.5; | |
//}; | |
-#endif | |
\ No newline at end of file | |
+#endif |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment