Import pyaudio to ROS Node

Viewed 110

Hi I wrote a ROS Node in python which imports pyaudio for processing audio. I am using virtulenv with all python modules installed. I can run my Node in Pycharm however when i use rosrun mic_pkg mic_app.py. I'm getting following error

AttributeError: 'module' object has no attribute 'PyAudio'

Here is my node to run.

#!/usr/bin/env python
import pyaudio
import numpy as np
import struct
import rospy
from std_msgs.msg import Float64


class AudioInterface:

def __init__ (self):
    self.NSAMPLES = 92000
    self.CHUNK = 1024 * 4
    self.FORMAT = 8
    self.CHANNELS = 1
    self.RATE = 92000  # Hz or 152000, 192000 max
    self.RECORD_SECONDS = 3
    self.FRAMES = []

    self.interface = pyaudio.PyAudio ()
    self.stream = self.interface.open (format=self.FORMAT,
                                       channels=self.CHANNELS, rate=self.RATE, input=True,
                                       frames_per_buffer=self.CHUNK)

    self.stream.start_stream ()
    self.set_device_index ()

def __del__ (self):
    self.stream.stop_stream ()
    self.interface.terminate ()

def set_device_index (self):
    for i in range (self.interface.get_device_count ()):
        devinfo = self.interface.get_device_info_by_index (i)
        print ('Device %{}: %{}'.format (i, devinfo['name']))

        for keyword in ['mic', 'input']:
            if keyword in devinfo['name'].lower ():
                print ('Found an input: device {} - {}'.format (i, devinfo['name']))
                self.device_index = i

def get_chunks (self):
    for i in range (0, int (self.RATE / self.CHUNK * self.RECORD_SECONDS)):
        data = np.frombuffer (self.stream.read (self.CHUNK), dtype=np.int16)
        data = data / 1000
        self.FRAMES.append (data)
    return self.FRAMES

def get_audio_block (self):
    data = np.frombuffer (self.stream.read (self.RATE), dtype=np.int16)
    data = data / 1000
    return data


class AudioProcessing:
@staticmethod
def calc_fft (array):
    fftdata = np.abs (np.fft.rfft (array))
    return fftdata

@staticmethod
def calc_rms (array):
    rms = np.sqrt (np.mean (array ** 2))
    return rms

@staticmethod
def calc_mean (array):
    result = np.mean (array)
    return result

@staticmethod
def normalize (array):
    buff = []
    min_value = min (array)
    max_value = max (array)
    for x in array:
        y = (x - min_value) / (max_value - min_value)
        buff.append (y)

    return buff

@staticmethod
def zeros (array):
    for n in range (0, 38000):
        array[n] = 0

    for k in range (42000, len (array)):
        array[k] = 0

    return array


LEAK_TRIGGER = 0.25
is_leaking = False
trigger = False

if __name__ == "__main__":
mic = AudioInterface ()
is_leaking = False

rospy.init_node ('microphone_node', anonymous=False)
pub = rospy.Publisher ('mic_data', Float64, queue_size=10)
rate = rospy.Rate (10)
while not rospy.is_shutdown ():
    audio = mic.get_audio_block ()
    audio_freq = AudioProcessing.calc_fft (audio)
    audio_normalized = AudioProcessing.normalize (audio)
    fft_normalized = AudioProcessing.normalize (audio_freq)
    fft_normalized = AudioProcessing.zeros (fft_normalized)
    max_val = max (fft_normalized)

    hello_str = "hello world %s" % rospy.get_time ()
    pub.publish (max_val)
    rospy.loginfo (max_val)
    rate.sleep ()

I can't tell whether this is not finding package issue or maybe some problem with pyaudio module itself. How do I import python modules (like pyaudio) to ROS Node Please help. Thanks!

Edit i do catkin_make each time i make some changes to the code and it passes with no errors.

0 Answers
Related