First Commit
This commit is contained in:
3958
externals/openal-soft/utils/CIAIR.def
vendored
Normal file
3958
externals/openal-soft/utils/CIAIR.def
vendored
Normal file
File diff suppressed because it is too large
Load Diff
425
externals/openal-soft/utils/IRC_1005.def
vendored
Normal file
425
externals/openal-soft/utils/IRC_1005.def
vendored
Normal file
@@ -0,0 +1,425 @@
|
||||
# This is a makemhr HRIR definition file. It is used to define the layout and
|
||||
# source data to be processed into an OpenAL Soft compatible HRTF.
|
||||
#
|
||||
# This definition is used to transform the left and right ear HRIRs of any
|
||||
# raw data set from the IRCAM/AKG Listen HRTF database.
|
||||
#
|
||||
# The data sets are available free of charge from:
|
||||
#
|
||||
# http://recherche.ircam.fr/equipes/salles/listen/index.html
|
||||
#
|
||||
# Contact for the Listen HRTF Database:
|
||||
#
|
||||
# Olivier Warusfel <olivier.warusfel@ircam.fr>,
|
||||
# Room Acoustics Team, IRCAM
|
||||
# 1, place Igor Stravinsky
|
||||
# 75004 PARIS, France
|
||||
|
||||
rate = 44100
|
||||
|
||||
# The IRCAM sets are stereo because they provide both ear HRIRs.
|
||||
type = stereo
|
||||
|
||||
# The raw sets have up to 8192 samples, but 2048 seems large enough.
|
||||
points = 2048
|
||||
|
||||
# No head radius was provided. Just use the average radius of 9 cm.
|
||||
radius = 0.09
|
||||
|
||||
# The IRCAM sets are single-field (like most others) with a distance between
|
||||
# the source and the listener of 1.95 meters.
|
||||
distance = 1.95
|
||||
|
||||
# This set isn't as dense as the MIT set.
|
||||
azimuths = 1, 6, 12, 24, 24, 24, 24, 24, 24, 24, 12, 6, 1
|
||||
|
||||
# The IRCAM source azimuth is counter-clockwise, so it needs to be flipped.
|
||||
# Left and right ear HRIRs (from the respective WAVE channels) are used to
|
||||
# create a stereo HRTF.
|
||||
|
||||
# Replace all occurrences of IRC_#### for the desired subject (1005 was used
|
||||
# in this demonstration).
|
||||
[ 3, 0 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T000_P315.wav" left
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T000_P315.wav" right
|
||||
[ 3, 1 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T345_P315.wav" left
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T345_P315.wav" right
|
||||
[ 3, 2 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T330_P315.wav" left
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T330_P315.wav" right
|
||||
[ 3, 3 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T315_P315.wav" left
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T315_P315.wav" right
|
||||
[ 3, 4 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T300_P315.wav" left
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T300_P315.wav" right
|
||||
[ 3, 5 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T285_P315.wav" left
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T285_P315.wav" right
|
||||
[ 3, 6 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T270_P315.wav" left
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T270_P315.wav" right
|
||||
[ 3, 7 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T255_P315.wav" left
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T255_P315.wav" right
|
||||
[ 3, 8 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T240_P315.wav" left
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T240_P315.wav" right
|
||||
[ 3, 9 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T225_P315.wav" left
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T225_P315.wav" right
|
||||
[ 3, 10 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T210_P315.wav" left
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T210_P315.wav" right
|
||||
[ 3, 11 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T195_P315.wav" left
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T195_P315.wav" right
|
||||
[ 3, 12 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T180_P315.wav" left
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T180_P315.wav" right
|
||||
[ 3, 13 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T165_P315.wav" left
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T165_P315.wav" right
|
||||
[ 3, 14 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T150_P315.wav" left
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T150_P315.wav" right
|
||||
[ 3, 15 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T135_P315.wav" left
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T135_P315.wav" right
|
||||
[ 3, 16 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T120_P315.wav" left
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T120_P315.wav" right
|
||||
[ 3, 17 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T105_P315.wav" left
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T105_P315.wav" right
|
||||
[ 3, 18 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T090_P315.wav" left
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T090_P315.wav" right
|
||||
[ 3, 19 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T075_P315.wav" left
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T075_P315.wav" right
|
||||
[ 3, 20 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T060_P315.wav" left
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T060_P315.wav" right
|
||||
[ 3, 21 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T045_P315.wav" left
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T045_P315.wav" right
|
||||
[ 3, 22 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T030_P315.wav" left
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T030_P315.wav" right
|
||||
[ 3, 23 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T015_P315.wav" left
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T015_P315.wav" right
|
||||
|
||||
[ 4, 0 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T000_P330.wav" left
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T000_P330.wav" right
|
||||
[ 4, 1 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T345_P330.wav" left
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T345_P330.wav" right
|
||||
[ 4, 2 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T330_P330.wav" left
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T330_P330.wav" right
|
||||
[ 4, 3 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T315_P330.wav" left
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T315_P330.wav" right
|
||||
[ 4, 4 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T300_P330.wav" left
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T300_P330.wav" right
|
||||
[ 4, 5 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T285_P330.wav" left
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T285_P330.wav" right
|
||||
[ 4, 6 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T270_P330.wav" left
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T270_P330.wav" right
|
||||
[ 4, 7 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T255_P330.wav" left
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T255_P330.wav" right
|
||||
[ 4, 8 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T240_P330.wav" left
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T240_P330.wav" right
|
||||
[ 4, 9 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T225_P330.wav" left
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T225_P330.wav" right
|
||||
[ 4, 10 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T210_P330.wav" left
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T210_P330.wav" right
|
||||
[ 4, 11 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T195_P330.wav" left
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T195_P330.wav" right
|
||||
[ 4, 12 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T180_P330.wav" left
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T180_P330.wav" right
|
||||
[ 4, 13 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T165_P330.wav" left
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T165_P330.wav" right
|
||||
[ 4, 14 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T150_P330.wav" left
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T150_P330.wav" right
|
||||
[ 4, 15 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T135_P330.wav" left
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T135_P330.wav" right
|
||||
[ 4, 16 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T120_P330.wav" left
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T120_P330.wav" right
|
||||
[ 4, 17 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T105_P330.wav" left
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T105_P330.wav" right
|
||||
[ 4, 18 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T090_P330.wav" left
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T090_P330.wav" right
|
||||
[ 4, 19 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T075_P330.wav" left
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T075_P330.wav" right
|
||||
[ 4, 20 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T060_P330.wav" left
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T060_P330.wav" right
|
||||
[ 4, 21 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T045_P330.wav" left
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T045_P330.wav" right
|
||||
[ 4, 22 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T030_P330.wav" left
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T030_P330.wav" right
|
||||
[ 4, 23 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T015_P330.wav" left
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T015_P330.wav" right
|
||||
|
||||
[ 5, 0 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T000_P345.wav" left
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T000_P345.wav" right
|
||||
[ 5, 1 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T345_P345.wav" left
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T345_P345.wav" right
|
||||
[ 5, 2 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T330_P345.wav" left
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T330_P345.wav" right
|
||||
[ 5, 3 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T315_P345.wav" left
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T315_P345.wav" right
|
||||
[ 5, 4 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T300_P345.wav" left
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T300_P345.wav" right
|
||||
[ 5, 5 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T285_P345.wav" left
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T285_P345.wav" right
|
||||
[ 5, 6 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T270_P345.wav" left
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T270_P345.wav" right
|
||||
[ 5, 7 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T255_P345.wav" left
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T255_P345.wav" right
|
||||
[ 5, 8 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T240_P345.wav" left
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T240_P345.wav" right
|
||||
[ 5, 9 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T225_P345.wav" left
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T225_P345.wav" right
|
||||
[ 5, 10 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T210_P345.wav" left
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T210_P345.wav" right
|
||||
[ 5, 11 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T195_P345.wav" left
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T195_P345.wav" right
|
||||
[ 5, 12 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T180_P345.wav" left
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T180_P345.wav" right
|
||||
[ 5, 13 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T165_P345.wav" left
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T165_P345.wav" right
|
||||
[ 5, 14 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T150_P345.wav" left
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T150_P345.wav" right
|
||||
[ 5, 15 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T135_P345.wav" left
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T135_P345.wav" right
|
||||
[ 5, 16 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T120_P345.wav" left
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T120_P345.wav" right
|
||||
[ 5, 17 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T105_P345.wav" left
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T105_P345.wav" right
|
||||
[ 5, 18 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T090_P345.wav" left
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T090_P345.wav" right
|
||||
[ 5, 19 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T075_P345.wav" left
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T075_P345.wav" right
|
||||
[ 5, 20 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T060_P345.wav" left
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T060_P345.wav" right
|
||||
[ 5, 21 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T045_P345.wav" left
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T045_P345.wav" right
|
||||
[ 5, 22 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T030_P345.wav" left
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T030_P345.wav" right
|
||||
[ 5, 23 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T015_P345.wav" left
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T015_P345.wav" right
|
||||
|
||||
[ 6, 0 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T000_P000.wav" left
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T000_P000.wav" right
|
||||
[ 6, 1 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T345_P000.wav" left
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T345_P000.wav" right
|
||||
[ 6, 2 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T330_P000.wav" left
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T330_P000.wav" right
|
||||
[ 6, 3 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T315_P000.wav" left
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T315_P000.wav" right
|
||||
[ 6, 4 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T300_P000.wav" left
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T300_P000.wav" right
|
||||
[ 6, 5 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T285_P000.wav" left
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T285_P000.wav" right
|
||||
[ 6, 6 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T270_P000.wav" left
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T270_P000.wav" right
|
||||
[ 6, 7 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T255_P000.wav" left
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T255_P000.wav" right
|
||||
[ 6, 8 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T240_P000.wav" left
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T240_P000.wav" right
|
||||
[ 6, 9 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T225_P000.wav" left
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T225_P000.wav" right
|
||||
[ 6, 10 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T210_P000.wav" left
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T210_P000.wav" right
|
||||
[ 6, 11 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T195_P000.wav" left
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T195_P000.wav" right
|
||||
[ 6, 12 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T180_P000.wav" left
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T180_P000.wav" right
|
||||
[ 6, 13 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T165_P000.wav" left
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T165_P000.wav" right
|
||||
[ 6, 14 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T150_P000.wav" left
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T150_P000.wav" right
|
||||
[ 6, 15 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T135_P000.wav" left
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T135_P000.wav" right
|
||||
[ 6, 16 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T120_P000.wav" left
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T120_P000.wav" right
|
||||
[ 6, 17 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T105_P000.wav" left
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T105_P000.wav" right
|
||||
[ 6, 18 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T090_P000.wav" left
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T090_P000.wav" right
|
||||
[ 6, 19 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T075_P000.wav" left
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T075_P000.wav" right
|
||||
[ 6, 20 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T060_P000.wav" left
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T060_P000.wav" right
|
||||
[ 6, 21 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T045_P000.wav" left
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T045_P000.wav" right
|
||||
[ 6, 22 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T030_P000.wav" left
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T030_P000.wav" right
|
||||
[ 6, 23 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T015_P000.wav" left
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T015_P000.wav" right
|
||||
|
||||
[ 7, 0 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T000_P015.wav" left
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T000_P015.wav" right
|
||||
[ 7, 1 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T345_P015.wav" left
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T345_P015.wav" right
|
||||
[ 7, 2 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T330_P015.wav" left
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T330_P015.wav" right
|
||||
[ 7, 3 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T315_P015.wav" left
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T315_P015.wav" right
|
||||
[ 7, 4 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T300_P015.wav" left
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T300_P015.wav" right
|
||||
[ 7, 5 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T285_P015.wav" left
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T285_P015.wav" right
|
||||
[ 7, 6 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T270_P015.wav" left
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T270_P015.wav" right
|
||||
[ 7, 7 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T255_P015.wav" left
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T255_P015.wav" right
|
||||
[ 7, 8 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T240_P015.wav" left
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T240_P015.wav" right
|
||||
[ 7, 9 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T225_P015.wav" left
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T225_P015.wav" right
|
||||
[ 7, 10 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T210_P015.wav" left
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T210_P015.wav" right
|
||||
[ 7, 11 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T195_P015.wav" left
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T195_P015.wav" right
|
||||
[ 7, 12 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T180_P015.wav" left
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T180_P015.wav" right
|
||||
[ 7, 13 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T165_P015.wav" left
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T165_P015.wav" right
|
||||
[ 7, 14 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T150_P015.wav" left
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T150_P015.wav" right
|
||||
[ 7, 15 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T135_P015.wav" left
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T135_P015.wav" right
|
||||
[ 7, 16 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T120_P015.wav" left
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T120_P015.wav" right
|
||||
[ 7, 17 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T105_P015.wav" left
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T105_P015.wav" right
|
||||
[ 7, 18 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T090_P015.wav" left
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T090_P015.wav" right
|
||||
[ 7, 19 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T075_P015.wav" left
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T075_P015.wav" right
|
||||
[ 7, 20 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T060_P015.wav" left
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T060_P015.wav" right
|
||||
[ 7, 21 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T045_P015.wav" left
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T045_P015.wav" right
|
||||
[ 7, 22 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T030_P015.wav" left
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T030_P015.wav" right
|
||||
[ 7, 23 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T015_P015.wav" left
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T015_P015.wav" right
|
||||
|
||||
[ 8, 0 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T000_P030.wav" left
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T000_P030.wav" right
|
||||
[ 8, 1 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T345_P030.wav" left
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T345_P030.wav" right
|
||||
[ 8, 2 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T330_P030.wav" left
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T330_P030.wav" right
|
||||
[ 8, 3 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T315_P030.wav" left
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T315_P030.wav" right
|
||||
[ 8, 4 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T300_P030.wav" left
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T300_P030.wav" right
|
||||
[ 8, 5 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T285_P030.wav" left
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T285_P030.wav" right
|
||||
[ 8, 6 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T270_P030.wav" left
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T270_P030.wav" right
|
||||
[ 8, 7 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T255_P030.wav" left
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T255_P030.wav" right
|
||||
[ 8, 8 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T240_P030.wav" left
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T240_P030.wav" right
|
||||
[ 8, 9 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T225_P030.wav" left
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T225_P030.wav" right
|
||||
[ 8, 10 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T210_P030.wav" left
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T210_P030.wav" right
|
||||
[ 8, 11 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T195_P030.wav" left
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T195_P030.wav" right
|
||||
[ 8, 12 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T180_P030.wav" left
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T180_P030.wav" right
|
||||
[ 8, 13 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T165_P030.wav" left
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T165_P030.wav" right
|
||||
[ 8, 14 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T150_P030.wav" left
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T150_P030.wav" right
|
||||
[ 8, 15 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T135_P030.wav" left
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T135_P030.wav" right
|
||||
[ 8, 16 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T120_P030.wav" left
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T120_P030.wav" right
|
||||
[ 8, 17 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T105_P030.wav" left
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T105_P030.wav" right
|
||||
[ 8, 18 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T090_P030.wav" left
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T090_P030.wav" right
|
||||
[ 8, 19 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T075_P030.wav" left
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T075_P030.wav" right
|
||||
[ 8, 20 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T060_P030.wav" left
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T060_P030.wav" right
|
||||
[ 8, 21 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T045_P030.wav" left
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T045_P030.wav" right
|
||||
[ 8, 22 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T030_P030.wav" left
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T030_P030.wav" right
|
||||
[ 8, 23 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T015_P030.wav" left
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T015_P030.wav" right
|
||||
|
||||
[ 9, 0 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T000_P045.wav" left
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T000_P045.wav" right
|
||||
[ 9, 1 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T345_P045.wav" left
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T345_P045.wav" right
|
||||
[ 9, 2 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T330_P045.wav" left
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T330_P045.wav" right
|
||||
[ 9, 3 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T315_P045.wav" left
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T315_P045.wav" right
|
||||
[ 9, 4 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T300_P045.wav" left
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T300_P045.wav" right
|
||||
[ 9, 5 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T285_P045.wav" left
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T285_P045.wav" right
|
||||
[ 9, 6 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T270_P045.wav" left
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T270_P045.wav" right
|
||||
[ 9, 7 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T255_P045.wav" left
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T255_P045.wav" right
|
||||
[ 9, 8 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T240_P045.wav" left
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T240_P045.wav" right
|
||||
[ 9, 9 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T225_P045.wav" left
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T225_P045.wav" right
|
||||
[ 9, 10 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T210_P045.wav" left
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T210_P045.wav" right
|
||||
[ 9, 11 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T195_P045.wav" left
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T195_P045.wav" right
|
||||
[ 9, 12 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T180_P045.wav" left
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T180_P045.wav" right
|
||||
[ 9, 13 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T165_P045.wav" left
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T165_P045.wav" right
|
||||
[ 9, 14 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T150_P045.wav" left
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T150_P045.wav" right
|
||||
[ 9, 15 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T135_P045.wav" left
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T135_P045.wav" right
|
||||
[ 9, 16 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T120_P045.wav" left
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T120_P045.wav" right
|
||||
[ 9, 17 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T105_P045.wav" left
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T105_P045.wav" right
|
||||
[ 9, 18 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T090_P045.wav" left
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T090_P045.wav" right
|
||||
[ 9, 19 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T075_P045.wav" left
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T075_P045.wav" right
|
||||
[ 9, 20 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T060_P045.wav" left
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T060_P045.wav" right
|
||||
[ 9, 21 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T045_P045.wav" left
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T045_P045.wav" right
|
||||
[ 9, 22 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T030_P045.wav" left
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T030_P045.wav" right
|
||||
[ 9, 23 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T015_P045.wav" left
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T015_P045.wav" right
|
||||
|
||||
[ 10, 0 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T000_P060.wav" left
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T000_P060.wav" right
|
||||
[ 10, 1 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T330_P060.wav" left
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T330_P060.wav" right
|
||||
[ 10, 2 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T300_P060.wav" left
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T300_P060.wav" right
|
||||
[ 10, 3 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T270_P060.wav" left
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T270_P060.wav" right
|
||||
[ 10, 4 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T240_P060.wav" left
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T240_P060.wav" right
|
||||
[ 10, 5 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T210_P060.wav" left
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T210_P060.wav" right
|
||||
[ 10, 6 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T180_P060.wav" left
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T180_P060.wav" right
|
||||
[ 10, 7 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T150_P060.wav" left
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T150_P060.wav" right
|
||||
[ 10, 8 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T120_P060.wav" left
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T120_P060.wav" right
|
||||
[ 10, 9 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T090_P060.wav" left
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T090_P060.wav" right
|
||||
[ 10, 10 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T060_P060.wav" left
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T060_P060.wav" right
|
||||
[ 10, 11 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T030_P060.wav" left
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T030_P060.wav" right
|
||||
|
||||
[ 11, 0 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T000_P075.wav" left
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T000_P075.wav" right
|
||||
[ 11, 1 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T300_P075.wav" left
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T300_P075.wav" right
|
||||
[ 11, 2 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T240_P075.wav" left
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T240_P075.wav" right
|
||||
[ 11, 3 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T180_P075.wav" left
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T180_P075.wav" right
|
||||
[ 11, 4 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T120_P075.wav" left
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T120_P075.wav" right
|
||||
[ 11, 5 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T060_P075.wav" left
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T060_P075.wav" right
|
||||
|
||||
[ 12, 0 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T000_P090.wav" left
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T000_P090.wav" right
|
||||
|
||||
844
externals/openal-soft/utils/MIT_KEMAR.def
vendored
Normal file
844
externals/openal-soft/utils/MIT_KEMAR.def
vendored
Normal file
@@ -0,0 +1,844 @@
|
||||
# This is a makemhr HRIR definition file. It is used to define the layout and
|
||||
# source data to be processed into an OpenAL Soft compatible HRTF.
|
||||
#
|
||||
# This definition is used to transform the left ear HRIRs from the full set
|
||||
# of KEMAR HRIRs provided by Bill Gardner <billg@media.mit.edu> and Keith
|
||||
# Martin <kdm@media.mit.edu> of MIT Media Laboratory.
|
||||
#
|
||||
# The data (full.zip) is available from:
|
||||
#
|
||||
# http://sound.media.mit.edu/resources/KEMAR.html
|
||||
#
|
||||
# It is copyrighted 1994 by MIT Media Laboratory, and provided free of charge
|
||||
# with no restrictions on use so long as the authors (above) are cited.
|
||||
#
|
||||
# This definition is used to generate the default HRTF table used by OpenAL
|
||||
# Soft.
|
||||
|
||||
# The following are the data set metrics. They must always be specified at
|
||||
# the start of a definition file, but their order is not important.
|
||||
|
||||
# Sampling rate of the HRIR data (in hertz).
|
||||
rate = 44100
|
||||
|
||||
# The channel type of incoming HRIR data (mono or stereo). Mono channel
|
||||
# inputs will result in mirroring to provide the right ear HRIRs. If not
|
||||
# specified, this defaults to mono.
|
||||
type = mono
|
||||
|
||||
# The number of points to use from the HRIR data. This should be a
|
||||
# sufficiently large value (to encompass the entire impulse response). It
|
||||
# cannot be smaller than the truncation size (default is 32) specified on the
|
||||
# command line.
|
||||
points = 512
|
||||
|
||||
# The radius of the listener's head (measured ear-to-ear in meters). The
|
||||
# makemhr utility uses this value to rescale measured propagation delays when
|
||||
# a custom head radius is specified on the command line. It is also used as
|
||||
# the default radius when the spherical model is used to calculate an
|
||||
# approximate set of delays. This should match the data set as close as
|
||||
# possible for accurate rescaling when using the measured delays (the
|
||||
# default). At the moment, radius rescaling does not adjust HRIR coupling.
|
||||
radius = 0.09
|
||||
|
||||
# A list of the distances between the source and the listener (in meters) for
|
||||
# each field. These must start at or above the head radius and proceed in
|
||||
# ascending order. Since the MIT set is single-field, there is only one
|
||||
# distance.
|
||||
distance = 1.4
|
||||
|
||||
# A list of the number of azimuths measured for each elevation per field.
|
||||
# Elevations are separated by commas (,) while fields are separated by
|
||||
# semicolons (;). There must be at least 5 elevations covering 180 degrees
|
||||
# degrees of elevation for the data set to be viable. The poles (first and
|
||||
# last elevation) must be singular (an azimuth count of 1).
|
||||
azimuths = 1, 12, 24, 36, 45, 56, 60, 72, 72, 72, 72, 72, 60, 56, 45, 36, 24, 12, 1
|
||||
|
||||
# Following the metrics is the list of source HRIRs for each field,
|
||||
# elevation, and azimuth triplet. They don't have to be specified in order,
|
||||
# but the final composition must not be sparse. They can however begin above
|
||||
# a number of elevations (as typical for HRIR measurements).
|
||||
#
|
||||
# The field index is used to determine the distance coordinate (for mult-
|
||||
# field HRTFs) while the elevation and azimuth indices are used to determine
|
||||
# the resulting polar coordinates following OpenAL Soft's convention (-90
|
||||
# degree elevation increasing counter-clockwise from the bottom; 0 degree
|
||||
# azimuth increasing clockwise from the front).
|
||||
#
|
||||
# More than one HRIR can be used per source. This allows the composition of
|
||||
# averaged magnitude responses or the specification of stereo HRTFs. Target
|
||||
# ears must (and can only be) specified for each source when the type metric
|
||||
# is set to 'stereo'.
|
||||
#
|
||||
# Source specification is of the form (~BNF):
|
||||
#
|
||||
# source = ( sf_index | mf_index ) source_ref [ '+' source_ref ]*
|
||||
#
|
||||
# sf_index = '[' ev_index ',' az_index ']' '='
|
||||
# mf_index = '[' fd_index ',' ev_index ',' az_index ']' '='
|
||||
# source_ref = mono_ref | stereo_ref
|
||||
#
|
||||
# fd_index = unsigned_integer
|
||||
# ev_index = unsigned_integer
|
||||
# az_index = unsigned_integer
|
||||
# mono_ref = ref_spec ':' filename
|
||||
# stereo_ref = ref_spec ':' filename ear
|
||||
#
|
||||
# ref_spec = ( wave_fmt '(' wave_parms ')' [ '@' start_sample ] ) |
|
||||
# ( bin_fmt '(' bini_parms ')' [ '@' start_byte ] ) |
|
||||
# ( bin_fmt '(' binf_parms ')' [ '@' start_byte ] ) |
|
||||
# ( ascii_fmt '(' asci_parms ')' [ '@' start_element ] ) |
|
||||
# ( ascii_fmt '(' ascf_parms ')' [ '@' start_element ] )
|
||||
# filename = double_quoted_string
|
||||
# ear = 'left' | 'right'
|
||||
#
|
||||
# wave_fmt = 'wave'
|
||||
# wave_parms = channel
|
||||
# bin_fmt = 'bin_le' | 'bin_be'
|
||||
# bini_parms = 'int' ',' byte_size [ ',' bin_sig_bits ] [ ';' skip_bytes ]
|
||||
# binf_parms = 'fp' ',' byte_size [ ';' skip_bytes ]
|
||||
# ascii_fmt = 'ascii'
|
||||
# asci_parms = 'int' ',' sig_bits [ ';' skip_elements ]
|
||||
# ascf_parms = 'fp' [ ';' skip_elements ]
|
||||
# start_sample = unsigned_integer
|
||||
# start_byte = unsigned_integer
|
||||
# start_element = unsigned_integer
|
||||
#
|
||||
# channel = unsigned_integer
|
||||
# byte_size = unsigned_integer
|
||||
# bin_sig_bits = signed_integer
|
||||
# skip_bytes = unsigned_integer
|
||||
# sig_bits = unsigned_integer
|
||||
# skip_elements = unsigned_integer
|
||||
#
|
||||
# For bin_sig_bits, positive values mean the significant bits start at the
|
||||
# MSB (padding toward the LSB) while negative values mean they start at the
|
||||
# LSB.
|
||||
|
||||
# Even though the MIT set is provided as stereo .wav files, each channel is
|
||||
# for a different sized KEMAR ear. Since it is not a stereo data set, no ear
|
||||
# is specified. The smaller KEMAR ear (in the left channel: 0) is used.
|
||||
[ 5, 0 ] = wave (0) : "./MITfull/elev-40/L-40e000a.wav"
|
||||
[ 5, 1 ] = wave (0) : "./MITfull/elev-40/L-40e006a.wav"
|
||||
[ 5, 2 ] = wave (0) : "./MITfull/elev-40/L-40e013a.wav"
|
||||
[ 5, 3 ] = wave (0) : "./MITfull/elev-40/L-40e019a.wav"
|
||||
[ 5, 4 ] = wave (0) : "./MITfull/elev-40/L-40e026a.wav"
|
||||
[ 5, 5 ] = wave (0) : "./MITfull/elev-40/L-40e032a.wav"
|
||||
[ 5, 6 ] = wave (0) : "./MITfull/elev-40/L-40e039a.wav"
|
||||
[ 5, 7 ] = wave (0) : "./MITfull/elev-40/L-40e045a.wav"
|
||||
[ 5, 8 ] = wave (0) : "./MITfull/elev-40/L-40e051a.wav"
|
||||
[ 5, 9 ] = wave (0) : "./MITfull/elev-40/L-40e058a.wav"
|
||||
[ 5, 10 ] = wave (0) : "./MITfull/elev-40/L-40e064a.wav"
|
||||
[ 5, 11 ] = wave (0) : "./MITfull/elev-40/L-40e071a.wav"
|
||||
[ 5, 12 ] = wave (0) : "./MITfull/elev-40/L-40e077a.wav"
|
||||
[ 5, 13 ] = wave (0) : "./MITfull/elev-40/L-40e084a.wav"
|
||||
[ 5, 14 ] = wave (0) : "./MITfull/elev-40/L-40e090a.wav"
|
||||
[ 5, 15 ] = wave (0) : "./MITfull/elev-40/L-40e096a.wav"
|
||||
[ 5, 16 ] = wave (0) : "./MITfull/elev-40/L-40e103a.wav"
|
||||
[ 5, 17 ] = wave (0) : "./MITfull/elev-40/L-40e109a.wav"
|
||||
[ 5, 18 ] = wave (0) : "./MITfull/elev-40/L-40e116a.wav"
|
||||
[ 5, 19 ] = wave (0) : "./MITfull/elev-40/L-40e122a.wav"
|
||||
[ 5, 20 ] = wave (0) : "./MITfull/elev-40/L-40e129a.wav"
|
||||
[ 5, 21 ] = wave (0) : "./MITfull/elev-40/L-40e135a.wav"
|
||||
[ 5, 22 ] = wave (0) : "./MITfull/elev-40/L-40e141a.wav"
|
||||
[ 5, 23 ] = wave (0) : "./MITfull/elev-40/L-40e148a.wav"
|
||||
[ 5, 24 ] = wave (0) : "./MITfull/elev-40/L-40e154a.wav"
|
||||
[ 5, 25 ] = wave (0) : "./MITfull/elev-40/L-40e161a.wav"
|
||||
[ 5, 26 ] = wave (0) : "./MITfull/elev-40/L-40e167a.wav"
|
||||
[ 5, 27 ] = wave (0) : "./MITfull/elev-40/L-40e174a.wav"
|
||||
[ 5, 28 ] = wave (0) : "./MITfull/elev-40/L-40e180a.wav"
|
||||
[ 5, 29 ] = wave (0) : "./MITfull/elev-40/L-40e186a.wav"
|
||||
[ 5, 30 ] = wave (0) : "./MITfull/elev-40/L-40e193a.wav"
|
||||
[ 5, 31 ] = wave (0) : "./MITfull/elev-40/L-40e199a.wav"
|
||||
[ 5, 32 ] = wave (0) : "./MITfull/elev-40/L-40e206a.wav"
|
||||
[ 5, 33 ] = wave (0) : "./MITfull/elev-40/L-40e212a.wav"
|
||||
[ 5, 34 ] = wave (0) : "./MITfull/elev-40/L-40e219a.wav"
|
||||
[ 5, 35 ] = wave (0) : "./MITfull/elev-40/L-40e225a.wav"
|
||||
[ 5, 36 ] = wave (0) : "./MITfull/elev-40/L-40e231a.wav"
|
||||
[ 5, 37 ] = wave (0) : "./MITfull/elev-40/L-40e238a.wav"
|
||||
[ 5, 38 ] = wave (0) : "./MITfull/elev-40/L-40e244a.wav"
|
||||
[ 5, 39 ] = wave (0) : "./MITfull/elev-40/L-40e251a.wav"
|
||||
[ 5, 40 ] = wave (0) : "./MITfull/elev-40/L-40e257a.wav"
|
||||
[ 5, 41 ] = wave (0) : "./MITfull/elev-40/L-40e264a.wav"
|
||||
[ 5, 42 ] = wave (0) : "./MITfull/elev-40/L-40e270a.wav"
|
||||
[ 5, 43 ] = wave (0) : "./MITfull/elev-40/L-40e276a.wav"
|
||||
[ 5, 44 ] = wave (0) : "./MITfull/elev-40/L-40e283a.wav"
|
||||
[ 5, 45 ] = wave (0) : "./MITfull/elev-40/L-40e289a.wav"
|
||||
[ 5, 46 ] = wave (0) : "./MITfull/elev-40/L-40e296a.wav"
|
||||
[ 5, 47 ] = wave (0) : "./MITfull/elev-40/L-40e302a.wav"
|
||||
[ 5, 48 ] = wave (0) : "./MITfull/elev-40/L-40e309a.wav"
|
||||
[ 5, 49 ] = wave (0) : "./MITfull/elev-40/L-40e315a.wav"
|
||||
[ 5, 50 ] = wave (0) : "./MITfull/elev-40/L-40e321a.wav"
|
||||
[ 5, 51 ] = wave (0) : "./MITfull/elev-40/L-40e328a.wav"
|
||||
[ 5, 52 ] = wave (0) : "./MITfull/elev-40/L-40e334a.wav"
|
||||
[ 5, 53 ] = wave (0) : "./MITfull/elev-40/L-40e341a.wav"
|
||||
[ 5, 54 ] = wave (0) : "./MITfull/elev-40/L-40e347a.wav"
|
||||
[ 5, 55 ] = wave (0) : "./MITfull/elev-40/L-40e354a.wav"
|
||||
|
||||
[ 6, 0 ] = wave (0) : "./MITfull/elev-30/L-30e000a.wav"
|
||||
[ 6, 1 ] = wave (0) : "./MITfull/elev-30/L-30e006a.wav"
|
||||
[ 6, 2 ] = wave (0) : "./MITfull/elev-30/L-30e012a.wav"
|
||||
[ 6, 3 ] = wave (0) : "./MITfull/elev-30/L-30e018a.wav"
|
||||
[ 6, 4 ] = wave (0) : "./MITfull/elev-30/L-30e024a.wav"
|
||||
[ 6, 5 ] = wave (0) : "./MITfull/elev-30/L-30e030a.wav"
|
||||
[ 6, 6 ] = wave (0) : "./MITfull/elev-30/L-30e036a.wav"
|
||||
[ 6, 7 ] = wave (0) : "./MITfull/elev-30/L-30e042a.wav"
|
||||
[ 6, 8 ] = wave (0) : "./MITfull/elev-30/L-30e048a.wav"
|
||||
[ 6, 9 ] = wave (0) : "./MITfull/elev-30/L-30e054a.wav"
|
||||
[ 6, 10 ] = wave (0) : "./MITfull/elev-30/L-30e060a.wav"
|
||||
[ 6, 11 ] = wave (0) : "./MITfull/elev-30/L-30e066a.wav"
|
||||
[ 6, 12 ] = wave (0) : "./MITfull/elev-30/L-30e072a.wav"
|
||||
[ 6, 13 ] = wave (0) : "./MITfull/elev-30/L-30e078a.wav"
|
||||
[ 6, 14 ] = wave (0) : "./MITfull/elev-30/L-30e084a.wav"
|
||||
[ 6, 15 ] = wave (0) : "./MITfull/elev-30/L-30e090a.wav"
|
||||
[ 6, 16 ] = wave (0) : "./MITfull/elev-30/L-30e096a.wav"
|
||||
[ 6, 17 ] = wave (0) : "./MITfull/elev-30/L-30e102a.wav"
|
||||
[ 6, 18 ] = wave (0) : "./MITfull/elev-30/L-30e108a.wav"
|
||||
[ 6, 19 ] = wave (0) : "./MITfull/elev-30/L-30e114a.wav"
|
||||
[ 6, 20 ] = wave (0) : "./MITfull/elev-30/L-30e120a.wav"
|
||||
[ 6, 21 ] = wave (0) : "./MITfull/elev-30/L-30e126a.wav"
|
||||
[ 6, 22 ] = wave (0) : "./MITfull/elev-30/L-30e132a.wav"
|
||||
[ 6, 23 ] = wave (0) : "./MITfull/elev-30/L-30e138a.wav"
|
||||
[ 6, 24 ] = wave (0) : "./MITfull/elev-30/L-30e144a.wav"
|
||||
[ 6, 25 ] = wave (0) : "./MITfull/elev-30/L-30e150a.wav"
|
||||
[ 6, 26 ] = wave (0) : "./MITfull/elev-30/L-30e156a.wav"
|
||||
[ 6, 27 ] = wave (0) : "./MITfull/elev-30/L-30e162a.wav"
|
||||
[ 6, 28 ] = wave (0) : "./MITfull/elev-30/L-30e168a.wav"
|
||||
[ 6, 29 ] = wave (0) : "./MITfull/elev-30/L-30e174a.wav"
|
||||
[ 6, 30 ] = wave (0) : "./MITfull/elev-30/L-30e180a.wav"
|
||||
[ 6, 31 ] = wave (0) : "./MITfull/elev-30/L-30e186a.wav"
|
||||
[ 6, 32 ] = wave (0) : "./MITfull/elev-30/L-30e192a.wav"
|
||||
[ 6, 33 ] = wave (0) : "./MITfull/elev-30/L-30e198a.wav"
|
||||
[ 6, 34 ] = wave (0) : "./MITfull/elev-30/L-30e204a.wav"
|
||||
[ 6, 35 ] = wave (0) : "./MITfull/elev-30/L-30e210a.wav"
|
||||
[ 6, 36 ] = wave (0) : "./MITfull/elev-30/L-30e216a.wav"
|
||||
[ 6, 37 ] = wave (0) : "./MITfull/elev-30/L-30e222a.wav"
|
||||
[ 6, 38 ] = wave (0) : "./MITfull/elev-30/L-30e228a.wav"
|
||||
[ 6, 39 ] = wave (0) : "./MITfull/elev-30/L-30e234a.wav"
|
||||
[ 6, 40 ] = wave (0) : "./MITfull/elev-30/L-30e240a.wav"
|
||||
[ 6, 41 ] = wave (0) : "./MITfull/elev-30/L-30e246a.wav"
|
||||
[ 6, 42 ] = wave (0) : "./MITfull/elev-30/L-30e252a.wav"
|
||||
[ 6, 43 ] = wave (0) : "./MITfull/elev-30/L-30e258a.wav"
|
||||
[ 6, 44 ] = wave (0) : "./MITfull/elev-30/L-30e264a.wav"
|
||||
[ 6, 45 ] = wave (0) : "./MITfull/elev-30/L-30e270a.wav"
|
||||
[ 6, 46 ] = wave (0) : "./MITfull/elev-30/L-30e276a.wav"
|
||||
[ 6, 47 ] = wave (0) : "./MITfull/elev-30/L-30e282a.wav"
|
||||
[ 6, 48 ] = wave (0) : "./MITfull/elev-30/L-30e288a.wav"
|
||||
[ 6, 49 ] = wave (0) : "./MITfull/elev-30/L-30e294a.wav"
|
||||
[ 6, 50 ] = wave (0) : "./MITfull/elev-30/L-30e300a.wav"
|
||||
[ 6, 51 ] = wave (0) : "./MITfull/elev-30/L-30e306a.wav"
|
||||
[ 6, 52 ] = wave (0) : "./MITfull/elev-30/L-30e312a.wav"
|
||||
[ 6, 53 ] = wave (0) : "./MITfull/elev-30/L-30e318a.wav"
|
||||
[ 6, 54 ] = wave (0) : "./MITfull/elev-30/L-30e324a.wav"
|
||||
[ 6, 55 ] = wave (0) : "./MITfull/elev-30/L-30e330a.wav"
|
||||
[ 6, 56 ] = wave (0) : "./MITfull/elev-30/L-30e336a.wav"
|
||||
[ 6, 57 ] = wave (0) : "./MITfull/elev-30/L-30e342a.wav"
|
||||
[ 6, 58 ] = wave (0) : "./MITfull/elev-30/L-30e348a.wav"
|
||||
[ 6, 59 ] = wave (0) : "./MITfull/elev-30/L-30e354a.wav"
|
||||
|
||||
[ 7, 0 ] = wave (0) : "./MITfull/elev-20/L-20e000a.wav"
|
||||
[ 7, 1 ] = wave (0) : "./MITfull/elev-20/L-20e005a.wav"
|
||||
[ 7, 2 ] = wave (0) : "./MITfull/elev-20/L-20e010a.wav"
|
||||
[ 7, 3 ] = wave (0) : "./MITfull/elev-20/L-20e015a.wav"
|
||||
[ 7, 4 ] = wave (0) : "./MITfull/elev-20/L-20e020a.wav"
|
||||
[ 7, 5 ] = wave (0) : "./MITfull/elev-20/L-20e025a.wav"
|
||||
[ 7, 6 ] = wave (0) : "./MITfull/elev-20/L-20e030a.wav"
|
||||
[ 7, 7 ] = wave (0) : "./MITfull/elev-20/L-20e035a.wav"
|
||||
[ 7, 8 ] = wave (0) : "./MITfull/elev-20/L-20e040a.wav"
|
||||
[ 7, 9 ] = wave (0) : "./MITfull/elev-20/L-20e045a.wav"
|
||||
[ 7, 10 ] = wave (0) : "./MITfull/elev-20/L-20e050a.wav"
|
||||
[ 7, 11 ] = wave (0) : "./MITfull/elev-20/L-20e055a.wav"
|
||||
[ 7, 12 ] = wave (0) : "./MITfull/elev-20/L-20e060a.wav"
|
||||
[ 7, 13 ] = wave (0) : "./MITfull/elev-20/L-20e065a.wav"
|
||||
[ 7, 14 ] = wave (0) : "./MITfull/elev-20/L-20e070a.wav"
|
||||
[ 7, 15 ] = wave (0) : "./MITfull/elev-20/L-20e075a.wav"
|
||||
[ 7, 16 ] = wave (0) : "./MITfull/elev-20/L-20e080a.wav"
|
||||
[ 7, 17 ] = wave (0) : "./MITfull/elev-20/L-20e085a.wav"
|
||||
[ 7, 18 ] = wave (0) : "./MITfull/elev-20/L-20e090a.wav"
|
||||
[ 7, 19 ] = wave (0) : "./MITfull/elev-20/L-20e095a.wav"
|
||||
[ 7, 20 ] = wave (0) : "./MITfull/elev-20/L-20e100a.wav"
|
||||
[ 7, 21 ] = wave (0) : "./MITfull/elev-20/L-20e105a.wav"
|
||||
[ 7, 22 ] = wave (0) : "./MITfull/elev-20/L-20e110a.wav"
|
||||
[ 7, 23 ] = wave (0) : "./MITfull/elev-20/L-20e115a.wav"
|
||||
[ 7, 24 ] = wave (0) : "./MITfull/elev-20/L-20e120a.wav"
|
||||
[ 7, 25 ] = wave (0) : "./MITfull/elev-20/L-20e125a.wav"
|
||||
[ 7, 26 ] = wave (0) : "./MITfull/elev-20/L-20e130a.wav"
|
||||
[ 7, 27 ] = wave (0) : "./MITfull/elev-20/L-20e135a.wav"
|
||||
[ 7, 28 ] = wave (0) : "./MITfull/elev-20/L-20e140a.wav"
|
||||
[ 7, 29 ] = wave (0) : "./MITfull/elev-20/L-20e145a.wav"
|
||||
[ 7, 30 ] = wave (0) : "./MITfull/elev-20/L-20e150a.wav"
|
||||
[ 7, 31 ] = wave (0) : "./MITfull/elev-20/L-20e155a.wav"
|
||||
[ 7, 32 ] = wave (0) : "./MITfull/elev-20/L-20e160a.wav"
|
||||
[ 7, 33 ] = wave (0) : "./MITfull/elev-20/L-20e165a.wav"
|
||||
[ 7, 34 ] = wave (0) : "./MITfull/elev-20/L-20e170a.wav"
|
||||
[ 7, 35 ] = wave (0) : "./MITfull/elev-20/L-20e175a.wav"
|
||||
[ 7, 36 ] = wave (0) : "./MITfull/elev-20/L-20e180a.wav"
|
||||
[ 7, 37 ] = wave (0) : "./MITfull/elev-20/L-20e185a.wav"
|
||||
[ 7, 38 ] = wave (0) : "./MITfull/elev-20/L-20e190a.wav"
|
||||
[ 7, 39 ] = wave (0) : "./MITfull/elev-20/L-20e195a.wav"
|
||||
[ 7, 40 ] = wave (0) : "./MITfull/elev-20/L-20e200a.wav"
|
||||
[ 7, 41 ] = wave (0) : "./MITfull/elev-20/L-20e205a.wav"
|
||||
[ 7, 42 ] = wave (0) : "./MITfull/elev-20/L-20e210a.wav"
|
||||
[ 7, 43 ] = wave (0) : "./MITfull/elev-20/L-20e215a.wav"
|
||||
[ 7, 44 ] = wave (0) : "./MITfull/elev-20/L-20e220a.wav"
|
||||
[ 7, 45 ] = wave (0) : "./MITfull/elev-20/L-20e225a.wav"
|
||||
[ 7, 46 ] = wave (0) : "./MITfull/elev-20/L-20e230a.wav"
|
||||
[ 7, 47 ] = wave (0) : "./MITfull/elev-20/L-20e235a.wav"
|
||||
[ 7, 48 ] = wave (0) : "./MITfull/elev-20/L-20e240a.wav"
|
||||
[ 7, 49 ] = wave (0) : "./MITfull/elev-20/L-20e245a.wav"
|
||||
[ 7, 50 ] = wave (0) : "./MITfull/elev-20/L-20e250a.wav"
|
||||
[ 7, 51 ] = wave (0) : "./MITfull/elev-20/L-20e255a.wav"
|
||||
[ 7, 52 ] = wave (0) : "./MITfull/elev-20/L-20e260a.wav"
|
||||
[ 7, 53 ] = wave (0) : "./MITfull/elev-20/L-20e265a.wav"
|
||||
[ 7, 54 ] = wave (0) : "./MITfull/elev-20/L-20e270a.wav"
|
||||
[ 7, 55 ] = wave (0) : "./MITfull/elev-20/L-20e275a.wav"
|
||||
[ 7, 56 ] = wave (0) : "./MITfull/elev-20/L-20e280a.wav"
|
||||
[ 7, 57 ] = wave (0) : "./MITfull/elev-20/L-20e285a.wav"
|
||||
[ 7, 58 ] = wave (0) : "./MITfull/elev-20/L-20e290a.wav"
|
||||
[ 7, 59 ] = wave (0) : "./MITfull/elev-20/L-20e295a.wav"
|
||||
[ 7, 60 ] = wave (0) : "./MITfull/elev-20/L-20e300a.wav"
|
||||
[ 7, 61 ] = wave (0) : "./MITfull/elev-20/L-20e305a.wav"
|
||||
[ 7, 62 ] = wave (0) : "./MITfull/elev-20/L-20e310a.wav"
|
||||
[ 7, 63 ] = wave (0) : "./MITfull/elev-20/L-20e315a.wav"
|
||||
[ 7, 64 ] = wave (0) : "./MITfull/elev-20/L-20e320a.wav"
|
||||
[ 7, 65 ] = wave (0) : "./MITfull/elev-20/L-20e325a.wav"
|
||||
[ 7, 66 ] = wave (0) : "./MITfull/elev-20/L-20e330a.wav"
|
||||
[ 7, 67 ] = wave (0) : "./MITfull/elev-20/L-20e335a.wav"
|
||||
[ 7, 68 ] = wave (0) : "./MITfull/elev-20/L-20e340a.wav"
|
||||
[ 7, 69 ] = wave (0) : "./MITfull/elev-20/L-20e345a.wav"
|
||||
[ 7, 70 ] = wave (0) : "./MITfull/elev-20/L-20e350a.wav"
|
||||
[ 7, 71 ] = wave (0) : "./MITfull/elev-20/L-20e355a.wav"
|
||||
|
||||
[ 8, 0 ] = wave (0) : "./MITfull/elev-10/L-10e000a.wav"
|
||||
[ 8, 1 ] = wave (0) : "./MITfull/elev-10/L-10e005a.wav"
|
||||
[ 8, 2 ] = wave (0) : "./MITfull/elev-10/L-10e010a.wav"
|
||||
[ 8, 3 ] = wave (0) : "./MITfull/elev-10/L-10e015a.wav"
|
||||
[ 8, 4 ] = wave (0) : "./MITfull/elev-10/L-10e020a.wav"
|
||||
[ 8, 5 ] = wave (0) : "./MITfull/elev-10/L-10e025a.wav"
|
||||
[ 8, 6 ] = wave (0) : "./MITfull/elev-10/L-10e030a.wav"
|
||||
[ 8, 7 ] = wave (0) : "./MITfull/elev-10/L-10e035a.wav"
|
||||
[ 8, 8 ] = wave (0) : "./MITfull/elev-10/L-10e040a.wav"
|
||||
[ 8, 9 ] = wave (0) : "./MITfull/elev-10/L-10e045a.wav"
|
||||
[ 8, 10 ] = wave (0) : "./MITfull/elev-10/L-10e050a.wav"
|
||||
[ 8, 11 ] = wave (0) : "./MITfull/elev-10/L-10e055a.wav"
|
||||
[ 8, 12 ] = wave (0) : "./MITfull/elev-10/L-10e060a.wav"
|
||||
[ 8, 13 ] = wave (0) : "./MITfull/elev-10/L-10e065a.wav"
|
||||
[ 8, 14 ] = wave (0) : "./MITfull/elev-10/L-10e070a.wav"
|
||||
[ 8, 15 ] = wave (0) : "./MITfull/elev-10/L-10e075a.wav"
|
||||
[ 8, 16 ] = wave (0) : "./MITfull/elev-10/L-10e080a.wav"
|
||||
[ 8, 17 ] = wave (0) : "./MITfull/elev-10/L-10e085a.wav"
|
||||
[ 8, 18 ] = wave (0) : "./MITfull/elev-10/L-10e090a.wav"
|
||||
[ 8, 19 ] = wave (0) : "./MITfull/elev-10/L-10e095a.wav"
|
||||
[ 8, 20 ] = wave (0) : "./MITfull/elev-10/L-10e100a.wav"
|
||||
[ 8, 21 ] = wave (0) : "./MITfull/elev-10/L-10e105a.wav"
|
||||
[ 8, 22 ] = wave (0) : "./MITfull/elev-10/L-10e110a.wav"
|
||||
[ 8, 23 ] = wave (0) : "./MITfull/elev-10/L-10e115a.wav"
|
||||
[ 8, 24 ] = wave (0) : "./MITfull/elev-10/L-10e120a.wav"
|
||||
[ 8, 25 ] = wave (0) : "./MITfull/elev-10/L-10e125a.wav"
|
||||
[ 8, 26 ] = wave (0) : "./MITfull/elev-10/L-10e130a.wav"
|
||||
[ 8, 27 ] = wave (0) : "./MITfull/elev-10/L-10e135a.wav"
|
||||
[ 8, 28 ] = wave (0) : "./MITfull/elev-10/L-10e140a.wav"
|
||||
[ 8, 29 ] = wave (0) : "./MITfull/elev-10/L-10e145a.wav"
|
||||
[ 8, 30 ] = wave (0) : "./MITfull/elev-10/L-10e150a.wav"
|
||||
[ 8, 31 ] = wave (0) : "./MITfull/elev-10/L-10e155a.wav"
|
||||
[ 8, 32 ] = wave (0) : "./MITfull/elev-10/L-10e160a.wav"
|
||||
[ 8, 33 ] = wave (0) : "./MITfull/elev-10/L-10e165a.wav"
|
||||
[ 8, 34 ] = wave (0) : "./MITfull/elev-10/L-10e170a.wav"
|
||||
[ 8, 35 ] = wave (0) : "./MITfull/elev-10/L-10e175a.wav"
|
||||
[ 8, 36 ] = wave (0) : "./MITfull/elev-10/L-10e180a.wav"
|
||||
[ 8, 37 ] = wave (0) : "./MITfull/elev-10/L-10e185a.wav"
|
||||
[ 8, 38 ] = wave (0) : "./MITfull/elev-10/L-10e190a.wav"
|
||||
[ 8, 39 ] = wave (0) : "./MITfull/elev-10/L-10e195a.wav"
|
||||
[ 8, 40 ] = wave (0) : "./MITfull/elev-10/L-10e200a.wav"
|
||||
[ 8, 41 ] = wave (0) : "./MITfull/elev-10/L-10e205a.wav"
|
||||
[ 8, 42 ] = wave (0) : "./MITfull/elev-10/L-10e210a.wav"
|
||||
[ 8, 43 ] = wave (0) : "./MITfull/elev-10/L-10e215a.wav"
|
||||
[ 8, 44 ] = wave (0) : "./MITfull/elev-10/L-10e220a.wav"
|
||||
[ 8, 45 ] = wave (0) : "./MITfull/elev-10/L-10e225a.wav"
|
||||
[ 8, 46 ] = wave (0) : "./MITfull/elev-10/L-10e230a.wav"
|
||||
[ 8, 47 ] = wave (0) : "./MITfull/elev-10/L-10e235a.wav"
|
||||
[ 8, 48 ] = wave (0) : "./MITfull/elev-10/L-10e240a.wav"
|
||||
[ 8, 49 ] = wave (0) : "./MITfull/elev-10/L-10e245a.wav"
|
||||
[ 8, 50 ] = wave (0) : "./MITfull/elev-10/L-10e250a.wav"
|
||||
[ 8, 51 ] = wave (0) : "./MITfull/elev-10/L-10e255a.wav"
|
||||
[ 8, 52 ] = wave (0) : "./MITfull/elev-10/L-10e260a.wav"
|
||||
[ 8, 53 ] = wave (0) : "./MITfull/elev-10/L-10e265a.wav"
|
||||
[ 8, 54 ] = wave (0) : "./MITfull/elev-10/L-10e270a.wav"
|
||||
[ 8, 55 ] = wave (0) : "./MITfull/elev-10/L-10e275a.wav"
|
||||
[ 8, 56 ] = wave (0) : "./MITfull/elev-10/L-10e280a.wav"
|
||||
[ 8, 57 ] = wave (0) : "./MITfull/elev-10/L-10e285a.wav"
|
||||
[ 8, 58 ] = wave (0) : "./MITfull/elev-10/L-10e290a.wav"
|
||||
[ 8, 59 ] = wave (0) : "./MITfull/elev-10/L-10e295a.wav"
|
||||
[ 8, 60 ] = wave (0) : "./MITfull/elev-10/L-10e300a.wav"
|
||||
[ 8, 61 ] = wave (0) : "./MITfull/elev-10/L-10e305a.wav"
|
||||
[ 8, 62 ] = wave (0) : "./MITfull/elev-10/L-10e310a.wav"
|
||||
[ 8, 63 ] = wave (0) : "./MITfull/elev-10/L-10e315a.wav"
|
||||
[ 8, 64 ] = wave (0) : "./MITfull/elev-10/L-10e320a.wav"
|
||||
[ 8, 65 ] = wave (0) : "./MITfull/elev-10/L-10e325a.wav"
|
||||
[ 8, 66 ] = wave (0) : "./MITfull/elev-10/L-10e330a.wav"
|
||||
[ 8, 67 ] = wave (0) : "./MITfull/elev-10/L-10e335a.wav"
|
||||
[ 8, 68 ] = wave (0) : "./MITfull/elev-10/L-10e340a.wav"
|
||||
[ 8, 69 ] = wave (0) : "./MITfull/elev-10/L-10e345a.wav"
|
||||
[ 8, 70 ] = wave (0) : "./MITfull/elev-10/L-10e350a.wav"
|
||||
[ 8, 71 ] = wave (0) : "./MITfull/elev-10/L-10e355a.wav"
|
||||
|
||||
[ 9, 0 ] = wave (0) : "./MITfull/elev0/L0e000a.wav"
|
||||
[ 9, 1 ] = wave (0) : "./MITfull/elev0/L0e005a.wav"
|
||||
[ 9, 2 ] = wave (0) : "./MITfull/elev0/L0e010a.wav"
|
||||
[ 9, 3 ] = wave (0) : "./MITfull/elev0/L0e015a.wav"
|
||||
[ 9, 4 ] = wave (0) : "./MITfull/elev0/L0e020a.wav"
|
||||
[ 9, 5 ] = wave (0) : "./MITfull/elev0/L0e025a.wav"
|
||||
[ 9, 6 ] = wave (0) : "./MITfull/elev0/L0e030a.wav"
|
||||
[ 9, 7 ] = wave (0) : "./MITfull/elev0/L0e035a.wav"
|
||||
[ 9, 8 ] = wave (0) : "./MITfull/elev0/L0e040a.wav"
|
||||
[ 9, 9 ] = wave (0) : "./MITfull/elev0/L0e045a.wav"
|
||||
[ 9, 10 ] = wave (0) : "./MITfull/elev0/L0e050a.wav"
|
||||
[ 9, 11 ] = wave (0) : "./MITfull/elev0/L0e055a.wav"
|
||||
[ 9, 12 ] = wave (0) : "./MITfull/elev0/L0e060a.wav"
|
||||
[ 9, 13 ] = wave (0) : "./MITfull/elev0/L0e065a.wav"
|
||||
[ 9, 14 ] = wave (0) : "./MITfull/elev0/L0e070a.wav"
|
||||
[ 9, 15 ] = wave (0) : "./MITfull/elev0/L0e075a.wav"
|
||||
[ 9, 16 ] = wave (0) : "./MITfull/elev0/L0e080a.wav"
|
||||
[ 9, 17 ] = wave (0) : "./MITfull/elev0/L0e085a.wav"
|
||||
[ 9, 18 ] = wave (0) : "./MITfull/elev0/L0e090a.wav"
|
||||
[ 9, 19 ] = wave (0) : "./MITfull/elev0/L0e095a.wav"
|
||||
[ 9, 20 ] = wave (0) : "./MITfull/elev0/L0e100a.wav"
|
||||
[ 9, 21 ] = wave (0) : "./MITfull/elev0/L0e105a.wav"
|
||||
[ 9, 22 ] = wave (0) : "./MITfull/elev0/L0e110a.wav"
|
||||
[ 9, 23 ] = wave (0) : "./MITfull/elev0/L0e115a.wav"
|
||||
[ 9, 24 ] = wave (0) : "./MITfull/elev0/L0e120a.wav"
|
||||
[ 9, 25 ] = wave (0) : "./MITfull/elev0/L0e125a.wav"
|
||||
[ 9, 26 ] = wave (0) : "./MITfull/elev0/L0e130a.wav"
|
||||
[ 9, 27 ] = wave (0) : "./MITfull/elev0/L0e135a.wav"
|
||||
[ 9, 28 ] = wave (0) : "./MITfull/elev0/L0e140a.wav"
|
||||
[ 9, 29 ] = wave (0) : "./MITfull/elev0/L0e145a.wav"
|
||||
[ 9, 30 ] = wave (0) : "./MITfull/elev0/L0e150a.wav"
|
||||
[ 9, 31 ] = wave (0) : "./MITfull/elev0/L0e155a.wav"
|
||||
[ 9, 32 ] = wave (0) : "./MITfull/elev0/L0e160a.wav"
|
||||
[ 9, 33 ] = wave (0) : "./MITfull/elev0/L0e165a.wav"
|
||||
[ 9, 34 ] = wave (0) : "./MITfull/elev0/L0e170a.wav"
|
||||
[ 9, 35 ] = wave (0) : "./MITfull/elev0/L0e175a.wav"
|
||||
[ 9, 36 ] = wave (0) : "./MITfull/elev0/L0e180a.wav"
|
||||
[ 9, 37 ] = wave (0) : "./MITfull/elev0/L0e185a.wav"
|
||||
[ 9, 38 ] = wave (0) : "./MITfull/elev0/L0e190a.wav"
|
||||
[ 9, 39 ] = wave (0) : "./MITfull/elev0/L0e195a.wav"
|
||||
[ 9, 40 ] = wave (0) : "./MITfull/elev0/L0e200a.wav"
|
||||
[ 9, 41 ] = wave (0) : "./MITfull/elev0/L0e205a.wav"
|
||||
[ 9, 42 ] = wave (0) : "./MITfull/elev0/L0e210a.wav"
|
||||
[ 9, 43 ] = wave (0) : "./MITfull/elev0/L0e215a.wav"
|
||||
[ 9, 44 ] = wave (0) : "./MITfull/elev0/L0e220a.wav"
|
||||
[ 9, 45 ] = wave (0) : "./MITfull/elev0/L0e225a.wav"
|
||||
[ 9, 46 ] = wave (0) : "./MITfull/elev0/L0e230a.wav"
|
||||
[ 9, 47 ] = wave (0) : "./MITfull/elev0/L0e235a.wav"
|
||||
[ 9, 48 ] = wave (0) : "./MITfull/elev0/L0e240a.wav"
|
||||
[ 9, 49 ] = wave (0) : "./MITfull/elev0/L0e245a.wav"
|
||||
[ 9, 50 ] = wave (0) : "./MITfull/elev0/L0e250a.wav"
|
||||
[ 9, 51 ] = wave (0) : "./MITfull/elev0/L0e255a.wav"
|
||||
[ 9, 52 ] = wave (0) : "./MITfull/elev0/L0e260a.wav"
|
||||
[ 9, 53 ] = wave (0) : "./MITfull/elev0/L0e265a.wav"
|
||||
[ 9, 54 ] = wave (0) : "./MITfull/elev0/L0e270a.wav"
|
||||
[ 9, 55 ] = wave (0) : "./MITfull/elev0/L0e275a.wav"
|
||||
[ 9, 56 ] = wave (0) : "./MITfull/elev0/L0e280a.wav"
|
||||
[ 9, 57 ] = wave (0) : "./MITfull/elev0/L0e285a.wav"
|
||||
[ 9, 58 ] = wave (0) : "./MITfull/elev0/L0e290a.wav"
|
||||
[ 9, 59 ] = wave (0) : "./MITfull/elev0/L0e295a.wav"
|
||||
[ 9, 60 ] = wave (0) : "./MITfull/elev0/L0e300a.wav"
|
||||
[ 9, 61 ] = wave (0) : "./MITfull/elev0/L0e305a.wav"
|
||||
[ 9, 62 ] = wave (0) : "./MITfull/elev0/L0e310a.wav"
|
||||
[ 9, 63 ] = wave (0) : "./MITfull/elev0/L0e315a.wav"
|
||||
[ 9, 64 ] = wave (0) : "./MITfull/elev0/L0e320a.wav"
|
||||
[ 9, 65 ] = wave (0) : "./MITfull/elev0/L0e325a.wav"
|
||||
[ 9, 66 ] = wave (0) : "./MITfull/elev0/L0e330a.wav"
|
||||
[ 9, 67 ] = wave (0) : "./MITfull/elev0/L0e335a.wav"
|
||||
[ 9, 68 ] = wave (0) : "./MITfull/elev0/L0e340a.wav"
|
||||
[ 9, 69 ] = wave (0) : "./MITfull/elev0/L0e345a.wav"
|
||||
[ 9, 70 ] = wave (0) : "./MITfull/elev0/L0e350a.wav"
|
||||
[ 9, 71 ] = wave (0) : "./MITfull/elev0/L0e355a.wav"
|
||||
|
||||
[ 10, 0 ] = wave (0) : "./MITfull/elev10/L10e000a.wav"
|
||||
[ 10, 1 ] = wave (0) : "./MITfull/elev10/L10e005a.wav"
|
||||
[ 10, 2 ] = wave (0) : "./MITfull/elev10/L10e010a.wav"
|
||||
[ 10, 3 ] = wave (0) : "./MITfull/elev10/L10e015a.wav"
|
||||
[ 10, 4 ] = wave (0) : "./MITfull/elev10/L10e020a.wav"
|
||||
[ 10, 5 ] = wave (0) : "./MITfull/elev10/L10e025a.wav"
|
||||
[ 10, 6 ] = wave (0) : "./MITfull/elev10/L10e030a.wav"
|
||||
[ 10, 7 ] = wave (0) : "./MITfull/elev10/L10e035a.wav"
|
||||
[ 10, 8 ] = wave (0) : "./MITfull/elev10/L10e040a.wav"
|
||||
[ 10, 9 ] = wave (0) : "./MITfull/elev10/L10e045a.wav"
|
||||
[ 10, 10 ] = wave (0) : "./MITfull/elev10/L10e050a.wav"
|
||||
[ 10, 11 ] = wave (0) : "./MITfull/elev10/L10e055a.wav"
|
||||
[ 10, 12 ] = wave (0) : "./MITfull/elev10/L10e060a.wav"
|
||||
[ 10, 13 ] = wave (0) : "./MITfull/elev10/L10e065a.wav"
|
||||
[ 10, 14 ] = wave (0) : "./MITfull/elev10/L10e070a.wav"
|
||||
[ 10, 15 ] = wave (0) : "./MITfull/elev10/L10e075a.wav"
|
||||
[ 10, 16 ] = wave (0) : "./MITfull/elev10/L10e080a.wav"
|
||||
[ 10, 17 ] = wave (0) : "./MITfull/elev10/L10e085a.wav"
|
||||
[ 10, 18 ] = wave (0) : "./MITfull/elev10/L10e090a.wav"
|
||||
[ 10, 19 ] = wave (0) : "./MITfull/elev10/L10e095a.wav"
|
||||
[ 10, 20 ] = wave (0) : "./MITfull/elev10/L10e100a.wav"
|
||||
[ 10, 21 ] = wave (0) : "./MITfull/elev10/L10e105a.wav"
|
||||
[ 10, 22 ] = wave (0) : "./MITfull/elev10/L10e110a.wav"
|
||||
[ 10, 23 ] = wave (0) : "./MITfull/elev10/L10e115a.wav"
|
||||
[ 10, 24 ] = wave (0) : "./MITfull/elev10/L10e120a.wav"
|
||||
[ 10, 25 ] = wave (0) : "./MITfull/elev10/L10e125a.wav"
|
||||
[ 10, 26 ] = wave (0) : "./MITfull/elev10/L10e130a.wav"
|
||||
[ 10, 27 ] = wave (0) : "./MITfull/elev10/L10e135a.wav"
|
||||
[ 10, 28 ] = wave (0) : "./MITfull/elev10/L10e140a.wav"
|
||||
[ 10, 29 ] = wave (0) : "./MITfull/elev10/L10e145a.wav"
|
||||
[ 10, 30 ] = wave (0) : "./MITfull/elev10/L10e150a.wav"
|
||||
[ 10, 31 ] = wave (0) : "./MITfull/elev10/L10e155a.wav"
|
||||
[ 10, 32 ] = wave (0) : "./MITfull/elev10/L10e160a.wav"
|
||||
[ 10, 33 ] = wave (0) : "./MITfull/elev10/L10e165a.wav"
|
||||
[ 10, 34 ] = wave (0) : "./MITfull/elev10/L10e170a.wav"
|
||||
[ 10, 35 ] = wave (0) : "./MITfull/elev10/L10e175a.wav"
|
||||
[ 10, 36 ] = wave (0) : "./MITfull/elev10/L10e180a.wav"
|
||||
[ 10, 37 ] = wave (0) : "./MITfull/elev10/L10e185a.wav"
|
||||
[ 10, 38 ] = wave (0) : "./MITfull/elev10/L10e190a.wav"
|
||||
[ 10, 39 ] = wave (0) : "./MITfull/elev10/L10e195a.wav"
|
||||
[ 10, 40 ] = wave (0) : "./MITfull/elev10/L10e200a.wav"
|
||||
[ 10, 41 ] = wave (0) : "./MITfull/elev10/L10e205a.wav"
|
||||
[ 10, 42 ] = wave (0) : "./MITfull/elev10/L10e210a.wav"
|
||||
[ 10, 43 ] = wave (0) : "./MITfull/elev10/L10e215a.wav"
|
||||
[ 10, 44 ] = wave (0) : "./MITfull/elev10/L10e220a.wav"
|
||||
[ 10, 45 ] = wave (0) : "./MITfull/elev10/L10e225a.wav"
|
||||
[ 10, 46 ] = wave (0) : "./MITfull/elev10/L10e230a.wav"
|
||||
[ 10, 47 ] = wave (0) : "./MITfull/elev10/L10e235a.wav"
|
||||
[ 10, 48 ] = wave (0) : "./MITfull/elev10/L10e240a.wav"
|
||||
[ 10, 49 ] = wave (0) : "./MITfull/elev10/L10e245a.wav"
|
||||
[ 10, 50 ] = wave (0) : "./MITfull/elev10/L10e250a.wav"
|
||||
[ 10, 51 ] = wave (0) : "./MITfull/elev10/L10e255a.wav"
|
||||
[ 10, 52 ] = wave (0) : "./MITfull/elev10/L10e260a.wav"
|
||||
[ 10, 53 ] = wave (0) : "./MITfull/elev10/L10e265a.wav"
|
||||
[ 10, 54 ] = wave (0) : "./MITfull/elev10/L10e270a.wav"
|
||||
[ 10, 55 ] = wave (0) : "./MITfull/elev10/L10e275a.wav"
|
||||
[ 10, 56 ] = wave (0) : "./MITfull/elev10/L10e280a.wav"
|
||||
[ 10, 57 ] = wave (0) : "./MITfull/elev10/L10e285a.wav"
|
||||
[ 10, 58 ] = wave (0) : "./MITfull/elev10/L10e290a.wav"
|
||||
[ 10, 59 ] = wave (0) : "./MITfull/elev10/L10e295a.wav"
|
||||
[ 10, 60 ] = wave (0) : "./MITfull/elev10/L10e300a.wav"
|
||||
[ 10, 61 ] = wave (0) : "./MITfull/elev10/L10e305a.wav"
|
||||
[ 10, 62 ] = wave (0) : "./MITfull/elev10/L10e310a.wav"
|
||||
[ 10, 63 ] = wave (0) : "./MITfull/elev10/L10e315a.wav"
|
||||
[ 10, 64 ] = wave (0) : "./MITfull/elev10/L10e320a.wav"
|
||||
[ 10, 65 ] = wave (0) : "./MITfull/elev10/L10e325a.wav"
|
||||
[ 10, 66 ] = wave (0) : "./MITfull/elev10/L10e330a.wav"
|
||||
[ 10, 67 ] = wave (0) : "./MITfull/elev10/L10e335a.wav"
|
||||
[ 10, 68 ] = wave (0) : "./MITfull/elev10/L10e340a.wav"
|
||||
[ 10, 69 ] = wave (0) : "./MITfull/elev10/L10e345a.wav"
|
||||
[ 10, 70 ] = wave (0) : "./MITfull/elev10/L10e350a.wav"
|
||||
[ 10, 71 ] = wave (0) : "./MITfull/elev10/L10e355a.wav"
|
||||
|
||||
[ 11, 0 ] = wave (0) : "./MITfull/elev20/L20e000a.wav"
|
||||
[ 11, 1 ] = wave (0) : "./MITfull/elev20/L20e005a.wav"
|
||||
[ 11, 2 ] = wave (0) : "./MITfull/elev20/L20e010a.wav"
|
||||
[ 11, 3 ] = wave (0) : "./MITfull/elev20/L20e015a.wav"
|
||||
[ 11, 4 ] = wave (0) : "./MITfull/elev20/L20e020a.wav"
|
||||
[ 11, 5 ] = wave (0) : "./MITfull/elev20/L20e025a.wav"
|
||||
[ 11, 6 ] = wave (0) : "./MITfull/elev20/L20e030a.wav"
|
||||
[ 11, 7 ] = wave (0) : "./MITfull/elev20/L20e035a.wav"
|
||||
[ 11, 8 ] = wave (0) : "./MITfull/elev20/L20e040a.wav"
|
||||
[ 11, 9 ] = wave (0) : "./MITfull/elev20/L20e045a.wav"
|
||||
[ 11, 10 ] = wave (0) : "./MITfull/elev20/L20e050a.wav"
|
||||
[ 11, 11 ] = wave (0) : "./MITfull/elev20/L20e055a.wav"
|
||||
[ 11, 12 ] = wave (0) : "./MITfull/elev20/L20e060a.wav"
|
||||
[ 11, 13 ] = wave (0) : "./MITfull/elev20/L20e065a.wav"
|
||||
[ 11, 14 ] = wave (0) : "./MITfull/elev20/L20e070a.wav"
|
||||
[ 11, 15 ] = wave (0) : "./MITfull/elev20/L20e075a.wav"
|
||||
[ 11, 16 ] = wave (0) : "./MITfull/elev20/L20e080a.wav"
|
||||
[ 11, 17 ] = wave (0) : "./MITfull/elev20/L20e085a.wav"
|
||||
[ 11, 18 ] = wave (0) : "./MITfull/elev20/L20e090a.wav"
|
||||
[ 11, 19 ] = wave (0) : "./MITfull/elev20/L20e095a.wav"
|
||||
[ 11, 20 ] = wave (0) : "./MITfull/elev20/L20e100a.wav"
|
||||
[ 11, 21 ] = wave (0) : "./MITfull/elev20/L20e105a.wav"
|
||||
[ 11, 22 ] = wave (0) : "./MITfull/elev20/L20e110a.wav"
|
||||
[ 11, 23 ] = wave (0) : "./MITfull/elev20/L20e115a.wav"
|
||||
[ 11, 24 ] = wave (0) : "./MITfull/elev20/L20e120a.wav"
|
||||
[ 11, 25 ] = wave (0) : "./MITfull/elev20/L20e125a.wav"
|
||||
[ 11, 26 ] = wave (0) : "./MITfull/elev20/L20e130a.wav"
|
||||
[ 11, 27 ] = wave (0) : "./MITfull/elev20/L20e135a.wav"
|
||||
[ 11, 28 ] = wave (0) : "./MITfull/elev20/L20e140a.wav"
|
||||
[ 11, 29 ] = wave (0) : "./MITfull/elev20/L20e145a.wav"
|
||||
[ 11, 30 ] = wave (0) : "./MITfull/elev20/L20e150a.wav"
|
||||
[ 11, 31 ] = wave (0) : "./MITfull/elev20/L20e155a.wav"
|
||||
[ 11, 32 ] = wave (0) : "./MITfull/elev20/L20e160a.wav"
|
||||
[ 11, 33 ] = wave (0) : "./MITfull/elev20/L20e165a.wav"
|
||||
[ 11, 34 ] = wave (0) : "./MITfull/elev20/L20e170a.wav"
|
||||
[ 11, 35 ] = wave (0) : "./MITfull/elev20/L20e175a.wav"
|
||||
[ 11, 36 ] = wave (0) : "./MITfull/elev20/L20e180a.wav"
|
||||
[ 11, 37 ] = wave (0) : "./MITfull/elev20/L20e185a.wav"
|
||||
[ 11, 38 ] = wave (0) : "./MITfull/elev20/L20e190a.wav"
|
||||
[ 11, 39 ] = wave (0) : "./MITfull/elev20/L20e195a.wav"
|
||||
[ 11, 40 ] = wave (0) : "./MITfull/elev20/L20e200a.wav"
|
||||
[ 11, 41 ] = wave (0) : "./MITfull/elev20/L20e205a.wav"
|
||||
[ 11, 42 ] = wave (0) : "./MITfull/elev20/L20e210a.wav"
|
||||
[ 11, 43 ] = wave (0) : "./MITfull/elev20/L20e215a.wav"
|
||||
[ 11, 44 ] = wave (0) : "./MITfull/elev20/L20e220a.wav"
|
||||
[ 11, 45 ] = wave (0) : "./MITfull/elev20/L20e225a.wav"
|
||||
[ 11, 46 ] = wave (0) : "./MITfull/elev20/L20e230a.wav"
|
||||
[ 11, 47 ] = wave (0) : "./MITfull/elev20/L20e235a.wav"
|
||||
[ 11, 48 ] = wave (0) : "./MITfull/elev20/L20e240a.wav"
|
||||
[ 11, 49 ] = wave (0) : "./MITfull/elev20/L20e245a.wav"
|
||||
[ 11, 50 ] = wave (0) : "./MITfull/elev20/L20e250a.wav"
|
||||
[ 11, 51 ] = wave (0) : "./MITfull/elev20/L20e255a.wav"
|
||||
[ 11, 52 ] = wave (0) : "./MITfull/elev20/L20e260a.wav"
|
||||
[ 11, 53 ] = wave (0) : "./MITfull/elev20/L20e265a.wav"
|
||||
[ 11, 54 ] = wave (0) : "./MITfull/elev20/L20e270a.wav"
|
||||
[ 11, 55 ] = wave (0) : "./MITfull/elev20/L20e275a.wav"
|
||||
[ 11, 56 ] = wave (0) : "./MITfull/elev20/L20e280a.wav"
|
||||
[ 11, 57 ] = wave (0) : "./MITfull/elev20/L20e285a.wav"
|
||||
[ 11, 58 ] = wave (0) : "./MITfull/elev20/L20e290a.wav"
|
||||
[ 11, 59 ] = wave (0) : "./MITfull/elev20/L20e295a.wav"
|
||||
[ 11, 60 ] = wave (0) : "./MITfull/elev20/L20e300a.wav"
|
||||
[ 11, 61 ] = wave (0) : "./MITfull/elev20/L20e305a.wav"
|
||||
[ 11, 62 ] = wave (0) : "./MITfull/elev20/L20e310a.wav"
|
||||
[ 11, 63 ] = wave (0) : "./MITfull/elev20/L20e315a.wav"
|
||||
[ 11, 64 ] = wave (0) : "./MITfull/elev20/L20e320a.wav"
|
||||
[ 11, 65 ] = wave (0) : "./MITfull/elev20/L20e325a.wav"
|
||||
[ 11, 66 ] = wave (0) : "./MITfull/elev20/L20e330a.wav"
|
||||
[ 11, 67 ] = wave (0) : "./MITfull/elev20/L20e335a.wav"
|
||||
[ 11, 68 ] = wave (0) : "./MITfull/elev20/L20e340a.wav"
|
||||
[ 11, 69 ] = wave (0) : "./MITfull/elev20/L20e345a.wav"
|
||||
[ 11, 70 ] = wave (0) : "./MITfull/elev20/L20e350a.wav"
|
||||
[ 11, 71 ] = wave (0) : "./MITfull/elev20/L20e355a.wav"
|
||||
|
||||
[ 12, 0 ] = wave (0) : "./MITfull/elev30/L30e000a.wav"
|
||||
[ 12, 1 ] = wave (0) : "./MITfull/elev30/L30e006a.wav"
|
||||
[ 12, 2 ] = wave (0) : "./MITfull/elev30/L30e012a.wav"
|
||||
[ 12, 3 ] = wave (0) : "./MITfull/elev30/L30e018a.wav"
|
||||
[ 12, 4 ] = wave (0) : "./MITfull/elev30/L30e024a.wav"
|
||||
[ 12, 5 ] = wave (0) : "./MITfull/elev30/L30e030a.wav"
|
||||
[ 12, 6 ] = wave (0) : "./MITfull/elev30/L30e036a.wav"
|
||||
[ 12, 7 ] = wave (0) : "./MITfull/elev30/L30e042a.wav"
|
||||
[ 12, 8 ] = wave (0) : "./MITfull/elev30/L30e048a.wav"
|
||||
[ 12, 9 ] = wave (0) : "./MITfull/elev30/L30e054a.wav"
|
||||
[ 12, 10 ] = wave (0) : "./MITfull/elev30/L30e060a.wav"
|
||||
[ 12, 11 ] = wave (0) : "./MITfull/elev30/L30e066a.wav"
|
||||
[ 12, 12 ] = wave (0) : "./MITfull/elev30/L30e072a.wav"
|
||||
[ 12, 13 ] = wave (0) : "./MITfull/elev30/L30e078a.wav"
|
||||
[ 12, 14 ] = wave (0) : "./MITfull/elev30/L30e084a.wav"
|
||||
[ 12, 15 ] = wave (0) : "./MITfull/elev30/L30e090a.wav"
|
||||
[ 12, 16 ] = wave (0) : "./MITfull/elev30/L30e096a.wav"
|
||||
[ 12, 17 ] = wave (0) : "./MITfull/elev30/L30e102a.wav"
|
||||
[ 12, 18 ] = wave (0) : "./MITfull/elev30/L30e108a.wav"
|
||||
[ 12, 19 ] = wave (0) : "./MITfull/elev30/L30e114a.wav"
|
||||
[ 12, 20 ] = wave (0) : "./MITfull/elev30/L30e120a.wav"
|
||||
[ 12, 21 ] = wave (0) : "./MITfull/elev30/L30e126a.wav"
|
||||
[ 12, 22 ] = wave (0) : "./MITfull/elev30/L30e132a.wav"
|
||||
[ 12, 23 ] = wave (0) : "./MITfull/elev30/L30e138a.wav"
|
||||
[ 12, 24 ] = wave (0) : "./MITfull/elev30/L30e144a.wav"
|
||||
[ 12, 25 ] = wave (0) : "./MITfull/elev30/L30e150a.wav"
|
||||
[ 12, 26 ] = wave (0) : "./MITfull/elev30/L30e156a.wav"
|
||||
[ 12, 27 ] = wave (0) : "./MITfull/elev30/L30e162a.wav"
|
||||
[ 12, 28 ] = wave (0) : "./MITfull/elev30/L30e168a.wav"
|
||||
[ 12, 29 ] = wave (0) : "./MITfull/elev30/L30e174a.wav"
|
||||
[ 12, 30 ] = wave (0) : "./MITfull/elev30/L30e180a.wav"
|
||||
[ 12, 31 ] = wave (0) : "./MITfull/elev30/L30e186a.wav"
|
||||
[ 12, 32 ] = wave (0) : "./MITfull/elev30/L30e192a.wav"
|
||||
[ 12, 33 ] = wave (0) : "./MITfull/elev30/L30e198a.wav"
|
||||
[ 12, 34 ] = wave (0) : "./MITfull/elev30/L30e204a.wav"
|
||||
[ 12, 35 ] = wave (0) : "./MITfull/elev30/L30e210a.wav"
|
||||
[ 12, 36 ] = wave (0) : "./MITfull/elev30/L30e216a.wav"
|
||||
[ 12, 37 ] = wave (0) : "./MITfull/elev30/L30e222a.wav"
|
||||
[ 12, 38 ] = wave (0) : "./MITfull/elev30/L30e228a.wav"
|
||||
[ 12, 39 ] = wave (0) : "./MITfull/elev30/L30e234a.wav"
|
||||
[ 12, 40 ] = wave (0) : "./MITfull/elev30/L30e240a.wav"
|
||||
[ 12, 41 ] = wave (0) : "./MITfull/elev30/L30e246a.wav"
|
||||
[ 12, 42 ] = wave (0) : "./MITfull/elev30/L30e252a.wav"
|
||||
[ 12, 43 ] = wave (0) : "./MITfull/elev30/L30e258a.wav"
|
||||
[ 12, 44 ] = wave (0) : "./MITfull/elev30/L30e264a.wav"
|
||||
[ 12, 45 ] = wave (0) : "./MITfull/elev30/L30e270a.wav"
|
||||
[ 12, 46 ] = wave (0) : "./MITfull/elev30/L30e276a.wav"
|
||||
[ 12, 47 ] = wave (0) : "./MITfull/elev30/L30e282a.wav"
|
||||
[ 12, 48 ] = wave (0) : "./MITfull/elev30/L30e288a.wav"
|
||||
[ 12, 49 ] = wave (0) : "./MITfull/elev30/L30e294a.wav"
|
||||
[ 12, 50 ] = wave (0) : "./MITfull/elev30/L30e300a.wav"
|
||||
[ 12, 51 ] = wave (0) : "./MITfull/elev30/L30e306a.wav"
|
||||
[ 12, 52 ] = wave (0) : "./MITfull/elev30/L30e312a.wav"
|
||||
[ 12, 53 ] = wave (0) : "./MITfull/elev30/L30e318a.wav"
|
||||
[ 12, 54 ] = wave (0) : "./MITfull/elev30/L30e324a.wav"
|
||||
[ 12, 55 ] = wave (0) : "./MITfull/elev30/L30e330a.wav"
|
||||
[ 12, 56 ] = wave (0) : "./MITfull/elev30/L30e336a.wav"
|
||||
[ 12, 57 ] = wave (0) : "./MITfull/elev30/L30e342a.wav"
|
||||
[ 12, 58 ] = wave (0) : "./MITfull/elev30/L30e348a.wav"
|
||||
[ 12, 59 ] = wave (0) : "./MITfull/elev30/L30e354a.wav"
|
||||
|
||||
[ 13, 0 ] = wave (0) : "./MITfull/elev40/L40e000a.wav"
|
||||
[ 13, 1 ] = wave (0) : "./MITfull/elev40/L40e006a.wav"
|
||||
[ 13, 2 ] = wave (0) : "./MITfull/elev40/L40e013a.wav"
|
||||
[ 13, 3 ] = wave (0) : "./MITfull/elev40/L40e019a.wav"
|
||||
[ 13, 4 ] = wave (0) : "./MITfull/elev40/L40e026a.wav"
|
||||
[ 13, 5 ] = wave (0) : "./MITfull/elev40/L40e032a.wav"
|
||||
[ 13, 6 ] = wave (0) : "./MITfull/elev40/L40e039a.wav"
|
||||
[ 13, 7 ] = wave (0) : "./MITfull/elev40/L40e045a.wav"
|
||||
[ 13, 8 ] = wave (0) : "./MITfull/elev40/L40e051a.wav"
|
||||
[ 13, 9 ] = wave (0) : "./MITfull/elev40/L40e058a.wav"
|
||||
[ 13, 10 ] = wave (0) : "./MITfull/elev40/L40e064a.wav"
|
||||
[ 13, 11 ] = wave (0) : "./MITfull/elev40/L40e071a.wav"
|
||||
[ 13, 12 ] = wave (0) : "./MITfull/elev40/L40e077a.wav"
|
||||
[ 13, 13 ] = wave (0) : "./MITfull/elev40/L40e084a.wav"
|
||||
[ 13, 14 ] = wave (0) : "./MITfull/elev40/L40e090a.wav"
|
||||
[ 13, 15 ] = wave (0) : "./MITfull/elev40/L40e096a.wav"
|
||||
[ 13, 16 ] = wave (0) : "./MITfull/elev40/L40e103a.wav"
|
||||
[ 13, 17 ] = wave (0) : "./MITfull/elev40/L40e109a.wav"
|
||||
[ 13, 18 ] = wave (0) : "./MITfull/elev40/L40e116a.wav"
|
||||
[ 13, 19 ] = wave (0) : "./MITfull/elev40/L40e122a.wav"
|
||||
[ 13, 20 ] = wave (0) : "./MITfull/elev40/L40e129a.wav"
|
||||
[ 13, 21 ] = wave (0) : "./MITfull/elev40/L40e135a.wav"
|
||||
[ 13, 22 ] = wave (0) : "./MITfull/elev40/L40e141a.wav"
|
||||
[ 13, 23 ] = wave (0) : "./MITfull/elev40/L40e148a.wav"
|
||||
[ 13, 24 ] = wave (0) : "./MITfull/elev40/L40e154a.wav"
|
||||
[ 13, 25 ] = wave (0) : "./MITfull/elev40/L40e161a.wav"
|
||||
[ 13, 26 ] = wave (0) : "./MITfull/elev40/L40e167a.wav"
|
||||
[ 13, 27 ] = wave (0) : "./MITfull/elev40/L40e174a.wav"
|
||||
[ 13, 28 ] = wave (0) : "./MITfull/elev40/L40e180a.wav"
|
||||
[ 13, 29 ] = wave (0) : "./MITfull/elev40/L40e186a.wav"
|
||||
[ 13, 30 ] = wave (0) : "./MITfull/elev40/L40e193a.wav"
|
||||
[ 13, 31 ] = wave (0) : "./MITfull/elev40/L40e199a.wav"
|
||||
[ 13, 32 ] = wave (0) : "./MITfull/elev40/L40e206a.wav"
|
||||
[ 13, 33 ] = wave (0) : "./MITfull/elev40/L40e212a.wav"
|
||||
[ 13, 34 ] = wave (0) : "./MITfull/elev40/L40e219a.wav"
|
||||
[ 13, 35 ] = wave (0) : "./MITfull/elev40/L40e225a.wav"
|
||||
[ 13, 36 ] = wave (0) : "./MITfull/elev40/L40e231a.wav"
|
||||
[ 13, 37 ] = wave (0) : "./MITfull/elev40/L40e238a.wav"
|
||||
[ 13, 38 ] = wave (0) : "./MITfull/elev40/L40e244a.wav"
|
||||
[ 13, 39 ] = wave (0) : "./MITfull/elev40/L40e251a.wav"
|
||||
[ 13, 40 ] = wave (0) : "./MITfull/elev40/L40e257a.wav"
|
||||
[ 13, 41 ] = wave (0) : "./MITfull/elev40/L40e264a.wav"
|
||||
[ 13, 42 ] = wave (0) : "./MITfull/elev40/L40e270a.wav"
|
||||
[ 13, 43 ] = wave (0) : "./MITfull/elev40/L40e276a.wav"
|
||||
[ 13, 44 ] = wave (0) : "./MITfull/elev40/L40e283a.wav"
|
||||
[ 13, 45 ] = wave (0) : "./MITfull/elev40/L40e289a.wav"
|
||||
[ 13, 46 ] = wave (0) : "./MITfull/elev40/L40e296a.wav"
|
||||
[ 13, 47 ] = wave (0) : "./MITfull/elev40/L40e302a.wav"
|
||||
[ 13, 48 ] = wave (0) : "./MITfull/elev40/L40e309a.wav"
|
||||
[ 13, 49 ] = wave (0) : "./MITfull/elev40/L40e315a.wav"
|
||||
[ 13, 50 ] = wave (0) : "./MITfull/elev40/L40e321a.wav"
|
||||
[ 13, 51 ] = wave (0) : "./MITfull/elev40/L40e328a.wav"
|
||||
[ 13, 52 ] = wave (0) : "./MITfull/elev40/L40e334a.wav"
|
||||
[ 13, 53 ] = wave (0) : "./MITfull/elev40/L40e341a.wav"
|
||||
[ 13, 54 ] = wave (0) : "./MITfull/elev40/L40e347a.wav"
|
||||
[ 13, 55 ] = wave (0) : "./MITfull/elev40/L40e354a.wav"
|
||||
|
||||
[ 14, 0 ] = wave (0) : "./MITfull/elev50/L50e000a.wav"
|
||||
[ 14, 1 ] = wave (0) : "./MITfull/elev50/L50e008a.wav"
|
||||
[ 14, 2 ] = wave (0) : "./MITfull/elev50/L50e016a.wav"
|
||||
[ 14, 3 ] = wave (0) : "./MITfull/elev50/L50e024a.wav"
|
||||
[ 14, 4 ] = wave (0) : "./MITfull/elev50/L50e032a.wav"
|
||||
[ 14, 5 ] = wave (0) : "./MITfull/elev50/L50e040a.wav"
|
||||
[ 14, 6 ] = wave (0) : "./MITfull/elev50/L50e048a.wav"
|
||||
[ 14, 7 ] = wave (0) : "./MITfull/elev50/L50e056a.wav"
|
||||
[ 14, 8 ] = wave (0) : "./MITfull/elev50/L50e064a.wav"
|
||||
[ 14, 9 ] = wave (0) : "./MITfull/elev50/L50e072a.wav"
|
||||
[ 14, 10 ] = wave (0) : "./MITfull/elev50/L50e080a.wav"
|
||||
[ 14, 11 ] = wave (0) : "./MITfull/elev50/L50e088a.wav"
|
||||
[ 14, 12 ] = wave (0) : "./MITfull/elev50/L50e096a.wav"
|
||||
[ 14, 13 ] = wave (0) : "./MITfull/elev50/L50e104a.wav"
|
||||
[ 14, 14 ] = wave (0) : "./MITfull/elev50/L50e112a.wav"
|
||||
[ 14, 15 ] = wave (0) : "./MITfull/elev50/L50e120a.wav"
|
||||
[ 14, 16 ] = wave (0) : "./MITfull/elev50/L50e128a.wav"
|
||||
[ 14, 17 ] = wave (0) : "./MITfull/elev50/L50e136a.wav"
|
||||
[ 14, 18 ] = wave (0) : "./MITfull/elev50/L50e144a.wav"
|
||||
[ 14, 19 ] = wave (0) : "./MITfull/elev50/L50e152a.wav"
|
||||
[ 14, 20 ] = wave (0) : "./MITfull/elev50/L50e160a.wav"
|
||||
[ 14, 21 ] = wave (0) : "./MITfull/elev50/L50e168a.wav"
|
||||
[ 14, 22 ] = wave (0) : "./MITfull/elev50/L50e176a.wav"
|
||||
[ 14, 23 ] = wave (0) : "./MITfull/elev50/L50e184a.wav"
|
||||
[ 14, 24 ] = wave (0) : "./MITfull/elev50/L50e192a.wav"
|
||||
[ 14, 25 ] = wave (0) : "./MITfull/elev50/L50e200a.wav"
|
||||
[ 14, 26 ] = wave (0) : "./MITfull/elev50/L50e208a.wav"
|
||||
[ 14, 27 ] = wave (0) : "./MITfull/elev50/L50e216a.wav"
|
||||
[ 14, 28 ] = wave (0) : "./MITfull/elev50/L50e224a.wav"
|
||||
[ 14, 29 ] = wave (0) : "./MITfull/elev50/L50e232a.wav"
|
||||
[ 14, 30 ] = wave (0) : "./MITfull/elev50/L50e240a.wav"
|
||||
[ 14, 31 ] = wave (0) : "./MITfull/elev50/L50e248a.wav"
|
||||
[ 14, 32 ] = wave (0) : "./MITfull/elev50/L50e256a.wav"
|
||||
[ 14, 33 ] = wave (0) : "./MITfull/elev50/L50e264a.wav"
|
||||
[ 14, 34 ] = wave (0) : "./MITfull/elev50/L50e272a.wav"
|
||||
[ 14, 35 ] = wave (0) : "./MITfull/elev50/L50e280a.wav"
|
||||
[ 14, 36 ] = wave (0) : "./MITfull/elev50/L50e288a.wav"
|
||||
[ 14, 37 ] = wave (0) : "./MITfull/elev50/L50e296a.wav"
|
||||
[ 14, 38 ] = wave (0) : "./MITfull/elev50/L50e304a.wav"
|
||||
[ 14, 39 ] = wave (0) : "./MITfull/elev50/L50e312a.wav"
|
||||
[ 14, 40 ] = wave (0) : "./MITfull/elev50/L50e320a.wav"
|
||||
[ 14, 41 ] = wave (0) : "./MITfull/elev50/L50e328a.wav"
|
||||
[ 14, 42 ] = wave (0) : "./MITfull/elev50/L50e336a.wav"
|
||||
[ 14, 43 ] = wave (0) : "./MITfull/elev50/L50e344a.wav"
|
||||
[ 14, 44 ] = wave (0) : "./MITfull/elev50/L50e352a.wav"
|
||||
|
||||
[ 15, 0 ] = wave (0) : "./MITfull/elev60/L60e000a.wav"
|
||||
[ 15, 1 ] = wave (0) : "./MITfull/elev60/L60e010a.wav"
|
||||
[ 15, 2 ] = wave (0) : "./MITfull/elev60/L60e020a.wav"
|
||||
[ 15, 3 ] = wave (0) : "./MITfull/elev60/L60e030a.wav"
|
||||
[ 15, 4 ] = wave (0) : "./MITfull/elev60/L60e040a.wav"
|
||||
[ 15, 5 ] = wave (0) : "./MITfull/elev60/L60e050a.wav"
|
||||
[ 15, 6 ] = wave (0) : "./MITfull/elev60/L60e060a.wav"
|
||||
[ 15, 7 ] = wave (0) : "./MITfull/elev60/L60e070a.wav"
|
||||
[ 15, 8 ] = wave (0) : "./MITfull/elev60/L60e080a.wav"
|
||||
[ 15, 9 ] = wave (0) : "./MITfull/elev60/L60e090a.wav"
|
||||
[ 15, 10 ] = wave (0) : "./MITfull/elev60/L60e100a.wav"
|
||||
[ 15, 11 ] = wave (0) : "./MITfull/elev60/L60e110a.wav"
|
||||
[ 15, 12 ] = wave (0) : "./MITfull/elev60/L60e120a.wav"
|
||||
[ 15, 13 ] = wave (0) : "./MITfull/elev60/L60e130a.wav"
|
||||
[ 15, 14 ] = wave (0) : "./MITfull/elev60/L60e140a.wav"
|
||||
[ 15, 15 ] = wave (0) : "./MITfull/elev60/L60e150a.wav"
|
||||
[ 15, 16 ] = wave (0) : "./MITfull/elev60/L60e160a.wav"
|
||||
[ 15, 17 ] = wave (0) : "./MITfull/elev60/L60e170a.wav"
|
||||
[ 15, 18 ] = wave (0) : "./MITfull/elev60/L60e180a.wav"
|
||||
[ 15, 19 ] = wave (0) : "./MITfull/elev60/L60e190a.wav"
|
||||
[ 15, 20 ] = wave (0) : "./MITfull/elev60/L60e200a.wav"
|
||||
[ 15, 21 ] = wave (0) : "./MITfull/elev60/L60e210a.wav"
|
||||
[ 15, 22 ] = wave (0) : "./MITfull/elev60/L60e220a.wav"
|
||||
[ 15, 23 ] = wave (0) : "./MITfull/elev60/L60e230a.wav"
|
||||
[ 15, 24 ] = wave (0) : "./MITfull/elev60/L60e240a.wav"
|
||||
[ 15, 25 ] = wave (0) : "./MITfull/elev60/L60e250a.wav"
|
||||
[ 15, 26 ] = wave (0) : "./MITfull/elev60/L60e260a.wav"
|
||||
[ 15, 27 ] = wave (0) : "./MITfull/elev60/L60e270a.wav"
|
||||
[ 15, 28 ] = wave (0) : "./MITfull/elev60/L60e280a.wav"
|
||||
[ 15, 29 ] = wave (0) : "./MITfull/elev60/L60e290a.wav"
|
||||
[ 15, 30 ] = wave (0) : "./MITfull/elev60/L60e300a.wav"
|
||||
[ 15, 31 ] = wave (0) : "./MITfull/elev60/L60e310a.wav"
|
||||
[ 15, 32 ] = wave (0) : "./MITfull/elev60/L60e320a.wav"
|
||||
[ 15, 33 ] = wave (0) : "./MITfull/elev60/L60e330a.wav"
|
||||
[ 15, 34 ] = wave (0) : "./MITfull/elev60/L60e340a.wav"
|
||||
[ 15, 35 ] = wave (0) : "./MITfull/elev60/L60e350a.wav"
|
||||
|
||||
[ 16, 0 ] = wave (0) : "./MITfull/elev70/L70e000a.wav"
|
||||
[ 16, 1 ] = wave (0) : "./MITfull/elev70/L70e015a.wav"
|
||||
[ 16, 2 ] = wave (0) : "./MITfull/elev70/L70e030a.wav"
|
||||
[ 16, 3 ] = wave (0) : "./MITfull/elev70/L70e045a.wav"
|
||||
[ 16, 4 ] = wave (0) : "./MITfull/elev70/L70e060a.wav"
|
||||
[ 16, 5 ] = wave (0) : "./MITfull/elev70/L70e075a.wav"
|
||||
[ 16, 6 ] = wave (0) : "./MITfull/elev70/L70e090a.wav"
|
||||
[ 16, 7 ] = wave (0) : "./MITfull/elev70/L70e105a.wav"
|
||||
[ 16, 8 ] = wave (0) : "./MITfull/elev70/L70e120a.wav"
|
||||
[ 16, 9 ] = wave (0) : "./MITfull/elev70/L70e135a.wav"
|
||||
[ 16, 10 ] = wave (0) : "./MITfull/elev70/L70e150a.wav"
|
||||
[ 16, 11 ] = wave (0) : "./MITfull/elev70/L70e165a.wav"
|
||||
[ 16, 12 ] = wave (0) : "./MITfull/elev70/L70e180a.wav"
|
||||
[ 16, 13 ] = wave (0) : "./MITfull/elev70/L70e195a.wav"
|
||||
[ 16, 14 ] = wave (0) : "./MITfull/elev70/L70e210a.wav"
|
||||
[ 16, 15 ] = wave (0) : "./MITfull/elev70/L70e225a.wav"
|
||||
[ 16, 16 ] = wave (0) : "./MITfull/elev70/L70e240a.wav"
|
||||
[ 16, 17 ] = wave (0) : "./MITfull/elev70/L70e255a.wav"
|
||||
[ 16, 18 ] = wave (0) : "./MITfull/elev70/L70e270a.wav"
|
||||
[ 16, 19 ] = wave (0) : "./MITfull/elev70/L70e285a.wav"
|
||||
[ 16, 20 ] = wave (0) : "./MITfull/elev70/L70e300a.wav"
|
||||
[ 16, 21 ] = wave (0) : "./MITfull/elev70/L70e315a.wav"
|
||||
[ 16, 22 ] = wave (0) : "./MITfull/elev70/L70e330a.wav"
|
||||
[ 16, 23 ] = wave (0) : "./MITfull/elev70/L70e345a.wav"
|
||||
|
||||
[ 17, 0 ] = wave (0) : "./MITfull/elev80/L80e000a.wav"
|
||||
[ 17, 1 ] = wave (0) : "./MITfull/elev80/L80e030a.wav"
|
||||
[ 17, 2 ] = wave (0) : "./MITfull/elev80/L80e060a.wav"
|
||||
[ 17, 3 ] = wave (0) : "./MITfull/elev80/L80e090a.wav"
|
||||
[ 17, 4 ] = wave (0) : "./MITfull/elev80/L80e120a.wav"
|
||||
[ 17, 5 ] = wave (0) : "./MITfull/elev80/L80e150a.wav"
|
||||
[ 17, 6 ] = wave (0) : "./MITfull/elev80/L80e180a.wav"
|
||||
[ 17, 7 ] = wave (0) : "./MITfull/elev80/L80e210a.wav"
|
||||
[ 17, 8 ] = wave (0) : "./MITfull/elev80/L80e240a.wav"
|
||||
[ 17, 9 ] = wave (0) : "./MITfull/elev80/L80e270a.wav"
|
||||
[ 17, 10 ] = wave (0) : "./MITfull/elev80/L80e300a.wav"
|
||||
[ 17, 11 ] = wave (0) : "./MITfull/elev80/L80e330a.wav"
|
||||
|
||||
[ 18, 0 ] = wave (0) : "./MITfull/elev90/L90e000a.wav"
|
||||
|
||||
51
externals/openal-soft/utils/MIT_KEMAR_sofa.def
vendored
Normal file
51
externals/openal-soft/utils/MIT_KEMAR_sofa.def
vendored
Normal file
@@ -0,0 +1,51 @@
|
||||
# This is a makemhr HRIR definition file. It is used to define the layout and
|
||||
# source data to be processed into an OpenAL Soft compatible HRTF.
|
||||
#
|
||||
# This definition is used to transform the SOFA packaged KEMAR HRIRs
|
||||
# originally provided by Bill Gardner <billg@media.mit.edu> and Keith Martin
|
||||
# <kdm@media.mit.edu> of MIT Media Laboratory.
|
||||
#
|
||||
# The SOFA conversion is available from:
|
||||
#
|
||||
# http://sofacoustics.org/data/database/mit/
|
||||
#
|
||||
# The original data is available from:
|
||||
#
|
||||
# http://sound.media.mit.edu/resources/KEMAR.html
|
||||
#
|
||||
# It is copyrighted 1994 by MIT Media Laboratory, and provided free of charge
|
||||
# with no restrictions on use so long as the authors (above) are cited.
|
||||
|
||||
# Sampling rate of the HRIR data (in hertz).
|
||||
rate = 44100
|
||||
|
||||
# The SOFA file is stereo, but the original data was mono. Channels are just
|
||||
# mirrored by azimuth; so save some memory by allowing OpenAL Soft to mirror
|
||||
# them at run time.
|
||||
type = mono
|
||||
|
||||
points = 512
|
||||
|
||||
radius = 0.09
|
||||
|
||||
# The MIT set has only one field with a distance of 1.4m.
|
||||
distance = 1.4
|
||||
|
||||
# The MIT set varies the number of azimuths for each elevation to maintain
|
||||
# an average distance between them.
|
||||
azimuths = 1, 12, 24, 36, 45, 56, 60, 72, 72, 72, 72, 72, 60, 56, 45, 36, 24, 12, 1
|
||||
|
||||
# Normally the dataset would be composed manually by listing all necessary
|
||||
# 'sofa' sources with the appropriate radius, elevation, azimuth (counter-
|
||||
# clockwise for SOFA files) and receiver arguments:
|
||||
#
|
||||
# [ 5, 0 ] = sofa (1.4, -40.0, 0.0 : 0) : "./mit_kemar_normal_pinna.sofa"
|
||||
# [ 5, 1 ] = sofa (1.4, -40.0, 353.6 : 0) : "./mit_kemar_normal_pinna.sofa"
|
||||
# [ 5, 2 ] = sofa (1.4, -40.0, 347.1 : 0) : "./mit_kemar_normal_pinna.sofa"
|
||||
# [ 5, 3 ] = sofa (1.4, -40.0, 340.7 : 0) : "./mit_kemar_normal_pinna.sofa"
|
||||
# ...
|
||||
#
|
||||
# If HRIR composition isn't necessary, it's easier to just use the following:
|
||||
|
||||
[ * ] = sofa : "./mit_kemar_normal_pinna.sofa" mono
|
||||
|
||||
48
externals/openal-soft/utils/SCUT_KEMAR.def
vendored
Normal file
48
externals/openal-soft/utils/SCUT_KEMAR.def
vendored
Normal file
@@ -0,0 +1,48 @@
|
||||
# This is a makemhr HRIR definition file. It is used to define the layout and
|
||||
# source data to be processed into an OpenAL Soft compatible HRTF.
|
||||
#
|
||||
# This definition is used to transform the near-field KEMAR HRIRs provided by
|
||||
# Bosun Xie <phbsxie@scut.edu.cn> of the South China University of
|
||||
# Technology, Guangzhou, China; and converted from SCUT to SOFA format by
|
||||
# Piotr Majdak <piotr@majdak.com> of the Acoustics Research Institute,
|
||||
# Austrian Academy of Sciences.
|
||||
#
|
||||
# A copy of the data (SCUT_KEMAR_radius_all.sofa) is available from:
|
||||
#
|
||||
# http://sofacoustics.org/data/database/scut/SCUT_KEMAR_radius_all.sofa
|
||||
#
|
||||
# It is provided under the Creative Commons CC 3.0 BY-SA-NC license:
|
||||
#
|
||||
# https://creativecommons.org/licenses/by-nc-sa/3.0/
|
||||
|
||||
rate = 44100
|
||||
|
||||
# While the SOFA file is stereo, doubling the size of the data set will cause
|
||||
# the utility to exhaust its address space if compiled 32-bit. Since the
|
||||
# dummy head is symmetric, the same results (ignoring variations caused by
|
||||
# measurement error) can be obtained using mono channel processing.
|
||||
type = mono
|
||||
|
||||
points = 512
|
||||
|
||||
radius = 0.09
|
||||
|
||||
# This data set has 10 fields ranging from 0.2m to 1m. The layout was
|
||||
# obtained using the sofa-info utility.
|
||||
distance = 0.2, 0.25, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1.0
|
||||
|
||||
azimuths = 1, 24, 36, 72, 72, 72, 72, 72, 72, 72, 36, 24, 1;
|
||||
1, 24, 36, 72, 72, 72, 72, 72, 72, 72, 36, 24, 1;
|
||||
1, 24, 36, 72, 72, 72, 72, 72, 72, 72, 36, 24, 1;
|
||||
1, 24, 36, 72, 72, 72, 72, 72, 72, 72, 36, 24, 1;
|
||||
1, 24, 36, 72, 72, 72, 72, 72, 72, 72, 36, 24, 1;
|
||||
1, 24, 36, 72, 72, 72, 72, 72, 72, 72, 36, 24, 1;
|
||||
1, 24, 36, 72, 72, 72, 72, 72, 72, 72, 36, 24, 1;
|
||||
1, 24, 36, 72, 72, 72, 72, 72, 72, 72, 36, 24, 1;
|
||||
1, 24, 36, 72, 72, 72, 72, 72, 72, 72, 36, 24, 1;
|
||||
1, 24, 36, 72, 72, 72, 72, 72, 72, 72, 36, 24, 1
|
||||
|
||||
# Given the above compatible layout, we can automatically process the entire
|
||||
# data set.
|
||||
[ * ] = sofa : "./SCUT_KEMAR_radius_all.sofa" mono
|
||||
|
||||
32
externals/openal-soft/utils/alsoft-config/CMakeLists.txt
vendored
Normal file
32
externals/openal-soft/utils/alsoft-config/CMakeLists.txt
vendored
Normal file
@@ -0,0 +1,32 @@
|
||||
project(alsoft-config)
|
||||
|
||||
if(Qt5Widgets_FOUND)
|
||||
qt5_wrap_ui(UIS mainwindow.ui)
|
||||
|
||||
qt5_wrap_cpp(MOCS mainwindow.h)
|
||||
|
||||
add_executable(alsoft-config
|
||||
main.cpp
|
||||
mainwindow.cpp
|
||||
mainwindow.h
|
||||
verstr.cpp
|
||||
verstr.h
|
||||
${UIS} ${RSCS} ${TRS} ${MOCS})
|
||||
target_link_libraries(alsoft-config Qt5::Widgets)
|
||||
target_include_directories(alsoft-config PRIVATE "${alsoft-config_BINARY_DIR}"
|
||||
"${OpenAL_BINARY_DIR}")
|
||||
set_target_properties(alsoft-config PROPERTIES ${DEFAULT_TARGET_PROPS}
|
||||
RUNTIME_OUTPUT_DIRECTORY ${OpenAL_BINARY_DIR})
|
||||
if(TARGET build_version)
|
||||
add_dependencies(alsoft-config build_version)
|
||||
endif()
|
||||
|
||||
message(STATUS "Building configuration program")
|
||||
|
||||
if(ALSOFT_INSTALL_UTILS)
|
||||
install(TARGETS alsoft-config
|
||||
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
|
||||
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
|
||||
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR})
|
||||
endif()
|
||||
endif()
|
||||
11
externals/openal-soft/utils/alsoft-config/main.cpp
vendored
Normal file
11
externals/openal-soft/utils/alsoft-config/main.cpp
vendored
Normal file
@@ -0,0 +1,11 @@
|
||||
#include "mainwindow.h"
|
||||
#include <QApplication>
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
QApplication a(argc, argv);
|
||||
MainWindow w;
|
||||
w.show();
|
||||
|
||||
return a.exec();
|
||||
}
|
||||
1449
externals/openal-soft/utils/alsoft-config/mainwindow.cpp
vendored
Normal file
1449
externals/openal-soft/utils/alsoft-config/mainwindow.cpp
vendored
Normal file
File diff suppressed because it is too large
Load Diff
86
externals/openal-soft/utils/alsoft-config/mainwindow.h
vendored
Normal file
86
externals/openal-soft/utils/alsoft-config/mainwindow.h
vendored
Normal file
@@ -0,0 +1,86 @@
|
||||
#ifndef MAINWINDOW_H
|
||||
#define MAINWINDOW_H
|
||||
|
||||
#include <QMainWindow>
|
||||
#include <QListWidget>
|
||||
|
||||
namespace Ui {
|
||||
class MainWindow;
|
||||
}
|
||||
|
||||
class MainWindow : public QMainWindow
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit MainWindow(QWidget *parent = 0);
|
||||
~MainWindow();
|
||||
|
||||
private slots:
|
||||
void cancelCloseAction();
|
||||
|
||||
void saveCurrentConfig();
|
||||
|
||||
void saveConfigAsFile();
|
||||
void loadConfigFromFile();
|
||||
|
||||
void showAboutPage();
|
||||
|
||||
void enableApplyButton();
|
||||
|
||||
void updateResamplerLabel(int num);
|
||||
|
||||
void updatePeriodSizeEdit(int size);
|
||||
void updatePeriodSizeSlider();
|
||||
void updatePeriodCountEdit(int size);
|
||||
void updatePeriodCountSlider();
|
||||
|
||||
void selectQuadDecoderFile();
|
||||
void select51DecoderFile();
|
||||
void select61DecoderFile();
|
||||
void select71DecoderFile();
|
||||
void select3D71DecoderFile();
|
||||
|
||||
void updateJackBufferSizeEdit(int size);
|
||||
void updateJackBufferSizeSlider();
|
||||
|
||||
void updateHrtfModeLabel(int num);
|
||||
void addHrtfFile();
|
||||
void removeHrtfFile();
|
||||
|
||||
void updateHrtfRemoveButton();
|
||||
|
||||
void showEnabledBackendMenu(QPoint pt);
|
||||
void showDisabledBackendMenu(QPoint pt);
|
||||
|
||||
void selectOSSPlayback();
|
||||
void selectOSSCapture();
|
||||
|
||||
void selectSolarisPlayback();
|
||||
|
||||
void selectWaveOutput();
|
||||
|
||||
private:
|
||||
Ui::MainWindow *ui;
|
||||
|
||||
QValidator *mPeriodSizeValidator;
|
||||
QValidator *mPeriodCountValidator;
|
||||
QValidator *mSourceCountValidator;
|
||||
QValidator *mEffectSlotValidator;
|
||||
QValidator *mSourceSendValidator;
|
||||
QValidator *mSampleRateValidator;
|
||||
QValidator *mJackBufferValidator;
|
||||
|
||||
bool mNeedsSave;
|
||||
|
||||
void closeEvent(QCloseEvent *event);
|
||||
|
||||
void selectDecoderFile(QLineEdit *line, const char *name);
|
||||
|
||||
QStringList collectHrtfs();
|
||||
|
||||
void loadConfig(const QString &fname);
|
||||
void saveConfig(const QString &fname) const;
|
||||
};
|
||||
|
||||
#endif // MAINWINDOW_H
|
||||
2693
externals/openal-soft/utils/alsoft-config/mainwindow.ui
vendored
Normal file
2693
externals/openal-soft/utils/alsoft-config/mainwindow.ui
vendored
Normal file
File diff suppressed because it is too large
Load Diff
10
externals/openal-soft/utils/alsoft-config/verstr.cpp
vendored
Normal file
10
externals/openal-soft/utils/alsoft-config/verstr.cpp
vendored
Normal file
@@ -0,0 +1,10 @@
|
||||
|
||||
#include "verstr.h"
|
||||
|
||||
#include "version.h"
|
||||
|
||||
|
||||
QString GetVersionString()
|
||||
{
|
||||
return QStringLiteral(ALSOFT_VERSION "-" ALSOFT_GIT_COMMIT_HASH " (" ALSOFT_GIT_BRANCH " branch).");
|
||||
}
|
||||
8
externals/openal-soft/utils/alsoft-config/verstr.h
vendored
Normal file
8
externals/openal-soft/utils/alsoft-config/verstr.h
vendored
Normal file
@@ -0,0 +1,8 @@
|
||||
#ifndef VERSTR_H
|
||||
#define VERSTR_H
|
||||
|
||||
#include <QString>
|
||||
|
||||
QString GetVersionString();
|
||||
|
||||
#endif /* VERSTR_H */
|
||||
137
externals/openal-soft/utils/getopt.c
vendored
Normal file
137
externals/openal-soft/utils/getopt.c
vendored
Normal file
@@ -0,0 +1,137 @@
|
||||
/* $NetBSD: getopt.c,v 1.26 2003/08/07 16:43:40 agc Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1987, 1993, 1994
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 4. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#if defined(LIBC_SCCS) && !defined(lint)
|
||||
static char sccsid[] = "@(#)getopt.c 8.3 (Berkeley) 4/27/95";
|
||||
#endif /* LIBC_SCCS and not lint */
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include "getopt.h"
|
||||
|
||||
int opterr = 1, /* if error message should be printed */
|
||||
optind = 1, /* index into parent argv vector */
|
||||
optopt, /* character checked for validity */
|
||||
optreset; /* reset getopt */
|
||||
char *optarg; /* argument associated with option */
|
||||
|
||||
#define BADCH (int)'?'
|
||||
#define BADARG (int)':'
|
||||
#define EMSG ""
|
||||
|
||||
/*
|
||||
* Get program name in Windows
|
||||
*/
|
||||
const char * _getprogname(void);
|
||||
|
||||
/*
|
||||
* getopt --
|
||||
* Parse argc/argv argument vector.
|
||||
*/
|
||||
int
|
||||
getopt(int nargc, char * const nargv[], const char *ostr)
|
||||
{
|
||||
static char *place = EMSG; /* option letter processing */
|
||||
char *oli; /* option letter list index */
|
||||
|
||||
if (optreset || *place == 0) { /* update scanning pointer */
|
||||
optreset = 0;
|
||||
place = nargv[optind];
|
||||
if (optind >= nargc || *place++ != '-') {
|
||||
/* Argument is absent or is not an option */
|
||||
place = EMSG;
|
||||
return (-1);
|
||||
}
|
||||
optopt = *place++;
|
||||
if (optopt == '-' && *place == 0) {
|
||||
/* "--" => end of options */
|
||||
++optind;
|
||||
place = EMSG;
|
||||
return (-1);
|
||||
}
|
||||
if (optopt == 0) {
|
||||
/* Solitary '-', treat as a '-' option
|
||||
if the program (eg su) is looking for it. */
|
||||
place = EMSG;
|
||||
if (strchr(ostr, '-') == NULL)
|
||||
return (-1);
|
||||
optopt = '-';
|
||||
}
|
||||
} else
|
||||
optopt = *place++;
|
||||
|
||||
/* See if option letter is one the caller wanted... */
|
||||
if (optopt == ':' || (oli = strchr(ostr, optopt)) == NULL) {
|
||||
if (*place == 0)
|
||||
++optind;
|
||||
if (opterr && *ostr != ':')
|
||||
(void)fprintf(stderr,
|
||||
"%s: illegal option -- %c\n", _getprogname(),
|
||||
optopt);
|
||||
return (BADCH);
|
||||
}
|
||||
|
||||
/* Does this option need an argument? */
|
||||
if (oli[1] != ':') {
|
||||
/* don't need argument */
|
||||
optarg = NULL;
|
||||
if (*place == 0)
|
||||
++optind;
|
||||
} else {
|
||||
/* Option-argument is either the rest of this argument or the
|
||||
entire next argument. */
|
||||
if (*place)
|
||||
optarg = place;
|
||||
else if (nargc > ++optind)
|
||||
optarg = nargv[optind];
|
||||
else {
|
||||
/* option-argument absent */
|
||||
place = EMSG;
|
||||
if (*ostr == ':')
|
||||
return (BADARG);
|
||||
if (opterr)
|
||||
(void)fprintf(stderr,
|
||||
"%s: option requires an argument -- %c\n",
|
||||
_getprogname(), optopt);
|
||||
return (BADCH);
|
||||
}
|
||||
place = EMSG;
|
||||
++optind;
|
||||
}
|
||||
return (optopt); /* return option letter */
|
||||
}
|
||||
|
||||
const char * _getprogname() {
|
||||
char *pgmptr = NULL;
|
||||
_get_pgmptr(&pgmptr);
|
||||
return strrchr(pgmptr,'\\')+1;
|
||||
}
|
||||
|
||||
26
externals/openal-soft/utils/getopt.h
vendored
Normal file
26
externals/openal-soft/utils/getopt.h
vendored
Normal file
@@ -0,0 +1,26 @@
|
||||
#ifndef GETOPT_H
|
||||
#define GETOPT_H
|
||||
|
||||
#ifndef _WIN32
|
||||
|
||||
#include <unistd.h>
|
||||
|
||||
#else /* _WIN32 */
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif /* __cplusplus */
|
||||
|
||||
extern char *optarg;
|
||||
extern int optind, opterr, optopt, optreset;
|
||||
|
||||
int getopt(int nargc, char * const nargv[], const char *ostr);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif /* __cplusplus */
|
||||
|
||||
#endif /* !_WIN32 */
|
||||
|
||||
#endif /* !GETOPT_H */
|
||||
|
||||
2058
externals/openal-soft/utils/makemhr/loaddef.cpp
vendored
Normal file
2058
externals/openal-soft/utils/makemhr/loaddef.cpp
vendored
Normal file
File diff suppressed because it is too large
Load Diff
13
externals/openal-soft/utils/makemhr/loaddef.h
vendored
Normal file
13
externals/openal-soft/utils/makemhr/loaddef.h
vendored
Normal file
@@ -0,0 +1,13 @@
|
||||
#ifndef LOADDEF_H
|
||||
#define LOADDEF_H
|
||||
|
||||
#include <istream>
|
||||
|
||||
#include "makemhr.h"
|
||||
|
||||
|
||||
bool LoadDefInput(std::istream &istream, const char *startbytes, std::streamsize startbytecount,
|
||||
const char *filename, const uint fftSize, const uint truncSize, const uint outRate,
|
||||
const ChannelModeT chanMode, HrirDataT *hData);
|
||||
|
||||
#endif /* LOADDEF_H */
|
||||
603
externals/openal-soft/utils/makemhr/loadsofa.cpp
vendored
Normal file
603
externals/openal-soft/utils/makemhr/loadsofa.cpp
vendored
Normal file
@@ -0,0 +1,603 @@
|
||||
/*
|
||||
* HRTF utility for producing and demonstrating the process of creating an
|
||||
* OpenAL Soft compatible HRIR data set.
|
||||
*
|
||||
* Copyright (C) 2018-2019 Christopher Fitzgerald
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Or visit: http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
|
||||
*/
|
||||
|
||||
#include "loadsofa.h"
|
||||
|
||||
#include <algorithm>
|
||||
#include <atomic>
|
||||
#include <chrono>
|
||||
#include <cmath>
|
||||
#include <cstdio>
|
||||
#include <functional>
|
||||
#include <future>
|
||||
#include <iterator>
|
||||
#include <memory>
|
||||
#include <numeric>
|
||||
#include <string>
|
||||
#include <thread>
|
||||
#include <vector>
|
||||
|
||||
#include "aloptional.h"
|
||||
#include "alspan.h"
|
||||
#include "makemhr.h"
|
||||
#include "polyphase_resampler.h"
|
||||
#include "sofa-support.h"
|
||||
|
||||
#include "mysofa.h"
|
||||
|
||||
|
||||
using uint = unsigned int;
|
||||
|
||||
/* Attempts to produce a compatible layout. Most data sets tend to be
|
||||
* uniform and have the same major axis as used by OpenAL Soft's HRTF model.
|
||||
* This will remove outliers and produce a maximally dense layout when
|
||||
* possible. Those sets that contain purely random measurements or use
|
||||
* different major axes will fail.
|
||||
*/
|
||||
static bool PrepareLayout(const uint m, const float *xyzs, HrirDataT *hData)
|
||||
{
|
||||
fprintf(stdout, "Detecting compatible layout...\n");
|
||||
|
||||
auto fds = GetCompatibleLayout(m, xyzs);
|
||||
if(fds.size() > MAX_FD_COUNT)
|
||||
{
|
||||
fprintf(stdout, "Incompatible layout (inumerable radii).\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
double distances[MAX_FD_COUNT]{};
|
||||
uint evCounts[MAX_FD_COUNT]{};
|
||||
auto azCounts = std::vector<std::array<uint,MAX_EV_COUNT>>(MAX_FD_COUNT);
|
||||
for(auto &azs : azCounts) azs.fill(0u);
|
||||
|
||||
uint fi{0u}, ir_total{0u};
|
||||
for(const auto &field : fds)
|
||||
{
|
||||
distances[fi] = field.mDistance;
|
||||
evCounts[fi] = field.mEvCount;
|
||||
|
||||
for(uint ei{0u};ei < field.mEvStart;ei++)
|
||||
azCounts[fi][ei] = field.mAzCounts[field.mEvCount-ei-1];
|
||||
for(uint ei{field.mEvStart};ei < field.mEvCount;ei++)
|
||||
{
|
||||
azCounts[fi][ei] = field.mAzCounts[ei];
|
||||
ir_total += field.mAzCounts[ei];
|
||||
}
|
||||
|
||||
++fi;
|
||||
}
|
||||
fprintf(stdout, "Using %u of %u IRs.\n", ir_total, m);
|
||||
const auto azs = al::as_span(azCounts).first<MAX_FD_COUNT>();
|
||||
return PrepareHrirData({distances, fi}, evCounts, azs, hData);
|
||||
}
|
||||
|
||||
|
||||
float GetSampleRate(MYSOFA_HRTF *sofaHrtf)
|
||||
{
|
||||
const char *srate_dim{nullptr};
|
||||
const char *srate_units{nullptr};
|
||||
MYSOFA_ARRAY *srate_array{&sofaHrtf->DataSamplingRate};
|
||||
MYSOFA_ATTRIBUTE *srate_attrs{srate_array->attributes};
|
||||
while(srate_attrs)
|
||||
{
|
||||
if(std::string{"DIMENSION_LIST"} == srate_attrs->name)
|
||||
{
|
||||
if(srate_dim)
|
||||
{
|
||||
fprintf(stderr, "Duplicate SampleRate.DIMENSION_LIST\n");
|
||||
return 0.0f;
|
||||
}
|
||||
srate_dim = srate_attrs->value;
|
||||
}
|
||||
else if(std::string{"Units"} == srate_attrs->name)
|
||||
{
|
||||
if(srate_units)
|
||||
{
|
||||
fprintf(stderr, "Duplicate SampleRate.Units\n");
|
||||
return 0.0f;
|
||||
}
|
||||
srate_units = srate_attrs->value;
|
||||
}
|
||||
else
|
||||
fprintf(stderr, "Unexpected sample rate attribute: %s = %s\n", srate_attrs->name,
|
||||
srate_attrs->value);
|
||||
srate_attrs = srate_attrs->next;
|
||||
}
|
||||
if(!srate_dim)
|
||||
{
|
||||
fprintf(stderr, "Missing sample rate dimensions\n");
|
||||
return 0.0f;
|
||||
}
|
||||
if(srate_dim != std::string{"I"})
|
||||
{
|
||||
fprintf(stderr, "Unsupported sample rate dimensions: %s\n", srate_dim);
|
||||
return 0.0f;
|
||||
}
|
||||
if(!srate_units)
|
||||
{
|
||||
fprintf(stderr, "Missing sample rate unit type\n");
|
||||
return 0.0f;
|
||||
}
|
||||
if(srate_units != std::string{"hertz"})
|
||||
{
|
||||
fprintf(stderr, "Unsupported sample rate unit type: %s\n", srate_units);
|
||||
return 0.0f;
|
||||
}
|
||||
/* I dimensions guarantees 1 element, so just extract it. */
|
||||
if(srate_array->values[0] < MIN_RATE || srate_array->values[0] > MAX_RATE)
|
||||
{
|
||||
fprintf(stderr, "Sample rate out of range: %f (expected %u to %u)", srate_array->values[0],
|
||||
MIN_RATE, MAX_RATE);
|
||||
return 0.0f;
|
||||
}
|
||||
return srate_array->values[0];
|
||||
}
|
||||
|
||||
enum class DelayType : uint8_t {
|
||||
None,
|
||||
I_R, /* [1][Channels] */
|
||||
M_R, /* [HRIRs][Channels] */
|
||||
Invalid,
|
||||
};
|
||||
DelayType PrepareDelay(MYSOFA_HRTF *sofaHrtf)
|
||||
{
|
||||
const char *delay_dim{nullptr};
|
||||
MYSOFA_ARRAY *delay_array{&sofaHrtf->DataDelay};
|
||||
MYSOFA_ATTRIBUTE *delay_attrs{delay_array->attributes};
|
||||
while(delay_attrs)
|
||||
{
|
||||
if(std::string{"DIMENSION_LIST"} == delay_attrs->name)
|
||||
{
|
||||
if(delay_dim)
|
||||
{
|
||||
fprintf(stderr, "Duplicate Delay.DIMENSION_LIST\n");
|
||||
return DelayType::Invalid;
|
||||
}
|
||||
delay_dim = delay_attrs->value;
|
||||
}
|
||||
else
|
||||
fprintf(stderr, "Unexpected delay attribute: %s = %s\n", delay_attrs->name,
|
||||
delay_attrs->value ? delay_attrs->value : "<null>");
|
||||
delay_attrs = delay_attrs->next;
|
||||
}
|
||||
if(!delay_dim)
|
||||
{
|
||||
fprintf(stderr, "Missing delay dimensions\n");
|
||||
return DelayType::None;
|
||||
}
|
||||
if(delay_dim == std::string{"I,R"})
|
||||
return DelayType::I_R;
|
||||
else if(delay_dim == std::string{"M,R"})
|
||||
return DelayType::M_R;
|
||||
|
||||
fprintf(stderr, "Unsupported delay dimensions: %s\n", delay_dim);
|
||||
return DelayType::Invalid;
|
||||
}
|
||||
|
||||
bool CheckIrData(MYSOFA_HRTF *sofaHrtf)
|
||||
{
|
||||
const char *ir_dim{nullptr};
|
||||
MYSOFA_ARRAY *ir_array{&sofaHrtf->DataIR};
|
||||
MYSOFA_ATTRIBUTE *ir_attrs{ir_array->attributes};
|
||||
while(ir_attrs)
|
||||
{
|
||||
if(std::string{"DIMENSION_LIST"} == ir_attrs->name)
|
||||
{
|
||||
if(ir_dim)
|
||||
{
|
||||
fprintf(stderr, "Duplicate IR.DIMENSION_LIST\n");
|
||||
return false;
|
||||
}
|
||||
ir_dim = ir_attrs->value;
|
||||
}
|
||||
else
|
||||
fprintf(stderr, "Unexpected IR attribute: %s = %s\n", ir_attrs->name,
|
||||
ir_attrs->value ? ir_attrs->value : "<null>");
|
||||
ir_attrs = ir_attrs->next;
|
||||
}
|
||||
if(!ir_dim)
|
||||
{
|
||||
fprintf(stderr, "Missing IR dimensions\n");
|
||||
return false;
|
||||
}
|
||||
if(ir_dim != std::string{"M,R,N"})
|
||||
{
|
||||
fprintf(stderr, "Unsupported IR dimensions: %s\n", ir_dim);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
/* Calculate the onset time of a HRIR. */
|
||||
static constexpr int OnsetRateMultiple{10};
|
||||
static double CalcHrirOnset(PPhaseResampler &rs, const uint rate, const uint n,
|
||||
al::span<double> upsampled, const double *hrir)
|
||||
{
|
||||
rs.process(n, hrir, static_cast<uint>(upsampled.size()), upsampled.data());
|
||||
|
||||
auto abs_lt = [](const double &lhs, const double &rhs) -> bool
|
||||
{ return std::abs(lhs) < std::abs(rhs); };
|
||||
auto iter = std::max_element(upsampled.cbegin(), upsampled.cend(), abs_lt);
|
||||
return static_cast<double>(std::distance(upsampled.cbegin(), iter)) /
|
||||
(double{OnsetRateMultiple}*rate);
|
||||
}
|
||||
|
||||
/* Calculate the magnitude response of a HRIR. */
|
||||
static void CalcHrirMagnitude(const uint points, const uint n, al::span<complex_d> h, double *hrir)
|
||||
{
|
||||
auto iter = std::copy_n(hrir, points, h.begin());
|
||||
std::fill(iter, h.end(), complex_d{0.0, 0.0});
|
||||
|
||||
FftForward(n, h.data());
|
||||
MagnitudeResponse(n, h.data(), hrir);
|
||||
}
|
||||
|
||||
static bool LoadResponses(MYSOFA_HRTF *sofaHrtf, HrirDataT *hData, const DelayType delayType,
|
||||
const uint outRate)
|
||||
{
|
||||
std::atomic<uint> loaded_count{0u};
|
||||
|
||||
auto load_proc = [sofaHrtf,hData,delayType,outRate,&loaded_count]() -> bool
|
||||
{
|
||||
const uint channels{(hData->mChannelType == CT_STEREO) ? 2u : 1u};
|
||||
hData->mHrirsBase.resize(channels * hData->mIrCount * hData->mIrSize, 0.0);
|
||||
double *hrirs = hData->mHrirsBase.data();
|
||||
|
||||
std::unique_ptr<double[]> restmp;
|
||||
al::optional<PPhaseResampler> resampler;
|
||||
if(outRate && outRate != hData->mIrRate)
|
||||
{
|
||||
resampler.emplace().init(hData->mIrRate, outRate);
|
||||
restmp = std::make_unique<double[]>(sofaHrtf->N);
|
||||
}
|
||||
|
||||
for(uint si{0u};si < sofaHrtf->M;++si)
|
||||
{
|
||||
loaded_count.fetch_add(1u);
|
||||
|
||||
float aer[3]{
|
||||
sofaHrtf->SourcePosition.values[3*si],
|
||||
sofaHrtf->SourcePosition.values[3*si + 1],
|
||||
sofaHrtf->SourcePosition.values[3*si + 2]
|
||||
};
|
||||
mysofa_c2s(aer);
|
||||
|
||||
if(std::abs(aer[1]) >= 89.999f)
|
||||
aer[0] = 0.0f;
|
||||
else
|
||||
aer[0] = std::fmod(360.0f - aer[0], 360.0f);
|
||||
|
||||
auto field = std::find_if(hData->mFds.cbegin(), hData->mFds.cend(),
|
||||
[&aer](const HrirFdT &fld) -> bool
|
||||
{ return (std::abs(aer[2] - fld.mDistance) < 0.001); });
|
||||
if(field == hData->mFds.cend())
|
||||
continue;
|
||||
|
||||
const double evscale{180.0 / static_cast<double>(field->mEvs.size()-1)};
|
||||
double ef{(90.0 + aer[1]) / evscale};
|
||||
auto ei = static_cast<uint>(std::round(ef));
|
||||
ef = (ef - ei) * evscale;
|
||||
if(std::abs(ef) >= 0.1) continue;
|
||||
|
||||
const double azscale{360.0 / static_cast<double>(field->mEvs[ei].mAzs.size())};
|
||||
double af{aer[0] / azscale};
|
||||
auto ai = static_cast<uint>(std::round(af));
|
||||
af = (af-ai) * azscale;
|
||||
ai %= static_cast<uint>(field->mEvs[ei].mAzs.size());
|
||||
if(std::abs(af) >= 0.1) continue;
|
||||
|
||||
HrirAzT *azd = &field->mEvs[ei].mAzs[ai];
|
||||
if(azd->mIrs[0] != nullptr)
|
||||
{
|
||||
fprintf(stderr, "\nMultiple measurements near [ a=%f, e=%f, r=%f ].\n",
|
||||
aer[0], aer[1], aer[2]);
|
||||
return false;
|
||||
}
|
||||
|
||||
for(uint ti{0u};ti < channels;++ti)
|
||||
{
|
||||
azd->mIrs[ti] = &hrirs[hData->mIrSize * (hData->mIrCount*ti + azd->mIndex)];
|
||||
if(!resampler)
|
||||
std::copy_n(&sofaHrtf->DataIR.values[(si*sofaHrtf->R + ti)*sofaHrtf->N],
|
||||
sofaHrtf->N, azd->mIrs[ti]);
|
||||
else
|
||||
{
|
||||
std::copy_n(&sofaHrtf->DataIR.values[(si*sofaHrtf->R + ti)*sofaHrtf->N],
|
||||
sofaHrtf->N, restmp.get());
|
||||
resampler->process(sofaHrtf->N, restmp.get(), hData->mIrSize, azd->mIrs[ti]);
|
||||
}
|
||||
}
|
||||
|
||||
/* Include any per-channel or per-HRIR delays. */
|
||||
if(delayType == DelayType::I_R)
|
||||
{
|
||||
const float *delayValues{sofaHrtf->DataDelay.values};
|
||||
for(uint ti{0u};ti < channels;++ti)
|
||||
azd->mDelays[ti] = delayValues[ti] / static_cast<float>(hData->mIrRate);
|
||||
}
|
||||
else if(delayType == DelayType::M_R)
|
||||
{
|
||||
const float *delayValues{sofaHrtf->DataDelay.values};
|
||||
for(uint ti{0u};ti < channels;++ti)
|
||||
azd->mDelays[ti] = delayValues[si*sofaHrtf->R + ti] /
|
||||
static_cast<float>(hData->mIrRate);
|
||||
}
|
||||
}
|
||||
|
||||
if(outRate && outRate != hData->mIrRate)
|
||||
{
|
||||
const double scale{static_cast<double>(outRate) / hData->mIrRate};
|
||||
hData->mIrRate = outRate;
|
||||
hData->mIrPoints = std::min(static_cast<uint>(std::ceil(hData->mIrPoints*scale)),
|
||||
hData->mIrSize);
|
||||
}
|
||||
return true;
|
||||
};
|
||||
|
||||
std::future_status load_status{};
|
||||
auto load_future = std::async(std::launch::async, load_proc);
|
||||
do {
|
||||
load_status = load_future.wait_for(std::chrono::milliseconds{50});
|
||||
printf("\rLoading HRIRs... %u of %u", loaded_count.load(), sofaHrtf->M);
|
||||
fflush(stdout);
|
||||
} while(load_status != std::future_status::ready);
|
||||
fputc('\n', stdout);
|
||||
return load_future.get();
|
||||
}
|
||||
|
||||
|
||||
/* Calculates the frequency magnitudes of the HRIR set. Work is delegated to
|
||||
* this struct, which runs asynchronously on one or more threads (sharing the
|
||||
* same calculator object).
|
||||
*/
|
||||
struct MagCalculator {
|
||||
const uint mFftSize{};
|
||||
const uint mIrPoints{};
|
||||
std::vector<double*> mIrs{};
|
||||
std::atomic<size_t> mCurrent{};
|
||||
std::atomic<size_t> mDone{};
|
||||
|
||||
void Worker()
|
||||
{
|
||||
auto htemp = std::vector<complex_d>(mFftSize);
|
||||
|
||||
while(1)
|
||||
{
|
||||
/* Load the current index to process. */
|
||||
size_t idx{mCurrent.load()};
|
||||
do {
|
||||
/* If the index is at the end, we're done. */
|
||||
if(idx >= mIrs.size())
|
||||
return;
|
||||
/* Otherwise, increment the current index atomically so other
|
||||
* threads know to go to the next one. If this call fails, the
|
||||
* current index was just changed by another thread and the new
|
||||
* value is loaded into idx, which we'll recheck.
|
||||
*/
|
||||
} while(!mCurrent.compare_exchange_weak(idx, idx+1, std::memory_order_relaxed));
|
||||
|
||||
CalcHrirMagnitude(mIrPoints, mFftSize, htemp, mIrs[idx]);
|
||||
|
||||
/* Increment the number of IRs done. */
|
||||
mDone.fetch_add(1);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
bool LoadSofaFile(const char *filename, const uint numThreads, const uint fftSize,
|
||||
const uint truncSize, const uint outRate, const ChannelModeT chanMode, HrirDataT *hData)
|
||||
{
|
||||
int err;
|
||||
MySofaHrtfPtr sofaHrtf{mysofa_load(filename, &err)};
|
||||
if(!sofaHrtf)
|
||||
{
|
||||
fprintf(stdout, "Error: Could not load %s: %s\n", filename, SofaErrorStr(err));
|
||||
return false;
|
||||
}
|
||||
|
||||
/* NOTE: Some valid SOFA files are failing this check. */
|
||||
err = mysofa_check(sofaHrtf.get());
|
||||
if(err != MYSOFA_OK)
|
||||
fprintf(stderr, "Warning: Supposedly malformed source file '%s' (%s).\n", filename,
|
||||
SofaErrorStr(err));
|
||||
|
||||
mysofa_tocartesian(sofaHrtf.get());
|
||||
|
||||
/* Make sure emitter and receiver counts are sane. */
|
||||
if(sofaHrtf->E != 1)
|
||||
{
|
||||
fprintf(stderr, "%u emitters not supported\n", sofaHrtf->E);
|
||||
return false;
|
||||
}
|
||||
if(sofaHrtf->R > 2 || sofaHrtf->R < 1)
|
||||
{
|
||||
fprintf(stderr, "%u receivers not supported\n", sofaHrtf->R);
|
||||
return false;
|
||||
}
|
||||
/* Assume R=2 is a stereo measurement, and R=1 is mono left-ear-only. */
|
||||
if(sofaHrtf->R == 2 && chanMode == CM_AllowStereo)
|
||||
hData->mChannelType = CT_STEREO;
|
||||
else
|
||||
hData->mChannelType = CT_MONO;
|
||||
|
||||
/* Check and set the FFT and IR size. */
|
||||
if(sofaHrtf->N > fftSize)
|
||||
{
|
||||
fprintf(stderr, "Sample points exceeds the FFT size.\n");
|
||||
return false;
|
||||
}
|
||||
if(sofaHrtf->N < truncSize)
|
||||
{
|
||||
fprintf(stderr, "Sample points is below the truncation size.\n");
|
||||
return false;
|
||||
}
|
||||
hData->mIrPoints = sofaHrtf->N;
|
||||
hData->mFftSize = fftSize;
|
||||
hData->mIrSize = std::max(1u + (fftSize/2u), sofaHrtf->N);
|
||||
|
||||
/* Assume a default head radius of 9cm. */
|
||||
hData->mRadius = 0.09;
|
||||
|
||||
hData->mIrRate = static_cast<uint>(GetSampleRate(sofaHrtf.get()) + 0.5f);
|
||||
if(!hData->mIrRate)
|
||||
return false;
|
||||
|
||||
DelayType delayType = PrepareDelay(sofaHrtf.get());
|
||||
if(delayType == DelayType::Invalid)
|
||||
return false;
|
||||
|
||||
if(!CheckIrData(sofaHrtf.get()))
|
||||
return false;
|
||||
if(!PrepareLayout(sofaHrtf->M, sofaHrtf->SourcePosition.values, hData))
|
||||
return false;
|
||||
if(!LoadResponses(sofaHrtf.get(), hData, delayType, outRate))
|
||||
return false;
|
||||
sofaHrtf = nullptr;
|
||||
|
||||
for(uint fi{0u};fi < hData->mFds.size();fi++)
|
||||
{
|
||||
uint ei{0u};
|
||||
for(;ei < hData->mFds[fi].mEvs.size();ei++)
|
||||
{
|
||||
uint ai{0u};
|
||||
for(;ai < hData->mFds[fi].mEvs[ei].mAzs.size();ai++)
|
||||
{
|
||||
HrirAzT &azd = hData->mFds[fi].mEvs[ei].mAzs[ai];
|
||||
if(azd.mIrs[0] != nullptr) break;
|
||||
}
|
||||
if(ai < hData->mFds[fi].mEvs[ei].mAzs.size())
|
||||
break;
|
||||
}
|
||||
if(ei >= hData->mFds[fi].mEvs.size())
|
||||
{
|
||||
fprintf(stderr, "Missing source references [ %d, *, * ].\n", fi);
|
||||
return false;
|
||||
}
|
||||
hData->mFds[fi].mEvStart = ei;
|
||||
for(;ei < hData->mFds[fi].mEvs.size();ei++)
|
||||
{
|
||||
for(uint ai{0u};ai < hData->mFds[fi].mEvs[ei].mAzs.size();ai++)
|
||||
{
|
||||
HrirAzT &azd = hData->mFds[fi].mEvs[ei].mAzs[ai];
|
||||
if(azd.mIrs[0] == nullptr)
|
||||
{
|
||||
fprintf(stderr, "Missing source reference [ %d, %d, %d ].\n", fi, ei, ai);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
size_t hrir_total{0};
|
||||
const uint channels{(hData->mChannelType == CT_STEREO) ? 2u : 1u};
|
||||
double *hrirs = hData->mHrirsBase.data();
|
||||
for(uint fi{0u};fi < hData->mFds.size();fi++)
|
||||
{
|
||||
for(uint ei{0u};ei < hData->mFds[fi].mEvStart;ei++)
|
||||
{
|
||||
for(uint ai{0u};ai < hData->mFds[fi].mEvs[ei].mAzs.size();ai++)
|
||||
{
|
||||
HrirAzT &azd = hData->mFds[fi].mEvs[ei].mAzs[ai];
|
||||
for(uint ti{0u};ti < channels;ti++)
|
||||
azd.mIrs[ti] = &hrirs[hData->mIrSize * (hData->mIrCount*ti + azd.mIndex)];
|
||||
}
|
||||
}
|
||||
|
||||
for(uint ei{hData->mFds[fi].mEvStart};ei < hData->mFds[fi].mEvs.size();ei++)
|
||||
hrir_total += hData->mFds[fi].mEvs[ei].mAzs.size() * channels;
|
||||
}
|
||||
|
||||
std::atomic<size_t> hrir_done{0};
|
||||
auto onset_proc = [hData,channels,&hrir_done]() -> bool
|
||||
{
|
||||
/* Temporary buffer used to calculate the IR's onset. */
|
||||
auto upsampled = std::vector<double>(OnsetRateMultiple * hData->mIrPoints);
|
||||
/* This resampler is used to help detect the response onset. */
|
||||
PPhaseResampler rs;
|
||||
rs.init(hData->mIrRate, OnsetRateMultiple*hData->mIrRate);
|
||||
|
||||
for(auto &field : hData->mFds)
|
||||
{
|
||||
for(auto &elev : field.mEvs.subspan(field.mEvStart))
|
||||
{
|
||||
for(auto &azd : elev.mAzs)
|
||||
{
|
||||
for(uint ti{0};ti < channels;ti++)
|
||||
{
|
||||
hrir_done.fetch_add(1u, std::memory_order_acq_rel);
|
||||
azd.mDelays[ti] += CalcHrirOnset(rs, hData->mIrRate, hData->mIrPoints,
|
||||
upsampled, azd.mIrs[ti]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
};
|
||||
|
||||
std::future_status load_status{};
|
||||
auto load_future = std::async(std::launch::async, onset_proc);
|
||||
do {
|
||||
load_status = load_future.wait_for(std::chrono::milliseconds{50});
|
||||
printf("\rCalculating HRIR onsets... %zu of %zu", hrir_done.load(), hrir_total);
|
||||
fflush(stdout);
|
||||
} while(load_status != std::future_status::ready);
|
||||
fputc('\n', stdout);
|
||||
if(!load_future.get())
|
||||
return false;
|
||||
|
||||
MagCalculator calculator{hData->mFftSize, hData->mIrPoints};
|
||||
for(auto &field : hData->mFds)
|
||||
{
|
||||
for(auto &elev : field.mEvs.subspan(field.mEvStart))
|
||||
{
|
||||
for(auto &azd : elev.mAzs)
|
||||
{
|
||||
for(uint ti{0};ti < channels;ti++)
|
||||
calculator.mIrs.push_back(azd.mIrs[ti]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
std::vector<std::thread> thrds;
|
||||
thrds.reserve(numThreads);
|
||||
for(size_t i{0};i < numThreads;++i)
|
||||
thrds.emplace_back(std::mem_fn(&MagCalculator::Worker), &calculator);
|
||||
size_t count;
|
||||
do {
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds{50});
|
||||
count = calculator.mDone.load();
|
||||
|
||||
printf("\rCalculating HRIR magnitudes... %zu of %zu", count, calculator.mIrs.size());
|
||||
fflush(stdout);
|
||||
} while(count != calculator.mIrs.size());
|
||||
fputc('\n', stdout);
|
||||
|
||||
for(auto &thrd : thrds)
|
||||
{
|
||||
if(thrd.joinable())
|
||||
thrd.join();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
10
externals/openal-soft/utils/makemhr/loadsofa.h
vendored
Normal file
10
externals/openal-soft/utils/makemhr/loadsofa.h
vendored
Normal file
@@ -0,0 +1,10 @@
|
||||
#ifndef LOADSOFA_H
|
||||
#define LOADSOFA_H
|
||||
|
||||
#include "makemhr.h"
|
||||
|
||||
|
||||
bool LoadSofaFile(const char *filename, const uint numThreads, const uint fftSize,
|
||||
const uint truncSize, const uint outRate, const ChannelModeT chanMode, HrirDataT *hData);
|
||||
|
||||
#endif /* LOADSOFA_H */
|
||||
1473
externals/openal-soft/utils/makemhr/makemhr.cpp
vendored
Normal file
1473
externals/openal-soft/utils/makemhr/makemhr.cpp
vendored
Normal file
File diff suppressed because it is too large
Load Diff
131
externals/openal-soft/utils/makemhr/makemhr.h
vendored
Normal file
131
externals/openal-soft/utils/makemhr/makemhr.h
vendored
Normal file
@@ -0,0 +1,131 @@
|
||||
#ifndef MAKEMHR_H
|
||||
#define MAKEMHR_H
|
||||
|
||||
#include <vector>
|
||||
#include <complex>
|
||||
|
||||
#include "alcomplex.h"
|
||||
#include "polyphase_resampler.h"
|
||||
|
||||
|
||||
// The maximum path length used when processing filenames.
|
||||
#define MAX_PATH_LEN (256)
|
||||
|
||||
// The limit to the number of 'distances' listed in the data set definition.
|
||||
// Must be less than 256
|
||||
#define MAX_FD_COUNT (16)
|
||||
|
||||
// The limits to the number of 'elevations' listed in the data set definition.
|
||||
// Must be less than 256.
|
||||
#define MIN_EV_COUNT (5)
|
||||
#define MAX_EV_COUNT (181)
|
||||
|
||||
// The limits for each of the 'azimuths' listed in the data set definition.
|
||||
// Must be less than 256.
|
||||
#define MIN_AZ_COUNT (1)
|
||||
#define MAX_AZ_COUNT (255)
|
||||
|
||||
// The limits for the 'distance' from source to listener for each field in
|
||||
// the definition file.
|
||||
#define MIN_DISTANCE (0.05)
|
||||
#define MAX_DISTANCE (2.50)
|
||||
|
||||
// The limits for the sample 'rate' metric in the data set definition and for
|
||||
// resampling.
|
||||
#define MIN_RATE (32000)
|
||||
#define MAX_RATE (96000)
|
||||
|
||||
// The limits for the HRIR 'points' metric in the data set definition.
|
||||
#define MIN_POINTS (16)
|
||||
#define MAX_POINTS (8192)
|
||||
|
||||
|
||||
using uint = unsigned int;
|
||||
|
||||
/* Complex double type. */
|
||||
using complex_d = std::complex<double>;
|
||||
|
||||
|
||||
enum ChannelModeT : bool {
|
||||
CM_AllowStereo = false,
|
||||
CM_ForceMono = true
|
||||
};
|
||||
|
||||
// Sample and channel type enum values.
|
||||
enum SampleTypeT {
|
||||
ST_S16 = 0,
|
||||
ST_S24 = 1
|
||||
};
|
||||
|
||||
// Certain iterations rely on these integer enum values.
|
||||
enum ChannelTypeT {
|
||||
CT_NONE = -1,
|
||||
CT_MONO = 0,
|
||||
CT_STEREO = 1
|
||||
};
|
||||
|
||||
// Structured HRIR storage for stereo azimuth pairs, elevations, and fields.
|
||||
struct HrirAzT {
|
||||
double mAzimuth{0.0};
|
||||
uint mIndex{0u};
|
||||
double mDelays[2]{0.0, 0.0};
|
||||
double *mIrs[2]{nullptr, nullptr};
|
||||
};
|
||||
|
||||
struct HrirEvT {
|
||||
double mElevation{0.0};
|
||||
al::span<HrirAzT> mAzs;
|
||||
};
|
||||
|
||||
struct HrirFdT {
|
||||
double mDistance{0.0};
|
||||
uint mEvStart{0u};
|
||||
al::span<HrirEvT> mEvs;
|
||||
};
|
||||
|
||||
// The HRIR metrics and data set used when loading, processing, and storing
|
||||
// the resulting HRTF.
|
||||
struct HrirDataT {
|
||||
uint mIrRate{0u};
|
||||
SampleTypeT mSampleType{ST_S24};
|
||||
ChannelTypeT mChannelType{CT_NONE};
|
||||
uint mIrPoints{0u};
|
||||
uint mFftSize{0u};
|
||||
uint mIrSize{0u};
|
||||
double mRadius{0.0};
|
||||
uint mIrCount{0u};
|
||||
|
||||
std::vector<double> mHrirsBase;
|
||||
std::vector<HrirEvT> mEvsBase;
|
||||
std::vector<HrirAzT> mAzsBase;
|
||||
|
||||
std::vector<HrirFdT> mFds;
|
||||
|
||||
/* GCC warns when it tries to inline this. */
|
||||
~HrirDataT();
|
||||
};
|
||||
|
||||
|
||||
bool PrepareHrirData(const al::span<const double> distances,
|
||||
const al::span<const uint,MAX_FD_COUNT> evCounts,
|
||||
const al::span<const std::array<uint,MAX_EV_COUNT>,MAX_FD_COUNT> azCounts, HrirDataT *hData);
|
||||
void MagnitudeResponse(const uint n, const complex_d *in, double *out);
|
||||
|
||||
// Performs a forward FFT.
|
||||
inline void FftForward(const uint n, complex_d *inout)
|
||||
{ forward_fft(al::as_span(inout, n)); }
|
||||
|
||||
// Performs an inverse FFT.
|
||||
inline void FftInverse(const uint n, complex_d *inout)
|
||||
{
|
||||
inverse_fft(al::as_span(inout, n));
|
||||
double f{1.0 / n};
|
||||
for(uint i{0};i < n;i++)
|
||||
inout[i] *= f;
|
||||
}
|
||||
|
||||
// Performs linear interpolation.
|
||||
inline double Lerp(const double a, const double b, const double f)
|
||||
{ return a + f * (b - a); }
|
||||
|
||||
#endif /* MAKEMHR_H */
|
||||
444
externals/openal-soft/utils/openal-info.c
vendored
Normal file
444
externals/openal-soft/utils/openal-info.c
vendored
Normal file
@@ -0,0 +1,444 @@
|
||||
/*
|
||||
* OpenAL Info Utility
|
||||
*
|
||||
* Copyright (c) 2010 by Chris Robinson <chris.kcat@gmail.com>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <assert.h>
|
||||
#include <stdarg.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "AL/alc.h"
|
||||
#include "AL/al.h"
|
||||
#include "AL/alext.h"
|
||||
|
||||
#include "win_main_utf8.h"
|
||||
|
||||
/* C doesn't allow casting between function and non-function pointer types, so
|
||||
* with C99 we need to use a union to reinterpret the pointer type. Pre-C99
|
||||
* still needs to use a normal cast and live with the warning (C++ is fine with
|
||||
* a regular reinterpret_cast).
|
||||
*/
|
||||
#if __STDC_VERSION__ >= 199901L
|
||||
#define FUNCTION_CAST(T, ptr) (union{void *p; T f;}){ptr}.f
|
||||
#else
|
||||
#define FUNCTION_CAST(T, ptr) (T)(ptr)
|
||||
#endif
|
||||
|
||||
#define MAX_WIDTH 80
|
||||
|
||||
static void printList(const char *list, char separator)
|
||||
{
|
||||
size_t col = MAX_WIDTH, len;
|
||||
const char *indent = " ";
|
||||
const char *next;
|
||||
|
||||
if(!list || *list == '\0')
|
||||
{
|
||||
fprintf(stdout, "\n%s!!! none !!!\n", indent);
|
||||
return;
|
||||
}
|
||||
|
||||
do {
|
||||
next = strchr(list, separator);
|
||||
if(next)
|
||||
{
|
||||
len = (size_t)(next-list);
|
||||
do {
|
||||
next++;
|
||||
} while(*next == separator);
|
||||
}
|
||||
else
|
||||
len = strlen(list);
|
||||
|
||||
if(len + col + 2 >= MAX_WIDTH)
|
||||
{
|
||||
fprintf(stdout, "\n%s", indent);
|
||||
col = strlen(indent);
|
||||
}
|
||||
else
|
||||
{
|
||||
fputc(' ', stdout);
|
||||
col++;
|
||||
}
|
||||
|
||||
len = fwrite(list, 1, len, stdout);
|
||||
col += len;
|
||||
|
||||
if(!next || *next == '\0')
|
||||
break;
|
||||
fputc(',', stdout);
|
||||
col++;
|
||||
|
||||
list = next;
|
||||
} while(1);
|
||||
fputc('\n', stdout);
|
||||
}
|
||||
|
||||
static void printDeviceList(const char *list)
|
||||
{
|
||||
if(!list || *list == '\0')
|
||||
printf(" !!! none !!!\n");
|
||||
else do {
|
||||
printf(" %s\n", list);
|
||||
list += strlen(list) + 1;
|
||||
} while(*list != '\0');
|
||||
}
|
||||
|
||||
|
||||
static ALenum checkALErrors(int linenum)
|
||||
{
|
||||
ALenum err = alGetError();
|
||||
if(err != AL_NO_ERROR)
|
||||
printf("OpenAL Error: %s (0x%x), @ %d\n", alGetString(err), err, linenum);
|
||||
return err;
|
||||
}
|
||||
#define checkALErrors() checkALErrors(__LINE__)
|
||||
|
||||
static ALCenum checkALCErrors(ALCdevice *device, int linenum)
|
||||
{
|
||||
ALCenum err = alcGetError(device);
|
||||
if(err != ALC_NO_ERROR)
|
||||
printf("ALC Error: %s (0x%x), @ %d\n", alcGetString(device, err), err, linenum);
|
||||
return err;
|
||||
}
|
||||
#define checkALCErrors(x) checkALCErrors((x),__LINE__)
|
||||
|
||||
|
||||
static void printALCInfo(ALCdevice *device)
|
||||
{
|
||||
ALCint major, minor;
|
||||
|
||||
if(device)
|
||||
{
|
||||
const ALCchar *devname = NULL;
|
||||
printf("\n");
|
||||
if(alcIsExtensionPresent(device, "ALC_ENUMERATE_ALL_EXT") != AL_FALSE)
|
||||
devname = alcGetString(device, ALC_ALL_DEVICES_SPECIFIER);
|
||||
if(checkALCErrors(device) != ALC_NO_ERROR || !devname)
|
||||
devname = alcGetString(device, ALC_DEVICE_SPECIFIER);
|
||||
printf("** Info for device \"%s\" **\n", devname);
|
||||
}
|
||||
alcGetIntegerv(device, ALC_MAJOR_VERSION, 1, &major);
|
||||
alcGetIntegerv(device, ALC_MINOR_VERSION, 1, &minor);
|
||||
if(checkALCErrors(device) == ALC_NO_ERROR)
|
||||
printf("ALC version: %d.%d\n", major, minor);
|
||||
if(device)
|
||||
{
|
||||
printf("ALC extensions:");
|
||||
printList(alcGetString(device, ALC_EXTENSIONS), ' ');
|
||||
checkALCErrors(device);
|
||||
}
|
||||
}
|
||||
|
||||
static void printHRTFInfo(ALCdevice *device)
|
||||
{
|
||||
LPALCGETSTRINGISOFT alcGetStringiSOFT;
|
||||
ALCint num_hrtfs;
|
||||
|
||||
if(alcIsExtensionPresent(device, "ALC_SOFT_HRTF") == ALC_FALSE)
|
||||
{
|
||||
printf("HRTF extension not available\n");
|
||||
return;
|
||||
}
|
||||
|
||||
alcGetStringiSOFT = FUNCTION_CAST(LPALCGETSTRINGISOFT,
|
||||
alcGetProcAddress(device, "alcGetStringiSOFT"));
|
||||
|
||||
alcGetIntegerv(device, ALC_NUM_HRTF_SPECIFIERS_SOFT, 1, &num_hrtfs);
|
||||
if(!num_hrtfs)
|
||||
printf("No HRTFs found\n");
|
||||
else
|
||||
{
|
||||
ALCint i;
|
||||
printf("Available HRTFs:\n");
|
||||
for(i = 0;i < num_hrtfs;++i)
|
||||
{
|
||||
const ALCchar *name = alcGetStringiSOFT(device, ALC_HRTF_SPECIFIER_SOFT, i);
|
||||
printf(" %s\n", name);
|
||||
}
|
||||
}
|
||||
checkALCErrors(device);
|
||||
}
|
||||
|
||||
static void printModeInfo(ALCdevice *device)
|
||||
{
|
||||
ALCint srate = 0;
|
||||
|
||||
if(alcIsExtensionPresent(device, "ALC_SOFT_output_mode"))
|
||||
{
|
||||
const char *modename = "(error)";
|
||||
ALCenum mode = 0;
|
||||
|
||||
alcGetIntegerv(device, ALC_OUTPUT_MODE_SOFT, 1, &mode);
|
||||
checkALCErrors(device);
|
||||
switch(mode)
|
||||
{
|
||||
case ALC_ANY_SOFT: modename = "Unknown / unspecified"; break;
|
||||
case ALC_MONO_SOFT: modename = "Mono"; break;
|
||||
case ALC_STEREO_SOFT: modename = "Stereo (unspecified encoding)"; break;
|
||||
case ALC_STEREO_BASIC_SOFT: modename = "Stereo (basic)"; break;
|
||||
case ALC_STEREO_UHJ_SOFT: modename = "Stereo (UHJ)"; break;
|
||||
case ALC_STEREO_HRTF_SOFT: modename = "Stereo (HRTF)"; break;
|
||||
case ALC_QUAD_SOFT: modename = "Quadraphonic"; break;
|
||||
case ALC_SURROUND_5_1_SOFT: modename = "5.1 Surround"; break;
|
||||
case ALC_SURROUND_6_1_SOFT: modename = "6.1 Surround"; break;
|
||||
case ALC_SURROUND_7_1_SOFT: modename = "7.1 Surround"; break;
|
||||
}
|
||||
printf("Device output mode: %s\n", modename);
|
||||
}
|
||||
else
|
||||
printf("Output mode extension not available\n");
|
||||
|
||||
alcGetIntegerv(device, ALC_FREQUENCY, 1, &srate);
|
||||
if(checkALCErrors(device) == ALC_NO_ERROR)
|
||||
printf("Device sample rate: %dhz\n", srate);
|
||||
}
|
||||
|
||||
static void printALInfo(void)
|
||||
{
|
||||
printf("OpenAL vendor string: %s\n", alGetString(AL_VENDOR));
|
||||
printf("OpenAL renderer string: %s\n", alGetString(AL_RENDERER));
|
||||
printf("OpenAL version string: %s\n", alGetString(AL_VERSION));
|
||||
printf("OpenAL extensions:");
|
||||
printList(alGetString(AL_EXTENSIONS), ' ');
|
||||
checkALErrors();
|
||||
}
|
||||
|
||||
static void printResamplerInfo(void)
|
||||
{
|
||||
LPALGETSTRINGISOFT alGetStringiSOFT;
|
||||
ALint num_resamplers;
|
||||
ALint def_resampler;
|
||||
|
||||
if(!alIsExtensionPresent("AL_SOFT_source_resampler"))
|
||||
{
|
||||
printf("Resampler info not available\n");
|
||||
return;
|
||||
}
|
||||
|
||||
alGetStringiSOFT = FUNCTION_CAST(LPALGETSTRINGISOFT, alGetProcAddress("alGetStringiSOFT"));
|
||||
|
||||
num_resamplers = alGetInteger(AL_NUM_RESAMPLERS_SOFT);
|
||||
def_resampler = alGetInteger(AL_DEFAULT_RESAMPLER_SOFT);
|
||||
|
||||
if(!num_resamplers)
|
||||
printf("!!! No resamplers found !!!\n");
|
||||
else
|
||||
{
|
||||
ALint i;
|
||||
printf("Available resamplers:\n");
|
||||
for(i = 0;i < num_resamplers;++i)
|
||||
{
|
||||
const ALchar *name = alGetStringiSOFT(AL_RESAMPLER_NAME_SOFT, i);
|
||||
printf(" %s%s\n", name, (i==def_resampler)?" *":"");
|
||||
}
|
||||
}
|
||||
checkALErrors();
|
||||
}
|
||||
|
||||
static void printEFXInfo(ALCdevice *device)
|
||||
{
|
||||
static LPALGENFILTERS palGenFilters;
|
||||
static LPALDELETEFILTERS palDeleteFilters;
|
||||
static LPALFILTERI palFilteri;
|
||||
static LPALGENEFFECTS palGenEffects;
|
||||
static LPALDELETEEFFECTS palDeleteEffects;
|
||||
static LPALEFFECTI palEffecti;
|
||||
|
||||
static const ALint filters[] = {
|
||||
AL_FILTER_LOWPASS, AL_FILTER_HIGHPASS, AL_FILTER_BANDPASS,
|
||||
AL_FILTER_NULL
|
||||
};
|
||||
char filterNames[] = "Low-pass,High-pass,Band-pass,";
|
||||
static const ALint effects[] = {
|
||||
AL_EFFECT_EAXREVERB, AL_EFFECT_REVERB, AL_EFFECT_CHORUS,
|
||||
AL_EFFECT_DISTORTION, AL_EFFECT_ECHO, AL_EFFECT_FLANGER,
|
||||
AL_EFFECT_FREQUENCY_SHIFTER, AL_EFFECT_VOCAL_MORPHER,
|
||||
AL_EFFECT_PITCH_SHIFTER, AL_EFFECT_RING_MODULATOR,
|
||||
AL_EFFECT_AUTOWAH, AL_EFFECT_COMPRESSOR, AL_EFFECT_EQUALIZER,
|
||||
AL_EFFECT_NULL
|
||||
};
|
||||
static const ALint dedeffects[] = {
|
||||
AL_EFFECT_DEDICATED_DIALOGUE, AL_EFFECT_DEDICATED_LOW_FREQUENCY_EFFECT,
|
||||
AL_EFFECT_NULL
|
||||
};
|
||||
char effectNames[] = "EAX Reverb,Reverb,Chorus,Distortion,Echo,Flanger,"
|
||||
"Frequency Shifter,Vocal Morpher,Pitch Shifter,Ring Modulator,Autowah,"
|
||||
"Compressor,Equalizer,Dedicated Dialog,Dedicated LFE,";
|
||||
ALCint major, minor, sends;
|
||||
ALuint object;
|
||||
char *current;
|
||||
int i;
|
||||
|
||||
if(alcIsExtensionPresent(device, "ALC_EXT_EFX") == AL_FALSE)
|
||||
{
|
||||
printf("EFX not available\n");
|
||||
return;
|
||||
}
|
||||
|
||||
palGenFilters = FUNCTION_CAST(LPALGENFILTERS, alGetProcAddress("alGenFilters"));
|
||||
palDeleteFilters = FUNCTION_CAST(LPALDELETEFILTERS, alGetProcAddress("alDeleteFilters"));
|
||||
palFilteri = FUNCTION_CAST(LPALFILTERI, alGetProcAddress("alFilteri"));
|
||||
palGenEffects = FUNCTION_CAST(LPALGENEFFECTS, alGetProcAddress("alGenEffects"));
|
||||
palDeleteEffects = FUNCTION_CAST(LPALDELETEEFFECTS, alGetProcAddress("alDeleteEffects"));
|
||||
palEffecti = FUNCTION_CAST(LPALEFFECTI, alGetProcAddress("alEffecti"));
|
||||
|
||||
alcGetIntegerv(device, ALC_EFX_MAJOR_VERSION, 1, &major);
|
||||
alcGetIntegerv(device, ALC_EFX_MINOR_VERSION, 1, &minor);
|
||||
if(checkALCErrors(device) == ALC_NO_ERROR)
|
||||
printf("EFX version: %d.%d\n", major, minor);
|
||||
alcGetIntegerv(device, ALC_MAX_AUXILIARY_SENDS, 1, &sends);
|
||||
if(checkALCErrors(device) == ALC_NO_ERROR)
|
||||
printf("Max auxiliary sends: %d\n", sends);
|
||||
|
||||
palGenFilters(1, &object);
|
||||
checkALErrors();
|
||||
|
||||
current = filterNames;
|
||||
for(i = 0;filters[i] != AL_FILTER_NULL;i++)
|
||||
{
|
||||
char *next = strchr(current, ',');
|
||||
assert(next != NULL);
|
||||
|
||||
palFilteri(object, AL_FILTER_TYPE, filters[i]);
|
||||
if(alGetError() != AL_NO_ERROR)
|
||||
memmove(current, next+1, strlen(next));
|
||||
else
|
||||
current = next+1;
|
||||
}
|
||||
printf("Supported filters:");
|
||||
printList(filterNames, ',');
|
||||
|
||||
palDeleteFilters(1, &object);
|
||||
palGenEffects(1, &object);
|
||||
checkALErrors();
|
||||
|
||||
current = effectNames;
|
||||
for(i = 0;effects[i] != AL_EFFECT_NULL;i++)
|
||||
{
|
||||
char *next = strchr(current, ',');
|
||||
assert(next != NULL);
|
||||
|
||||
palEffecti(object, AL_EFFECT_TYPE, effects[i]);
|
||||
if(alGetError() != AL_NO_ERROR)
|
||||
memmove(current, next+1, strlen(next));
|
||||
else
|
||||
current = next+1;
|
||||
}
|
||||
if(alcIsExtensionPresent(device, "ALC_EXT_DEDICATED"))
|
||||
{
|
||||
for(i = 0;dedeffects[i] != AL_EFFECT_NULL;i++)
|
||||
{
|
||||
char *next = strchr(current, ',');
|
||||
assert(next != NULL);
|
||||
|
||||
palEffecti(object, AL_EFFECT_TYPE, dedeffects[i]);
|
||||
if(alGetError() != AL_NO_ERROR)
|
||||
memmove(current, next+1, strlen(next));
|
||||
else
|
||||
current = next+1;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for(i = 0;dedeffects[i] != AL_EFFECT_NULL;i++)
|
||||
{
|
||||
char *next = strchr(current, ',');
|
||||
assert(next != NULL);
|
||||
memmove(current, next+1, strlen(next));
|
||||
}
|
||||
}
|
||||
printf("Supported effects:");
|
||||
printList(effectNames, ',');
|
||||
|
||||
palDeleteEffects(1, &object);
|
||||
checkALErrors();
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
ALCdevice *device;
|
||||
ALCcontext *context;
|
||||
|
||||
#ifdef _WIN32
|
||||
/* OpenAL Soft gives UTF-8 strings, so set the console to expect that. */
|
||||
SetConsoleOutputCP(CP_UTF8);
|
||||
#endif
|
||||
|
||||
if(argc > 1 && (strcmp(argv[1], "--help") == 0 ||
|
||||
strcmp(argv[1], "-h") == 0))
|
||||
{
|
||||
printf("Usage: %s [playback device]\n", argv[0]);
|
||||
return 0;
|
||||
}
|
||||
|
||||
printf("Available playback devices:\n");
|
||||
if(alcIsExtensionPresent(NULL, "ALC_ENUMERATE_ALL_EXT") != AL_FALSE)
|
||||
printDeviceList(alcGetString(NULL, ALC_ALL_DEVICES_SPECIFIER));
|
||||
else
|
||||
printDeviceList(alcGetString(NULL, ALC_DEVICE_SPECIFIER));
|
||||
printf("Available capture devices:\n");
|
||||
printDeviceList(alcGetString(NULL, ALC_CAPTURE_DEVICE_SPECIFIER));
|
||||
|
||||
if(alcIsExtensionPresent(NULL, "ALC_ENUMERATE_ALL_EXT") != AL_FALSE)
|
||||
printf("Default playback device: %s\n",
|
||||
alcGetString(NULL, ALC_DEFAULT_ALL_DEVICES_SPECIFIER));
|
||||
else
|
||||
printf("Default playback device: %s\n",
|
||||
alcGetString(NULL, ALC_DEFAULT_DEVICE_SPECIFIER));
|
||||
printf("Default capture device: %s\n",
|
||||
alcGetString(NULL, ALC_CAPTURE_DEFAULT_DEVICE_SPECIFIER));
|
||||
|
||||
printALCInfo(NULL);
|
||||
|
||||
device = alcOpenDevice((argc>1) ? argv[1] : NULL);
|
||||
if(!device)
|
||||
{
|
||||
printf("\n!!! Failed to open %s !!!\n\n", ((argc>1) ? argv[1] : "default device"));
|
||||
return 1;
|
||||
}
|
||||
printALCInfo(device);
|
||||
printHRTFInfo(device);
|
||||
|
||||
context = alcCreateContext(device, NULL);
|
||||
if(!context || alcMakeContextCurrent(context) == ALC_FALSE)
|
||||
{
|
||||
if(context)
|
||||
alcDestroyContext(context);
|
||||
alcCloseDevice(device);
|
||||
printf("\n!!! Failed to set a context !!!\n\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
printModeInfo(device);
|
||||
printALInfo();
|
||||
printResamplerInfo();
|
||||
printEFXInfo(device);
|
||||
|
||||
alcMakeContextCurrent(NULL);
|
||||
alcDestroyContext(context);
|
||||
alcCloseDevice(device);
|
||||
|
||||
return 0;
|
||||
}
|
||||
139
externals/openal-soft/utils/sofa-info.cpp
vendored
Normal file
139
externals/openal-soft/utils/sofa-info.cpp
vendored
Normal file
@@ -0,0 +1,139 @@
|
||||
/*
|
||||
* SOFA info utility for inspecting SOFA file metrics and determining HRTF
|
||||
* utility compatible layouts.
|
||||
*
|
||||
* Copyright (C) 2018-2019 Christopher Fitzgerald
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Or visit: http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#include <memory>
|
||||
#include <vector>
|
||||
|
||||
#include "sofa-support.h"
|
||||
|
||||
#include "mysofa.h"
|
||||
|
||||
#include "win_main_utf8.h"
|
||||
|
||||
using uint = unsigned int;
|
||||
|
||||
static void PrintSofaAttributes(const char *prefix, struct MYSOFA_ATTRIBUTE *attribute)
|
||||
{
|
||||
while(attribute)
|
||||
{
|
||||
fprintf(stdout, "%s.%s: %s\n", prefix, attribute->name, attribute->value);
|
||||
attribute = attribute->next;
|
||||
}
|
||||
}
|
||||
|
||||
static void PrintSofaArray(const char *prefix, struct MYSOFA_ARRAY *array)
|
||||
{
|
||||
PrintSofaAttributes(prefix, array->attributes);
|
||||
for(uint i{0u};i < array->elements;i++)
|
||||
fprintf(stdout, "%s[%u]: %.6f\n", prefix, i, array->values[i]);
|
||||
}
|
||||
|
||||
/* Attempts to produce a compatible layout. Most data sets tend to be
|
||||
* uniform and have the same major axis as used by OpenAL Soft's HRTF model.
|
||||
* This will remove outliers and produce a maximally dense layout when
|
||||
* possible. Those sets that contain purely random measurements or use
|
||||
* different major axes will fail.
|
||||
*/
|
||||
static void PrintCompatibleLayout(const uint m, const float *xyzs)
|
||||
{
|
||||
fputc('\n', stdout);
|
||||
|
||||
auto fds = GetCompatibleLayout(m, xyzs);
|
||||
if(fds.empty())
|
||||
{
|
||||
fprintf(stdout, "No compatible field layouts in SOFA file.\n");
|
||||
return;
|
||||
}
|
||||
|
||||
uint used_elems{0};
|
||||
for(size_t fi{0u};fi < fds.size();++fi)
|
||||
{
|
||||
for(uint ei{fds[fi].mEvStart};ei < fds[fi].mEvCount;++ei)
|
||||
used_elems += fds[fi].mAzCounts[ei];
|
||||
}
|
||||
|
||||
fprintf(stdout, "Compatible Layout (%u of %u measurements):\n\ndistance = %.3f", used_elems, m,
|
||||
fds[0].mDistance);
|
||||
for(size_t fi{1u};fi < fds.size();fi++)
|
||||
fprintf(stdout, ", %.3f", fds[fi].mDistance);
|
||||
|
||||
fprintf(stdout, "\nazimuths = ");
|
||||
for(size_t fi{0u};fi < fds.size();++fi)
|
||||
{
|
||||
for(uint ei{0u};ei < fds[fi].mEvStart;++ei)
|
||||
fprintf(stdout, "%d%s", fds[fi].mAzCounts[fds[fi].mEvCount - 1 - ei], ", ");
|
||||
for(uint ei{fds[fi].mEvStart};ei < fds[fi].mEvCount;++ei)
|
||||
fprintf(stdout, "%d%s", fds[fi].mAzCounts[ei],
|
||||
(ei < (fds[fi].mEvCount - 1)) ? ", " :
|
||||
(fi < (fds.size() - 1)) ? ";\n " : "\n");
|
||||
}
|
||||
}
|
||||
|
||||
// Load and inspect the given SOFA file.
|
||||
static void SofaInfo(const char *filename)
|
||||
{
|
||||
int err;
|
||||
MySofaHrtfPtr sofa{mysofa_load(filename, &err)};
|
||||
if(!sofa)
|
||||
{
|
||||
fprintf(stdout, "Error: Could not load source file '%s' (%s).\n", filename,
|
||||
SofaErrorStr(err));
|
||||
return;
|
||||
}
|
||||
|
||||
/* NOTE: Some valid SOFA files are failing this check. */
|
||||
err = mysofa_check(sofa.get());
|
||||
if(err != MYSOFA_OK)
|
||||
fprintf(stdout, "Warning: Supposedly malformed source file '%s' (%s).\n", filename,
|
||||
SofaErrorStr(err));
|
||||
|
||||
mysofa_tocartesian(sofa.get());
|
||||
|
||||
PrintSofaAttributes("Info", sofa->attributes);
|
||||
|
||||
fprintf(stdout, "Measurements: %u\n", sofa->M);
|
||||
fprintf(stdout, "Receivers: %u\n", sofa->R);
|
||||
fprintf(stdout, "Emitters: %u\n", sofa->E);
|
||||
fprintf(stdout, "Samples: %u\n", sofa->N);
|
||||
|
||||
PrintSofaArray("SampleRate", &sofa->DataSamplingRate);
|
||||
PrintSofaArray("DataDelay", &sofa->DataDelay);
|
||||
|
||||
PrintCompatibleLayout(sofa->M, sofa->SourcePosition.values);
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
if(argc != 2)
|
||||
{
|
||||
fprintf(stdout, "Usage: %s <sofa-file>\n", argv[0]);
|
||||
return 0;
|
||||
}
|
||||
|
||||
SofaInfo(argv[1]);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
292
externals/openal-soft/utils/sofa-support.cpp
vendored
Normal file
292
externals/openal-soft/utils/sofa-support.cpp
vendored
Normal file
@@ -0,0 +1,292 @@
|
||||
/*
|
||||
* SOFA utility methods for inspecting SOFA file metrics and determining HRTF
|
||||
* utility compatible layouts.
|
||||
*
|
||||
* Copyright (C) 2018-2019 Christopher Fitzgerald
|
||||
* Copyright (C) 2019 Christopher Robinson
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Or visit: http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
|
||||
*/
|
||||
|
||||
#include "sofa-support.h"
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#include <algorithm>
|
||||
#include <array>
|
||||
#include <cmath>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
#include "mysofa.h"
|
||||
|
||||
|
||||
namespace {
|
||||
|
||||
using uint = unsigned int;
|
||||
using double3 = std::array<double,3>;
|
||||
|
||||
|
||||
/* Produces a sorted array of unique elements from a particular axis of the
|
||||
* triplets array. The filters are used to focus on particular coordinates
|
||||
* of other axes as necessary. The epsilons are used to constrain the
|
||||
* equality of unique elements.
|
||||
*/
|
||||
std::vector<double> GetUniquelySortedElems(const std::vector<double3> &aers, const uint axis,
|
||||
const double *const (&filters)[3], const double (&epsilons)[3])
|
||||
{
|
||||
std::vector<double> elems;
|
||||
for(const double3 &aer : aers)
|
||||
{
|
||||
const double elem{aer[axis]};
|
||||
|
||||
uint j;
|
||||
for(j = 0;j < 3;j++)
|
||||
{
|
||||
if(filters[j] && std::abs(aer[j] - *filters[j]) > epsilons[j])
|
||||
break;
|
||||
}
|
||||
if(j < 3)
|
||||
continue;
|
||||
|
||||
auto iter = elems.begin();
|
||||
for(;iter != elems.end();++iter)
|
||||
{
|
||||
const double delta{elem - *iter};
|
||||
if(delta > epsilons[axis]) continue;
|
||||
if(delta >= -epsilons[axis]) break;
|
||||
|
||||
iter = elems.emplace(iter, elem);
|
||||
break;
|
||||
}
|
||||
if(iter == elems.end())
|
||||
elems.emplace_back(elem);
|
||||
}
|
||||
return elems;
|
||||
}
|
||||
|
||||
/* Given a list of azimuths, this will produce the smallest step size that can
|
||||
* uniformly cover the list. Ideally this will be over half, but in degenerate
|
||||
* cases this can fall to a minimum of 5 (the lower limit).
|
||||
*/
|
||||
double GetUniformAzimStep(const double epsilon, const std::vector<double> &elems)
|
||||
{
|
||||
if(elems.size() < 5) return 0.0;
|
||||
|
||||
/* Get the maximum count possible, given the first two elements. It would
|
||||
* be impossible to have more than this since the first element must be
|
||||
* included.
|
||||
*/
|
||||
uint count{static_cast<uint>(std::ceil(360.0 / (elems[1]-elems[0])))};
|
||||
count = std::min(count, 255u);
|
||||
|
||||
for(;count >= 5;--count)
|
||||
{
|
||||
/* Given the stepping value for this number of elements, check each
|
||||
* multiple to ensure there's a matching element.
|
||||
*/
|
||||
const double step{360.0 / count};
|
||||
bool good{true};
|
||||
size_t idx{1u};
|
||||
for(uint mult{1u};mult < count && good;++mult)
|
||||
{
|
||||
const double target{step*mult + elems[0]};
|
||||
while(idx < elems.size() && target-elems[idx] > epsilon)
|
||||
++idx;
|
||||
good &= (idx < elems.size()) && !(std::abs(target-elems[idx++]) > epsilon);
|
||||
}
|
||||
if(good)
|
||||
return step;
|
||||
}
|
||||
return 0.0;
|
||||
}
|
||||
|
||||
/* Given a list of elevations, this will produce the smallest step size that
|
||||
* can uniformly cover the list. Ideally this will be over half, but in
|
||||
* degenerate cases this can fall to a minimum of 5 (the lower limit).
|
||||
*/
|
||||
double GetUniformElevStep(const double epsilon, std::vector<double> &elems)
|
||||
{
|
||||
if(elems.size() < 5) return 0.0;
|
||||
|
||||
/* Reverse the elevations so it increments starting with -90 (flipped from
|
||||
* +90). This makes it easier to work out a proper stepping value.
|
||||
*/
|
||||
std::reverse(elems.begin(), elems.end());
|
||||
for(auto &v : elems) v *= -1.0;
|
||||
|
||||
uint count{static_cast<uint>(std::ceil(180.0 / (elems[1]-elems[0])))};
|
||||
count = std::min(count, 255u);
|
||||
|
||||
double ret{0.0};
|
||||
for(;count >= 5;--count)
|
||||
{
|
||||
const double step{180.0 / count};
|
||||
bool good{true};
|
||||
size_t idx{1u};
|
||||
/* Elevations don't need to match all multiples if there's not enough
|
||||
* elements to check. Missing elevations can be synthesized.
|
||||
*/
|
||||
for(uint mult{1u};mult <= count && idx < elems.size() && good;++mult)
|
||||
{
|
||||
const double target{step*mult + elems[0]};
|
||||
while(idx < elems.size() && target-elems[idx] > epsilon)
|
||||
++idx;
|
||||
good &= !(idx < elems.size()) || !(std::abs(target-elems[idx++]) > epsilon);
|
||||
}
|
||||
if(good)
|
||||
{
|
||||
ret = step;
|
||||
break;
|
||||
}
|
||||
}
|
||||
/* Re-reverse the elevations to restore the correct order. */
|
||||
for(auto &v : elems) v *= -1.0;
|
||||
std::reverse(elems.begin(), elems.end());
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
|
||||
const char *SofaErrorStr(int err)
|
||||
{
|
||||
switch(err)
|
||||
{
|
||||
case MYSOFA_OK: return "OK";
|
||||
case MYSOFA_INVALID_FORMAT: return "Invalid format";
|
||||
case MYSOFA_UNSUPPORTED_FORMAT: return "Unsupported format";
|
||||
case MYSOFA_INTERNAL_ERROR: return "Internal error";
|
||||
case MYSOFA_NO_MEMORY: return "Out of memory";
|
||||
case MYSOFA_READ_ERROR: return "Read error";
|
||||
}
|
||||
return "Unknown";
|
||||
}
|
||||
|
||||
std::vector<SofaField> GetCompatibleLayout(const size_t m, const float *xyzs)
|
||||
{
|
||||
auto aers = std::vector<double3>(m, double3{});
|
||||
for(size_t i{0u};i < m;++i)
|
||||
{
|
||||
float vals[3]{xyzs[i*3], xyzs[i*3 + 1], xyzs[i*3 + 2]};
|
||||
mysofa_c2s(&vals[0]);
|
||||
aers[i] = {vals[0], vals[1], vals[2]};
|
||||
}
|
||||
|
||||
auto radii = GetUniquelySortedElems(aers, 2, {}, {0.1, 0.1, 0.001});
|
||||
std::vector<SofaField> fds;
|
||||
fds.reserve(radii.size());
|
||||
|
||||
for(const double dist : radii)
|
||||
{
|
||||
auto elevs = GetUniquelySortedElems(aers, 1, {nullptr, nullptr, &dist}, {0.1, 0.1, 0.001});
|
||||
|
||||
/* Remove elevations that don't have a valid set of azimuths. */
|
||||
auto invalid_elev = [&dist,&aers](const double ev) -> bool
|
||||
{
|
||||
auto azims = GetUniquelySortedElems(aers, 0, {nullptr, &ev, &dist}, {0.1, 0.1, 0.001});
|
||||
|
||||
if(std::abs(ev) > 89.999)
|
||||
return azims.size() != 1;
|
||||
if(azims.empty() || !(std::abs(azims[0]) < 0.1))
|
||||
return true;
|
||||
return GetUniformAzimStep(0.1, azims) <= 0.0;
|
||||
};
|
||||
elevs.erase(std::remove_if(elevs.begin(), elevs.end(), invalid_elev), elevs.end());
|
||||
|
||||
double step{GetUniformElevStep(0.1, elevs)};
|
||||
if(step <= 0.0)
|
||||
{
|
||||
if(elevs.empty())
|
||||
fprintf(stdout, "No usable elevations on field distance %f.\n", dist);
|
||||
else
|
||||
{
|
||||
fprintf(stdout, "Non-uniform elevations on field distance %.3f.\nGot: %+.2f", dist,
|
||||
elevs[0]);
|
||||
for(size_t ei{1u};ei < elevs.size();++ei)
|
||||
fprintf(stdout, ", %+.2f", elevs[ei]);
|
||||
fputc('\n', stdout);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
uint evStart{0u};
|
||||
for(uint ei{0u};ei < elevs.size();ei++)
|
||||
{
|
||||
if(!(elevs[ei] < 0.0))
|
||||
{
|
||||
fprintf(stdout, "Too many missing elevations on field distance %f.\n", dist);
|
||||
return fds;
|
||||
}
|
||||
|
||||
double eif{(90.0+elevs[ei]) / step};
|
||||
const double ev_start{std::round(eif)};
|
||||
|
||||
if(std::abs(eif - ev_start) < (0.1/step))
|
||||
{
|
||||
evStart = static_cast<uint>(ev_start);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
const auto evCount = static_cast<uint>(std::round(180.0 / step)) + 1;
|
||||
if(evCount < 5)
|
||||
{
|
||||
fprintf(stdout, "Too few uniform elevations on field distance %f.\n", dist);
|
||||
continue;
|
||||
}
|
||||
|
||||
SofaField field{};
|
||||
field.mDistance = dist;
|
||||
field.mEvCount = evCount;
|
||||
field.mEvStart = evStart;
|
||||
field.mAzCounts.resize(evCount, 0u);
|
||||
auto &azCounts = field.mAzCounts;
|
||||
|
||||
for(uint ei{evStart};ei < evCount;ei++)
|
||||
{
|
||||
double ev{-90.0 + ei*180.0/(evCount - 1)};
|
||||
auto azims = GetUniquelySortedElems(aers, 0, {nullptr, &ev, &dist}, {0.1, 0.1, 0.001});
|
||||
|
||||
if(ei == 0 || ei == (evCount-1))
|
||||
{
|
||||
if(azims.size() != 1)
|
||||
{
|
||||
fprintf(stdout, "Non-singular poles on field distance %f.\n", dist);
|
||||
return fds;
|
||||
}
|
||||
azCounts[ei] = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
step = GetUniformAzimStep(0.1, azims);
|
||||
if(step <= 0.0)
|
||||
{
|
||||
fprintf(stdout, "Non-uniform azimuths on elevation %f, field distance %f.\n",
|
||||
ev, dist);
|
||||
return fds;
|
||||
}
|
||||
azCounts[ei] = static_cast<uint>(std::round(360.0f / step));
|
||||
}
|
||||
}
|
||||
|
||||
fds.emplace_back(std::move(field));
|
||||
}
|
||||
|
||||
return fds;
|
||||
}
|
||||
30
externals/openal-soft/utils/sofa-support.h
vendored
Normal file
30
externals/openal-soft/utils/sofa-support.h
vendored
Normal file
@@ -0,0 +1,30 @@
|
||||
#ifndef UTILS_SOFA_SUPPORT_H
|
||||
#define UTILS_SOFA_SUPPORT_H
|
||||
|
||||
#include <cstddef>
|
||||
#include <memory>
|
||||
#include <vector>
|
||||
|
||||
#include "mysofa.h"
|
||||
|
||||
|
||||
struct MySofaDeleter {
|
||||
void operator()(MYSOFA_HRTF *sofa) { mysofa_free(sofa); }
|
||||
};
|
||||
using MySofaHrtfPtr = std::unique_ptr<MYSOFA_HRTF,MySofaDeleter>;
|
||||
|
||||
// Per-field measurement info.
|
||||
struct SofaField {
|
||||
using uint = unsigned int;
|
||||
|
||||
double mDistance{0.0};
|
||||
uint mEvCount{0u};
|
||||
uint mEvStart{0u};
|
||||
std::vector<uint> mAzCounts;
|
||||
};
|
||||
|
||||
const char *SofaErrorStr(int err);
|
||||
|
||||
std::vector<SofaField> GetCompatibleLayout(const size_t m, const float *xyzs);
|
||||
|
||||
#endif /* UTILS_SOFA_SUPPORT_H */
|
||||
538
externals/openal-soft/utils/uhjdecoder.cpp
vendored
Normal file
538
externals/openal-soft/utils/uhjdecoder.cpp
vendored
Normal file
@@ -0,0 +1,538 @@
|
||||
/*
|
||||
* 2-channel UHJ Decoder
|
||||
*
|
||||
* Copyright (c) Chris Robinson <chris.kcat@gmail.com>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <array>
|
||||
#include <complex>
|
||||
#include <cstring>
|
||||
#include <memory>
|
||||
#include <stddef.h>
|
||||
#include <string>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
#include "albit.h"
|
||||
#include "albyte.h"
|
||||
#include "alcomplex.h"
|
||||
#include "almalloc.h"
|
||||
#include "alnumbers.h"
|
||||
#include "alspan.h"
|
||||
#include "vector.h"
|
||||
#include "opthelpers.h"
|
||||
#include "phase_shifter.h"
|
||||
|
||||
#include "sndfile.h"
|
||||
|
||||
#include "win_main_utf8.h"
|
||||
|
||||
|
||||
struct FileDeleter {
|
||||
void operator()(FILE *file) { fclose(file); }
|
||||
};
|
||||
using FilePtr = std::unique_ptr<FILE,FileDeleter>;
|
||||
|
||||
struct SndFileDeleter {
|
||||
void operator()(SNDFILE *sndfile) { sf_close(sndfile); }
|
||||
};
|
||||
using SndFilePtr = std::unique_ptr<SNDFILE,SndFileDeleter>;
|
||||
|
||||
|
||||
using ubyte = unsigned char;
|
||||
using ushort = unsigned short;
|
||||
using uint = unsigned int;
|
||||
using complex_d = std::complex<double>;
|
||||
|
||||
using byte4 = std::array<al::byte,4>;
|
||||
|
||||
|
||||
constexpr ubyte SUBTYPE_BFORMAT_FLOAT[]{
|
||||
0x03, 0x00, 0x00, 0x00, 0x21, 0x07, 0xd3, 0x11, 0x86, 0x44, 0xc8, 0xc1,
|
||||
0xca, 0x00, 0x00, 0x00
|
||||
};
|
||||
|
||||
void fwrite16le(ushort val, FILE *f)
|
||||
{
|
||||
ubyte data[2]{ static_cast<ubyte>(val&0xff), static_cast<ubyte>((val>>8)&0xff) };
|
||||
fwrite(data, 1, 2, f);
|
||||
}
|
||||
|
||||
void fwrite32le(uint val, FILE *f)
|
||||
{
|
||||
ubyte data[4]{ static_cast<ubyte>(val&0xff), static_cast<ubyte>((val>>8)&0xff),
|
||||
static_cast<ubyte>((val>>16)&0xff), static_cast<ubyte>((val>>24)&0xff) };
|
||||
fwrite(data, 1, 4, f);
|
||||
}
|
||||
|
||||
template<al::endian = al::endian::native>
|
||||
byte4 f32AsLEBytes(const float &value) = delete;
|
||||
|
||||
template<>
|
||||
byte4 f32AsLEBytes<al::endian::little>(const float &value)
|
||||
{
|
||||
byte4 ret{};
|
||||
std::memcpy(ret.data(), &value, 4);
|
||||
return ret;
|
||||
}
|
||||
template<>
|
||||
byte4 f32AsLEBytes<al::endian::big>(const float &value)
|
||||
{
|
||||
byte4 ret{};
|
||||
std::memcpy(ret.data(), &value, 4);
|
||||
std::swap(ret[0], ret[3]);
|
||||
std::swap(ret[1], ret[2]);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
constexpr uint BufferLineSize{1024};
|
||||
|
||||
using FloatBufferLine = std::array<float,BufferLineSize>;
|
||||
using FloatBufferSpan = al::span<float,BufferLineSize>;
|
||||
|
||||
|
||||
struct UhjDecoder {
|
||||
constexpr static size_t sFilterDelay{1024};
|
||||
|
||||
alignas(16) std::array<float,BufferLineSize+sFilterDelay> mS{};
|
||||
alignas(16) std::array<float,BufferLineSize+sFilterDelay> mD{};
|
||||
alignas(16) std::array<float,BufferLineSize+sFilterDelay> mT{};
|
||||
alignas(16) std::array<float,BufferLineSize+sFilterDelay> mQ{};
|
||||
|
||||
/* History for the FIR filter. */
|
||||
alignas(16) std::array<float,sFilterDelay-1> mDTHistory{};
|
||||
alignas(16) std::array<float,sFilterDelay-1> mSHistory{};
|
||||
|
||||
alignas(16) std::array<float,BufferLineSize + sFilterDelay*2> mTemp{};
|
||||
|
||||
void decode(const float *RESTRICT InSamples, const size_t InChannels,
|
||||
const al::span<FloatBufferLine> OutSamples, const size_t SamplesToDo);
|
||||
void decode2(const float *RESTRICT InSamples, const al::span<FloatBufferLine> OutSamples,
|
||||
const size_t SamplesToDo);
|
||||
|
||||
DEF_NEWDEL(UhjDecoder)
|
||||
};
|
||||
|
||||
const PhaseShifterT<UhjDecoder::sFilterDelay*2> PShift{};
|
||||
|
||||
|
||||
/* Decoding UHJ is done as:
|
||||
*
|
||||
* S = Left + Right
|
||||
* D = Left - Right
|
||||
*
|
||||
* W = 0.981532*S + 0.197484*j(0.828331*D + 0.767820*T)
|
||||
* X = 0.418496*S - j(0.828331*D + 0.767820*T)
|
||||
* Y = 0.795968*D - 0.676392*T + j(0.186633*S)
|
||||
* Z = 1.023332*Q
|
||||
*
|
||||
* where j is a +90 degree phase shift. 3-channel UHJ excludes Q, while 2-
|
||||
* channel excludes Q and T. The B-Format signal reconstructed from 2-channel
|
||||
* UHJ should not be run through a normal B-Format decoder, as it needs
|
||||
* different shelf filters.
|
||||
*
|
||||
* NOTE: Some sources specify
|
||||
*
|
||||
* S = (Left + Right)/2
|
||||
* D = (Left - Right)/2
|
||||
*
|
||||
* However, this is incorrect. It's halving Left and Right even though they
|
||||
* were already halved during encoding, causing S and D to be half what they
|
||||
* initially were at the encoding stage. This division is not present in
|
||||
* Gerzon's original paper for deriving Sigma (S) or Delta (D) from the L and R
|
||||
* signals. As proof, taking Y for example:
|
||||
*
|
||||
* Y = 0.795968*D - 0.676392*T + j(0.186633*S)
|
||||
*
|
||||
* * Plug in the encoding parameters, using ? as a placeholder for whether S
|
||||
* and D should receive an extra 0.5 factor
|
||||
* Y = 0.795968*(j(-0.3420201*W + 0.5098604*X) + 0.6554516*Y)*? -
|
||||
* 0.676392*(j(-0.1432*W + 0.6512*X) - 0.7071068*Y) +
|
||||
* 0.186633*j(0.9396926*W + 0.1855740*X)*?
|
||||
*
|
||||
* * Move common factors in
|
||||
* Y = (j(-0.3420201*0.795968*?*W + 0.5098604*0.795968*?*X) + 0.6554516*0.795968*?*Y) -
|
||||
* (j(-0.1432*0.676392*W + 0.6512*0.676392*X) - 0.7071068*0.676392*Y) +
|
||||
* j(0.9396926*0.186633*?*W + 0.1855740*0.186633*?*X)
|
||||
*
|
||||
* * Clean up extraneous groupings
|
||||
* Y = j(-0.3420201*0.795968*?*W + 0.5098604*0.795968*?*X) + 0.6554516*0.795968*?*Y -
|
||||
* j(-0.1432*0.676392*W + 0.6512*0.676392*X) + 0.7071068*0.676392*Y +
|
||||
* j*(0.9396926*0.186633*?*W + 0.1855740*0.186633*?*X)
|
||||
*
|
||||
* * Move phase shifts together and combine them
|
||||
* Y = j(-0.3420201*0.795968*?*W + 0.5098604*0.795968*?*X - -0.1432*0.676392*W -
|
||||
* 0.6512*0.676392*X + 0.9396926*0.186633*?*W + 0.1855740*0.186633*?*X) +
|
||||
* 0.6554516*0.795968*?*Y + 0.7071068*0.676392*Y
|
||||
*
|
||||
* * Reorder terms
|
||||
* Y = j(-0.3420201*0.795968*?*W + 0.1432*0.676392*W + 0.9396926*0.186633*?*W +
|
||||
* 0.5098604*0.795968*?*X + -0.6512*0.676392*X + 0.1855740*0.186633*?*X) +
|
||||
* 0.7071068*0.676392*Y + 0.6554516*0.795968*?*Y
|
||||
*
|
||||
* * Move common factors out
|
||||
* Y = j((-0.3420201*0.795968*? + 0.1432*0.676392 + 0.9396926*0.186633*?)*W +
|
||||
* ( 0.5098604*0.795968*? + -0.6512*0.676392 + 0.1855740*0.186633*?)*X) +
|
||||
* (0.7071068*0.676392 + 0.6554516*0.795968*?)*Y
|
||||
*
|
||||
* * Result w/ 0.5 factor:
|
||||
* -0.3420201*0.795968*0.5 + 0.1432*0.676392 + 0.9396926*0.186633*0.5 = 0.04843*W
|
||||
* 0.5098604*0.795968*0.5 + -0.6512*0.676392 + 0.1855740*0.186633*0.5 = -0.22023*X
|
||||
* 0.7071068*0.676392 + 0.6554516*0.795968*0.5 = 0.73914*Y
|
||||
* -> Y = j(0.04843*W + -0.22023*X) + 0.73914*Y
|
||||
*
|
||||
* * Result w/o 0.5 factor:
|
||||
* -0.3420201*0.795968 + 0.1432*0.676392 + 0.9396926*0.186633 = 0.00000*W
|
||||
* 0.5098604*0.795968 + -0.6512*0.676392 + 0.1855740*0.186633 = 0.00000*X
|
||||
* 0.7071068*0.676392 + 0.6554516*0.795968 = 1.00000*Y
|
||||
* -> Y = j(0.00000*W + 0.00000*X) + 1.00000*Y
|
||||
*
|
||||
* Not halving produces a result matching the original input.
|
||||
*/
|
||||
void UhjDecoder::decode(const float *RESTRICT InSamples, const size_t InChannels,
|
||||
const al::span<FloatBufferLine> OutSamples, const size_t SamplesToDo)
|
||||
{
|
||||
ASSUME(SamplesToDo > 0);
|
||||
|
||||
float *woutput{OutSamples[0].data()};
|
||||
float *xoutput{OutSamples[1].data()};
|
||||
float *youtput{OutSamples[2].data()};
|
||||
|
||||
/* Add a delay to the input channels, to align it with the all-passed
|
||||
* signal.
|
||||
*/
|
||||
|
||||
/* S = Left + Right */
|
||||
for(size_t i{0};i < SamplesToDo;++i)
|
||||
mS[sFilterDelay+i] = InSamples[i*InChannels + 0] + InSamples[i*InChannels + 1];
|
||||
|
||||
/* D = Left - Right */
|
||||
for(size_t i{0};i < SamplesToDo;++i)
|
||||
mD[sFilterDelay+i] = InSamples[i*InChannels + 0] - InSamples[i*InChannels + 1];
|
||||
|
||||
if(InChannels > 2)
|
||||
{
|
||||
/* T */
|
||||
for(size_t i{0};i < SamplesToDo;++i)
|
||||
mT[sFilterDelay+i] = InSamples[i*InChannels + 2];
|
||||
}
|
||||
if(InChannels > 3)
|
||||
{
|
||||
/* Q */
|
||||
for(size_t i{0};i < SamplesToDo;++i)
|
||||
mQ[sFilterDelay+i] = InSamples[i*InChannels + 3];
|
||||
}
|
||||
|
||||
/* Precompute j(0.828331*D + 0.767820*T) and store in xoutput. */
|
||||
auto tmpiter = std::copy(mDTHistory.cbegin(), mDTHistory.cend(), mTemp.begin());
|
||||
std::transform(mD.cbegin(), mD.cbegin()+SamplesToDo+sFilterDelay, mT.cbegin(), tmpiter,
|
||||
[](const float d, const float t) noexcept { return 0.828331f*d + 0.767820f*t; });
|
||||
std::copy_n(mTemp.cbegin()+SamplesToDo, mDTHistory.size(), mDTHistory.begin());
|
||||
PShift.process({xoutput, SamplesToDo}, mTemp.data());
|
||||
|
||||
for(size_t i{0};i < SamplesToDo;++i)
|
||||
{
|
||||
/* W = 0.981532*S + 0.197484*j(0.828331*D + 0.767820*T) */
|
||||
woutput[i] = 0.981532f*mS[i] + 0.197484f*xoutput[i];
|
||||
/* X = 0.418496*S - j(0.828331*D + 0.767820*T) */
|
||||
xoutput[i] = 0.418496f*mS[i] - xoutput[i];
|
||||
}
|
||||
|
||||
/* Precompute j*S and store in youtput. */
|
||||
tmpiter = std::copy(mSHistory.cbegin(), mSHistory.cend(), mTemp.begin());
|
||||
std::copy_n(mS.cbegin(), SamplesToDo+sFilterDelay, tmpiter);
|
||||
std::copy_n(mTemp.cbegin()+SamplesToDo, mSHistory.size(), mSHistory.begin());
|
||||
PShift.process({youtput, SamplesToDo}, mTemp.data());
|
||||
|
||||
for(size_t i{0};i < SamplesToDo;++i)
|
||||
{
|
||||
/* Y = 0.795968*D - 0.676392*T + j(0.186633*S) */
|
||||
youtput[i] = 0.795968f*mD[i] - 0.676392f*mT[i] + 0.186633f*youtput[i];
|
||||
}
|
||||
|
||||
if(OutSamples.size() > 3)
|
||||
{
|
||||
float *zoutput{OutSamples[3].data()};
|
||||
/* Z = 1.023332*Q */
|
||||
for(size_t i{0};i < SamplesToDo;++i)
|
||||
zoutput[i] = 1.023332f*mQ[i];
|
||||
}
|
||||
|
||||
std::copy(mS.begin()+SamplesToDo, mS.begin()+SamplesToDo+sFilterDelay, mS.begin());
|
||||
std::copy(mD.begin()+SamplesToDo, mD.begin()+SamplesToDo+sFilterDelay, mD.begin());
|
||||
std::copy(mT.begin()+SamplesToDo, mT.begin()+SamplesToDo+sFilterDelay, mT.begin());
|
||||
std::copy(mQ.begin()+SamplesToDo, mQ.begin()+SamplesToDo+sFilterDelay, mQ.begin());
|
||||
}
|
||||
|
||||
/* This is an alternative equation for decoding 2-channel UHJ. Not sure what
|
||||
* the intended benefit is over the above equation as this slightly reduces the
|
||||
* amount of the original left response and has more of the phase-shifted
|
||||
* forward response on the left response.
|
||||
*
|
||||
* This decoding is done as:
|
||||
*
|
||||
* S = Left + Right
|
||||
* D = Left - Right
|
||||
*
|
||||
* W = 0.981530*S + j*0.163585*D
|
||||
* X = 0.418504*S - j*0.828347*D
|
||||
* Y = 0.762956*D + j*0.384230*S
|
||||
*
|
||||
* where j is a +90 degree phase shift.
|
||||
*
|
||||
* NOTE: As above, S and D should not be halved. The only consequence of
|
||||
* halving here is merely a -6dB reduction in output, but it's still incorrect.
|
||||
*/
|
||||
void UhjDecoder::decode2(const float *RESTRICT InSamples,
|
||||
const al::span<FloatBufferLine> OutSamples, const size_t SamplesToDo)
|
||||
{
|
||||
ASSUME(SamplesToDo > 0);
|
||||
|
||||
float *woutput{OutSamples[0].data()};
|
||||
float *xoutput{OutSamples[1].data()};
|
||||
float *youtput{OutSamples[2].data()};
|
||||
|
||||
/* S = Left + Right */
|
||||
for(size_t i{0};i < SamplesToDo;++i)
|
||||
mS[sFilterDelay+i] = InSamples[i*2 + 0] + InSamples[i*2 + 1];
|
||||
|
||||
/* D = Left - Right */
|
||||
for(size_t i{0};i < SamplesToDo;++i)
|
||||
mD[sFilterDelay+i] = InSamples[i*2 + 0] - InSamples[i*2 + 1];
|
||||
|
||||
/* Precompute j*D and store in xoutput. */
|
||||
auto tmpiter = std::copy(mDTHistory.cbegin(), mDTHistory.cend(), mTemp.begin());
|
||||
std::copy_n(mD.cbegin(), SamplesToDo+sFilterDelay, tmpiter);
|
||||
std::copy_n(mTemp.cbegin()+SamplesToDo, mDTHistory.size(), mDTHistory.begin());
|
||||
PShift.process({xoutput, SamplesToDo}, mTemp.data());
|
||||
|
||||
for(size_t i{0};i < SamplesToDo;++i)
|
||||
{
|
||||
/* W = 0.981530*S + j*0.163585*D */
|
||||
woutput[i] = 0.981530f*mS[i] + 0.163585f*xoutput[i];
|
||||
/* X = 0.418504*S - j*0.828347*D */
|
||||
xoutput[i] = 0.418504f*mS[i] - 0.828347f*xoutput[i];
|
||||
}
|
||||
|
||||
/* Precompute j*S and store in youtput. */
|
||||
tmpiter = std::copy(mSHistory.cbegin(), mSHistory.cend(), mTemp.begin());
|
||||
std::copy_n(mS.cbegin(), SamplesToDo+sFilterDelay, tmpiter);
|
||||
std::copy_n(mTemp.cbegin()+SamplesToDo, mSHistory.size(), mSHistory.begin());
|
||||
PShift.process({youtput, SamplesToDo}, mTemp.data());
|
||||
|
||||
for(size_t i{0};i < SamplesToDo;++i)
|
||||
{
|
||||
/* Y = 0.762956*D + j*0.384230*S */
|
||||
youtput[i] = 0.762956f*mD[i] + 0.384230f*youtput[i];
|
||||
}
|
||||
|
||||
std::copy(mS.begin()+SamplesToDo, mS.begin()+SamplesToDo+sFilterDelay, mS.begin());
|
||||
std::copy(mD.begin()+SamplesToDo, mD.begin()+SamplesToDo+sFilterDelay, mD.begin());
|
||||
}
|
||||
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
if(argc < 2 || std::strcmp(argv[1], "-h") == 0 || std::strcmp(argv[1], "--help") == 0)
|
||||
{
|
||||
printf("Usage: %s <[options] filename.wav...>\n\n"
|
||||
" Options:\n"
|
||||
" --general Use the general equations for 2-channel UHJ (default).\n"
|
||||
" --alternative Use the alternative equations for 2-channel UHJ.\n"
|
||||
"\n"
|
||||
"Note: When decoding 2-channel UHJ to an .amb file, the result should not use\n"
|
||||
"the normal B-Format shelf filters! Only 3- and 4-channel UHJ can accurately\n"
|
||||
"reconstruct the original B-Format signal.",
|
||||
argv[0]);
|
||||
return 1;
|
||||
}
|
||||
|
||||
size_t num_files{0}, num_decoded{0};
|
||||
bool use_general{true};
|
||||
for(int fidx{1};fidx < argc;++fidx)
|
||||
{
|
||||
if(std::strcmp(argv[fidx], "--general") == 0)
|
||||
{
|
||||
use_general = true;
|
||||
continue;
|
||||
}
|
||||
if(std::strcmp(argv[fidx], "--alternative") == 0)
|
||||
{
|
||||
use_general = false;
|
||||
continue;
|
||||
}
|
||||
++num_files;
|
||||
SF_INFO ininfo{};
|
||||
SndFilePtr infile{sf_open(argv[fidx], SFM_READ, &ininfo)};
|
||||
if(!infile)
|
||||
{
|
||||
fprintf(stderr, "Failed to open %s\n", argv[fidx]);
|
||||
continue;
|
||||
}
|
||||
if(sf_command(infile.get(), SFC_WAVEX_GET_AMBISONIC, NULL, 0) == SF_AMBISONIC_B_FORMAT)
|
||||
{
|
||||
fprintf(stderr, "%s is already B-Format\n", argv[fidx]);
|
||||
continue;
|
||||
}
|
||||
uint outchans{};
|
||||
if(ininfo.channels == 2)
|
||||
outchans = 3;
|
||||
else if(ininfo.channels == 3 || ininfo.channels == 4)
|
||||
outchans = static_cast<uint>(ininfo.channels);
|
||||
else
|
||||
{
|
||||
fprintf(stderr, "%s is not a 2-, 3-, or 4-channel file\n", argv[fidx]);
|
||||
continue;
|
||||
}
|
||||
printf("Converting %s from %d-channel UHJ%s...\n", argv[fidx], ininfo.channels,
|
||||
(ininfo.channels == 2) ? use_general ? " (general)" : " (alternative)" : "");
|
||||
|
||||
std::string outname{argv[fidx]};
|
||||
auto lastslash = outname.find_last_of('/');
|
||||
if(lastslash != std::string::npos)
|
||||
outname.erase(0, lastslash+1);
|
||||
auto lastdot = outname.find_last_of('.');
|
||||
if(lastdot != std::string::npos)
|
||||
outname.resize(lastdot+1);
|
||||
outname += "amb";
|
||||
|
||||
FilePtr outfile{fopen(outname.c_str(), "wb")};
|
||||
if(!outfile)
|
||||
{
|
||||
fprintf(stderr, "Failed to create %s\n", outname.c_str());
|
||||
continue;
|
||||
}
|
||||
|
||||
fputs("RIFF", outfile.get());
|
||||
fwrite32le(0xFFFFFFFF, outfile.get()); // 'RIFF' header len; filled in at close
|
||||
|
||||
fputs("WAVE", outfile.get());
|
||||
|
||||
fputs("fmt ", outfile.get());
|
||||
fwrite32le(40, outfile.get()); // 'fmt ' header len; 40 bytes for EXTENSIBLE
|
||||
|
||||
// 16-bit val, format type id (extensible: 0xFFFE)
|
||||
fwrite16le(0xFFFE, outfile.get());
|
||||
// 16-bit val, channel count
|
||||
fwrite16le(static_cast<ushort>(outchans), outfile.get());
|
||||
// 32-bit val, frequency
|
||||
fwrite32le(static_cast<uint>(ininfo.samplerate), outfile.get());
|
||||
// 32-bit val, bytes per second
|
||||
fwrite32le(static_cast<uint>(ininfo.samplerate)*sizeof(float)*outchans, outfile.get());
|
||||
// 16-bit val, frame size
|
||||
fwrite16le(static_cast<ushort>(sizeof(float)*outchans), outfile.get());
|
||||
// 16-bit val, bits per sample
|
||||
fwrite16le(static_cast<ushort>(sizeof(float)*8), outfile.get());
|
||||
// 16-bit val, extra byte count
|
||||
fwrite16le(22, outfile.get());
|
||||
// 16-bit val, valid bits per sample
|
||||
fwrite16le(static_cast<ushort>(sizeof(float)*8), outfile.get());
|
||||
// 32-bit val, channel mask
|
||||
fwrite32le(0, outfile.get());
|
||||
// 16 byte GUID, sub-type format
|
||||
fwrite(SUBTYPE_BFORMAT_FLOAT, 1, 16, outfile.get());
|
||||
|
||||
fputs("data", outfile.get());
|
||||
fwrite32le(0xFFFFFFFF, outfile.get()); // 'data' header len; filled in at close
|
||||
if(ferror(outfile.get()))
|
||||
{
|
||||
fprintf(stderr, "Error writing wave file header: %s (%d)\n", strerror(errno), errno);
|
||||
continue;
|
||||
}
|
||||
|
||||
auto DataStart = ftell(outfile.get());
|
||||
|
||||
auto decoder = std::make_unique<UhjDecoder>();
|
||||
auto inmem = std::make_unique<float[]>(BufferLineSize*static_cast<uint>(ininfo.channels));
|
||||
auto decmem = al::vector<std::array<float,BufferLineSize>, 16>(outchans);
|
||||
auto outmem = std::make_unique<byte4[]>(BufferLineSize*outchans);
|
||||
|
||||
/* A number of initial samples need to be skipped to cut the lead-in
|
||||
* from the all-pass filter delay. The same number of samples need to
|
||||
* be fed through the decoder after reaching the end of the input file
|
||||
* to ensure none of the original input is lost.
|
||||
*/
|
||||
size_t LeadIn{UhjDecoder::sFilterDelay};
|
||||
sf_count_t LeadOut{UhjDecoder::sFilterDelay};
|
||||
while(LeadOut > 0)
|
||||
{
|
||||
sf_count_t sgot{sf_readf_float(infile.get(), inmem.get(), BufferLineSize)};
|
||||
sgot = std::max<sf_count_t>(sgot, 0);
|
||||
if(sgot < BufferLineSize)
|
||||
{
|
||||
const sf_count_t remaining{std::min(BufferLineSize - sgot, LeadOut)};
|
||||
std::fill_n(inmem.get() + sgot*ininfo.channels, remaining*ininfo.channels, 0.0f);
|
||||
sgot += remaining;
|
||||
LeadOut -= remaining;
|
||||
}
|
||||
|
||||
auto got = static_cast<size_t>(sgot);
|
||||
if(ininfo.channels > 2 || use_general)
|
||||
decoder->decode(inmem.get(), static_cast<uint>(ininfo.channels), decmem, got);
|
||||
else
|
||||
decoder->decode2(inmem.get(), decmem, got);
|
||||
if(LeadIn >= got)
|
||||
{
|
||||
LeadIn -= got;
|
||||
continue;
|
||||
}
|
||||
|
||||
got -= LeadIn;
|
||||
for(size_t i{0};i < got;++i)
|
||||
{
|
||||
/* Attenuate by -3dB for FuMa output levels. */
|
||||
constexpr auto inv_sqrt2 = static_cast<float>(1.0/al::numbers::sqrt2);
|
||||
for(size_t j{0};j < outchans;++j)
|
||||
outmem[i*outchans + j] = f32AsLEBytes(decmem[j][LeadIn+i] * inv_sqrt2);
|
||||
}
|
||||
LeadIn = 0;
|
||||
|
||||
size_t wrote{fwrite(outmem.get(), sizeof(byte4)*outchans, got, outfile.get())};
|
||||
if(wrote < got)
|
||||
{
|
||||
fprintf(stderr, "Error writing wave data: %s (%d)\n", strerror(errno), errno);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
auto DataEnd = ftell(outfile.get());
|
||||
if(DataEnd > DataStart)
|
||||
{
|
||||
long dataLen{DataEnd - DataStart};
|
||||
if(fseek(outfile.get(), 4, SEEK_SET) == 0)
|
||||
fwrite32le(static_cast<uint>(DataEnd-8), outfile.get()); // 'WAVE' header len
|
||||
if(fseek(outfile.get(), DataStart-4, SEEK_SET) == 0)
|
||||
fwrite32le(static_cast<uint>(dataLen), outfile.get()); // 'data' header len
|
||||
}
|
||||
fflush(outfile.get());
|
||||
++num_decoded;
|
||||
}
|
||||
if(num_decoded == 0)
|
||||
fprintf(stderr, "Failed to decode any input files\n");
|
||||
else if(num_decoded < num_files)
|
||||
fprintf(stderr, "Decoded %zu of %zu files\n", num_decoded, num_files);
|
||||
else
|
||||
printf("Decoded %zu file%s\n", num_decoded, (num_decoded==1)?"":"s");
|
||||
return 0;
|
||||
}
|
||||
531
externals/openal-soft/utils/uhjencoder.cpp
vendored
Normal file
531
externals/openal-soft/utils/uhjencoder.cpp
vendored
Normal file
@@ -0,0 +1,531 @@
|
||||
/*
|
||||
* 2-channel UHJ Encoder
|
||||
*
|
||||
* Copyright (c) Chris Robinson <chris.kcat@gmail.com>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <array>
|
||||
#include <cstring>
|
||||
#include <inttypes.h>
|
||||
#include <memory>
|
||||
#include <stddef.h>
|
||||
#include <string>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
#include "almalloc.h"
|
||||
#include "alnumbers.h"
|
||||
#include "alspan.h"
|
||||
#include "opthelpers.h"
|
||||
#include "phase_shifter.h"
|
||||
#include "vector.h"
|
||||
|
||||
#include "sndfile.h"
|
||||
|
||||
#include "win_main_utf8.h"
|
||||
|
||||
|
||||
namespace {
|
||||
|
||||
struct SndFileDeleter {
|
||||
void operator()(SNDFILE *sndfile) { sf_close(sndfile); }
|
||||
};
|
||||
using SndFilePtr = std::unique_ptr<SNDFILE,SndFileDeleter>;
|
||||
|
||||
|
||||
using uint = unsigned int;
|
||||
|
||||
constexpr uint BufferLineSize{1024};
|
||||
|
||||
using FloatBufferLine = std::array<float,BufferLineSize>;
|
||||
using FloatBufferSpan = al::span<float,BufferLineSize>;
|
||||
|
||||
|
||||
struct UhjEncoder {
|
||||
constexpr static size_t sFilterDelay{1024};
|
||||
|
||||
/* Delays and processing storage for the unfiltered signal. */
|
||||
alignas(16) std::array<float,BufferLineSize+sFilterDelay> mW{};
|
||||
alignas(16) std::array<float,BufferLineSize+sFilterDelay> mX{};
|
||||
alignas(16) std::array<float,BufferLineSize+sFilterDelay> mY{};
|
||||
alignas(16) std::array<float,BufferLineSize+sFilterDelay> mZ{};
|
||||
|
||||
alignas(16) std::array<float,BufferLineSize> mS{};
|
||||
alignas(16) std::array<float,BufferLineSize> mD{};
|
||||
alignas(16) std::array<float,BufferLineSize> mT{};
|
||||
|
||||
/* History for the FIR filter. */
|
||||
alignas(16) std::array<float,sFilterDelay*2 - 1> mWXHistory1{};
|
||||
alignas(16) std::array<float,sFilterDelay*2 - 1> mWXHistory2{};
|
||||
|
||||
alignas(16) std::array<float,BufferLineSize + sFilterDelay*2> mTemp{};
|
||||
|
||||
void encode(const al::span<FloatBufferLine> OutSamples,
|
||||
const al::span<FloatBufferLine,4> InSamples, const size_t SamplesToDo);
|
||||
|
||||
DEF_NEWDEL(UhjEncoder)
|
||||
};
|
||||
|
||||
const PhaseShifterT<UhjEncoder::sFilterDelay*2> PShift{};
|
||||
|
||||
|
||||
/* Encoding UHJ from B-Format is done as:
|
||||
*
|
||||
* S = 0.9396926*W + 0.1855740*X
|
||||
* D = j(-0.3420201*W + 0.5098604*X) + 0.6554516*Y
|
||||
*
|
||||
* Left = (S + D)/2.0
|
||||
* Right = (S - D)/2.0
|
||||
* T = j(-0.1432*W + 0.6512*X) - 0.7071068*Y
|
||||
* Q = 0.9772*Z
|
||||
*
|
||||
* where j is a wide-band +90 degree phase shift. T is excluded from 2-channel
|
||||
* output, and Q is excluded from 2- and 3-channel output.
|
||||
*/
|
||||
void UhjEncoder::encode(const al::span<FloatBufferLine> OutSamples,
|
||||
const al::span<FloatBufferLine,4> InSamples, const size_t SamplesToDo)
|
||||
{
|
||||
const float *RESTRICT winput{al::assume_aligned<16>(InSamples[0].data())};
|
||||
const float *RESTRICT xinput{al::assume_aligned<16>(InSamples[1].data())};
|
||||
const float *RESTRICT yinput{al::assume_aligned<16>(InSamples[2].data())};
|
||||
const float *RESTRICT zinput{al::assume_aligned<16>(InSamples[3].data())};
|
||||
|
||||
/* Combine the previously delayed input signal with the new input. */
|
||||
std::copy_n(winput, SamplesToDo, mW.begin()+sFilterDelay);
|
||||
std::copy_n(xinput, SamplesToDo, mX.begin()+sFilterDelay);
|
||||
std::copy_n(yinput, SamplesToDo, mY.begin()+sFilterDelay);
|
||||
std::copy_n(zinput, SamplesToDo, mZ.begin()+sFilterDelay);
|
||||
|
||||
/* S = 0.9396926*W + 0.1855740*X */
|
||||
for(size_t i{0};i < SamplesToDo;++i)
|
||||
mS[i] = 0.9396926f*mW[i] + 0.1855740f*mX[i];
|
||||
|
||||
/* Precompute j(-0.3420201*W + 0.5098604*X) and store in mD. */
|
||||
auto tmpiter = std::copy(mWXHistory1.cbegin(), mWXHistory1.cend(), mTemp.begin());
|
||||
std::transform(winput, winput+SamplesToDo, xinput, tmpiter,
|
||||
[](const float w, const float x) noexcept -> float
|
||||
{ return -0.3420201f*w + 0.5098604f*x; });
|
||||
std::copy_n(mTemp.cbegin()+SamplesToDo, mWXHistory1.size(), mWXHistory1.begin());
|
||||
PShift.process({mD.data(), SamplesToDo}, mTemp.data());
|
||||
|
||||
/* D = j(-0.3420201*W + 0.5098604*X) + 0.6554516*Y */
|
||||
for(size_t i{0};i < SamplesToDo;++i)
|
||||
mD[i] = mD[i] + 0.6554516f*mY[i];
|
||||
|
||||
/* Left = (S + D)/2.0 */
|
||||
float *RESTRICT left{al::assume_aligned<16>(OutSamples[0].data())};
|
||||
for(size_t i{0};i < SamplesToDo;i++)
|
||||
left[i] = (mS[i] + mD[i]) * 0.5f;
|
||||
/* Right = (S - D)/2.0 */
|
||||
float *RESTRICT right{al::assume_aligned<16>(OutSamples[1].data())};
|
||||
for(size_t i{0};i < SamplesToDo;i++)
|
||||
right[i] = (mS[i] - mD[i]) * 0.5f;
|
||||
|
||||
if(OutSamples.size() > 2)
|
||||
{
|
||||
/* Precompute j(-0.1432*W + 0.6512*X) and store in mT. */
|
||||
tmpiter = std::copy(mWXHistory2.cbegin(), mWXHistory2.cend(), mTemp.begin());
|
||||
std::transform(winput, winput+SamplesToDo, xinput, tmpiter,
|
||||
[](const float w, const float x) noexcept -> float
|
||||
{ return -0.1432f*w + 0.6512f*x; });
|
||||
std::copy_n(mTemp.cbegin()+SamplesToDo, mWXHistory2.size(), mWXHistory2.begin());
|
||||
PShift.process({mT.data(), SamplesToDo}, mTemp.data());
|
||||
|
||||
/* T = j(-0.1432*W + 0.6512*X) - 0.7071068*Y */
|
||||
float *RESTRICT t{al::assume_aligned<16>(OutSamples[2].data())};
|
||||
for(size_t i{0};i < SamplesToDo;i++)
|
||||
t[i] = mT[i] - 0.7071068f*mY[i];
|
||||
}
|
||||
if(OutSamples.size() > 3)
|
||||
{
|
||||
/* Q = 0.9772*Z */
|
||||
float *RESTRICT q{al::assume_aligned<16>(OutSamples[3].data())};
|
||||
for(size_t i{0};i < SamplesToDo;i++)
|
||||
q[i] = 0.9772f*mZ[i];
|
||||
}
|
||||
|
||||
/* Copy the future samples to the front for next time. */
|
||||
std::copy(mW.cbegin()+SamplesToDo, mW.cbegin()+SamplesToDo+sFilterDelay, mW.begin());
|
||||
std::copy(mX.cbegin()+SamplesToDo, mX.cbegin()+SamplesToDo+sFilterDelay, mX.begin());
|
||||
std::copy(mY.cbegin()+SamplesToDo, mY.cbegin()+SamplesToDo+sFilterDelay, mY.begin());
|
||||
std::copy(mZ.cbegin()+SamplesToDo, mZ.cbegin()+SamplesToDo+sFilterDelay, mZ.begin());
|
||||
}
|
||||
|
||||
|
||||
struct SpeakerPos {
|
||||
int mChannelID;
|
||||
float mAzimuth;
|
||||
float mElevation;
|
||||
};
|
||||
|
||||
/* Azimuth is counter-clockwise. */
|
||||
constexpr SpeakerPos StereoMap[2]{
|
||||
{ SF_CHANNEL_MAP_LEFT, 30.0f, 0.0f },
|
||||
{ SF_CHANNEL_MAP_RIGHT, -30.0f, 0.0f },
|
||||
}, QuadMap[4]{
|
||||
{ SF_CHANNEL_MAP_LEFT, 45.0f, 0.0f },
|
||||
{ SF_CHANNEL_MAP_RIGHT, -45.0f, 0.0f },
|
||||
{ SF_CHANNEL_MAP_REAR_LEFT, 135.0f, 0.0f },
|
||||
{ SF_CHANNEL_MAP_REAR_RIGHT, -135.0f, 0.0f },
|
||||
}, X51Map[6]{
|
||||
{ SF_CHANNEL_MAP_LEFT, 30.0f, 0.0f },
|
||||
{ SF_CHANNEL_MAP_RIGHT, -30.0f, 0.0f },
|
||||
{ SF_CHANNEL_MAP_CENTER, 0.0f, 0.0f },
|
||||
{ SF_CHANNEL_MAP_LFE, 0.0f, 0.0f },
|
||||
{ SF_CHANNEL_MAP_SIDE_LEFT, 110.0f, 0.0f },
|
||||
{ SF_CHANNEL_MAP_SIDE_RIGHT, -110.0f, 0.0f },
|
||||
}, X51RearMap[6]{
|
||||
{ SF_CHANNEL_MAP_LEFT, 30.0f, 0.0f },
|
||||
{ SF_CHANNEL_MAP_RIGHT, -30.0f, 0.0f },
|
||||
{ SF_CHANNEL_MAP_CENTER, 0.0f, 0.0f },
|
||||
{ SF_CHANNEL_MAP_LFE, 0.0f, 0.0f },
|
||||
{ SF_CHANNEL_MAP_REAR_LEFT, 110.0f, 0.0f },
|
||||
{ SF_CHANNEL_MAP_REAR_RIGHT, -110.0f, 0.0f },
|
||||
}, X71Map[8]{
|
||||
{ SF_CHANNEL_MAP_LEFT, 30.0f, 0.0f },
|
||||
{ SF_CHANNEL_MAP_RIGHT, -30.0f, 0.0f },
|
||||
{ SF_CHANNEL_MAP_CENTER, 0.0f, 0.0f },
|
||||
{ SF_CHANNEL_MAP_LFE, 0.0f, 0.0f },
|
||||
{ SF_CHANNEL_MAP_REAR_LEFT, 150.0f, 0.0f },
|
||||
{ SF_CHANNEL_MAP_REAR_RIGHT, -150.0f, 0.0f },
|
||||
{ SF_CHANNEL_MAP_SIDE_LEFT, 90.0f, 0.0f },
|
||||
{ SF_CHANNEL_MAP_SIDE_RIGHT, -90.0f, 0.0f },
|
||||
}, X714Map[12]{
|
||||
{ SF_CHANNEL_MAP_LEFT, 30.0f, 0.0f },
|
||||
{ SF_CHANNEL_MAP_RIGHT, -30.0f, 0.0f },
|
||||
{ SF_CHANNEL_MAP_CENTER, 0.0f, 0.0f },
|
||||
{ SF_CHANNEL_MAP_LFE, 0.0f, 0.0f },
|
||||
{ SF_CHANNEL_MAP_REAR_LEFT, 150.0f, 0.0f },
|
||||
{ SF_CHANNEL_MAP_REAR_RIGHT, -150.0f, 0.0f },
|
||||
{ SF_CHANNEL_MAP_SIDE_LEFT, 90.0f, 0.0f },
|
||||
{ SF_CHANNEL_MAP_SIDE_RIGHT, -90.0f, 0.0f },
|
||||
{ SF_CHANNEL_MAP_TOP_FRONT_LEFT, 45.0f, 35.0f },
|
||||
{ SF_CHANNEL_MAP_TOP_FRONT_RIGHT, -45.0f, 35.0f },
|
||||
{ SF_CHANNEL_MAP_TOP_REAR_LEFT, 135.0f, 35.0f },
|
||||
{ SF_CHANNEL_MAP_TOP_REAR_RIGHT, -135.0f, 35.0f },
|
||||
};
|
||||
|
||||
constexpr auto GenCoeffs(double x /*+front*/, double y /*+left*/, double z /*+up*/) noexcept
|
||||
{
|
||||
/* Coefficients are +3dB of FuMa. */
|
||||
return std::array<float,4>{{
|
||||
1.0f,
|
||||
static_cast<float>(al::numbers::sqrt2 * x),
|
||||
static_cast<float>(al::numbers::sqrt2 * y),
|
||||
static_cast<float>(al::numbers::sqrt2 * z)
|
||||
}};
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
if(argc < 2 || std::strcmp(argv[1], "-h") == 0 || std::strcmp(argv[1], "--help") == 0)
|
||||
{
|
||||
printf("Usage: %s <infile...>\n\n", argv[0]);
|
||||
return 1;
|
||||
}
|
||||
|
||||
uint uhjchans{2};
|
||||
size_t num_files{0}, num_encoded{0};
|
||||
for(int fidx{1};fidx < argc;++fidx)
|
||||
{
|
||||
if(strcmp(argv[fidx], "-bhj") == 0)
|
||||
{
|
||||
uhjchans = 2;
|
||||
continue;
|
||||
}
|
||||
if(strcmp(argv[fidx], "-thj") == 0)
|
||||
{
|
||||
uhjchans = 3;
|
||||
continue;
|
||||
}
|
||||
if(strcmp(argv[fidx], "-phj") == 0)
|
||||
{
|
||||
uhjchans = 4;
|
||||
continue;
|
||||
}
|
||||
++num_files;
|
||||
|
||||
std::string outname{argv[fidx]};
|
||||
size_t lastslash{outname.find_last_of('/')};
|
||||
if(lastslash != std::string::npos)
|
||||
outname.erase(0, lastslash+1);
|
||||
size_t extpos{outname.find_last_of('.')};
|
||||
if(extpos != std::string::npos)
|
||||
outname.resize(extpos);
|
||||
outname += ".uhj.flac";
|
||||
|
||||
SF_INFO ininfo{};
|
||||
SndFilePtr infile{sf_open(argv[fidx], SFM_READ, &ininfo)};
|
||||
if(!infile)
|
||||
{
|
||||
fprintf(stderr, "Failed to open %s\n", argv[fidx]);
|
||||
continue;
|
||||
}
|
||||
printf("Converting %s to %s...\n", argv[fidx], outname.c_str());
|
||||
|
||||
/* Work out the channel map, preferably using the actual channel map
|
||||
* from the file/format, but falling back to assuming WFX order.
|
||||
*/
|
||||
al::span<const SpeakerPos> spkrs;
|
||||
auto chanmap = std::vector<int>(static_cast<uint>(ininfo.channels), SF_CHANNEL_MAP_INVALID);
|
||||
if(sf_command(infile.get(), SFC_GET_CHANNEL_MAP_INFO, chanmap.data(),
|
||||
ininfo.channels*int{sizeof(int)}) == SF_TRUE)
|
||||
{
|
||||
static const std::array<int,2> stereomap{{SF_CHANNEL_MAP_LEFT, SF_CHANNEL_MAP_RIGHT}};
|
||||
static const std::array<int,4> quadmap{{SF_CHANNEL_MAP_LEFT, SF_CHANNEL_MAP_RIGHT,
|
||||
SF_CHANNEL_MAP_REAR_LEFT, SF_CHANNEL_MAP_REAR_RIGHT}};
|
||||
static const std::array<int,6> x51map{{SF_CHANNEL_MAP_LEFT, SF_CHANNEL_MAP_RIGHT,
|
||||
SF_CHANNEL_MAP_CENTER, SF_CHANNEL_MAP_LFE,
|
||||
SF_CHANNEL_MAP_SIDE_LEFT, SF_CHANNEL_MAP_SIDE_RIGHT}};
|
||||
static const std::array<int,6> x51rearmap{{SF_CHANNEL_MAP_LEFT, SF_CHANNEL_MAP_RIGHT,
|
||||
SF_CHANNEL_MAP_CENTER, SF_CHANNEL_MAP_LFE,
|
||||
SF_CHANNEL_MAP_REAR_LEFT, SF_CHANNEL_MAP_REAR_RIGHT}};
|
||||
static const std::array<int,8> x71map{{SF_CHANNEL_MAP_LEFT, SF_CHANNEL_MAP_RIGHT,
|
||||
SF_CHANNEL_MAP_CENTER, SF_CHANNEL_MAP_LFE,
|
||||
SF_CHANNEL_MAP_REAR_LEFT, SF_CHANNEL_MAP_REAR_RIGHT,
|
||||
SF_CHANNEL_MAP_SIDE_LEFT, SF_CHANNEL_MAP_SIDE_RIGHT}};
|
||||
static const std::array<int,12> x714map{{SF_CHANNEL_MAP_LEFT, SF_CHANNEL_MAP_RIGHT,
|
||||
SF_CHANNEL_MAP_CENTER, SF_CHANNEL_MAP_LFE,
|
||||
SF_CHANNEL_MAP_REAR_LEFT, SF_CHANNEL_MAP_REAR_RIGHT,
|
||||
SF_CHANNEL_MAP_SIDE_LEFT, SF_CHANNEL_MAP_SIDE_RIGHT,
|
||||
SF_CHANNEL_MAP_TOP_FRONT_LEFT, SF_CHANNEL_MAP_TOP_FRONT_RIGHT,
|
||||
SF_CHANNEL_MAP_TOP_REAR_LEFT, SF_CHANNEL_MAP_TOP_REAR_RIGHT}};
|
||||
static const std::array<int,3> ambi2dmap{{SF_CHANNEL_MAP_AMBISONIC_B_W,
|
||||
SF_CHANNEL_MAP_AMBISONIC_B_X, SF_CHANNEL_MAP_AMBISONIC_B_Y}};
|
||||
static const std::array<int,4> ambi3dmap{{SF_CHANNEL_MAP_AMBISONIC_B_W,
|
||||
SF_CHANNEL_MAP_AMBISONIC_B_X, SF_CHANNEL_MAP_AMBISONIC_B_Y,
|
||||
SF_CHANNEL_MAP_AMBISONIC_B_Z}};
|
||||
|
||||
auto match_chanmap = [](const al::span<int> a, const al::span<const int> b) -> bool
|
||||
{
|
||||
if(a.size() != b.size())
|
||||
return false;
|
||||
for(const int id : a)
|
||||
{
|
||||
if(std::find(b.begin(), b.end(), id) != b.end())
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
};
|
||||
if(match_chanmap(chanmap, stereomap))
|
||||
spkrs = StereoMap;
|
||||
else if(match_chanmap(chanmap, quadmap))
|
||||
spkrs = QuadMap;
|
||||
else if(match_chanmap(chanmap, x51map))
|
||||
spkrs = X51Map;
|
||||
else if(match_chanmap(chanmap, x51rearmap))
|
||||
spkrs = X51RearMap;
|
||||
else if(match_chanmap(chanmap, x71map))
|
||||
spkrs = X71Map;
|
||||
else if(match_chanmap(chanmap, x714map))
|
||||
spkrs = X714Map;
|
||||
else if(match_chanmap(chanmap, ambi2dmap) || match_chanmap(chanmap, ambi3dmap))
|
||||
{
|
||||
/* Do nothing. */
|
||||
}
|
||||
else
|
||||
{
|
||||
std::string mapstr;
|
||||
if(!chanmap.empty())
|
||||
{
|
||||
mapstr = std::to_string(chanmap[0]);
|
||||
for(int idx : al::span<int>{chanmap}.subspan<1>())
|
||||
{
|
||||
mapstr += ',';
|
||||
mapstr += std::to_string(idx);
|
||||
}
|
||||
}
|
||||
fprintf(stderr, " ... %zu channels not supported (map: %s)\n", chanmap.size(),
|
||||
mapstr.c_str());
|
||||
continue;
|
||||
}
|
||||
}
|
||||
else if(ininfo.channels == 2)
|
||||
{
|
||||
fprintf(stderr, " ... assuming WFX order stereo\n");
|
||||
spkrs = StereoMap;
|
||||
chanmap[0] = SF_CHANNEL_MAP_FRONT_LEFT;
|
||||
chanmap[1] = SF_CHANNEL_MAP_FRONT_RIGHT;
|
||||
}
|
||||
else if(ininfo.channels == 6)
|
||||
{
|
||||
fprintf(stderr, " ... assuming WFX order 5.1\n");
|
||||
spkrs = X51Map;
|
||||
chanmap[0] = SF_CHANNEL_MAP_FRONT_LEFT;
|
||||
chanmap[1] = SF_CHANNEL_MAP_FRONT_RIGHT;
|
||||
chanmap[2] = SF_CHANNEL_MAP_FRONT_CENTER;
|
||||
chanmap[3] = SF_CHANNEL_MAP_LFE;
|
||||
chanmap[4] = SF_CHANNEL_MAP_SIDE_LEFT;
|
||||
chanmap[5] = SF_CHANNEL_MAP_SIDE_RIGHT;
|
||||
}
|
||||
else if(ininfo.channels == 8)
|
||||
{
|
||||
fprintf(stderr, " ... assuming WFX order 7.1\n");
|
||||
spkrs = X71Map;
|
||||
chanmap[0] = SF_CHANNEL_MAP_FRONT_LEFT;
|
||||
chanmap[1] = SF_CHANNEL_MAP_FRONT_RIGHT;
|
||||
chanmap[2] = SF_CHANNEL_MAP_FRONT_CENTER;
|
||||
chanmap[3] = SF_CHANNEL_MAP_LFE;
|
||||
chanmap[4] = SF_CHANNEL_MAP_REAR_LEFT;
|
||||
chanmap[5] = SF_CHANNEL_MAP_REAR_RIGHT;
|
||||
chanmap[6] = SF_CHANNEL_MAP_SIDE_LEFT;
|
||||
chanmap[7] = SF_CHANNEL_MAP_SIDE_RIGHT;
|
||||
}
|
||||
else
|
||||
{
|
||||
fprintf(stderr, " ... unmapped %d-channel audio not supported\n", ininfo.channels);
|
||||
continue;
|
||||
}
|
||||
|
||||
SF_INFO outinfo{};
|
||||
outinfo.frames = ininfo.frames;
|
||||
outinfo.samplerate = ininfo.samplerate;
|
||||
outinfo.channels = static_cast<int>(uhjchans);
|
||||
outinfo.format = SF_FORMAT_PCM_24 | SF_FORMAT_FLAC;
|
||||
SndFilePtr outfile{sf_open(outname.c_str(), SFM_WRITE, &outinfo)};
|
||||
if(!outfile)
|
||||
{
|
||||
fprintf(stderr, " ... failed to create %s\n", outname.c_str());
|
||||
continue;
|
||||
}
|
||||
|
||||
auto encoder = std::make_unique<UhjEncoder>();
|
||||
auto splbuf = al::vector<FloatBufferLine, 16>(static_cast<uint>(9+ininfo.channels)+uhjchans);
|
||||
auto ambmem = al::span<FloatBufferLine,4>{splbuf.data(), 4};
|
||||
auto encmem = al::span<FloatBufferLine,4>{&splbuf[4], 4};
|
||||
auto srcmem = al::span<float,BufferLineSize>{splbuf[8].data(), BufferLineSize};
|
||||
auto outmem = al::span<float>{splbuf[9].data(), BufferLineSize*uhjchans};
|
||||
|
||||
/* A number of initial samples need to be skipped to cut the lead-in
|
||||
* from the all-pass filter delay. The same number of samples need to
|
||||
* be fed through the encoder after reaching the end of the input file
|
||||
* to ensure none of the original input is lost.
|
||||
*/
|
||||
size_t total_wrote{0};
|
||||
size_t LeadIn{UhjEncoder::sFilterDelay};
|
||||
sf_count_t LeadOut{UhjEncoder::sFilterDelay};
|
||||
while(LeadIn > 0 || LeadOut > 0)
|
||||
{
|
||||
auto inmem = outmem.data() + outmem.size();
|
||||
auto sgot = sf_readf_float(infile.get(), inmem, BufferLineSize);
|
||||
|
||||
sgot = std::max<sf_count_t>(sgot, 0);
|
||||
if(sgot < BufferLineSize)
|
||||
{
|
||||
const sf_count_t remaining{std::min(BufferLineSize - sgot, LeadOut)};
|
||||
std::fill_n(inmem + sgot*ininfo.channels, remaining*ininfo.channels, 0.0f);
|
||||
sgot += remaining;
|
||||
LeadOut -= remaining;
|
||||
}
|
||||
|
||||
for(auto&& buf : ambmem)
|
||||
buf.fill(0.0f);
|
||||
|
||||
auto got = static_cast<size_t>(sgot);
|
||||
if(spkrs.empty())
|
||||
{
|
||||
/* B-Format is already in the correct order. It just needs a
|
||||
* +3dB boost.
|
||||
*/
|
||||
static constexpr float scale{al::numbers::sqrt2_v<float>};
|
||||
const size_t chans{std::min<size_t>(static_cast<uint>(ininfo.channels), 4u)};
|
||||
for(size_t c{0};c < chans;++c)
|
||||
{
|
||||
for(size_t i{0};i < got;++i)
|
||||
ambmem[c][i] = inmem[i*static_cast<uint>(ininfo.channels)] * scale;
|
||||
++inmem;
|
||||
}
|
||||
}
|
||||
else for(const int chanid : chanmap)
|
||||
{
|
||||
/* Skip LFE. Or mix directly into W? Or W+X? */
|
||||
if(chanid == SF_CHANNEL_MAP_LFE)
|
||||
{
|
||||
++inmem;
|
||||
continue;
|
||||
}
|
||||
|
||||
const auto spkr = std::find_if(spkrs.cbegin(), spkrs.cend(),
|
||||
[chanid](const SpeakerPos &pos){return pos.mChannelID == chanid;});
|
||||
if(spkr == spkrs.cend())
|
||||
{
|
||||
fprintf(stderr, " ... failed to find channel ID %d\n", chanid);
|
||||
continue;
|
||||
}
|
||||
|
||||
for(size_t i{0};i < got;++i)
|
||||
srcmem[i] = inmem[i * static_cast<uint>(ininfo.channels)];
|
||||
++inmem;
|
||||
|
||||
static constexpr auto Deg2Rad = al::numbers::pi / 180.0;
|
||||
const auto coeffs = GenCoeffs(
|
||||
std::cos(spkr->mAzimuth*Deg2Rad) * std::cos(spkr->mElevation*Deg2Rad),
|
||||
std::sin(spkr->mAzimuth*Deg2Rad) * std::cos(spkr->mElevation*Deg2Rad),
|
||||
std::sin(spkr->mElevation*Deg2Rad));
|
||||
for(size_t c{0};c < 4;++c)
|
||||
{
|
||||
for(size_t i{0};i < got;++i)
|
||||
ambmem[c][i] += srcmem[i] * coeffs[c];
|
||||
}
|
||||
}
|
||||
|
||||
encoder->encode(encmem.subspan(0, uhjchans), ambmem, got);
|
||||
if(LeadIn >= got)
|
||||
{
|
||||
LeadIn -= got;
|
||||
continue;
|
||||
}
|
||||
|
||||
got -= LeadIn;
|
||||
for(size_t c{0};c < uhjchans;++c)
|
||||
{
|
||||
constexpr float max_val{8388607.0f / 8388608.0f};
|
||||
auto clamp = [](float v, float mn, float mx) noexcept
|
||||
{ return std::min(std::max(v, mn), mx); };
|
||||
for(size_t i{0};i < got;++i)
|
||||
outmem[i*uhjchans + c] = clamp(encmem[c][LeadIn+i], -1.0f, max_val);
|
||||
}
|
||||
LeadIn = 0;
|
||||
|
||||
sf_count_t wrote{sf_writef_float(outfile.get(), outmem.data(),
|
||||
static_cast<sf_count_t>(got))};
|
||||
if(wrote < 0)
|
||||
fprintf(stderr, " ... failed to write samples: %d\n", sf_error(outfile.get()));
|
||||
else
|
||||
total_wrote += static_cast<size_t>(wrote);
|
||||
}
|
||||
printf(" ... wrote %zu samples (%" PRId64 ").\n", total_wrote, int64_t{ininfo.frames});
|
||||
++num_encoded;
|
||||
}
|
||||
if(num_encoded == 0)
|
||||
fprintf(stderr, "Failed to encode any input files\n");
|
||||
else if(num_encoded < num_files)
|
||||
fprintf(stderr, "Encoded %zu of %zu files\n", num_encoded, num_files);
|
||||
else
|
||||
printf("Encoded %s%zu file%s\n", (num_encoded > 1) ? "all " : "", num_encoded,
|
||||
(num_encoded == 1) ? "" : "s");
|
||||
return 0;
|
||||
}
|
||||
Reference in New Issue
Block a user