interpolateHRTF
Syntax
Description
returns the interpolated head-related transfer function (HRTF) at the desired
position.interpolatedHRTF
= interpolateHRTF(HRTF
,sourcePositions
,desiredSourcePositions
)
specifies options using one or more interpolatedHRTF
= interpolateHRTF(___,Name,Value
)Name,Value
pair arguments.
Examples
Render 3-D Audio on Headphones
Modify the 3-D audio image of a sound file by filtering it through a head-related transfer function (HRTF). Set the location of the sound source by specifying the desired azimuth and elevation.
load 'ReferenceHRTF.mat' hrtfData sourcePosition hrtfData = permute(double(hrtfData),[2,3,1]); sourcePosition = sourcePosition(:,[1,2]);
Calculate the head-related impulse response (HRIR) using the VBAP algorithm at a desired source position. Separate the output, interpolatedIR
, into the impulse responses for the left and right ears.
desiredAz = 110; desiredEl = -45; desiredPosition = [desiredAz desiredEl]; interpolatedIR = interpolateHRTF(hrtfData,sourcePosition,desiredPosition, ... "Algorithm","VBAP"); leftIR = squeeze(interpolatedIR(:,1,:))'; rightIR = squeeze(interpolatedIR(:,2,:))';
Create a dsp.AudioFileReader
object to read in a file frame by frame. Create an audioDeviceWriter
object to play audio to your sound card frame by frame. Create two dsp.FIRFilter
objects and specify the filter coefficients using the head-related transfer function interpolated impulse responses.
fileReader = dsp.AudioFileReader('RockDrums-48-stereo-11secs.mp3'); deviceWriter = audioDeviceWriter('SampleRate',fileReader.SampleRate); leftFilter = dsp.FIRFilter('Numerator',leftIR); rightFilter = dsp.FIRFilter('Numerator',rightIR);
In an audio stream loop:
Read in a frame of audio data.
Feed the stereo audio data through the left and right HRIR filters, respectively.
Concatenate the left and right channels and write the audio to your output device.
while ~isDone(fileReader) audioIn = fileReader(); leftChannel = leftFilter(audioIn(:,1)); rightChannel = rightFilter(audioIn(:,2)); deviceWriter([leftChannel,rightChannel]); end
As a best practice, release your System objects when complete.
release(deviceWriter) release(fileReader)
Model Moving Source Using HRIR Filtering
Create arrays of head-related impulse responses corresponding to desired source positions. Filter mono input to model a moving source.
Load the ARI HRTF dataset. Cast the hrtfData
to type double, and reshape it to the required dimensions: (number of source positions)-by-2-by-(number of HRTF samples). Use the first two columns of the sourcePosition
matrix only, which correspond to the azimuth and elevation of the source in degrees.
load 'ReferenceHRTF.mat' hrtfData sourcePosition hrtfData = permute(double(hrtfData),[2,3,1]); sourcePosition = sourcePosition(:,[1,2]);
Specify the desired source positions and then calculate the HRTF at these locations using the interpolateHRTF
function. Separate the output, interpolatedIR
, into the impulse responses for the left and right ears.
desiredAz = [-120;-60;0;60;120;0;-120;120]; desiredEl = [-90;90;45;0;-45;0;45;45]; desiredPosition = [desiredAz desiredEl]; interpolatedIR = interpolateHRTF(hrtfData,sourcePosition,desiredPosition); leftIR = squeeze(interpolatedIR(:,1,:)); rightIR = squeeze(interpolatedIR(:,2,:));
Create an audio file sampled at 48 kHz for compatibility with the HRTF dataset.
desiredFs = 48e3; [audio,fs] = audioread('Counting-16-44p1-mono-15secs.wav'); audio = 0.8*resample(audio,desiredFs,fs); audiowrite('Counting-16-48-mono-15secs.wav',audio,desiredFs);
Create a dsp.AudioFileReader
object to read in a file frame by frame. Create an audioDeviceWriter
object to play audio to your sound card frame by frame. Create two dsp.FIRFilter
objects with NumeratorSource
set to Input port
. Setting NumeratorSource
to Input port
enables you to modify the filter coefficients while streaming.
fileReader = dsp.AudioFileReader('Counting-16-48-mono-15secs.wav'); deviceWriter = audioDeviceWriter('SampleRate',fileReader.SampleRate); leftFilter = dsp.FIRFilter('NumeratorSource','Input port'); rightFilter = dsp.FIRFilter('NumeratorSource','Input port');
In an audio stream loop:
Read in a frame of audio data.
Feed the audio data through the left and right HRIR filters.
Concatenate the left and right channels and write the audio to your output device. If you have a stereo output hardware, such as headphones, you can hear the source shifting position over time.
Modify the desired source position in 2-second intervals by updating the filter coefficients.
durationPerPosition = 2; samplesPerPosition = durationPerPosition*fileReader.SampleRate; samplesPerPosition = samplesPerPosition - rem(samplesPerPosition,fileReader.SamplesPerFrame); sourcePositionIndex = 1; samplesRead = 0; while ~isDone(fileReader) audioIn = fileReader(); samplesRead = samplesRead + fileReader.SamplesPerFrame; leftChannel = leftFilter(audioIn,leftIR(sourcePositionIndex,:)); rightChannel = rightFilter(audioIn,rightIR(sourcePositionIndex,:)); deviceWriter([leftChannel,rightChannel]); if mod(samplesRead,samplesPerPosition) == 0 sourcePositionIndex = sourcePositionIndex + 1; end end
As a best practice, release your System objects when complete.
release(deviceWriter) release(fileReader)
Input Arguments
HRTF
— HRTF values measured at source positions
N-by-2-by-M array
HRTF values measured at the source positions, specified as a N-by-2-by-M array.
N –– Number of known HRTF pairs
M –– Number of samples in each known HRTF
If you specify HRTF
with real numbers, the function assumes
that the input represents an impulse response, and M corresponds to
the length of the impulse response. If you specify HRTF
with
complex numbers, the function assumes that the input represents a transfer function, and
M corresponds to the number of bins in the frequency response. The
output of the interpolateHRTF
function has the same complexity and
interpretation as the input.
Data Types: single
| double
Complex Number Support: Yes
sourcePositions
— Source positions corresponding to measured HRTF values
N-by-2 matrix
Source positions corresponding to measured HRTF values, specified as a N-by-2 matrix. N is the number of known HRTF pairs. The two columns correspond to the azimuth and elevation of the source in degrees, respectively.
Azimuth must be in the range [−180,360]. You can use the −180 to 180 convention or the 0 to 360 convention.
Elevation must be in the range [−90,180]. You can use the −90 to 90 convention or the 0 to 180 convention.
Data Types: single
| double
desiredSourcePositions
— Desired source positions for HRTF interpolation
P-by-2 matrix
Desired source position for HRTF interpolation, specified as a P-by-2 matrix. P is the number of desired source positions. The columns correspond to the desired azimuth and elevation of the source in degrees, respectively.
Azimuth must be in the range [−180,360]. You can use the −180 to 180 convention or the 0 to 360 convention.
Elevation must be in the range [−90,180]. You can use the −90 to 90 convention or the 0 to 180 convention.
Data Types: single
| double
Name-Value Arguments
Specify optional pairs of arguments as
Name1=Value1,...,NameN=ValueN
, where Name
is
the argument name and Value
is the corresponding value.
Name-value arguments must appear after other arguments, but the order of the
pairs does not matter.
Before R2021a, use commas to separate each name and value, and enclose
Name
in quotes.
Example: 'Algorithm','VBAP'
Output Arguments
interpolatedHRTF
— Interpolated HRTF
P-by-2-by-M
Interpolated HRTF, returned as a P-by-2-by-M array.
P –– Number of desired source positions, specified by the number of rows in the
desiredSourcePositions
input argument.M –– Number of samples in each known HRTF, specified by the number of pages in the
HRTF
input argument.
interpolatedHRTF
has the same complexity and interpretation as
the input. If you specify the input, HRTF
, with real numbers, the
function assumes that the input represents an impulse response. If you specify the input
with complex numbers, the function assumes that the input represents a transfer
function.
Data Types: single
| double
Complex Number Support: Yes
References
[1] F.P. Freeland, L.W.P. Biscainho and P.S.R. Diniz, "Interpolation of Head-Related Transfer Functions (HRTFS): A multi-source approach." 2004 12th European Signal Processing Conference. Vienna, 2004, pp. 1761–1764.
[2] Pulkki, Ville. "Virtual Sound Source Positioning Using Vector Based Amplitude Panning." Journal of Audio Engineering Society. Vol. 45. Issue 6, pp. 456–466.
Extended Capabilities
C/C++ Code Generation
Generate C and C++ code using MATLAB® Coder™.
Version History
Introduced in R2018b
See Also
Ouvrir l'exemple
Vous possédez une version modifiée de cet exemple. Souhaitez-vous ouvrir cet exemple avec vos modifications ?
Commande MATLAB
Vous avez cliqué sur un lien qui correspond à cette commande MATLAB :
Pour exécuter la commande, saisissez-la dans la fenêtre de commande de MATLAB. Les navigateurs web ne supportent pas les commandes MATLAB.
Select a Web Site
Choose a web site to get translated content where available and see local events and offers. Based on your location, we recommend that you select: .
You can also select a web site from the following list:
How to Get Best Site Performance
Select the China site (in Chinese or English) for best site performance. Other MathWorks country sites are not optimized for visits from your location.
Americas
- América Latina (Español)
- Canada (English)
- United States (English)
Europe
- Belgium (English)
- Denmark (English)
- Deutschland (Deutsch)
- España (Español)
- Finland (English)
- France (Français)
- Ireland (English)
- Italia (Italiano)
- Luxembourg (English)
- Netherlands (English)
- Norway (English)
- Österreich (Deutsch)
- Portugal (English)
- Sweden (English)
- Switzerland
- United Kingdom (English)