Skip to content

Instantly share code, notes, and snippets.

@jpcima
Created September 29, 2018 19:26
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jpcima/0b9088e39c45f52b68cbfb3212e2c3af to your computer and use it in GitHub Desktop.
Save jpcima/0b9088e39c45f52b68cbfb3212e2c3af to your computer and use it in GitHub Desktop.
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