aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChris Kiefer <chrisk13fer@gmail.com>2013-07-05 11:03:20 +0100
committerChris Kiefer <chrisk13fer@gmail.com>2013-07-05 11:03:20 +0100
commit7f4c6ff482637ea9be4fe69448099fc3cebe73fd (patch)
tree0008691e62024d1639841dfad88ab4c41d83c4d8
parent7e200e7f4e18022046b8ba694930827a8672a8f1 (diff)
sample looping methods
-rw-r--r--ofxMaxim/ofxMaxim/libs/maximilian.cpp106
-rwxr-xr-xofxMaxim/ofxMaxim/libs/maximilian.h47
2 files changed, 130 insertions, 23 deletions
diff --git a/ofxMaxim/ofxMaxim/libs/maximilian.cpp b/ofxMaxim/ofxMaxim/libs/maximilian.cpp
index 68de474..e26e153 100644
--- a/ofxMaxim/ofxMaxim/libs/maximilian.cpp
+++ b/ofxMaxim/ofxMaxim/libs/maximilian.cpp
@@ -566,8 +566,8 @@ bool maxiSample::read()
{
bool result;
ifstream inFile( myPath.c_str(), ios::in | ios::binary);
- result = inFile;
- if (inFile) {
+ result = inFile.is_open();
+ if (result) {
bool datafound = false;
inFile.seekg(4, ios::beg);
inFile.read( (char*) &myChunkSize, 4 ); // read the ChunkSize
@@ -645,7 +645,16 @@ bool maxiSample::read()
double maxiSample::play() {
position++;
- if ((long) position == length) position=0;
+ if ((long) position >= length) position=0;
+ output = (double) temp[(long)position]/32767.0;
+ return output;
+}
+
+//start end and points are between 0 and 1
+double maxiSample::playLoop(double start, double end) {
+ position++;
+ if (position < length * start) position = length * start;
+ if ((long) position >= length * end) position = length * start;
output = (double) temp[(long)position]/32767.0;
return output;
}
@@ -661,6 +670,20 @@ double maxiSample::playOnce() {
}
+void maxiSample::setPosition(double newPos) {
+ position = maxiMap::clamp<double>(newPos, 0.0, 1.0) * length;
+}
+
+double maxiSample::playUntil(double end) {
+ position++;
+ if ((long) position<length * end)
+ output = (double) temp[(long)position]/32767.0;
+ else {
+ output=0;
+ }
+ return output;
+}
+
double maxiSample::playOnce(double speed) {
position=position+((speed*chandiv)/(maxiSettings::sampleRate/mySampleRate));
double remainder = position - (long) position;
@@ -1069,6 +1092,74 @@ void maxiSample::reset() {
}
+void maxiSample::normalise(float maxLevel) {
+ short maxValue = 0;
+ for(int i=0; i < length; i++) {
+ if (abs(temp[i]) > maxValue) {
+ maxValue = abs(temp[i]);
+ }
+ }
+ float scale = 32767.0 * maxLevel / (float) maxValue;
+ for(int i=0; i < length; i++) {
+ temp[i] = round(scale * (float) temp[i]);
+ }
+}
+
+void maxiSample::autoTrim(float alpha, float threshold, bool trimStart, bool trimEnd) {
+
+ int startMarker=0;
+ if(trimStart) {
+ maxiLagExp<float> startLag(alpha, 0);
+ while(startMarker < length) {
+ startLag.addSample(abs(temp[startMarker]));
+ if (startLag.value() > threshold) {
+ break;
+ }
+ startMarker++;
+ }
+ }
+
+ int endMarker = length-1;
+ if(trimEnd) {
+ maxiLagExp<float> endLag(alpha, 0);
+ while(endMarker > 0) {
+ endLag.addSample(abs(temp[endMarker]));
+ if (endLag.value() > threshold) {
+ break;
+ }
+ endMarker--;
+ }
+ }
+
+ cout << "Autotrim: start: " << startMarker << ", end: " << endMarker << endl;
+
+ int newLength = endMarker - startMarker;
+ if (newLength > 0) {
+ short *newData = (short*) malloc(sizeof(short) * newLength);
+ for(int i=0; i < newLength; i++) {
+ newData[i] = temp[i+startMarker];
+ }
+ free(temp);
+ temp = newData;
+ myDataSize = newLength * 2;
+ length=newLength;
+ position=0;
+ recordPosition=0;
+ //envelope the start
+ int fadeSize=min((long)100, length);
+ for(int i=0; i < fadeSize; i++) {
+ float factor = i / (float) fadeSize;
+ temp[i] = round(temp[i] * factor);
+ temp[length - 1 - i] = round(temp[length - 1 - i] * factor);
+ }
+ }
+}
+
+
+
+
+
+
@@ -1248,12 +1339,3 @@ double convert::mtof(int midinote) {
return mtofarray[midinote];
}
-
-void maxiEnvelopeFollower::setAttack(double attackMS) {
- attack = pow( 0.01, 1.0 / (attackMS * maxiSettings::sampleRate * 0.001 ) );
-}
-
-void maxiEnvelopeFollower::setRelease(double releaseMS) {
- release = pow( 0.01, 1.0 / (releaseMS * maxiSettings::sampleRate * 0.001 ) );
-}
-
diff --git a/ofxMaxim/ofxMaxim/libs/maximilian.h b/ofxMaxim/ofxMaxim/libs/maximilian.h
index ce3ddd1..f46a2e3 100755
--- a/ofxMaxim/ofxMaxim/libs/maximilian.h
+++ b/ofxMaxim/ofxMaxim/libs/maximilian.h
@@ -30,6 +30,12 @@
*
*/
+/*
+ Feature request:
+ maxiNANINFAlarm
+ maxiLimiter
+ */
+
#ifndef MAXIMILIAN_H
#define MAXIMILIAN_H
@@ -262,8 +268,9 @@ public:
//read an ogg file into this class using stb_vorbis
bool readOgg();
- void loopRecord(double newSample, const bool recordEnabled, const double recordMix) {
+ void loopRecord(double newSample, const bool recordEnabled, const double recordMix, double start = 0.0, double end = 1.0) {
loopRecordLag.addSample(recordEnabled);
+ if (recordPosition < start * length) recordPosition = start * length;
if(recordEnabled) {
double currentSample = temp[(unsigned long)recordPosition] / 32767.0;
newSample = (recordMix * currentSample) + ((1.0 - recordMix) * newSample);
@@ -271,8 +278,8 @@ public:
temp[(unsigned long)recordPosition] = newSample * 32767;
}
++recordPosition;
- if (recordPosition == length)
- recordPosition=0;
+ if (recordPosition >= end * length)
+ recordPosition= start * length;
}
void clear();
@@ -280,10 +287,16 @@ public:
void reset();
double play();
+
+ double playLoop(double start, double end); // start and end are between 0.0 and 1.0
double playOnce();
double playOnce(double speed);
+
+ void setPosition(double newPos); // between 0.0 and 1.0
+
+ double playUntil(double end);
double play(double speed);
@@ -335,12 +348,16 @@ public:
sprintf(summary, " Format: %d\n Channels: %d\n SampleRate: %d\n ByteRate: %d\n BlockAlign: %d\n BitsPerSample: %d\n DataSize: %d\n", myFormat, myChannels, mySampleRate, myByteRate, myBlockAlign, myBitsPerSample, myDataSize);
return summary;
}
+
+ void normalise(float maxLevel = 0.99); //0 < maxLevel < 1.0
+ void autoTrim(float alpha = 0.3, float threshold = 6000, bool trimStart = true, bool trimEnd = true); //alpha of lag filter (lower == slower reaction), threshold to mark start and end, < 32767
};
class maxiMap {
public:
static double inline linlin(double val, double inMin, double inMax, double outMin, double outMax) {
+ val = max(min(val, inMax), inMin);
return ((val - inMin) / (inMax - inMin) * (outMax - outMin)) + outMin;
}
@@ -490,16 +507,21 @@ inline double maxiChorus::chorus(const double input, const unsigned int delay, c
return (output1 + output2 + input) / 3.0;
}
-class maxiEnvelopeFollower {
+template<typename T>
+class maxiEnvelopeFollowerType {
public:
- maxiEnvelopeFollower() {
+ maxiEnvelopeFollowerType() {
setAttack(100);
setRelease(100);
env = 0;
}
- void setAttack(double attackMS);
- void setRelease(double releaseMS);
- inline double play(double input) {
+ void setAttack(T attackMS) {
+ attack = pow( 0.01, 1.0 / (attackMS * maxiSettings::sampleRate * 0.001 ) );
+ }
+ void setRelease(T releaseMS) {
+ release = pow( 0.01, 1.0 / (releaseMS * maxiSettings::sampleRate * 0.001 ) );
+ }
+ inline T play(T input) {
input = fabs(input);
if (input>env)
env = attack * (env - input) + input;
@@ -508,12 +530,15 @@ public:
return env;
}
void reset() {env=0;}
- inline double getEnv(){return env;}
- inline void setEnv(double val){env = val;}
+ inline T getEnv(){return env;}
+ inline void setEnv(T val){env = val;}
private:
- double attack, release, env;
+ T attack, release, env;
};
+typedef maxiEnvelopeFollowerType<double> maxiEnvelopeFollower;
+typedef maxiEnvelopeFollowerType<float> maxiEnvelopeFollowerF;
+
//from https://ccrma.stanford.edu/~jos/filters/DC_Blocker_Software_Implementations.html
class maxiDCBlocker {
public: