Closed dferrandizmont closed 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 :)
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)
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.
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);
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);
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
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
//-------------------------------------------------------------- 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.
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.
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
More things:
output.start()
should be after your connections are done. Move it to the end of setup()
.play()
or .loop()
anywhere?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.
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()
?
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();
}
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();
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?
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
//-------------------------------------------------------------- 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.
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
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
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);
@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.
Sorry for being so painful but I can not make it run. My code is:
ofApp.cpp
//-------------------------------------------------------------- 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
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.
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.
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.
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
Oh, I didn't read it ... I'll take a look later.
Thank you so much admsyn.
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?
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).
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.
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.
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.
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?.
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.
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?
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!
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();)
and in draw() I have the .play()
How can I translate all that code to make it work with the addon?
Thank you so much.