ofSoundStream: Different sound device for input and output

Hello,

I’m working with multichannel audio involving both multichannel input, processing and multichannel output of the processed sound. I moved from a MacBook to a windows machine and I’m facing a problem. Windows split the inputs and outputs of my sound devices into stereo groups of only inputs and only outputs (so that I end up with 19 separate devices listed by ofSoundStream.listDevices() ). Since I can’t or I don’t know how to create an aggregate device on Win7, which was a very convenient solution on MacOSX, I end up with a device that supports either only inputs or only outputs, as it is set by ofSoundStream.setDeviceID().

Is there a way to set different devices for input and output? I noticed that the documentation of OF presents two versions of audioIn and audioOut functions, the usual one and another which goes like:

virtual void ofBaseSoundInput::audioIn (
float * input,
int bufferSize,
int nChannels,
int deviceID,
long unsigned long tickCount
) [inline, virtual]

and

virtual void ofBaseSoundOutput::audioOut (
float * output,
int bufferSize,
int nChannels,
int deviceID,
long unsigned long tickCount
) [inline, virtual]

Does that mean that it is possible to set up different devices somehow? And if yes, how do you pass these arguments to these functions? It seems to me that these values are read automatically from the way the ofSoundStream object is initialised, but I’m not very proficient with C++ to really understand what’s going on there…

Things would have been much easier if the there was asio support enabled in the audio libraries of OF, again if somebody knows a clear way to get asio up and running with OF please let me know…

i have not been in your exact situation and don’t know much about windows.

but on osx you have an utility app call “Audio MIDI Setup” which allows you to aggregate multiple devices in to one. this one shows up as a separate device when calling .listDevices()

maybe there is something like this for windows.

but i have noticed in my case when selecting more then 2 devices with each 2 output channels ofsoundstream does not seem to output anything.
not sure why

I’m not deeply familiar with how Windows sets up device IDs for audio but you should be able to have different devices for both. OF 073 has a way to set the device ID for input and output

  
  
void ofRtAudioSoundStream::setInDeviceID(int _deviceID){  
	inDeviceID = _deviceID;  
}  
  
void ofRtAudioSoundStream::setOutDeviceID(int _deviceID){  
	outDeviceID = _deviceID;  
}  
  
  

and RTAudio doesn’t care, though DirectSound might?

mmh, yes that’s a bug you should be able to use those separately, by now you can create an instance of ofRtAudioSoundStream, which already alows that and then call setInDeviceID/setOutDeviceID before starting the soundStream.

if you need several out modules you can create several instances of soundStream.

but there is only one void testApp::audioOut (float * output, int bufferSize, int nChannels){ in the app.

how would i tell the separate instances of ofRtAudioSoundStream to get separate data?
in my case i am loading multiple audio files/sample via sampleloader and want to direct them to different outputs.

you can change that function to:

  
  
virtual void ofBaseSoundOutput::audioOut   (     
float *    output,  
int    bufferSize,  
int    nChannels,  
int    deviceID,  
long unsigned long    tickCount  
)        
  

to receive the deviceID

thank you very much.

as an update:
i was able to use 7 maudio usb fast tracks with this method. each of them having a left and right channels.
i was not able to connect more then 2 fast tracks per usb port.

here is a snippet of my code:

  
  
void testApp::audioOut (float * output, int bufferSize, int nChannels,  int deviceID, long unsigned long tickCount){  
      
    
    cout<<"outDeviceID "<<deviceID<<endl;  
  
    int ii = deviceID-deviceIDlist[0];  
    volume = 1;  
  
    for (int i = 0; i < bufferSize; i++){  
          
        for(int c=0; c<channels_per_device;c++){  
            if(sounds[c+ii*2].isPlaying)  output[i*nChannels + c] = sounds[c+ii*2].play(4) * volume;  
        }  
   
    }  
      
}  
  

Hello,
I had the same problem of requiring different audio devices for audio input and output, on the windows platform I saw that ofRtAudioSoundStream is used. As stated earlier in the post it does support different device IDs so I lightly modified ofBaseSoundStream.h to include the following 2 lines:

  
  
virtual void setInDeviceID(int deviceID) = 0;  
virtual void setOutDeviceID(int deviceID) = 0;  
  

and in ofBaseSoundStream.cpp added:

  
  
void ofSoundStream::setInDeviceID(int deviceID){  
    if( soundStream ){  
        soundStream->setInDeviceID(deviceID);  
    }  
}  
  
//------------------------------------------------------------  
void ofSoundStream::setOutDeviceID(int deviceID){  
    if( soundStream ){  
        soundStream->setOutDeviceID(deviceID);  
    }  
}  
  

and in ofSoundStream.h added:

  
  
void setInDeviceID(int deviceID);  
void setOutDeviceID(int deviceID);  
  

The input and output devices can then be chosen simply by using in the application code:

  
  
soundStream.setInDeviceID(InDevID);  
soundStream.setOutDeviceID(OutDevID);  
  

This works fine in windows BUT for other platforms using ofPASoundStream, has anyone done or is planning to do the necessary mods? It would require more work than the above.

BTW if you want to route an audio output into your application, I used VB-audio virtual cable (free).