Re: [pyo-discuss] Mono input to stereo output

298 views
Skip to first unread message

Olivier Bélanger

unread,
Mar 1, 2015, 7:54:42 AM3/1/15
to pyo-discuss
Hi,

It's not possible for the moment but it should be easy enough to make
it possible. I'll keep you in touch about that!

Olivier


2015-02-27 0:13 GMT-05:00 Yao Sun <mr.su...@gmail.com>:
> Hi,
>
> I was wondering if its possible to connecting single channel input and still
> have a stereo output. I have a USB 3.5mm soundcard that has a mono input and
> stereo output. I want to keep duplex=1 as I want to take the microphone
> input to process.
>
> Presently portaudio will give me an error saying it cannot find the channel,
> which is valid because it expects a 2 channel input stream. Is there a way
> to somehow set the input channel to 1 and output channel to 2?
>
> Thanks,
> Yao
>
> --
> You received this message because you are subscribed to the Google Groups
> "pyo-discuss" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to pyo-discuss...@googlegroups.com.
> For more options, visit https://groups.google.com/d/optout.

Olivier Bélanger

unread,
Mar 3, 2015, 10:31:47 AM3/3/15
to pyo-discuss
It's done in the sources. Will be in the next release...

The number of input channels can be set separately with the new
`ichnls` Server's argument. If `ichnls` = None (the default), the
number of input channels is the same as output channels.

Olivier

Robin Parmar

unread,
Apr 24, 2015, 12:02:18 PM4/24/15
to pyo-d...@googlegroups.com
This may be the same question... or maybe not.

Take the provided mixer.py example, which is really close to what I want to achieve. In my code I am using SfPlayer.setPath() to change the input files periodically. If you feed it stereo files it works just fine. If you feed it a mono file, a warning is sent to the console.

Is there a way to have it accept either? Perhaps by panning a mono signal to centre, and then sending that along?

But I cannot figure out how to do that, since the setPath() method is not explicitly using a stream. Instead it is changing the properties of one that exists already.

-- Robin

Olivier Bélanger

unread,
Apr 24, 2015, 12:42:08 PM4/24/15
to pyo-discuss
Hi Robin,

If you use a SndTable, initialized with 2 channels, instead of a SfPlayer, you will get what you want. SndTable will load a mono sound in both channels. Something like this:

#!/usr/bin/env python
# encoding: utf-8
from pyo import *

s = Server().boot()

t = SndTable(initchnls=2)
r = TableRead(t, freq=1, loop=True)

m = Mixer(outs=1, chnls=2)
m.addInput(0, r)
m.setAmp(0, 0, 0.5)
output = Sig(m[0]).out()

# call new("path/to/a/sound") to load a new sound and adjust the playback speed
def new(path):
    t.setSound(path)
    r.freq = t.getRate()
    r.play()

s.gui(locals())



Olivier
 

--

Robin Parmar

unread,
Apr 24, 2015, 1:51:26 PM4/24/15
to pyo-d...@googlegroups.com
Thanks Olivier! You are so helpful.

In the meantime, I determined that one can also pipe the player output through Pan like so:


from pyo import *
s = Server().boot()

a = SfPlayer('mono.wav', loop=True, mul=.3).out()
b = Pan(a, outs=2, pan=0.5).out()

s.gui(locals())

Oddly, Pan is not panning to the centre... the left channel is significantly louder. But it plays without issuing a warning.

Robin Parmar

unread,
Apr 24, 2015, 2:56:12 PM4/24/15
to pyo-d...@googlegroups.com
Olivier, I am not getting your code to work for some reason. No crashes, but also no audio.

-- Robin

Olivier Bélanger

unread,
Apr 24, 2015, 3:16:29 PM4/24/15
to pyo-discuss
Did you call new("path/to/your/sound") in the interpreter entry of the Server GUI ? By default the table is empty...

Olivier


2015-04-24 14:56 GMT-04:00 Robin Parmar <robi...@gmail.com>:
Olivier, I am not getting your code to work for some reason. No crashes, but also no audio.

-- Robin

Olivier Bélanger

unread,
Apr 24, 2015, 3:18:38 PM4/24/15
to pyo-discuss
The error message you got earlier was coming from a stereo SfPlayer trying to load a mono soundfile... I should really change this behaviour for the next release!

Olivier

Robin Parmar

unread,
Apr 24, 2015, 7:24:26 PM4/24/15
to pyo-d...@googlegroups.com
OK, I tried a simpler code snippet and it worked. Thanks again.

Robin Parmar

unread,
Apr 24, 2015, 8:24:19 PM4/24/15
to pyo-d...@googlegroups.com
I think I know why your snippet is working but my actual app is not. It has something to do with the mysterious line below:

output = Sig(m[0]).out()

Why is this required? The variable "output" is never used. I would have thought that the mixer is already sending sound to the output. Also, there is no line like this in the version of the code that runs off SfPlayer.

In my application, I use multiple tables with different WAV files being loaded into each, periodically. I can see this happening if I view the tables. But I hear nothing, likely because the "output" line needs to be modified to something more complex. I do not understand how.


