multichannel output using the RTaudio library

Hi folks,
I am working on an installation that uses 5 output of sound that I am recording in real time using OF, the problem is the following, trying to set the output channels to more than 2 I am encountering some problems:
In the testApp class I have set the ofSoundStreamSetup(4,2,this,44100,4);
and in the class that records and playback audio I am doing this:

  
if (bPlayback == true && bufferSize>0){  
	for (int i = 0; i < bufferSize; i++){  
		output[i*nChannels    ] += audioRecordingBuffer[playbackPos] * volume;  
               output[i*nChannels + 1] += audioRecordingBuffer[playbackPos] * volume;  
	 output[i*nChannels + 2 ] += audioRecordingBuffer[playbackPos] * volume;  
	output[i*nChannels + 3] += audioRecordingBuffer[playbackPos] * volume;   
			playbackPos++;  
			playbackPos %= bufferLength;  
		}  
	  
	  
		  
	}  

[/code]

the result in audio is something close to a kind of noise…

it outputs the 4 speakers but it sounds terrible…
I think I might doing the wrong method

any advise will be more than appreciated
Thanks!

can you print out nChannels in the audioRequested function ? does it equal 4 ?

take care,
zach

Yeah I did that

I have the audioRequested function in both the audioRecorder class and the testApp
those settings are done in the audioRecorder class and the cout happens in the audioRecorder class

hope that this makes sense

sorry, what’s does nChannels print out as ?

can you upload a sample code?

I’d try making a much simpler code to begin with – 0 input channels, 4 output channels, just put noise or a sin wave to each channel as in the audio output example. can you try that first and see if it works?

take care,
zach

thanks for the fast response

  
if (bPlayback == true && bufferSize>0)  
	{  
		for (int i = 0; i < bufferSize; i++){  
			output[i*nChannels    ] += audioRecordingBuffer[playbackPos] * volume;  
  
			output[i*nChannels + 1] += audioRecordingBuffer[playbackPos] * volume;  
		 output[i*nChannels + 2 ] += audioRecordingBuffer[playbackPos] * volume;  
			output[i*nChannels + 3] += audioRecordingBuffer[playbackPos] * volume;  
			playbackPos++;  
			playbackPos %= bufferLength;  
		}  
	  
	  
		  
	}  
		cout<<"nChannels"<<nChannels<<"\n";  
  

this is located in the audioRecorder class that has a function called audioRequested
which is being called in the testApp audioRequested function as well

the nChannels printed are 4
and I tried to use noise to test it as u mentioned
but the output is the same

it is a kind of clipping noise

can you post the full source of the noise test?
-z

Hi zach
im emailing the src code

thanks for the help!

Can you try a noise test but taking this line out:

  
  
(bPlayback == true && bufferSize>0)   
  

Just continually feed the outputs with samples…don’t try and break up the stream.
If you want to turn the audio off it’s usually better to send samples with a volume of zero than to starve the audio stream…which could be causing some of your problems.

Are you sure your card supports full-duplex - i.e. recording and playing back multiple channels at the same time?

I would try only 4 channel playback with no recording and get that right first…i.e. call the setup using:

  
  
ofSoundStreamSetup(4,0,this,44100,4);   
  

Thanks grimus,
Yeah I tested that and I have just noticed that what make it sound like that is the += cuz when I change it to** =** it outputs pretty well
now the problem is that In order to have multiple recordings playing back I need to use the += otherwise it will only output the last recording…

I hope that makes sense.

This is a tool to record and playback, with the idea of having multiple playbacks sounding in different speakers… so thats why I need the +=
any suggestions or advise?

Aaah yes I missed that.

If you use += then the output buffer values will get larger and larger until they exceed 1.0f at which point they will clip and make horrible noises.

You need to mix the incoming signal with the current values in the output buffer.
Maybe try something like this:

  
  
 output[i*nChannels] = output[i*nChannels] * 0.5f + audioRecordingBuffer[playbackPos] * 0.5f * volume;   
  

That way if the current sample in the output buffer is 1.0f, then it is halved to 0.5f…the same applies to the incoming signal. Add them together and you never get more than 1.0f.

hey great point grimus !

If you use += then the output buffer values will get larger and larger until they exceed 1.0f at which point they will clip and make horrible noises.

but I’m not sure halving makes sense, because you’d be diluting the original samples, no?

ie, considering samples 10, 7, 5

_(I know, we should be talking about numbers between -1 and 1, but this is just academic)
_

10 * 0.5 + 7 * 0.5 = 7.5

7.5 * 0.5 + 3 * 0.5 = 5.25

I feel like 10 is less present then the 3, no ?

really, you’d want (10+7+5) / 3 = 7.33

therefore, I think what you need to do, is to make sure the volume of the sound is ok, ie, if you are adding 2 things to the channel, have a volume of 1/2 (0.5), if you are adding three things 1/3 (0.33), and this will make sure that in the maximum case, you always will add to -1 or 1 and not clip. for example, if all the samples are 1, and you have four (volume 0.25):

1 * 0.25 + 1 * 0.25 + 1 * 0.25 + 1 * 0.25 =

0.25 + 0.25 + 0.25 + 0.25 =

1

no clipping :slight_smile: !

hope that helps –

yeep, sorry late night post…

Divide by the number of channels you want to mix (I had stereo in mind…forgot about the original requirements)

Amen!