From 7e88f1e361893b936cc1d9924ea29c9a9be90c2f Mon Sep 17 00:00:00 2001 From: alexCharters Date: Sat, 5 Feb 2022 11:54:22 -0800 Subject: [PATCH] moved audio services from testing to dedicated audio package --- src/audio/CMakeLists.txt | 29 ++++++------- src/audio/scripts/AudioServer.py | 69 +++++++++++++++++++++++++++++++ src/audio/scripts/audio_client.py | 28 +++++++++++++ src/audio/srv/audio.srv | 3 ++ 4 files changed, 115 insertions(+), 14 deletions(-) create mode 100755 src/audio/scripts/AudioServer.py create mode 100755 src/audio/scripts/audio_client.py create mode 100644 src/audio/srv/audio.srv diff --git a/src/audio/CMakeLists.txt b/src/audio/CMakeLists.txt index a3580c6..24acade 100644 --- a/src/audio/CMakeLists.txt +++ b/src/audio/CMakeLists.txt @@ -11,6 +11,7 @@ find_package(catkin REQUIRED COMPONENTS roscpp rospy std_msgs + message_generation ) ## System dependencies are found with CMake's conventions @@ -54,11 +55,10 @@ find_package(catkin REQUIRED COMPONENTS # ) ## Generate services in the 'srv' folder -# add_service_files( -# FILES -# Service1.srv -# Service2.srv -# ) +add_service_files( + FILES + audio.srv +) ## Generate actions in the 'action' folder # add_action_files( @@ -68,10 +68,10 @@ find_package(catkin REQUIRED COMPONENTS # ) ## Generate added messages and services with any dependencies listed here -# generate_messages( -# DEPENDENCIES -# std_msgs -# ) +generate_messages( + DEPENDENCIES + std_msgs +) ################################################ ## Declare ROS dynamic reconfigure parameters ## @@ -105,7 +105,7 @@ find_package(catkin REQUIRED COMPONENTS catkin_package( # INCLUDE_DIRS include # LIBRARIES audio -# CATKIN_DEPENDS roscpp rospy std_msgs +CATKIN_DEPENDS roscpp rospy std_msgs # DEPENDS system_lib ) @@ -159,10 +159,11 @@ include_directories( ## Mark executable scripts (Python etc.) for installation ## in contrast to setup.py, you can choose the destination -# catkin_install_python(PROGRAMS -# scripts/my_python_script -# DESTINATION ${CATKIN_PACKAGE_BIN_DESTINATION} -# ) +catkin_install_python(PROGRAMS + scripts/audio_client.py + scripts/AudioServer.py + DESTINATION ${CATKIN_PACKAGE_BIN_DESTINATION} +) ## Mark executables for installation ## See http://docs.ros.org/melodic/api/catkin/html/howto/format1/building_executables.html diff --git a/src/audio/scripts/AudioServer.py b/src/audio/scripts/AudioServer.py new file mode 100755 index 0000000..f288a68 --- /dev/null +++ b/src/audio/scripts/AudioServer.py @@ -0,0 +1,69 @@ +#!/usr/bin/env python + +import pyaudio +import wave +import rospy +from testing.srv import audio,audioResponse +import time as tm +import os +import errno + +class AudioServer(): + + def __init__(self): + rospy.init_node('AudioServer') + self.audio_service = rospy.Service("Audio", audio, self.sendAudio) + #self.audio = some audio file + print("Ready to respond") + rospy.spin() + + + def getAudio(self, time): + form_1 = pyaudio.paInt16 # 16-bit resolution + chans = 1 # 1 channel + samp_rate = 44100 # 44.1kHz sampling rate + chunk = 4096 # 2^12 samples for buffer + record_secs = time # seconds to record + dev_index = 22 # device index found by p.get_device_info_by_index(ii) + try: + os.makedirs("/home/usr/recordings/") + except OSError as e: + if e.errno != errno.EEXIST: + raise + wav_output_filename = '/home/usr/recordings/'+str(tm.time())+'.wav' # name of .wav file + + audio = pyaudio.PyAudio() # create pyaudio instantiation + + # create pyaudio stream + stream = audio.open(format = form_1,rate = samp_rate,channels = chans, \ + input_device_index = dev_index,input = True, \ + frames_per_buffer=chunk) + print("recording") + frames = [] + + # loop through stream and append audio chunks to frame array + for ii in range(0,int((samp_rate/chunk)*record_secs)): + data = stream.read(chunk) + frames.append(data) + + print("finished recording") + + # stop the stream, close it, and terminate the pyaudio instantiation + stream.stop_stream() + stream.close() + audio.terminate() + + # save the audio frames as .wav file + wavefile = wave.open(wav_output_filename,'wb') + wavefile.setnchannels(chans) + wavefile.setsampwidth(audio.get_sample_size(form_1)) + wavefile.setframerate(samp_rate) + wavefile.writeframes(b''.join(frames)) + wavefile.close() + return wav_output_filename + + def sendAudio(self,req): + return audioResponse(self.getAudio(req.time)) + +if __name__ == '__main__': + audioServer = AudioServer() diff --git a/src/audio/scripts/audio_client.py b/src/audio/scripts/audio_client.py new file mode 100755 index 0000000..8803617 --- /dev/null +++ b/src/audio/scripts/audio_client.py @@ -0,0 +1,28 @@ +#!/usr/bin/env python + +from __future__ import print_function + +import sys +import rospy +import errno +from testing.srv import audio + +def audio_client(time): + rospy.wait_for_service('Audio') + try: + audio_srv = rospy.ServiceProxy('Audio', audio) + resp1 = audio_srv(time) + return resp1.filePath + except rospy.ServiceException as e: + print("Service call failed: %s"%e) + +def usage(): + return "%s [time]"%sys.argv[0] + +if __name__ == "__main__": + if len(sys.argv) == 2: + time = float(sys.argv[1]) + else: + print(usage()) + sys.exit(1) + print("%s"%(audio_client(time))) diff --git a/src/audio/srv/audio.srv b/src/audio/srv/audio.srv new file mode 100644 index 0000000..76a41c1 --- /dev/null +++ b/src/audio/srv/audio.srv @@ -0,0 +1,3 @@ +float32 time +--- +string filePath