Skip to content

Commit

Permalink
Merge branch 'master' into reinit
Browse files Browse the repository at this point in the history
  • Loading branch information
danomatika committed Nov 30, 2015
2 parents 69b2a42 + 8c6b771 commit c5f76a0
Show file tree
Hide file tree
Showing 12 changed files with 124 additions and 52 deletions.
63 changes: 37 additions & 26 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -41,20 +41,18 @@ Installation
------------

Place ofxPd within a folder in the apps folder of the OF dir tree:
<pre>
openframeworks/addons/ofxPd
</pre>

openframeworks/addons/ofxPd

#### Which version to use?

If you are using a stable version (0062, 007, ...) of OpenFrameworks then you want to use a git tag of ofxPd for that version. You can select the tag in the Github "Current Branch" menu or clone and check it out using git.

For example, the following commands will clone ofxPd and switch to the OF 0062 tagged version:
<pre>
git clone git://github.com/danomatika/ofxPd.git
cd ofxPd
git checkout 0062
</pre>

git clone git://github.com/danomatika/ofxPd.git
cd ofxPd
git checkout 0062

Running the Example Projects
----------------------------
Expand All @@ -74,10 +72,9 @@ Open the Xcode project, select the "pdExample Debug" scheme, and hit "Run".
Open the Code::Blocks .cbp and hit F9 to build. Optionally, you can build the example with the Makefile.

To build and run it on the terminal:
<pre>
make
make run
</pre>

make
make run

### Windows

Expand All @@ -94,16 +91,14 @@ How to Create a New ofxPd Project
_Note: These instructions are for manually creating a new project from an existing ofxPd project and it's project files (aka Xcode, C::B, etc). You do not need to follow these steps if you use the ProjecGenerator app in which case you *may* need to add the C Flags as the PG currently seems to have a problem doing this. See the IDE specific instructions on how to do this._

To develop your own project based on ofxPd, either generate a new project with the ProjectGenerator or generate one of the examples, copy, and rename it. You probably want to put it in your apps folder, for example, after copying:
<pre>
openFrameworks/addons/ofxPd/pdExample/ => openFrameworks/apps/myApps/pdExample/
</pre>

openFrameworks/addons/ofxPd/pdExample/ => openFrameworks/apps/myApps/pdExample/

It must be 3 levels down in the openframeworks folder structure.

Then after renaming:
<pre>
openFrameworks/apps/myApps/myPdProject/
</pre>

openFrameworks/apps/myApps/myPdProject/

### For Xcode:

Expand All @@ -119,9 +114,8 @@ Adding ofxPd to an Existing Project
_Note: These instructions are for manually add ofxPd to an existing project. You do not need to follow these steps if you use the ProjecGenerator app in which case you *may* need to add the C Flags as the PG currently seems to have a problem doing this. See the IDE specific instructions on how to do this._

If you want to add ofxPd to another project, you need to make sure you include the src folder:
<pre>
openFrameworks/addons/ofxPd/src
</pre>

openFrameworks/addons/ofxPd/src

You will also need to include some additional C Flags for building the libpd source:

Expand Down Expand Up @@ -187,10 +181,26 @@ libpd as utilized in ofxPd does not handle any of the audio interfacing itself,
The sample rate is set to 44100 when initializing ofxPd in the examples. If your sample rate is higher, the playback pitch will be higher. Make sure the sample rate is the same as your system audio sample rate to hear the correct pitch.

For example: The default sample rate on Mac OSX is 96000. Running the app at 44100 results in double the playback pitch while initing ofxPd at 96000 gives the correct pitch.


### Running App in the Background on iOS

If you're using ofxPd to build an audio app on iOS, you probably want the app to keep running while in the background (aka switching between other apps or going to the home screen). You can enable this in Xcode by clicking on the Project in the project tree, selecting the "Capabilities" tab, and turning on the "Background Modes" switch, then checking "Audio, Airplay and Picture in Picture". Next, Set "Application does not run in background" to NO in the "Info" tab.

### Disabling Automatic Screen Locking on iOS

You may be building an audio app for iOS that you want to run without the automatic screen locking mechanism closing it. You can disable the screen lock timer by adding the following to your ofApp setup() function:

[[UIApplication sharedApplication] setIdleTimerDisabled:YES];

Bugs & Errors
-------------

### Pitch is off on the iPhone 6S

The iPhone 6S hardware seems to prefer a sample rate of 48000 and calling ofSoundStreamSetup() with 44100 will not change that in versions of OF 0.8.4 and previous. This means ofxPd will be running at 44100 but the audio stream is actually 48000, resulting in a higher pitch coming out of your patches and a lower pitch going in.

