admsyn / ofxAudioUnit

An openFrameworks addon which makes it easy to work with Audio Units on OSX and iOS
MIT License
120 stars 24 forks source link

Use it with array #14

Closed dferrandizmont closed 10 years ago

dferrandizmont commented 10 years ago

Hi, for one work I would like to use this addon but I need to load an array of sounds (33 exactly).

How can I do it? Because if I do it at the same way I do with ofSoundPlayer (ofSoundPlayer sound[ NSOUNDS ];) with the #define NSOUNDS 33; at the top of the page it doesn't work .

Then, I think I need to use an array with output too, right?

This is how I have it right now with soundPlayer (setup();)

for ( int i=0; i<NSOUNDS; i++) {
sound[i].loadSound("Sounds/" + ofToString( i + 1 ) + ".wav" );
}

and in draw() I have the .play()

 for ( int i=0; i<NSOUNDS; i++) {
     int ran = ofRandom(33);
     if (doOnce == true){
         sound[ran].play();
         sound[ran].setLoop(true);
     }

How can I translate all that code to make it work with the addon?

Thank you so much.

admsyn commented 10 years ago

Sounds like you probably want to use a bunch of ofxAudioUnitFilePlayers, and plug them into an ofxAudioUnitMixer. It's probably better to use a std::vector instead of an array, but that's your choice.

Example:

(in ofApp.h)

class ofApp : public ofBaseApp {
  ...
    vector<ofxAudioUnitFilePlayer> filePlayers;
    ofxAudioUnitMixer mixer;
    ofxAudioUnitOutput output;
};

(in ofApp.cpp)

void ofApp::setup() {
    filePlayers.resize(33);
    mixer.setInputBusCount(33);

    for(int i = 0; i < filePlayers.size(); i++) {
        string fileDataPath("Sounds/" + ofToString( i + 1 ) + ".wav");
        filePlayers[i].setFile(ofFilePath::getAbsolutePath(fileDataPath));
        filePlayers[i].connectTo(mixer, i);
        mixer.setInputVolume(1.0, i);
    }

    mixer.connectTo(output);
    output.start();
}

void ofApp::draw() {
   for ( int i=0; i<NSOUNDS; i++) {
     int ran = ofRandom(33);
     if (doOnce == true){
         filePlayers[ran].loop();
     }
  }
}

I'm going to close this, since it's not really a bug or enhancement as far as I can tell. Feel free to ask questions here if you like, though :)

dferrandizmont commented 10 years ago

Yeah thank you so much for the quick reply! Everything seems okey but it doesn't work. I'm trying to edit the example-parameters.xcodeproj to use it with more than one sound.

Here is my code (I delete the comments to make it more lighter):

(in ofApp.h)

include "ofMain.h"

include "ofxAudioUnit.h"

define NSOUNDS 33

class testApp : public ofBaseApp{

public: void setup(); void update(); void draw();

void keyPressed  (int key);
void keyReleased(int key);
void mouseMoved(int x, int y );
void mouseDragged(int x, int y, int button);
void mousePressed(int x, int y, int button);
void mouseReleased(int x, int y, int button);
void windowResized(int w, int h);
void dragEvent(ofDragInfo dragInfo);
void gotMessage(ofMessage msg);

ofxAudioUnit                    varispeed;
ofxAudioUnit                    lowpass;
   vector <ofxAudioUnitFilePlayer> filePlayers;
    ofxAudioUnitMixer               mixer;
ofxAudioUnitOutput              output;
ofxAudioUnitTap                 tap;

bool doOnce;

ofPolyline waveform;

(in ofApp.cpp)

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

varispeed = ofxAudioUnit(kAudioUnitType_FormatConverter,
                         kAudioUnitSubType_Varispeed);

lowpass = ofxAudioUnit(kAudioUnitType_Effect,
                       kAudioUnitSubType_LowPassFilter);

filePlayers.resize(33);
mixer.setInputBusCount(33);

for (int i = 0; i < filePlayers.size(); i++){

    string fileDataPath("Sounds/" + ofToString( i + 1 ) + ".wav");
    filePlayers[i].setFile(ofFilePath::getAbsolutePath(fileDataPath));
    filePlayers[i].connectTo(mixer, i).connectTo(varispeed).connectTo(lowpass).connectTo(tap);
    mixer.setInputVolume(1.0, i);
}

doOnce = false;

AudioUnitSetParameter(lowpass.getUnit(), kLowPassParam_Resonance,
                      kAudioUnitScope_Global, 0, 10, 0);

mixer.connectTo(output);

ofSetVerticalSync(true);

} //-------------------------------------------------------------- void testApp::update(){

tap.getLeftWaveform(waveform, ofGetWidth(), ofGetHeight());

} //-------------------------------------------------------------- void testApp::draw(){

ofBackground(40);
ofSetColor(255);
waveform.draw();
ofDrawBitmapString("Press 'f' to show the file player", ofPoint(40,20));

ofSetColor(255, 125, 50);
ofCircle(20, ofGetMouseY(), 15);
ofDrawBitmapString("|\nFilter\nFrequency\n|", ofPoint(40, ofGetHeight()/2));

ofSetColor(20, 255, 150);
ofCircle(ofGetMouseX(), ofGetHeight() - 20, 15);
ofDrawBitmapString("<- Playback Speed ->", ofPoint(ofGetWidth()/2 - 100, ofGetHeight() - 40));

for ( int i=0; i<filePlayers.size(); i++) {

    int ran = ofRandom(33);
    if (doOnce == true){
        filePlayers[ran].loop();
          output.start();
    }    
    doOnce = false;
}

} //-------------------------------------------------------------- void testApp::keyPressed(int key){

for(int i = 0; i < filePlayers.size(); i++) {
    if(key == 'f') filePlayers[i].showUI();
}

} //-------------------------------------------------------------- void testApp::mouseMoved(int x, int y ){

float newSpeed = ofMap(x, 0, ofGetWidth(), 0.01, 2, true);

AudioUnitSetParameter(varispeed.getUnit(),
                      kVarispeedParam_PlaybackRate,
                      kAudioUnitScope_Global,
                      0,
                      newSpeed,
                      0);

float newCutoff = ofMap(y, 0, ofGetHeight(), 10, 6900);

AudioUnitSetParameter(lowpass.getUnit(),
                      kLowPassParam_CutoffFrequency,
                      kAudioUnitScope_Global,
                      0,
                      newCutoff,
                      0);

}

//-------------------------------------------------------------- void testApp::keyReleased(int key){} //-------------------------------------------------------------- void testApp::mouseDragged(int x, int y, int button){} //-------------------------------------------------------------- void testApp::mousePressed(int x, int y, int button){

    doOnce = true;

}

Thank you so much.

admsyn commented 10 years ago

It looks like your connections are a little off. Assuming you probably don't want the varispeed and lowpass, you should change the line:

filePlayers[i].connectTo(mixer, i).connectTo(varispeed).connectTo(lowpass).connectTo(tap);

to just:

filePlayers[i].connectTo(mixer, i);
admsyn commented 10 years ago

If you want to have 33 taps as well (to get 33 waveforms to visualize), you'd need to add something like vector<ofxAudioUnitTap> taps to your ofApp, do taps.resize(33) and then do your connections like this:

filePlayers[i].connectTo(taps[i]).connectTo(mixer, i);
dferrandizmont commented 10 years ago

Hi admsyn, thank you so much for your reply but I can not make it play sound. I don't know what I missing.

I would like to load 33 sounds and make it play (one by one) everytime I press the mousclick and when I released it stop the audio, then if I press again the mouseclick play the second (or random, doesn't matter right now) sound. All that would be nice if I could edit the sound like you do in the parameters example.

Righ now my code is that:

ofApp.h

pragma once

include "ofMain.h"

include "ofxAudioUnit.h"

class testApp : public ofBaseApp{

public: void setup(); void update(); void draw();

void keyPressed  (int key);
void keyReleased(int key);
void mouseMoved(int x, int y );
void mouseDragged(int x, int y, int button);
void mousePressed(int x, int y, int button);
void mouseReleased(int x, int y, int button);
void windowResized(int w, int h);
void dragEvent(ofDragInfo dragInfo);
void gotMessage(ofMessage msg);

ofxAudioUnit           varispeed;
ofxAudioUnit           lowpass;
vector <ofxAudioUnitFilePlayer> filePlayer;
ofxAudioUnitOutput     output;
vector <ofxAudioUnitTap>        tap;
ofxAudioUnitMixer      mixer;

ofPolyline waveform;

};

ofApp.cpp

include "testApp.h"

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

varispeed = ofxAudioUnit(kAudioUnitType_FormatConverter,
                         kAudioUnitSubType_Varispeed);

lowpass = ofxAudioUnit(kAudioUnitType_Effect,
                       kAudioUnitSubType_LowPassFilter);

AudioUnitSetParameter(lowpass.getUnit(), kLowPassParam_Resonance,
                      kAudioUnitScope_Global, 0, 10, 0);

lowpass.printParameterList();

filePlayer.resize(1);
tap.resize(1);
mixer.setInputBusCount(1);
output.start();
mixer.connectTo(output);

for (int i = 0; i < filePlayer.size(); i++){
filePlayer[i].setFile(ofFilePath::getAbsolutePath("Sounds/" + ofToString( i + 1 ) + ".wav"));
    filePlayer[i].connectTo(mixer, i).connectTo(tap[i]).connectTo(varispeed).connectTo(lowpass);

    //filePlayer[i].loop();     //If I enable it the app won't run. 
mixer.setInputVolume(1.0, i);
}   
ofSetVerticalSync(true);

}

//-------------------------------------------------------------- void testApp::update(){

    for (int i = 0; i < tap.size(); i++){
    tap[i].getLeftWaveform(waveform, ofGetWidth(), ofGetHeight());        
}

}

//-------------------------------------------------------------- void testApp::draw(){

    ofBackground(40);
ofSetColor(255);
waveform.draw();
ofDrawBitmapString("Press 'f' to show the file player", ofPoint(40,20));

ofSetColor(255, 125, 50);
ofCircle(20, ofGetMouseY(), 15);
ofDrawBitmapString("|\nFilter\nFrequency\n|", ofPoint(40, ofGetHeight()/2));

ofSetColor(20, 255, 150);
ofCircle(ofGetMouseX(), ofGetHeight() - 20, 15);
ofDrawBitmapString("<- Playback Speed ->", ofPoint(ofGetWidth()/2 - 100, ofGetHeight() - 40));

}

//-------------------------------------------------------------- void testApp::keyPressed(int key){

  for (int i = 0; i < filePlayer.size(); i++){
if(key == 'f') filePlayer[i].showUI();
}

}

//-------------------------------------------------------------- void testApp::mouseMoved(int x, int y ){

float newSpeed = ofMap(x, 0, ofGetWidth(), 0.01, 2, true);

AudioUnitSetParameter(varispeed.getUnit(),
                      kVarispeedParam_PlaybackRate,
                      kAudioUnitScope_Global,
                      0,
                      newSpeed,
                      0);

float newCutoff = ofMap(y, 0, ofGetHeight(), 10, 6900);

AudioUnitSetParameter(lowpass.getUnit(),
                      kLowPassParam_CutoffFrequency,
                      kAudioUnitScope_Global,
                      0,
                      newCutoff,
                      0);

}

//-------------------------------------------------------------- void testApp::keyReleased(int key){} //-------------------------------------------------------------- void testApp::mouseDragged(int x, int y, int button){} //-------------------------------------------------------------- void testApp::mousePressed(int x, int y, int button){} //-------------------------------------------------------------- void testApp::mouseReleased(int x, int y, int button){} //-------------------------------------------------------------- void testApp::windowResized(int w, int h){} //-------------------------------------------------------------- void testApp::gotMessage(ofMessage msg){} //-------------------------------------------------------------- void testApp::dragEvent(ofDragInfo dragInfo){}

What I missing?

Again, thank you so much for your time.

admsyn commented 10 years ago

You didn't edit the line quite right. Change:

filePlayer[i].connectTo(mixer, i).connectTo(tap[i]).connectTo(varispeed).connectTo(lowpass);

to

filePlayer[i].connectTo(tap[i]).connectTo(mixer, i);

You need to end your signal chain with the mixer, since it'll be the thing that turns your 33 independent file players into a single audio stream, which can be connected to the output.

dferrandizmont commented 10 years ago

Okey, I edit the line and now is that:

for (int i = 0; i < filePlayer.size(); i++){ filePlayer[i].setFile(ofFilePath::getAbsolutePath("Sounds/" + ofToString( i + 1 ) + ".wav")); filePlayer[i].connectTo(tap[i]).connectTo(mixer, i); mixer.setInputVolume(1.0, i); }

But the sound keeps without playing.

I'm a little bit stress haha

admsyn commented 10 years ago

More things:

dferrandizmont commented 10 years ago

I put the output.star() at the end of setup() and doesn't work.

No, I'm not actually calling .play() or .loop(); I'm not calling loop because if I call it on the setup inside the for( --- ) like filePlayer[i].loop(); the application doesn't start and i'm not calling .play() because in the parameters example I didn't found anywhere where you call .play().

Thank you, i'll going crazy with that.

admsyn commented 10 years ago

Sure, but you need to call .play() or .loop() for it to start making sound. The .loop() starts the file playing as well, it doesn't just mean it will loop when you call .play().

If the application doesn't start when you call .loop(), that sounds like a different problem. Are you getting any errors in the console?

What happens if you just add filePlayer[0].play() after your output.start() ?

dferrandizmont commented 10 years ago

It's so bizzare, if I add filePlayer[0].play() after output.star() or filePlayer[1] or [2], etc, dons't play any sound.

If I put .loop() the application doesn't start and I'm not getting any error in the console, just that:

[id] param name [min : max : default] [0] Cutoff Frequency [10 : 21829.5 : 6900] [1] Resonance [-20 : 40 : 0]

This is how I have right now the setup()

