pythonraspberry-pimicrophonestereotype

How to play music in left speaker and microphone voice in right speaker with raspberry pi python?


I have a USB mic and raspberry pi. Here is what I'm trying to do.

I have "music.wav" file where the sound track is set to left channel and I have USB mic connected to raspberry pi.

When I play "music.wav" and speak in mic .I can hear music in left speaker and mic voice in both left and right speaker.

I tried the below code and tried different ways,could not achieve the to restrict the voice to be in right speaker only.

Can someone help me how to restrict music in only left speaker and voice in only right speaker using python language?

Below code for voice from microphone coming in both speaker. Need to restrict only in right speaker.Please help!!

import pyaudio
import os
import numpy as np

chunk=2800
RATE=44100

p=pyaudio.PyAudio()

#input stream setup
stream=p.open(format = pyaudio.paInt16,rate=RATE,channels=1, 
input_device_index = 1, input=True, frames_per_buffer=chunk)

#the code below is from the pyAudio library documentation referenced 
#below
#output stream setup
player=p.open(format = pyaudio.paInt16,rate=RATE,channels=1, 
output=True, frames_per_buffer=chunk)

while True:            #Used to continuously stream audio
   try:
       data=np.fromstring(stream.read(chunk,exception_on_overflow 
       =False),dtype=np.int16)
       player.write(data,chunk)
   except IOError:
       continue

#closes streams
stream.stop_stream()
stream.close()
p.terminate   

UPDATE: After many tries,I executed the below code:Now voice is breaking not clear and I'm still getting in both speakers...I also changed the "player"--output channel to 2..No luck!!

import pyaudio
import os
import numpy as np

  
chunk=2800
RATE=44100

p=pyaudio.PyAudio()

#input stream setup
stream=p.open(format = pyaudio.paInt16,rate=RATE,channels=1, 
input_device_index = 1, input=True, frames_per_buffer=chunk)

player=p.open(format = pyaudio.paInt16,rate=RATE,channels=1, 
output=True, 
frames_per_buffer=chunk) #tried changing channels=2

while True:            #Used to continuously stream audio
   try:
      data=np.fromstring(stream.read(chunk,exception_on_overflow = 
      False),dtype=np.int16)    
      chunk_length = int(len(data)/2)           
      result = np.reshape(data, (chunk_length, 2),order='f')
      #result = np.reshape(data, (chunk_length, 2))  
      print(result)

      rightchannel=result[:, 1] #I need right
      #leftchannel=result[:, 0]
   
      print(rightchannel)
      player.write(rightchannel,chunk_length)
      #player.write(result,chunk)
  except IOError:
      continue

UPDATE 2:

stream=p.open(format = pyaudio.paInt16,rate=RATE,channels=1, 
input_device_index = 1, input=True, frames_per_buffer=chunk)
player=p.open(format = pyaudio.paInt16,rate=RATE,channels=2, 
output=True, 
frames_per_buffer=chunk)

while True:            #Used to continuously stream audio
   try:
      data=np.fromstring(stream.read(chunk,exception_on_overflow = 
      False),dtype=np.int16)    
      chunk_length = int(len(data)/2)           
      result = np.reshape(data, (chunk_length, 2))     
      print(result)
      rightchannel=result[:, 1] #I need right
      #leftchannel=result[:, 0]      
      print(rightchannel)
      player.write(rightchannel,chunk)      
  except IOError:
      continue
 
  **ERROR**>>>>
  [[185 179]
  [183 175]
  [190 197]
  ..., 
  [156 156]
  [149 144]
  [145 146]]
  [179 175 197 ..., 156 144 146]
  Traceback (most recent call last):
  File 
  "/home/pi/RKR_MainAudioBase/Audio_GUI_RKR/MicFuncFiles/recorder.py", 
  line 25, in <module>
  player.write(rightchannel,chunk)
  File "/usr/lib/python3/dist-packages/pyaudio.py", line 586, in write
  exception_on_underflow)
  ValueError: ndarray is not C-contiguous

Solution

  • Solution which I got after many research and findings:

    It is working when you make input array channel as 1,Input data=[1 2 3 4 5 6] this mono which is from stream read for example,to make stereo just make output player channel=2 and make data into dataout=[ 1 1 2 2 3 3 4 4 5 5 6 6] this format which is [L0 R0 L1 R1...etc]. then "player.write(dataout,chunk)".

    And to have control over right channel make every 2nd,4th,6th etc position element as 0 ex:dataout=[ 1 0 2 0 3 0 4 0 5 0 6 0] and for left channel make 1st,3rd,5th element as 0. dataout=[ 0 1 0 2 0 3 0 4 0 5 0 6]

    This is working perfectly well !!!!