-2

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
  • I guess you’ll have to convert mono microphone input to right-only stereo (with every left channel sample set to zero) before sending it to audio output. Maybe see https://stackoverflow.com/questions/22636499/convert-multi-channel-pyaudio-into-numpy-array – DisappointedByUnaccountableMod Jul 18 '20 at 10:29
  • Thanks for sharing,I tried it.. as https://stackoverflow.com/questions/62862652/how-to-play-music-in-left-speaker-and-microphone-voice-in-right-speaker-with-ras/62971828#62971828 But getting below error Traceback (most recent call last): File "/home/pi/RKR_MainAudioBase/Audio_GUI_RKR/MicFuncFiles/recorder.py", line 25, in 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 – Rakshith kr Jul 18 '20 at 17:46
  • Please update the code in your question with a [mre] that shows this error. – DisappointedByUnaccountableMod Jul 19 '20 at 08:50
  • You have set player to be 2 channels? – DisappointedByUnaccountableMod Jul 19 '20 at 08:51
  • @barny..yes i have tried and posted the method which you stated me to look into..Still not able to achieve. I was able to resolve that ndarray not C contagious error by adding order='f' while i reshape. however not able to resolve. – Rakshith kr Jul 19 '20 at 10:51
  • Not in a position to try this ATM - the player *must* be two channels – DisappointedByUnaccountableMod Jul 19 '20 at 19:16
  • Thanks for the support....I changed the output channel to 2, if i make result = np.reshape(data, (chunk_length, 2),order='f'),the code executes with no error but voice data is breaking and appears in both speakers. So without order='f' I have posted code and error as "UPDATE 2" in the question. Not able to solve this C-contiguous error,your help is appreciated. – Rakshith kr Jul 20 '20 at 15:58
  • The chunk length doesn’t change - if it’s one second of mono microphone sound it must still play as one second of stereo sound - but as r and l are interleaved and you want the left channel to be silent you have to add the same number of zeroes alternately with the samples. – DisappointedByUnaccountableMod Jul 20 '20 at 21:26
  • @barny thanks helped a lot. Wonderful support..really appreciating. 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 and for left channel make 1st,3rd,5th element as 0. This is working perfectly well !!!! – Rakshith kr Jul 21 '20 at 19:10
  • Well done for getting it working! – DisappointedByUnaccountableMod Jul 21 '20 at 20:17

1 Answers1

0

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 !!!!