void testApp::setup(){

varispeed = ofxAudioUnit(kAudioUnitType_FormatConverter,
                         kAudioUnitSubType_Varispeed);

lowpass = ofxAudioUnit(kAudioUnitType_Effect,
                       kAudioUnitSubType_LowPassFilter);

AudioUnitSetParameter(lowpass.getUnit(), kLowPassParam_Resonance,
                      kAudioUnitScope_Global, 0, 10, 0);

lowpass.printParameterList();

filePlayer.resize(33);
tap.resize(33);
mixer.setInputBusCount(33);

for (int i = 0; i < filePlayer.size(); i++){
filePlayer[i].setFile(ofFilePath::getAbsolutePath("Sounds/" + ofToString( i + 1 ) + ".wav"));
    filePlayer[i].connectTo(tap[i]).connectTo(mixer, i);
    //filePlayer[i].connectTo(mixer, i).connectTo(tap[i]).connectTo(varispeed).connectTo(lowpass);

    //filePlayer[i].loop();
mixer.setInputVolume(1.0, i);
}

ofSetVerticalSync(true);
mixer.connectTo(output);
output.start();
filePlayer[1].play();

}

admsyn commented 10 years ago

What if you just simplify everything: a single file player straight into the output. Instead of what you have in setup, just:

filePlayer.resize(1);
filePlayer[0].setFile(ofFilePath::getAbsolutePath("Sounds/1.wav"));
filePlayer[0].connectTo(output);
output.start();
filePlayer[0].play();
dferrandizmont commented 10 years ago

Yeah, it works, but only if I put the filePlayer[0].play() anywhere out from setup(). I put it inside void testApp::mousePressed(int x, int y, int button) because is where I want it.

Now, if I would like to play each sound everytime I click who I have to do it?

dferrandizmont commented 10 years ago

Hey admsyn, i think this will be the last or one of the last questions.

Righ now everything seems to work, when I press the mouse it starts one sound (random) and when I release it it stops. That's what I want, but now I want to edit the sound with the mouseMoved.

ofApp.cpp

include "testApp.h"

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

varispeed = ofxAudioUnit(kAudioUnitType_FormatConverter,
                         kAudioUnitSubType_Varispeed);

lowpass = ofxAudioUnit(kAudioUnitType_Effect,
                       kAudioUnitSubType_LowPassFilter);

AudioUnitSetParameter(lowpass.getUnit(), kLowPassParam_Resonance,
                      kAudioUnitScope_Global, 0, 10, 0);

lowpass.printParameterList();

filePlayer.resize(33);
tap.resize(33);
mixer.setInputBusCount(33);
doOnce = false;

for (int i = 0; i < filePlayer.size(); i++){
    filePlayer[i].setFile(ofFilePath::getAbsolutePath("Sounds/" + ofToString( i + 1 ) + ".wav"));
    filePlayer[i].connectTo(tap[i]).connectTo(mixer, i);//.connectTo(varispeed).connectTo(lowpass)
    mixer.setInputVolume(1.0, i);
}

ofSetVerticalSync(true);
mixer.connectTo(output);

output.start();

}

//-------------------------------------------------------------- void testApp::update(){ for (int i = 0; i < tap.size(); i++){ tap[i].getLeftWaveform(waveform, ofGetWidth(), ofGetHeight());

}

}

//-------------------------------------------------------------- void testApp::draw(){ ofBackground(40); ofSetColor(255); waveform.draw(); ofDrawBitmapString("Press 'f' to show the file player", ofPoint(40,20));

ofSetColor(255, 125, 50);
ofCircle(20, ofGetMouseY(), 15);
ofDrawBitmapString("|\nFilter\nFrequency\n|", ofPoint(40, ofGetHeight()/2));

ofSetColor(20, 255, 150);
ofCircle(ofGetMouseX(), ofGetHeight() - 20, 15);
ofDrawBitmapString("<- Playback Speed ->", ofPoint(ofGetWidth()/2 - 100, ofGetHeight() - 40));

for ( int i=0; i<filePlayer.size(); i++) {

    int aleatori = ofRandom(33);
    if (doOnce == true){
        filePlayer[aleatori].play();
        filePlayer[aleatori].loop();
    }

    doOnce = false;
}

}

//-------------------------------------------------------------- void testApp::keyPressed(int key){

// if(key == 'f') filePlayer[output].showUI();

}

//-------------------------------------------------------------- void testApp::mouseMoved(int x, int y ){

float newSpeed = ofMap(x, 0, ofGetWidth(), 0.01, 2, true);

AudioUnitSetParameter(varispeed.getUnit(),
                      kVarispeedParam_PlaybackRate,
                      kAudioUnitScope_Global,
                      0,
                      newSpeed,
                      0);

float newCutoff = ofMap(y, 0, ofGetHeight(), 10, 6900);

AudioUnitSetParameter(lowpass.getUnit(),
                      kLowPassParam_CutoffFrequency,
                      kAudioUnitScope_Global,
                      0,
                      newCutoff,
                      0);

}

