Skip to content

Commit

Permalink
Add AnechoicRoom class (#224)
Browse files Browse the repository at this point in the history
  • Loading branch information
duembgen authored Nov 10, 2022
1 parent e4b937c commit c30a0a6
Show file tree
Hide file tree
Showing 15 changed files with 381 additions and 50 deletions.
4 changes: 4 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -11,3 +11,7 @@ docs/_build
dist/
local_examples/
*.ipynb_checkpoints
# files added after editable install (pip install -e . )
pyroomacoustics.egg-info/
pyroomacoustics/build_rir.c
pyroomacoustics/**/*.so
1 change: 1 addition & 0 deletions CHANGELOG.rst
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ adheres to `Semantic Versioning <http://semver.org/spec/v2.0.0.html>`_.
Added
~~~~~

- Added the AnechoicRoom class.
- Added FastMNMF2 (Fast Multichannel Nonnegative Matrix Factorization 2) to ``bss`` subpackage.
- Randomized image source method for removing sweeping echoes in shoebox rooms.
- Adds the ``cart2spher`` method in ``pyroomacoustics.doa.utils`` to convert from cartesian
Expand Down
2 changes: 1 addition & 1 deletion CONTRIBUTING.rst
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ style <https://github.com/numpy/numpy/blob/master/doc/HOWTO_DOCUMENT.rst.txt>`__
We recommend the following steps for generating the documentation:

- Create a separate environment, e.g. with Anaconda, as such:
``conda create -n mkdocs37 python=3.7 sphinx numpydoc mock sphinx_rtd_theme``
``conda create -n mkdocs37 python=3.7 sphinx numpydoc mock sphinx_rtd_theme sphinxcontrib-napoleon tabulate``
- Switch to the environment: ``source activate mkdocs37``
- Navigate to the ``docs`` folder and run: ``./make_apidoc.sh``
- The materials database page is generated with the script ``./make_materials_table.py``
Expand Down
2 changes: 2 additions & 0 deletions docs/make_materials_table.py
100644 → 100755
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
#!/usr/bin/env python
"""
This helper script creates a documentation page from the materials database
that is stored in JSON format.
Expand Down Expand Up @@ -83,3 +84,4 @@ def print_section(title, data, headers, file):
headers=headers,
file=f,
)
print("Wrote file", docfile)
7 changes: 7 additions & 0 deletions docs/pyroomacoustics.doa.normmusic.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
pyroomacoustics.doa.normmusic module
====================================

.. automodule:: pyroomacoustics.doa.normmusic
:members:
:undoc-members:
:show-inheritance:
7 changes: 7 additions & 0 deletions docs/pyroomacoustics.libroom.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
pyroomacoustics.libroom module
==============================

.. automodule:: pyroomacoustics.libroom
:members:
:undoc-members:
:show-inheritance:
1 change: 1 addition & 0 deletions docs/requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,4 @@ sphinx>=1.6.2
mock>=2.0
sphinx_rtd_theme
sphinxcontrib-napoleon
tabulate
6 changes: 3 additions & 3 deletions examples/beamforming_delay_and_sum.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@
import matplotlib.pyplot as plt
import pyroomacoustics as pra

# Create a 4 by 6 metres shoe box room
room = pra.ShoeBox([4, 6])
# Create a 4 by 6 metres anechoic room
room = pra.AnechoicRoom(dim=2)

# Add a source somewhere in the room
room.add_source([2.5, 4.5])
Expand All @@ -22,5 +22,5 @@
room.mic_array.rake_delay_and_sum_weights(room.sources[0][:1])

# plot the room and resulting beamformer
room.plot(freq=[1000, 2000, 4000, 8000], img_order=0)
room.plot(freq=[1000, 2000, 4000, 8000])
plt.show()
14 changes: 12 additions & 2 deletions examples/doa_algorithms.py
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,14 @@
# Location of original source
azimuth = 61.0 / 180.0 * np.pi # 60 degrees
distance = 3.0 # 3 meters
dim = 2 # dimensions (2 or 3)
room_dim = np.r_[10.0, 10.0]

# Use AnechoicRoom or ShoeBox implementation. The results are equivalent because max_order=0 for both.
# The plots change a little because in one case there are no walls.
use_anechoic_class = True

print("============ Using anechoic: {} ==================".format(anechoic))

#######################
# algorithms parameters
Expand All @@ -68,8 +76,10 @@
sigma2 = 10 ** (-SNR / 10) / (4.0 * np.pi * distance) ** 2

# Create an anechoic room
room_dim = np.r_[10.0, 10.0]
aroom = pra.ShoeBox(room_dim, fs=fs, max_order=0, sigma2_awgn=sigma2)
if use_anechoic_class:
aroom = pra.AnechoicRoom(dim, fs=fs, sigma2_awgn=sigma2)
else:
aroom = pra.ShoeBox(room_dim, fs=fs, max_order=0, sigma2_awgn=sigma2)

# add the source
source_location = room_dim / 2 + distance * np.r_[np.cos(azimuth), np.sin(azimuth)]
Expand Down
64 changes: 64 additions & 0 deletions examples/doa_anechoic_room.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
"""
This example creates a free-field simulation of direction of arrival estimation.
"""

import argparse

import numpy as np

import pyroomacoustics as pra

methods = ["MUSIC", "FRIDA", "WAVES", "TOPS", "CSSM", "SRP", "NormMUSIC"]

if __name__ == "__main__":

parser = argparse.ArgumentParser(
description="Estimates the direction of arrival of a sound source."
)
parser.add_argument(
"--method",
"-m",
choices=methods,
default=methods[0],
help="DOA method to use",
)
args = parser.parse_args()

# we use a white noise signal for the source
nfft = 256
fs = 16000
x = np.random.randn((nfft // 2 + 1) * nfft)

# create anechoic room
room = pra.AnechoicRoom(fs=fs)

# place the source at a 90 degree angle and 5 meters distance from origin
azimuth_true = np.pi / 2
room.add_source([5 * np.cos(azimuth_true), 5 * np.sin(azimuth_true), 0], signal=x)

# place the microphone array
mic_locs = np.c_[
[0.1, 0.1, 0],
[-0.1, 0.1, 0],
[-0.1, -0.1, 0],
[0.1, -0.1, 0],
]
room.add_microphone_array(mic_locs)

# run the simulation
room.simulate()

# create frequency-domain input for DOA algorithms
X = pra.transform.stft.analysis(
room.mic_array.signals.T, nfft, nfft // 2, win=np.hanning(nfft)
)
X = np.swapaxes(X, 2, 0)

# perform DOA estimation
doa = pra.doa.algorithms[args.method](mic_locs, fs, nfft)
doa.locate_sources(X)

# evaluate result
print("Source is estimated at:", doa.azimuth_recon)
print("Real source is at:", azimuth_true)
print("Error:", pra.doa.circ_dist(azimuth_true, doa.azimuth_recon))
6 changes: 2 additions & 4 deletions pyroomacoustics/beamforming.py
Original file line number Diff line number Diff line change
Expand Up @@ -187,7 +187,7 @@ def square_2D_array(center, M, N, phi, d):
The center of the array
M: int
The number of points in the first dimension
M: int
N: int
The number of points in the second dimension
phi: float
The counterclockwise rotation of the array (from the x-axis)
Expand Down Expand Up @@ -806,9 +806,7 @@ def plot_beam_response(self):
if self.weights is None and self.filters is not None:
self.weights_from_filters()
elif self.weights is None and self.filters is None:
raise NameError(
"Beamforming weights or filters need to be computed" " first."
)
raise NameError("Beamforming weights or filters need to be computed first.")

phi = np.linspace(-np.pi, np.pi - np.pi / 180, 360)
freq = self.frequencies
Expand Down
2 changes: 1 addition & 1 deletion pyroomacoustics/doa/doa.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
import math
import sys
import warnings
from abc import ABCMeta, abstractmethod
from abc import ABCMeta

import numpy as np

Expand Down
Loading

0 comments on commit c30a0a6

Please sign in to comment.