Getting sound card audio as an input

Hello, I’d like to use ofSoundGetSpectrum(), but with sounds coming from other programs instead of an audio file. Is this not possible? I’ve tried to look at some of the ofSoundStream methods, like getDeviceList(), but it doesn’t even show my PreSonus audio interface as one of the available devices, and even if it did, I don’t know how to set its out channels as the input for audioIn().

Hi, you can not use the ofSoundGetSpectrum() function as it uses the audio file player implementation to generate the spectrum. If you want to use the sound input you can use ofxFft which is a bit outdated or you can use ofxSoundObjects. Otherwise search in ofxaddons.com

As of the sound interface not being detected it can be because of the sound api in windows.

instead of calling sound.getDeviceList(ofSoundDevice::DEFAULT);
try calling one of of the following instead.

sound.getDeviceList(ofSoundDevice::MS_WASAPI); /// < The Microsoft WASAPI API. 
sound.getDeviceList(ofSoundDevice::MS_ASIO);   /// < The Steinberg Audio Stream I/O API. 
sound.getDeviceList(ofSoundDevice::MS_DS);     /// < The Microsoft Direct Sound API.

Then use the api type that showed your audio interface for seting the soundstream as follows

toggle between the commented ones.

ofSoundStreamSettings streamSettings;
	streamSettings.numInputChannels = 2;
	streamSettings.numOutputChannels = 2;
	streamSettings.sampleRate = 44100;
	streamSettings.bufferSize = 256;
	streamSettings.numBuffers = 4;
streamSettings.setApi(ofSoundDevice::MS_WASAPI); /// < The Microsoft WASAPI API. 
//streamSettings.setApi(ofSoundDevice::MS_ASIO);   /// < The Steinberg Audio Stream I/O API. 
//streamSettings.setApi(ofSoundDevice::MS_DS);     /// < The Microsoft Direct Sound API. 

sound.setup(streamSettings);

Hey, thanks a lot for the answer. Once I get the ofSoundStream set up as you instructed, how do I use it with ofxFft or your extension of it? If I copy this example script, it’s set up to work by reacting to what comes into ofApp::audioReceived(). How do I get it to work instead with the output of the ofSoundStream that I’ve set up?

The example script is so long and has so many methods that, of course, don’t know, so it’s a bit hard to navigate what’s going on…

I see there’s the fft->setSignal() method, so I’d think I’d need to get my ofSoundStream’s data in there instead of the input variable from ofApp::audioReceived(), but not sure how. I tried copying the contents of ofApp::audioReceived() into ofApp::update() and adding this to the beginning:

std::shared_ptr<float> stream = std::make_shared<float>();
	stream = sound.getSoundStream();

	fft->setSignal(stream.get());

but upon compiling I get the error:

|Error|C2440|’’: cannot convert from ‘std::shared_ptr’ to ‘std::shared_ptr’

EDIT: OK, that error is because I’m trying to assign an ofBaseSoundStream ptr to a float ptr. But if I fix that error, I’m left without a correct argument format for setSignal()

std::shared_ptr<ofBaseSoundStream> stream = std::make_shared<ofBaseSoundStream>();
	stream = sound.getSoundStream();

	fft->setSignal((std::_Ptr_base<float>)stream.get()); //this doesn't work

Hi, in ofxSoundObjects there is an ofxFft example. Check it. It allows you to toggle between live input and a sound player by pressing the spacebar.

dont put the sound processing stuff in the update method as sound runs on a different thread and it will most probablt make the app crash.

the soundstream object is not the same as the signal, so it wont work that way.

1 Like

OK, I’ve got example-ofxFft up and working, and setting streamSettings.setApi(ofSoundDevice::MS_WASAPI) works to use my PreSonus.

But none of the three input options (sound file, oscillator, mic input) seems to do what I want- I want to get the output from the sound card. So if I play some sounds on the same computer in Pure Data, or even if just play something on YouTube I can run an fft on that sound.

I see. It does not work that way. you can not get the output, as that data goes straight into the sound interface. What you have to do is to use something as JACK which creates a virtual output which you use as the audio output of PD, and then you can catch that as an input in OF (and choosing the input device as the JACK router and output device as the sound interface. Or you can do it in hardware by connecting the output of the sound interface to an input channel of it (but make sure that you dont output that input otherwise you will create feedback )

Thank you! I need to get this running soon, so since I only need the sound from PD this time, I think I’ll try doing the fft in PD and sending the values to oF via OSC messages. But I’ll keep JACK in mind in the future.

1 Like

This is not only an OF thing it is how computer audio works so it should be useful for any kind of setup.
IT is a good idea to do all the audio in PD. you might want to take a look to ofxPD, which lets you run the PD patch trhough libpd from within openFrameworks, that way once you have your patch done you can have a single app that runs it all. It is quite handy. And if I am correct you can pass messages directly from PD to OF when you use ofxPD.

Oh wow, big problem trying to do it in PD running separately. Just turning DSP on in PD (even with no patch open) makes the Kinect’s depth image very slow and choppy. The Kinect’s RGB image remains smooth though. Is GPU being used for one and CPU for the other?

I guess I’ll have to try ofxPD and hope it works…

that’s strange. try using the kinect and your sound interface on different USB ports not through a hub; connect each directly to the computer. ofxKinect uses the CPU to ingest data, the GPU is just used for displaying the already ingested data.
A USB/peripheral problem sounds like the problem