//-------------------------------------------------------------- void testApp::keyReleased(int key){} //-------------------------------------------------------------- void testApp::mouseDragged(int x, int y, int button){} //-------------------------------------------------------------- void testApp::mousePressed(int x, int y, int button){ doOnce = true;

} //-------------------------------------------------------------- void testApp::mouseReleased(int x, int y, int button){

for ( int i=0; i<filePlayer.size(); i++) {
    filePlayer[i].stop();
}

} //-------------------------------------------------------------- void testApp::windowResized(int w, int h){} //-------------------------------------------------------------- void testApp::gotMessage(ofMessage msg){} //-------------------------------------------------------------- void testApp::dragEvent(ofDragInfo dragInfo){}

The waveform doesn't show in the screen and I cant edit the sound. How I have to do it?

Thank you so much for everything.

jasonlevine commented 10 years ago

Hey Dani,

In less there has been an update I don't know about(@admsyn?), I would recommend against large numbers of fileplayers. They may not play as expected. Another solution would be to create sound bank with your 33 sounds and use the DLS Synth to play them back. Then your code would look something like this:

void setup() {

ofxAudioUnitSampler sampler = ofxAudioUnitSampler('aumu', 'dls ', 'appl');

sampler.connectTo(tap).connectTo(output);

output.start();

}

/// get the waveform during update

void mousePressed {

midiNote = ofRandom(33); // midiNote is a member of testApp

sampler.midiNoteOne(midiNote, 80);

}

void mouseReleased {

sampler.midiNoteOff(midiNote, 0);

}

Best of luck, Jason

On Tue, Feb 11, 2014 at 6:59 PM, Dani Ferrandiz Mont < notifications@github.com> wrote:

Hey admsyn, i think this will be the last or one of the last questions.

Righ now everything seems to work, when I press the mouse it starts one sound (random) and when I release it it stops. That's what I want, but now I want to edit the sound with the mouseMoved.

ofApp.cpp

include "testApp.h"

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

varispeed = ofxAudioUnit(kAudioUnitType_FormatConverter, kAudioUnitSubType_Varispeed);

lowpass = ofxAudioUnit(kAudioUnitType_Effect, kAudioUnitSubType_LowPassFilter);

AudioUnitSetParameter(lowpass. getUnit(), kLowPassParam_Resonance, kAudioUnitScope_Global, 0, 10, 0);

lowpass.printParameterList();

filePlayer.resize(33); tap.resize(33); mixer.setInputBusCount(33); doOnce = false;

for (int i = 0; i < filePlayer.size(); i++){ filePlayer[i].setFile(ofFilePath::getAbsolutePath("Sounds/" + ofToString( i + 1 ) + ".wav")); filePlayer[i].connectTo(tap[i]).connectTo(mixer, i);//.connectTo(varispeed).connectTo(lowpass) mixer.setInputVolume(1.0, i); }

ofSetVerticalSync(true); mixer.connectTo(output);

output.start();

}

//--------------------------------------------------------------

void testApp::update(){ for (int i = 0; i < tap.size(); i++){ tap[i].getLeftWaveform(waveform, ofGetWidth(), ofGetHeight());

}

}

//-------------------------------------------------------------- void testApp::draw(){ ofBackground(40); ofSetColor(255); waveform.draw(); ofDrawBitmapString("Press 'f' to show the file player", ofPoint(40,20));

ofSetColor(255, 125, 50); ofCircle(20, ofGetMouseY(), 15); ofDrawBitmapString("|\nFilter\ nFrequency\n|", ofPoint(40, ofGetHeight()/2));

ofSetColor(20, 255, 150); ofCircle(ofGetMouseX(), ofGetHeight() - 20, 15); ofDrawBitmapString("<- Playback Speed ->", ofPoint(ofGetWidth()/2 - 100, ofGetHeight() - 40));

for ( int i=0; i<filePlayer.size(); i++) {

int aleatori = ofRandom(33);
if (doOnce == true){
    filePlayer[aleatori].play();
    filePlayer[aleatori].loop();
}

doOnce = false;

}

}

//-------------------------------------------------------------- void testApp::keyPressed(int key){

// if(key == 'f') filePlayer[output].showUI();

}

//-------------------------------------------------------------- void testApp::mouseMoved(int x, int y ){

float newSpeed = ofMap(x, 0, ofGetWidth(), 0.01, 2, true);

AudioUnitSetParameter(varispeed.getUnit(), kVarispeedParam_PlaybackRate, kAudioUnitScope_Global, 0, newSpeed, 0);

float newCutoff = ofMap(y, 0, ofGetHeight(), 10, 6900);

AudioUnitSetParameter(lowpass.getUnit(), kLowPassParam_CutoffFrequency, kAudioUnitScope_Global, 0, newCutoff, 0);

}

