Robotframework: created .wav file with python sounddevice missing

61 Views Asked by At

in my robotframework project i'm recording an audio input (microphone) and create a wav file for audio procressing. When i'm running my .py file the audio is recorded and a wav file can be received. When the robot file is executed, the test is pass but i have no wav file in my directory.

This is my code:

# Start Audio Recording - Robotframework

def StartAudioRecording():

    Thread(target=Start).start()


# Start Audio Recording - Function

def Start():

    global q

    global file

    global stop_flag

    global filename



    stop_flag = False

    parser = argparse.ArgumentParser(add_help=False)

    parser.add_argument(

    '-l', '--list-devices', action='store_true',

    help='show list of audio devices and exit')

    args, remaining = parser.parse_known_args()

    if args.list_devices:

        print(sd.query_devices())

        parser.exit(0)

    parser = argparse.ArgumentParser(

    description=__doc__,

    formatter_class=argparse.RawDescriptionHelpFormatter,

    parents=[parser])

    parser.add_argument(

    'filename', nargs='?', metavar='FILENAME',

    help='audio file to store recording to')

    parser.add_argument(

    '-d', '--device', type=int_or_str,

    help='input device (numeric ID or substring)')

    parser.add_argument(

    '-r', '--samplerate', type=int, help='sampling rate')

    parser.add_argument(

    '-c', '--channels', type=int, default=1, help='number of input channels')

    parser.add_argument(

    '-t', '--subtype', type=str, help='sound file subtype (e.g. "PCM_24")')

    args = parser.parse_args(remaining)



    q = queue.Queue()

    

    if args.samplerate is None:

        device_info = sd.query_devices(args.device, 'input')

        # soundfile expects an int, sounddevice provides a float:

        args.samplerate = int(device_info['default_samplerate'])

    if args.filename is None:

        #args.filename = tempfile.mktemp(prefix='output_',suffix='.wav', dir='')

        args.filename = 'recording.wav'



    # Make sure the file is opened before recording anything:

    with sf.SoundFile(args.filename, mode='x', samplerate=args.samplerate,

                    channels=args.channels, subtype=args.subtype) as file:

        with sd.InputStream(samplerate=args.samplerate, device=args.device,

                            channels=args.channels, callback=callback):

            print('Recording')

            while not stop_flag:

                file.write(q.get())


# Stop Audio Recording - Robotframework

def Stop_Audio_Recording():

    Thread(target=Stop).start()



# Stop Audio Recording - Function

def Stop():

    global stop_flag

    stop_flag = True

    print('Recording stopped.')

    # StartAudioRecording_2

    #write("recording.wav", freq, recording)


if __name__ == '__main__':

    StartAudioRecording()

    time.sleep(10)

    Stop_Audio_Recording()

    

In my code example i'm getting a wav file with an audio duration of ~10 seconds. I'm not sure whats wrong, maybe someone has an idea :) Thanks for help!

3

There are 3 best solutions below

0
Philipp On BEST ANSWER

I solved it! All the part with "parser".."parser.add_argument" was the problem. For testing i wrote the values for these variables manually and it worked:

device = 0

channels = 1

samplerate = 48000

filename = 'recording.wav'

devices = sd.query_devices()

print(devices)

with sf.SoundFile(filename, mode='x', samplerate=samplerate,

                channels=channels) as file:

    with sd.InputStream(samplerate=samplerate, device=device,

                        channels=channels, callback=callback):

        print('Recording')

        while not stop_flag:

            file.write(q.get())  
1
Helio On

How do you call your library? Please show a basic example.

My guess is that you are expecting Robot Framework to run the script in the "main" call. This does not happen. You need to modify the code to run those functions, either at Library import time, or by calling keywords.

You could have, for example:

*** Test Cases ***
Record Audio
    Start Audio Recording
    Sleep    10 seconds
    Stop Audio Recording

Note: I am not sure if your code would be adapted directly to be a Library, due to the use of global variables. Please see the https://robotframework.org User Guide, about libraries sections.

3
Philipp On

@Helio The library is called with

*** Settings ***
Library    AudioAnalysis.py

*** Keywords ***
Run SoundTest
StartAudioRecording
#something is happening
Stop_Audio_Recording

*** Test cases***
Sound_Test  
      Run SoundTest

Sound_Test includes some functions for a device.

The keywords in my robot file are the names of functions. All neccassary packages were installed.

The code in my first post was just to check if the functions are working when i execute the main.