LCAV / pyroomacoustics

Pyroomacoustics is a package for audio signal processing for indoor applications. It was developed as a fast prototyping platform for beamforming algorithms in indoor scenarios.
https://pyroomacoustics.readthedocs.io
MIT License
1.33k stars 417 forks source link

room.mic_array.to_wav wrong sample rate? #307

Closed rorywalsh closed 1 year ago

rorywalsh commented 1 year ago

I can't seem to get room.mic_array.to_wav() to write with the sample rate specified for the room? It always writes at 8kHz? Here is my code:

import numpy as np
import matplotlib.pyplot as plt
from scipy.io import wavfile
from scipy.signal import fftconvolve
import scipy as sci
from scipy.fftpack import fft
import pyroomacoustics as pra

corners = np.array([[0,0], [0,3], [5,3], [5,1], [3,1], [3,0]]).T  # [x,y]
room = pra.Room.from_corners(corners)
room.extrude(2.)

fs, signal = wavfile.read("sample44100kHz.wav")
room = pra.Room.from_corners(corners, fs, max_order=3, materials=pra.Material(0.2, 0.15), ray_tracing=True, air_absorption=True)
room.extrude(2., materials=pra.Material(0.2, 0.15))
room.set_ray_tracing(receiver_radius=0.5, n_rays=10000, energy_thres=1e-5)
room.add_source([.1, .1, 0.1], signal=signal)
R = np.array([[0.5], [.2], [0.5]]) # [[x], [y], [z]]
room.add_microphone(R)
room.compute_rir()
room.simulate()

# ir_room3 is always 8kHz? 
room.mic_array.to_wav('ir_room3.wav', norm=True, bitdepth=np.int16)

I can get around this by simply writing the contents of room.mic_array.signals[0] to file using wavfile.write, but am I'd like to know if I'm missing something here that's causing this issue?

fakufaku commented 1 year ago

Hello @rorywalsh , I have just tried your code and it works without issue. The output file has the same sampling frequency as the input file.

Are you sure that sample44100kHz.wav is not, in fact, an 8 kHz file ? (also 44100 kHz is a lot of Hertz πŸ˜„) This would be the simplest explanation...

rorywalsh commented 1 year ago

You're right that is a lot of hertz πŸ˜‚ I have dicky checked the file and it is definitely 44.1kHz. anyway, if your not experiencing the issue there I'll close this. It's obviously something on my end causing the problem πŸ‘

fakufaku commented 1 year ago

Sorry, I didn't mean to negate your experience! I have modified the script to re-read the file and write out the new sampling frequency.

import numpy as np
import matplotlib.pyplot as plt
from scipy.io import wavfile
from scipy.signal import fftconvolve
import scipy as sci
from scipy.fftpack import fft
import pyroomacoustics as pra

corners = np.array([[0, 0], [0, 3], [5, 3], [5, 1], [3, 1], [3, 0]]).T  # [x,y]
room = pra.Room.from_corners(corners)
room.extrude(2.0)

fs, signal = wavfile.read("B3zlo5wV9Vo.2.wav")
print("Input freq:", fs)
room = pra.Room.from_corners(
    corners,
    fs,
    max_order=3,
    materials=pra.Material(0.2, 0.15),
    ray_tracing=True,
    air_absorption=True,
)
room.extrude(2.0, materials=pra.Material(0.2, 0.15))
room.set_ray_tracing(receiver_radius=0.5, n_rays=10000, energy_thres=1e-5)
room.add_source([0.1, 0.1, 0.1], signal=signal)
R = np.array([[0.5], [0.2], [0.5]])  # [[x], [y], [z]]
room.add_microphone(R)
room.compute_rir()
room.simulate()

# ir_room3 is always 8kHz?
room.mic_array.to_wav("B3zlo5wV9Vo.2.rev.wav", norm=True, bitdepth=np.int16)

fs_after, signal_after = wavfile.read("B3zlo5wV9Vo.2.rev.wav")
print("Output freq:", fs)

Just the file name is different since I did not have your file.

Which version of pyroomacoustics are you using ?

rorywalsh commented 1 year ago

Don't worry, you've been most helpful. I will try this once I get a chance.

[edit] Hi @fakufaku, I just tried this here. It outputs 44100, which we would expect. But when I open the resulting file in Audacity or Reaper it shows 8000kHz.

image

Perhaps the wav header is not being written correctly?

fakufaku commented 1 year ago

πŸ™‡

Could you post the file here for me to check ?

rorywalsh commented 1 year ago

sineSweep.zip

Here it is. Btw, you asked about what version of pyroom I'm using, I'm using the latest release afaik.

fakufaku commented 1 year ago

Thanks, can you please also post the file produced by pyroomacoustics ?

rorywalsh commented 1 year ago

Sure. Here it is. sineRev.zip

fakufaku commented 1 year ago

Ouch, there was a mistake in my script above!!! I was not printing fs_after in the final print. I have corrected and tried again and I get the same error as you do now!

rorywalsh commented 1 year ago

Ok, we're on the same footing now :)

fakufaku commented 1 year ago

Ok, I have identified the problem. You need to provide the sampling frequency as a keyword argument to the from_corners method.

room = pra.Room.from_corners(
    corners,
    fs=fs,
    max_order=3,
    materials=pra.Material(0.2, 0.15),
    ray_tracing=True,
    air_absorption=True,
)

If you omit the keyword, python automatically infer that you are providing the second positional argument of the method, in this case absorption. Absorption is a deprecated argument that has been replaced by materials and is ignored, which is why there was no apparent warning or problem with the simulation...

The absorption argument has been deprecated for a while and I will soon remove it, which will solve the issue altogether. In the meantime, providing fs=fs will solve the problem too.

rorywalsh commented 1 year ago

Thanks @fakufaku That's makes perfect sense, and also explains why I wasn't seeing this behaviour in other examples. Thanks again for taking the time to look into this πŸ‘