//-------------------------------------------------------------- void testApp::keyReleased(int key){} //-------------------------------------------------------------- void testApp::mouseDragged(int x, int y, int button){} //-------------------------------------------------------------- void testApp::mousePressed(int x, int y, int button){ doOnce = true;

} //-------------------------------------------------------------- void testApp::mouseReleased(int x, int y, int button){

for ( int i=0; i<filePlayer.size(); i++) { filePlayer[i].stop(); }

} //-------------------------------------------------------------- void testApp::windowResized(int w, int h){} //-------------------------------------------------------------- void testApp::gotMessage(ofMessage msg){} //-------------------------------------------------------------- void testApp::dragEvent(ofDragInfo dragInfo){}

The waveform doesn't show in the screen and I cant edit the sound. How I have to do it?

Thank you so much for everything.

Reply to this email directly or view it on GitHubhttps://github.com/admsyn/ofxAudioUnit/issues/14#issuecomment-34823912 .

Jason Levine new media performer + creative coder http://jasonlevine.ca

dferrandizmont commented 10 years ago

Thank you so much jasonlevine but I don't understand how to do it with the DLS synth.

I'm at the same point as yesterday, I can play each audio everytime I press mouseclick but I can't edit the sound using the .connectTo(lowpass) and (varispeed). I can connect but it doesn't make any effect.

I have to create a vector for each one?

Thank you jason and admsyn

admsyn commented 10 years ago

Yes, you'll need an independent effect unit for each file if you want to edit them all separately. So, you'll need a vector<ofxAudioUnit> effects, need to do effects.resize(33), and initialize each of them with the effect you want (for example, effects[0] = ofxAudioUnit(kAudioUnitType_Effect, kAudioUnitSubType_LowPassFilter);), and then connect them like:

filePlayer[i].connectTo(effects[i]).connectTo(tap[i]).connectTo(mixer, i);

If you just want to edit all the sound at once, you can just have one effect, and connect the mixer to it like this:

mixer.connectTo(effect).connectTo(output);
admsyn commented 10 years ago

@jasonlevine yeah no update there. I'm pretty sure the AUFilePlayer itself is buggy, or there's some really obscure incantation (like this) needed to make it behave more consistently.

dferrandizmont commented 10 years ago

Sorry for being so painful but I can not make it run. My code is:

ofApp.cpp

include "testApp.h"

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

lowpass.resize(33);

for (int i = 0; i < lowpass.size(); i ++){

    lowpass[i] = ofxAudioUnit(kAudioUnitType_Effect,
                              kAudioUnitSubType_LowPassFilter);
    lowpass[i].printParameterList();
    AudioUnitSetParameter(lowpass[0].getUnit(), kLowPassParam_Resonance,
                          kAudioUnitScope_Global, 0, 10, 0);
}

filePlayer.resize(33);
tap.resize(33);
mixer.setInputBusCount(33);
doOnce = false;

for (int i = 0; i < filePlayer.size(); i++){
    filePlayer[i].setFile(ofFilePath::getAbsolutePath("Sounds/" + ofToString(i) + ".wav"));
    filePlayer[i].connectTo(lowpass[i]).connectTo(tap[i]).connectTo(mixer, i);
    mixer.setInputVolume(1.0, i);
}

ofSetVerticalSync(true);
mixer.connectTo(output);

output.start();

}

//-------------------------------------------------------------- void testApp::update(){

for (int i = 0; i < tap.size(); i++){
    tap[i].getLeftWaveform(waveform, ofGetWidth(), ofGetHeight());

}

}

//-------------------------------------------------------------- void testApp::draw(){

ofBackground(40);
ofSetColor(255);
waveform.draw();
ofDrawBitmapString("Press 'f' to show the file player", ofPoint(40,20));

ofSetColor(255, 125, 50);
ofCircle(20, ofGetMouseY(), 15);
ofDrawBitmapString("|\nFilter\nFrequency\n|", ofPoint(40, ofGetHeight()/2));

ofSetColor(20, 255, 150);
ofCircle(ofGetMouseX(), ofGetHeight() - 20, 15);
ofDrawBitmapString("<- Playback Speed ->", ofPoint(ofGetWidth()/2 - 100, ofGetHeight() - 40));

for ( int i=0; i<filePlayer.size(); i++) {

    int aleatori = ofRandom(33);
    if (doOnce == true){
        filePlayer[aleatori].play();
        filePlayer[aleatori].loop();
    }

    doOnce = false;
}

}

//-------------------------------------------------------------- void testApp::keyPressed(int key){}

//-------------------------------------------------------------- void testApp::mouseMoved(int x, int y ){

float newCutoff = ofMap(y, 0, ofGetHeight(), 10, 6900);