The fix is to follow Apple's method of setting the *preferred* sample rate, then grabbing what the *actual* sample rate is afterwards. You can then use this real value in ofSoundStreamSetup() and ofxPd::init(). The pdExampleIOS has been updated to show how to do this. Hopefully, this funtionality will be added to OF in the future.

### File "tr1/memory" not found in Xcode

You just upgraded to OSX 10.9 and Xcode 5 right? The default compiler is now LLVM and you need to rebuild your Xcode project files so OF will build correctly. Ude the ProjectGenerator in the OF 0.8.0 download to regenerate the project:
Expand All @@ -209,9 +219,9 @@ The compiler doesn't recognize the internal Pd types because it's missing the C
### Undefined basic_ostream in XCode

If you get the following [linker error](http://www.openframeworks.cc/forum/viewtopic.php?f=8&t=5344&p=26537&hilit=Undefined+symbol#p26537) in XCode:
<pre>
Undefined symbols: "std::basic_ostream<char, std::char_traits<char> ...
</pre>

Undefined symbols: "std::basic_ostream<char, std::char_traits<char> ...

you need to change the Base SDK to 10.6: Project > Edit Project Settings

### RtAudio Hang on Exit in 0062
Expand All @@ -238,7 +248,8 @@ ofxPd only includes the standard set of Pure Data objects as found in the "Vanil
The source files for externals included with Pd-Extended can be found in the Pure Data Subversion repository on Sourceforge. It is recommended that you use the latest Pd-Extended release branch as it will be more stable then the development version. See http://puredata.info/docs/developer/GettingPdSource

For example, if we want to include the zexy external in our project, we first download the sources files for the latest stable Pd-Extended (0.42 as of this writing) from the Subversion repository (make sure you have svn installed):
<pre>svn checkout https://pure-data.svn.sourceforge.net/svnroot/pure-data/branches/pd-extended/0.42</pre>

svn checkout https://pure-data.svn.sourceforge.net/svnroot/pure-data/branches/pd-extended/0.42

The external sources can be found in the `externals` folder. For instance, the zexy sources are in `externals/zexy/src/`. Copy the .h and .c files into your project folder. In my case I create an externals folder in src folder of my project, something like `myProject/src/externals/zexy`. Then add these files to your ofxPd project.

Expand Down
2 changes: 1 addition & 1 deletion addon_config.mk
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ common:
# required for libpd
ADDON_CFLAGS = -DHAVE_UNISTD_H -DHAVE_ALLOCA_H -DUSEAPI_DUMMY -DPD -DLIBPD_EXTRA

win_cb:
msys2:
# not sure if pd~ is working on Windows, so leave it out
ADDON_SOURCES_EXCLUDE = libs/libpd/pure-data/extra/pd~
ADDON_INCLUDES_EXCLUDE = libs/libpd/pure-data/extra/pd~
2 changes: 1 addition & 1 deletion pdExample/src/ofApp.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -193,7 +193,7 @@ void ofApp::setup() {

pd.sendSymbol("fromOF", "test");

cout << "FINISH PD Test" << endl << endl;
cout << "FINISH PD Test" << endl;

// -----------------------------------------------------
cout << endl << "BEGIN Instance Test" << endl;
Expand Down
12 changes: 11 additions & 1 deletion pdExampleIOS/bin/data/pd/test.pd
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
#N canvas 486 364 409 355 10;
#N canvas 711 355 409 355 10;
#X obj 272 270 dac~;
#N canvas 369 98 675 256 test 0;
#N canvas 0 22 450 300 (subpatch) 0;
Expand Down Expand Up @@ -302,6 +302,11 @@ in this distribution.;
#X connect 3 0 6 0;
#X connect 4 0 2 0;
#X restore 272 240 pd scope~;
#X obj 163 237 loadbang;
#X obj 162 269 metro 1000;
#X obj 197 302 + 1;
#X obj 160 300 f 0;
#X obj 164 329 s toOF;
#X connect 3 0 21 0;
#X connect 4 0 21 0;
#X connect 5 0 6 0;
Expand All @@ -318,3 +323,8 @@ in this distribution.;
#X connect 19 3 14 0;
#X connect 21 0 0 0;
#X connect 21 0 0 1;
#X connect 22 0 23 0;
#X connect 23 0 25 0;
#X connect 24 0 25 1;
#X connect 25 0 24 0;
#X connect 25 0 26 0;
4 changes: 4 additions & 0 deletions pdExampleIOS/src/ofApp.h
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,10 @@ class ofApp : public ofxiOSApp, public PdReceiver, public PdMidiReceiver {

// do something
void playTone(int pitch);

// sets the preferred sample rate, returns the *actual* samplerate
// which may be different ie. iPhone 6S only wants 48k
float setAVSessionSampleRate(float preferredSampleRate);

ofxPd pd;
vector<float> scopeArray;
Expand Down
55 changes: 51 additions & 4 deletions pdExampleIOS/src/ofApp.mm
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@
*/
#include "ofApp.h"

#import <AVFoundation/AVFoundation.h>

//--------------------------------------------------------------
void ofApp::setup() {

Expand All @@ -33,12 +35,17 @@
// set landscape
//ofSetOrientation(OF_ORIENTATION_90_RIGHT;

// try to set the preferred iOS sample rate, but get the actual sample rate
// being used by the AVSession since newer devices like the iPhone 6S only
// want specific values (ie 48000 instead of 44100)
float sampleRate = setAVSessionSampleRate(44100);

// the number if libpd ticks per buffer,
// used to compute the audio buffer len: tpb * blocksize (always 64)
int ticksPerBuffer = 8; // 8 * 64 = buffer len of 512

// setup OF sound stream
ofSoundStreamSetup(2, 1, this, 44100, ofxPd::blockSize()*ticksPerBuffer, 3);
// setup OF sound stream using the current *actual* samplerate
ofSoundStreamSetup(2, 1, this, sampleRate, ofxPd::blockSize()*ticksPerBuffer, 3);

// setup Pd
//
Expand All @@ -49,7 +56,7 @@
// note: you won't see any message prints until update() is called since
// the queued messages are processed there, this is normal
//
if(!pd.init(2, 1, 44100, ticksPerBuffer, false)) {
if(!pd.init(2, 1, sampleRate, ticksPerBuffer, false)) {
OF_EXIT_APP(1);
}

Expand Down Expand Up @@ -199,7 +206,7 @@

pd.sendSymbol("fromOF", "test");

cout << "FINISH PD Test" << endl << endl;
cout << "FINISH PD Test" << endl;

// -----------------------------------------------------
cout << endl << "BEGIN Instance Test" << endl;
Expand Down Expand Up @@ -457,3 +464,43 @@
void ofApp::playTone(int pitch) {
pd << StartMessage() << "pitch" << pitch << FinishList("tone") << Bang("tone");
}

//--------------------------------------------------------------
// set the samplerate the Apple approved way since newer devices
// like the iPhone 6S only allow certain sample rates,
// the following code may not be needed once this functionality is
// incorporated into the ofxiOSSoundStream
// thanks to Seth aka cerupcat
float ofApp::setAVSessionSampleRate(float preferredSampleRate) {

NSError *audioSessionError = nil;
AVAudioSession *session = [AVAudioSession sharedInstance];

// disable active
[session setActive:NO error:&audioSessionError];
if (audioSessionError) {
NSLog(@"Error %ld, %@", (long)audioSessionError.code, audioSessionError.localizedDescription);
}

// set category
[session setCategory:AVAudioSessionCategoryPlayAndRecord withOptions:AVAudioSessionCategoryOptionAllowBluetooth|AVAudioSessionCategoryOptionMixWithOthers|AVAudioSessionCategoryOptionDefaultToSpeaker error:&audioSessionError];
if(audioSessionError) {
NSLog(@"Error %ld, %@", (long)audioSessionError.code, audioSessionError.localizedDescription);
}

// try to set the preferred sample rate
[session setPreferredSampleRate:preferredSampleRate error:&audioSessionError];
if(audioSessionError) {
NSLog(@"Error %ld, %@", (long)audioSessionError.code, audioSessionError.localizedDescription);
}

// *** Activate the audio session before asking for the "current" values ***
[session setActive:YES error:&audioSessionError];
if (audioSessionError) {
NSLog(@"Error %ld, %@", (long)audioSessionError.code, audioSessionError.localizedDescription);
}
ofLogNotice() << "AVSession samplerate: " << session.sampleRate << ", I/O buffer duration: " << session.IOBufferDuration;

// our actual samplerate, might be differnt aka 48k on iPhone 6S
return session.sampleRate;
}
13 changes: 6 additions & 7 deletions pdMultiExample/src/ofApp.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -63,11 +63,11 @@ void ofApp::setup() {
pd.setReceiver(this);

// allocate instance output buffers
int bufferSize = numOutputs*ticksPerBuffer*ofxPd::blockSize();
outputBuffer1 = new float[bufferSize];
outputBuffer2 = new float[bufferSize];
memset(outputBuffer1, 0, bufferSize);
memset(outputBuffer2, 0, bufferSize);
outputBufferSize = numOutputs*ticksPerBuffer*ofxPd::blockSize();
outputBuffer1 = new float[outputBufferSize];
outputBuffer2 = new float[outputBufferSize];
memset(outputBuffer1, 0, outputBufferSize);
memset(outputBuffer2, 0, outputBufferSize);

instanceMutex.lock();
pd_setinstance(pdinstance1); // talk to first pd instance
Expand Down Expand Up @@ -157,8 +157,7 @@ void ofApp::audioRequested(float * output, int bufferSize, int nChannels) {
pd.audioOut(outputBuffer2, bufferSize, nChannels);

// mix the two instance output buffers together
int size = bufferSize*sizeof(float);
for(int i = 0; i < size; i += sizeof(float)) {
for(int i = 0; i < outputBufferSize; i += 1) {
output[i] = (outputBuffer1[i] + outputBuffer2[i]) * 0.5f; // mix
}
}
Expand Down
1 change: 1 addition & 0 deletions pdMultiExample/src/ofApp.h
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@ class ofApp : public ofBaseApp, public PdReceiver{
// when accessing currently non thread safe pd instance functions
ofMutex instanceMutex;

int outputBufferSize; //< audio output buffer size
float* outputBuffer1; //< interleaved audio output buffer for instance 1
float* outputBuffer2; //< interleaved audio output buffer for instance 2
};
2 changes: 1 addition & 1 deletion pitchShifter/src/ofApp.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@ void ofApp::draw() {
float x = 1, y = ofGetHeight()/2;
float w = ofGetWidth() / (float) scopeArray.size(), h = ofGetHeight()/2;
for(int i = 0; i < scopeArray.size()-1; ++i) {
ofLine(x, y+scopeArray[i]*h, x+w, y+scopeArray[i+1]*h);
ofDrawLine(x, y+scopeArray[i]*h, x+w, y+scopeArray[i+1]*h);
x += w;
}
ofSetLineWidth(1.0);
Expand Down
10 changes: 5 additions & 5 deletions pitchShifter/src/ofxSimpleSlider.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -82,26 +82,26 @@ void ofxSimpleSlider::draw(ofEventArgs& event){
ofSetLineWidth(1.0);
ofSetColor(200,200,200, sliderAlpha);
ofSetRectMode(OF_RECTMODE_CORNER);
ofRect(0,0, width,height);
ofDrawRectangle(0,0, width,height);

// draw spine
ofSetLineWidth(1.0);
ofSetColor(255,255,255, spineAlpha);
if (bVertical){
ofLine(width/2,0, width/2,height);
ofDrawLine(width/2,0, width/2,height);
} else {
ofLine(0,height/2, width,height/2);
ofDrawLine(0,height/2, width,height/2);
}

// draw thumb
ofSetLineWidth(5.0);
ofSetColor(255,255,255, thumbAlpha);
if (bVertical){
float thumbY = ofMap(percent, 0,1, height,0, true);
ofLine(0,thumbY, width,thumbY);
ofDrawLine(0,thumbY, width,thumbY);
} else {
float thumbX = ofMap(percent, 0,1, 0,width, true);
ofLine(thumbX,0, thumbX,height);
ofDrawLine(thumbX,0, thumbX,height);
}


Expand Down
2 changes: 1 addition & 1 deletion pitchShifterIOS/src/ofApp.mm
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,7 @@
float x = 1, y = ofGetHeight()/2;
float w = ofGetWidth() / (float) scopeArray.size(), h = ofGetHeight()/2;
for(int i = 0; i < scopeArray.size()-1; ++i) {
ofLine(x, y+scopeArray[i]*h, x+w, y+scopeArray[i+1]*h);
ofDrawLine(x, y+scopeArray[i]*h, x+w, y+scopeArray[i+1]*h);
x += w;
}
ofSetLineWidth(1.0);
Expand Down
10 changes: 5 additions & 5 deletions pitchShifterIOS/src/ofxSimpleSlider.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -82,26 +82,26 @@ void ofxSimpleSlider::draw(ofEventArgs& event){
ofSetLineWidth(1.0);
ofSetColor(200,200,200, sliderAlpha);
ofSetRectMode(OF_RECTMODE_CORNER);
ofRect(0,0, width,height);
ofDrawRectangle(0,0, width,height);

// draw spine
ofSetLineWidth(1.0);
ofSetColor(255,255,255, spineAlpha);
if (bVertical){
ofLine(width/2,0, width/2,height);
ofDrawLine(width/2,0, width/2,height);
} else {
ofLine(0,height/2, width,height/2);
ofDrawLine(0,height/2, width,height/2);
}

// draw thumb
ofSetLineWidth(5.0);
ofSetColor(255,255,255, thumbAlpha);
if (bVertical){
float thumbY = ofMap(percent, 0,1, height,0, true);
ofLine(0,thumbY, width,thumbY);
ofDrawLine(0,thumbY, width,thumbY);
} else {
float thumbX = ofMap(percent, 0,1, 0,width, true);
ofLine(thumbX,0, thumbX,height);
ofDrawLine(thumbX,0, thumbX,height);
}


Expand Down

0 comments on commit c5f76a0

Please sign in to comment.