How to convert a numpy array waveform into a wav file-like object?
Asked Answered
G

1

0

I want to convert a numpy array waveform into a wav-like object so that I can upload it to S3 without having to save the waveform to file locally. Imagine I have a numpy array waveform, y,

y, sr = librosa.load('something.wav', sr = 44100)

How can I convert this numpy array, y into a wav file-like object to upload to S3 using boto3's upload_fileobj method?

According to the boto3 docs, the file-like object must have the properties:

A file-like object to upload. At a minimum, it must implement the read method, and must return bytes.

This is how I would like to upload the file-like object:

import boto3
s3 = boto3.resource('s3')
bucket = s3.Bucket('mybucket')

# with open('filename', 'rb') as data:
#    bucket.upload_fileobj(data, 'mykey')
bucket.upload_fileobj(wav_object, 'something.wav')

TLDR:

I want a function that converts a numpy array into a wav-like object that implements the read method and returns bytes.

Grisette answered 28/6, 2022 at 8:39 Comment(6)
Does this answer your question? Writing WAV file using Python, Numpy array and WAVE moduleElectromagnetic
Python has a built-in docs.python.org/3/library/wave.html module.Electromagnetic
@Electromagnetic that link doesn't answer my question because my starting point is a numpy array - not a wave file. I want to go from np array --> wav-like objectGrisette
You'll have to scroll to the second answer, https://mcmap.net/q/1132550/-writing-wav-file-using-python-numpy-array-and-wave-moduleElectromagnetic
@Electromagnetic the second answer has with wave.open("sound1.wav", "w") as f: but I don't want to write to a file locally , I just want to return a file-like object.Grisette
Based on the title, I thought the "file like object" part is clear. Anyway, if you don't want a file, just a buffer to write to, io.BytesIO(), and docs.python.org/3/library/io.html#io.BytesIO.getvalue when you're done.Electromagnetic
G
1

You can try like this:

import io 
from scipy.io.wavfile import write
import boto3

bytes_wav = bytes()
wav_object = io.BytesIO(bytes_wav)
write(wav_object, sr, y) # y is your numpy array


s3 = boto3.resource('s3')
bucket = s3.Bucket('mybucket')

bucket.upload_fileobj(wav_object, 'something.wav')
Garygarza answered 28/6, 2022 at 13:29 Comment(1)
Oooh let me try this and get back to you if it worksGrisette

© 2022 - 2024 — McMap. All rights reserved.