On Friday, 24 April 2015 17:42:08 UTC+1, bela...@gmail.com wrote:

Olivier Bélanger

unread,
Apr 24, 2015, 8:48:12 PM4/24/15
to pyo-discuss
Hi Robin,

I think you interpret the Mixer object in pyo as if it behaves like a DAW's mixer... This is not the case. The only purpose of the Mixer object is to sum multiple inputs to arbitrary outputs. It has nothing to do with the samples actually sent to the soundcard. That is the purpose of the out() method (defined in PyoObject). This is why the mysterious line actually makes you hear something. The variable "output" is not used anywhere else in the script, but it hold the reference to the audio object sending samples to the soundcard.

I hope that clears the audio routing in pyo!

Olivier

Robin Parmar

unread,
Apr 25, 2015, 2:11:19 PM4/25/15
to pyo-d...@googlegroups.com
I am still confused. :-)

I understand that each audio stream has an out() method to output the audio. And the return value of each of these holds the reference to that audio. I also understand that Mixer is an internal summing object.

But what confuses me is that there is no explicit function/method that sends the final output to the sound card. This seems to happen magically! Is it simply the case that the last encountered out() method will do this?


On Saturday, 25 April 2015 01:48:12 UTC+1, bela...@gmail.com wrote:
Hi Robin,

I think you interpret the Mixer object in pyo as if it behaves like a DAW's mixer... This is not the case. The only purpose of the Mixer object is to sum multiple inputs to arbitrary outputs. It has nothing to do with the samples actually sent to the soundcard. That is the purpose of the out() method (defined in PyoObject). This is why the mysterious line actually makes you hear something. The variable "output" is not used anywhere else in the script, but it hold the reference to the audio object sending samples to the soundcard.

I hope that clears the audio routing in pyo!

Olivier

Olivier Bélanger

unread,
Apr 25, 2015, 2:44:25 PM4/25/15
to pyo-discuss
HI,

2015-04-25 14:11 GMT-04:00 Robin Parmar <robi...@gmail.com>:
I am still confused. :-)

I understand that each audio stream has an out() method to output the audio. And the return value of each of these holds the reference to that audio. I also understand that Mixer is an internal summing object.

But what confuses me is that there is no explicit function/method that sends the final output to the sound card. This seems to happen magically! Is it simply the case that the last encountered out() method will do this?

Not just the last encountered out() method but every object for which the out() method has been called. That's the job of the Server object to mix them all before send samples to the soundcard.

Olivier
 

On Saturday, 25 April 2015 01:48:12 UTC+1, bela...@gmail.com wrote:
Hi Robin,

I think you interpret the Mixer object in pyo as if it behaves like a DAW's mixer... This is not the case. The only purpose of the Mixer object is to sum multiple inputs to arbitrary outputs. It has nothing to do with the samples actually sent to the soundcard. That is the purpose of the out() method (defined in PyoObject). This is why the mysterious line actually makes you hear something. The variable "output" is not used anywhere else in the script, but it hold the reference to the audio object sending samples to the soundcard.

I hope that clears the audio routing in pyo!

Olivier

Robin Parmar

unread,
Apr 26, 2015, 8:17:44 AM4/26/15
to pyo-d...@googlegroups.com
I didn't understand that simple fact. Breakthrough!

This explains the problem in the code I posted previously. This is designed to use the Pan object to make two channel output from a mono file.

from pyo import *
s = Server().boot()
a = SfPlayer('mono.wav', loop=True).out()

b = Pan(a, outs=2, pan=0.5).out()
s.gui(locals())

The first out() should be omitted.

Olivier Bélanger

unread,
Apr 26, 2015, 8:46:55 AM4/26/15
to pyo-discuss
Yes, it should be omitted. Otherwise it sums up the signal twice on the left channel...

Olivier

Darren Sholes

unread,
Sep 22, 2021, 3:14:55 PM9/22/21
to pyo-discuss
I'm still confused. I have a mono input that I set up with:

a = Input(chnl=0)

When I call a.out(), I get the audio out of the left channel. That makes sense since .out(chnl=0) is the default argument. When I call a.out(1) I get it out of the right ear, which still makes sense. 

However, when I call a.out([0,1]), I only get audio out of the left channel. Is that because my Input object is mono and from chnl=0?

What is the best way to hear a mono input in both channels? I've used a Mixer object in the past, but is that the best way?

Cheers,
Darren

Olivier Bélanger

unread,
Sep 22, 2021, 3:22:11 PM9/22/21
to pyo-d...@googlegroups.com
Hi,

If you give a list as the chnl argument of the out method, it is the specific output channels assigned to the successive streams managed by your object. It is assumed that you have enough streams to fulfil the list (in fact, the smaller number between the number of streams and the list size is used).

To hear a mono signal in both channels, all you have to do is to mix it up:

a = Input()
b = a.mix(2).out()

Olivier
 

Darren Sholes

unread,
Sep 22, 2021, 3:46:05 PM9/22/21
to pyo-discuss
Awesome, thank you! And is there any reason to use a Mixer object instead? Or is that just preferred when you have multiple PyoObjects and want a way to control relative volumes more easily?
Reply all
Reply to author
Forward
0 new messages