3

Suppose I have a song, which plays on both of the speakers on my headphones. I want to write a code using pyAudio, so that I get output on only on speaker. Like those videos demonstrating left-right check.

I went through this question, but I don't think this solves my problem. Also, since I am a new member, I cannot comment on it, for further clarification.

I tried to implement a solution from the above linked question, but it wasn't giving me correct answers. Here is the implementation.

from struct import pack
from math import sin, pi
import wave
import random

RATE=44100

## GENERATE MONO FILE ##
wv = wave.open('music.wav', 'w')
wv.setparams((1, 2, RATE, 0, 'NONE', 'not compressed'))
maxVol=2**15-1.0 #maximum amplitude
wvData=bytes()

for i in range(0, RATE*3):
    # print(type(pack('h', int(maxVol*sin(i*500/RATE)))))
    wvData+=pack('h', int(maxVol*sin(i*500.0/RATE))) #500Hz

wv.writeframes(wvData)
wv.close()

I got a 3 second clip containing noise as the output, which is not expected. The actual output should only play the audio on one channel only, either be left or right.

  • Not sure this is possible with pyAduio actually. I have no basis for this comment tho other than working with the library and read the documentation pretty thoroughly. What you could do is that you could control the actual output sink in your OS. That's possible via [pulsectl](https://pypi.org/project/pulsectl/) or similarly. – Torxed Jan 24 '19 at 15:46
  • Thanks @Torxed for the info. However, according to [this](https://stackoverflow.com/questions/35970282/what-are-chunks-samples-and-frames-when-using-pyaudio) question, each frame has two channels. I guess that these channels are basically the left and right outputs (I don't know if this is correct or not). Maybe if we can do something, to remove one of them, then I guess it might be possible. – Kaptain Kirk Jan 24 '19 at 15:49
  • That question is reffering to the source media, yes, that has two channels. But the playback can also has to channels and I don't think pyAudio lets you control individual output channels. You can probably manipulate the raw source media - sure. But that's not the same as getting the left/right channel of pyAudio (output/mixing). – Torxed Jan 24 '19 at 16:06
  • Does this question still relevant to you @KaptainKirk? – handras Jan 26 '19 at 12:55

1 Answers1

0

wv.setparams((1, 2, RATE, 0, 'NONE', 'not compressed')) creates a mono wave file. That means that the left and the rigth channel are the same (in fact there isn't a left and rigth channel just the channel).

To make sound only on one side you need a stereo file with two channels. See these examples. Write 0 to either of the channels to make that side 'mute'.

I show an example how to achive a fade between two sides:

for i in range(0, RATE * 3):
    percent = (float(i) / (RATE * 3 - 1)) # for fade effect
    wvData += pack('h', int((1 - percent) * maxVol * sin(2 * pi * i * 500.0 / RATE)))
    wvData += pack('h', int(percent * maxVol * sin(2 * pi * i * 488.0 / RATE)))

Also note that the sin() function takes its argument in radian, so you have to multiply the value with 2pi. Missing this step is the reason for hearing just noise.

handras
  • 1,548
  • 14
  • 28