for (int i = 0; i < lowpass.size(); i ++){

    AudioUnitSetParameter(lowpass[i].getUnit(),
                          kLowPassParam_CutoffFrequency,
                          kAudioUnitScope_Global,
                          0,
                          newCutoff,
                          0);
}

}

//-------------------------------------------------------------- void testApp::keyReleased(int key){} //-------------------------------------------------------------- void testApp::mouseDragged(int x, int y, int button){} //-------------------------------------------------------------- void testApp::mousePressed(int x, int y, int button){

doOnce = true;

} //-------------------------------------------------------------- void testApp::mouseReleased(int x, int y, int button){

for ( int i=0; i<filePlayer.size(); i++) {
    filePlayer[i].stop();
}

} //-------------------------------------------------------------- void testApp::windowResized(int w, int h){} //-------------------------------------------------------------- void testApp::gotMessage(ofMessage msg){} //-------------------------------------------------------------- void testApp::dragEvent(ofDragInfo dragInfo){}

ofApp.h

pragma once

include "ofMain.h"

include "ofxAudioUnit.h"

class testApp : public ofBaseApp{

public: void setup(); void update(); void draw();

void keyPressed  (int key);
void keyReleased(int key);
void mouseMoved(int x, int y );
void mouseDragged(int x, int y, int button);
void mousePressed(int x, int y, int button);
void mouseReleased(int x, int y, int button);
void windowResized(int w, int h);
void dragEvent(ofDragInfo dragInfo);
void gotMessage(ofMessage msg);

vector <ofxAudioUnit>                  lowpass;
vector <ofxAudioUnitFilePlayer>  filePlayer;
ofxAudioUnitOutput                      output;
vector <ofxAudioUnitTap>            tap;
ofxAudioUnitMixer                        mixer;

    bool doOnce;

ofPolyline waveform;

};

So, I can't edit any sound, if I use the lowpass filter the applications doesn't start, the console shows this error:

Couldn't locate component for description (lldb)

And the code where the error is:

{ return __sync_fetch_and_add(mem, val); } Thread 1: EXC_BAD_ACCESS (code=2, address=0x5).

Ah, and finally I can't see every sound wave, just one of them (the first one).

Thank you so much.

admsyn commented 10 years ago

Couldn't locate component for description means that you tried to create an audio unit type that doesn't exist. I'd guess it's failing on the low pass for some reason, and then when you try to set the parameter on it later it crashes. You also don't need the printParameterList() in there since it will just flood the console.

This line is probably wrong:

AudioUnitSetParameter(lowpass[0].getUnit(), ...

I'd think you want

AudioUnitSetParameter(lowpass[i].getUnit(), ...

Also, when you paste code on github it helps if you start and end the code section with three backticks like: ``` then your code will be more readable here.

dferrandizmont commented 10 years ago

admsyn, you're my hero. Finally I connect the filters to the mixer.connectTo(lowpass).connectTo(varispeed).connectTo(output); and now I can edit each song.

Righ now I have at least what I think would like to do but now I have a new commit:

Now I can edit the speed and the frequency from the sound I'm playing but, what about if I want to edit more parameters? How I have to do it? For example, I would like to edit the Lowpass filter, the delay, decay, decimation or the "Apple Delay" (you can see all of them if you press the correct key in the example-busses.xcodeproject that you made) from and external input (like you do it in the parameters example), how I would have to do it? How can I get acces to that parameters?

Thank you so much for your time, your reply and for the hard work you're doing to help me.

admsyn commented 10 years ago

Take a look at the parameters example, it will explain. For instance:

//  The easiest way to find the parameters for your Audio Unit
//  are to type kNameOfYourUnit and let Xcode's auto-complete
//  show you what's available. You can also see all of the parameters
//  defined in <AudioUnit/AudioUnitParameters.h>. It is a good idea
//  to read this header file anyway, as it'll tell you what values 
//  these parameters are expecting. One way to get information
//  on the parameter you want to change is to type it, then Cmd-click
//  on it to take you to its entry in AudioUnitParameters.h
dferrandizmont commented 10 years ago

Oh, I didn't read it ... I'll take a look later.

Thank you so much admsyn.

dferrandizmont commented 10 years ago

Hey, it's me again haha.

I've read all that explanation and now I'm trying to implement Decay effect.

First of all I declare an ofxAudioUnit variDecay; then in setup() i'm not sure what I have to write.

Now I put this

variDecay = ofxAudioUnit(kAudioUnitType_Effect, kAudioUnitSubType_Distortion); I don't know if this is what I have to put, I don't know where can I find the kAudioUnitType correct and the UnitSubType.

Then I write

float newDecay = ofMap(y, 0, ofGetHeight(), 0.1, 50);

    AudioUnitSetParameter(variDecay.getUnit(),
                          kDistortionParam_Decay,
                          kAudioUnitScope_Global,
                          0,
                          newDecay,
                          0);

Is that correct?

admsyn commented 10 years ago

Yes that looks about right. "variDecay" is kind of a weird name but that's up to you :)

Note that you can show the effect's UI in a pop-up window, which can help if you're trying to find which parameters to tweak. Just call variDecay.showUI() at the end of your setup()

You can see the list of audio unit identifiers by running auval -a in a terminal. You'll have to use some logic to deduce the 4-character codes (i.e. aufx is kAudioUnitType_Effect, aufc is kAudioUnitType_FormatConverter, etc).

dferrandizmont commented 10 years ago

Hey admsyn, just the last question and you'll be free :)!

When I write this AudioUnitSetParameter(reverb.getUnit(), kReverbParam_SmallLargeMix, kAudioUnitScope_Global, 0, newReverb, 0);

What exacly means the '0'? I saw what is when I write AudioUnitSetParameter, the first one is <#AudioUnitElement inElement#> and the other 0 is <#UInt32 inBufferOffsetInFrames#>.

This is something relation with this 0

( // Global, EqPow CrossFade, 0->100, 50 kReverbParam_SmallLargeMix = 1,)

because the other parameters from Reverb has other numbers (2,3,4,5,6, etc).

If the answer si yes, which one I have to change?

Thank you so much.

dferrandizmont commented 10 years ago

And the last last question, I tried to use it with iOS but Xcode didn't find <AudioToolbox/AudioUnitUtilities.h>and I notice that this doesn't exist for iOS, what would I need to make it work for iOS?

Thanks.

admsyn commented 10 years ago

The first 0 in AudioUnitSetParameter, the one called inElement specifies which bus you want the parameter to apply to. It only matters if the scope is kAudioUnitScope_Input or kAudioUnitScope_Output. Parameters are almost always kAudioUnitScope_Global, so inElement is almost always just 0. inBufferOffsetInFrames is how many "frames" in the future you want the parameter to change. 0 just means "now", which is usually what you want.

You should only have to change kReverbParam_SmallLargeMix and newReverb to change different parameters.

ofxAudioUnit won't work right away on iOS, you'll have your work cut out for you. You need to do a few hacks and tricky things to get it to work, I wouldn't suggest it unless you're quite comfortable with C++. You can see me walking someone else through the process here: http://irclog.perlgeek.de/openframeworks/2013-12-20

I wouldn't recommend it right now unless you really need it on iOS. Also, be aware that iOS has way fewer built-in audio units.

dferrandizmont commented 10 years ago

Thank you for everything admsyn! Finally I could use the addon and everything looks fine.

You'll prepare this addon for iOS in the near future?.

admsyn commented 10 years ago

iOS is on my to-do list for sure, but I wouldn't count on it if you're trying to plan out a course of action for a project.

Wenzy-- commented 8 years ago

Hi Adam, I am using of_v0.9.0_ios_release and trying to use the ofxAudioUnitSampler on ios9 but when I initialize the unit the way I do on OSX like this: sampler = ofxAudioUnitSampler('aumu', 'dls ', 'appl'); I'm receiving this error: Couldn't locate component for description: aumu, dls , appl

I saw that you mentioned that the builtin audio units on ios are not the same as on osx. How can I find out what audio units are available on my device? Is there an equivalent of auval -a for ios?

dimitre commented 4 years ago

Hello @admsyn , I'm writing in here because it mentioned using with array. I'm using inside an object, and I've noticed some functionalities are working when using arrays but not working when using vectors.

I'm using each object to forward audio to Logic using AUNetSender, in a different address. When I create a normal object or array, it plays allright and the server name is OK (AREIA0, AREIA1) but when using with vectors I have no audio and a generic name for the server.

    struct play {
        public:
        ofxAudioUnitFilePlayer source;
        ofxAudioUnit varispeed;
        ofxAudioUnitMixer mixerPan;
        ofxAudioUnitNetSend send;

        ofxAudioUnitMixer mixerOut;
        ofxAudioUnitOutput output;
        ofxAudioUnitTap tap;
        play() {
            int index = 0;
            string sendName = "AREIA" + ofToString(index);
            cout << sendName << endl;
            send.setName(sendName);

            varispeed.setup(kAudioUnitType_FormatConverter, kAudioUnitSubType_Varispeed);
            AudioUnitSetParameter(varispeed,
                                  kVarispeedParam_PlaybackRate,
                                  kAudioUnitScope_Global,
                                  0, 1.0, 0);

            source.connectTo(varispeed).connectTo(mixerPan).connectTo(send).connectTo(mixerOut).connectTo(output);
            mixerPan.setOutputVolume(1);
            mixerOut.setOutputVolume(1);
            output.start();
            source.setFile("/Volumes/werk/AREIA_AUDIO/dmtrnick1.aif");
            source.loop();
        }
    };

Thank you!