Skip to content
GitLab
Menu
Projects
Groups
Snippets
/
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Sign in
Toggle navigation
Menu
Open sidebar
Institute of Technical Acoustics (ITA)
ITADataSources
Commits
36768833
Commit
36768833
authored
Aug 10, 2017
by
Dipl.-Ing. Jonas Stienen
Browse files
Trying reciprocal latency measurement implementation with Portaudio using ASIO host API
parent
27cd064b
Changes
5
Hide whitespace changes
Inline
Side-by-side
.gitignore
View file @
36768833
...
...
@@ -26,4 +26,3 @@ svnaccess
*.lib
*.exp
*.log
*.txt
tests/AsioTests/CMakeLists.txt
View file @
36768833
...
...
@@ -26,12 +26,3 @@ vista_install( NativeAsioThreadedMultiInstanceTest )
vista_create_default_info_file
(
NativeAsioThreadedMultiInstanceTest
)
set_property
(
TARGET NativeAsioThreadedMultiInstanceTest PROPERTY FOLDER
"ITACoreLibs/Tests/ITADataSources/Asio"
)
add_executable
(
ReciprocalDAADLatencyMeasurement ReciprocalDAADLatencyMeasurement.cpp
)
target_link_libraries
(
ReciprocalDAADLatencyMeasurement
${
VISTA_USE_PACKAGE_LIBRARIES
}
)
vista_configure_app
(
ReciprocalDAADLatencyMeasurement
)
vista_install
(
ReciprocalDAADLatencyMeasurement
)
vista_create_default_info_file
(
ReciprocalDAADLatencyMeasurement
)
set_property
(
TARGET ReciprocalDAADLatencyMeasurement PROPERTY FOLDER
"ITACoreLibs/Tests/ITADataSources/Asio"
)
tests/AsioTests/ReciprocalDAADLatencyMeasurement.cpp
deleted
100644 → 0
View file @
27cd064b
#include
<cassert>
#include
<conio.h>
#include
<iostream>
#include
<string>
#include
<vector>
#include
<algorithm>
#include
<host/asiodrivers.h>
#include
<common/asio.h>
#include
<VistaBase/VistaTimeUtils.h>
using
namespace
std
;
ASIOTime
*
AsioBufferSwitchTimeInfoA
(
ASIOTime
*
timeInfo
,
long
,
ASIOBool
)
{
return
timeInfo
;
};
void
AsioBufferSwitchA
(
long
nIndex
,
ASIOBool
processNow
)
{
ASIOTime
timeInfo
;
memset
(
&
timeInfo
,
0
,
sizeof
(
timeInfo
)
);
if
(
ASIOGetSamplePosition
(
&
timeInfo
.
timeInfo
.
samplePosition
,
&
timeInfo
.
timeInfo
.
systemTime
)
==
ASE_OK
)
timeInfo
.
timeInfo
.
flags
=
kSystemTimeValid
|
kSamplePositionValid
;
AsioBufferSwitchTimeInfoA
(
&
timeInfo
,
nIndex
,
processNow
);
};
void
AsioSampleRateChangedA
(
ASIOSampleRate
fs
)
{
cout
<<
"Sample rate changed to "
<<
fs
<<
endl
;
return
;
};
long
AsioMessagesA
(
long
,
long
,
void
*
,
double
*
)
{
return
0
;
};
ASIOTime
*
AsioBufferSwitchTimeInfoB
(
ASIOTime
*
timeInfo
,
long
,
ASIOBool
)
{
return
timeInfo
;
};
void
AsioBufferSwitchB
(
long
nIndex
,
ASIOBool
processNow
)
{
ASIOTime
timeInfo
;
memset
(
&
timeInfo
,
0
,
sizeof
(
timeInfo
)
);
if
(
ASIOGetSamplePosition
(
&
timeInfo
.
timeInfo
.
samplePosition
,
&
timeInfo
.
timeInfo
.
systemTime
)
==
ASE_OK
)
timeInfo
.
timeInfo
.
flags
=
kSystemTimeValid
|
kSamplePositionValid
;
AsioBufferSwitchTimeInfoB
(
&
timeInfo
,
nIndex
,
processNow
);
};
void
AsioSampleRateChangedB
(
ASIOSampleRate
fs
)
{
cout
<<
"Sample rate changed to "
<<
fs
<<
endl
;
return
;
};
long
AsioMessagesB
(
long
,
long
,
void
*
,
double
*
)
{
return
0
;
};
int
main
(
int
,
char
[]
)
{
ASIOError
ae
;
AsioDriverList
*
pDrivers
=
new
AsioDriverList
();
long
nNumDrivers
=
pDrivers
->
asioGetNumDev
();
cout
<<
"Number of ASIO drivers: "
<<
nNumDrivers
<<
endl
;
delete
pDrivers
;
// Driver A
int
iDriverIndexA
=
1
;
AsioDrivers
*
pDriverA
=
new
AsioDrivers
();
string
sDriverNameA
;
sDriverNameA
.
resize
(
256
);
pDriverA
->
asioGetDriverName
(
iDriverIndexA
,
&
sDriverNameA
[
0
],
int
(
sDriverNameA
.
size
()
)
);
sDriverNameA
=
std
::
string
(
sDriverNameA
.
c_str
()
);
// Strip
cout
<<
"Driver name: "
<<
sDriverNameA
<<
"."
<<
endl
;
int
iDriverIndexB
=
1
;
//AsioDrivers* pDriverB = new AsioDrivers();
string
sDriverNameB
;
sDriverNameB
.
resize
(
256
);
pDriverA
->
asioGetDriverName
(
iDriverIndexB
,
&
sDriverNameB
[
0
],
int
(
sDriverNameB
.
size
()
)
);
sDriverNameB
=
std
::
string
(
sDriverNameB
.
c_str
()
);
// Strip
cout
<<
"Driver name: "
<<
sDriverNameB
<<
"."
<<
endl
;
bool
bLoadSuccessA
=
pDriverA
->
loadDriver
(
&
sDriverNameA
[
0
]
);
assert
(
bLoadSuccessA
);
bool
bLoadSuccessB
=
pDriverA
->
loadDriver
(
&
sDriverNameB
[
0
]
);
assert
(
bLoadSuccessB
);
ASIODriverInfo
oDriverInfo
;
oDriverInfo
.
asioVersion
=
2
;
if
(
ASIOInit
(
&
oDriverInfo
)
!=
ASE_OK
)
{
cout
<<
"Could not initialize "
<<
sDriverNameA
<<
", skipping."
<<
endl
;
return
255
;
}
ASIOCallbacks
oAsioCallbackA
;
oAsioCallbackA
.
asioMessage
=
&
AsioMessagesA
;
oAsioCallbackA
.
bufferSwitch
=
&
AsioBufferSwitchA
;
oAsioCallbackA
.
bufferSwitchTimeInfo
=
&
AsioBufferSwitchTimeInfoA
;
oAsioCallbackA
.
sampleRateDidChange
=
&
AsioSampleRateChangedA
;
vector
<
ASIOBufferInfo
>
voBufferInfosA
(
4
);
voBufferInfosA
[
0
].
buffers
;
voBufferInfosA
[
0
].
channelNum
=
0
;
voBufferInfosA
[
0
].
isInput
=
ASIOTrue
;
voBufferInfosA
[
1
].
buffers
;
voBufferInfosA
[
1
].
channelNum
=
1
;
voBufferInfosA
[
1
].
isInput
=
ASIOTrue
;
voBufferInfosA
[
2
].
buffers
;
voBufferInfosA
[
2
].
channelNum
=
0
;
voBufferInfosA
[
2
].
isInput
=
ASIOFalse
;
voBufferInfosA
[
3
].
buffers
;
voBufferInfosA
[
3
].
channelNum
=
1
;
voBufferInfosA
[
3
].
isInput
=
ASIOFalse
;
ASIOSampleRate
fs
;
if
(
ASIOGetSampleRate
(
&
fs
)
==
ASE_NotPresent
)
return
255
;
long
minSize
,
maxSize
,
preferredSize
,
granularity
;
ae
=
ASIOGetBufferSize
(
&
minSize
,
&
maxSize
,
&
preferredSize
,
&
granularity
);
preferredSize
=
(
preferredSize
==
0
?
min
(
1024
,
maxSize
)
:
preferredSize
);
ae
=
ASIOCreateBuffers
(
&
voBufferInfosA
.
front
(),
4
,
preferredSize
,
&
oAsioCallbackA
);
assert
(
ae
==
ASE_OK
);
ae
=
ASIOStart
();
assert
(
ae
==
ASE_OK
);
VistaTimeUtils
::
Sleep
(
int
(
2e3
)
);
ae
=
ASIOStop
();
assert
(
ae
==
ASE_OK
);
// Driver B
ASIODriverInfo
oDriverInfoB
;
oDriverInfoB
.
asioVersion
=
2
;
if
(
ASIOInit
(
&
oDriverInfoB
)
!=
ASE_OK
)
{
cout
<<
"Could not initialize "
<<
sDriverNameB
<<
", skipping."
<<
endl
;
return
255
;
}
ASIOCallbacks
oAsioCallbackB
;
oAsioCallbackB
.
asioMessage
=
&
AsioMessagesB
;
oAsioCallbackB
.
bufferSwitch
=
&
AsioBufferSwitchB
;
oAsioCallbackB
.
bufferSwitchTimeInfo
=
&
AsioBufferSwitchTimeInfoB
;
oAsioCallbackB
.
sampleRateDidChange
=
&
AsioSampleRateChangedB
;
vector
<
ASIOBufferInfo
>
voBufferInfosB
(
4
);
voBufferInfosB
[
0
].
buffers
;
voBufferInfosB
[
0
].
channelNum
=
0
;
voBufferInfosB
[
0
].
isInput
=
ASIOTrue
;
voBufferInfosB
[
1
].
buffers
;
voBufferInfosB
[
1
].
channelNum
=
1
;
voBufferInfosB
[
1
].
isInput
=
ASIOTrue
;
voBufferInfosB
[
2
].
buffers
;
voBufferInfosB
[
2
].
channelNum
=
0
;
voBufferInfosB
[
2
].
isInput
=
ASIOFalse
;
voBufferInfosB
[
3
].
buffers
;
voBufferInfosB
[
3
].
channelNum
=
1
;
voBufferInfosB
[
3
].
isInput
=
ASIOFalse
;
if
(
ASIOGetSampleRate
(
&
fs
)
==
ASE_NotPresent
)
return
255
;
ae
=
ASIOGetBufferSize
(
&
minSize
,
&
maxSize
,
&
preferredSize
,
&
granularity
);
preferredSize
=
(
preferredSize
==
0
?
min
(
1024
,
maxSize
)
:
preferredSize
);
ae
=
ASIOCreateBuffers
(
&
voBufferInfosB
.
front
(),
4
,
preferredSize
,
&
oAsioCallbackB
);
assert
(
ae
==
ASE_OK
);
ae
=
ASIOStart
();
assert
(
ae
==
ASE_OK
);
VistaTimeUtils
::
Sleep
(
int
(
2e3
)
);
ae
=
ASIOStop
();
assert
(
ae
==
ASE_OK
);
pDriverA
->
removeCurrentDriver
();
delete
pDriverA
;
// pDriverB->removeCurrentDriver();
//delete pDriverB;
return
0
;
}
tests/ITAPortaudioTests/CMakeLists.txt
View file @
36768833
...
...
@@ -37,3 +37,14 @@ vista_install( ITAPortaudioMeasurementTest )
vista_create_default_info_file
(
ITAPortaudioMeasurementTest
)
set_property
(
TARGET ITAPortaudioMeasurementTest PROPERTY FOLDER
"ITACoreLibs/Tests/ITADataSources/Portaudio"
)
add_executable
(
ReciprocalDAADLatencyMeasurement ReciprocalDAADLatencyMeasurement.cpp
)
target_link_libraries
(
ReciprocalDAADLatencyMeasurement
${
VISTA_USE_PACKAGE_LIBRARIES
}
)
vista_set_target_msvc_arguments
(
ReciprocalDAADLatencyMeasurement 1 1
"
${
CMAKE_CURRENT_SOURCE_DIR
}
/sweep.wav
${
CMAKE_CURRENT_SOURCE_DIR
}
/recordA.wav
${
CMAKE_CURRENT_SOURCE_DIR
}
/recordB.wav 44100 2048"
)
vista_configure_app
(
ReciprocalDAADLatencyMeasurement
)
vista_install
(
ReciprocalDAADLatencyMeasurement
)
vista_create_default_info_file
(
ReciprocalDAADLatencyMeasurement
)
set_property
(
TARGET ReciprocalDAADLatencyMeasurement PROPERTY FOLDER
"ITACoreLibs/Tests/ITADataSources/Portaudio"
)
tests/ITAPortaudioTests/ReciprocalDAADLatencyMeasurement.cpp
0 → 100644
View file @
36768833
#include
<ITADataSourceUtils.h>
#include
<ITAPortaudioInterface.h>
#include
<ITAStreamProbe.h>
#include
<ITAFileDataSource.h>
#include
<ITAException.h>
#include
<ITAStringUtils.h>
#include
<iostream>
#include
<string>
using
namespace
std
;
int
main
(
int
argc
,
char
*
argv
[]
)
{
if
(
argc
!=
8
)
ITA_EXCEPT1
(
INVALID_PARAMETER
,
"Syntax error: ReciprocalDAADLatencyMeasurement.exe DeviceIndexA DeviceIndexB excitation.wav recordingA.wav recordingB.wav samplerate blocklength"
);
try
{
// Arguments
int
iDeviceA
=
StringToInt
(
string
(
argv
[
1
]
)
);
int
iDeviceB
=
StringToInt
(
string
(
argv
[
2
]
)
);
string
sExcitationSignalPath
=
string
(
argv
[
3
]
);
string
sRecordingSignalPathA
=
string
(
argv
[
4
]
);
string
sRecordingSignalPathB
=
string
(
argv
[
5
]
);
double
dSampleRate
=
StringToDouble
(
string
(
argv
[
6
]
)
);
int
iBlockLength
=
StringToInt
(
string
(
argv
[
7
]
)
);
// --- Device A ---
ITAPortaudioInterface
oPADeviceA
(
dSampleRate
,
iBlockLength
);
oPADeviceA
.
Initialize
(
iDeviceA
);
string
sInDevice
=
oPADeviceA
.
GetDeviceName
(
iDeviceA
);
cout
<<
"Input device identifier: "
<<
sInDevice
<<
endl
;
int
iNumInputChannelsA
,
iNumOutputChannelsA
;
oPADeviceA
.
GetNumChannels
(
iDeviceA
,
iNumInputChannelsA
,
iNumOutputChannelsA
);
assert
(
iNumInputChannelsA
>
1
&&
iNumOutputChannelsA
>
1
);
ITAFileDatasource
oPlaybackA
(
sExcitationSignalPath
,
iBlockLength
);
oPADeviceA
.
SetPlaybackEnabled
(
true
);
oPADeviceA
.
SetPlaybackDatasource
(
&
oPlaybackA
);
oPADeviceA
.
SetRecordEnabled
(
true
);
ITAStreamProbe
oRecordStreamProbeA
(
oPADeviceA
.
GetRecordDatasource
(),
sRecordingSignalPathA
);
// --- Device B ---
ITAPortaudioInterface
oPADeviceB
(
dSampleRate
,
iBlockLength
);
oPADeviceB
.
Initialize
(
iDeviceB
);
sInDevice
=
oPADeviceB
.
GetDeviceName
(
iDeviceB
);
cout
<<
"Input device identifier: "
<<
sInDevice
<<
endl
;
int
iNumInputChannelsB
,
iNumOutputChannelsB
;
oPADeviceB
.
GetNumChannels
(
iDeviceB
,
iNumInputChannelsB
,
iNumOutputChannelsB
);
ITAFileDatasource
oPlaybackB
(
sExcitationSignalPath
,
iBlockLength
);
oPADeviceB
.
SetPlaybackEnabled
(
true
);
oPADeviceB
.
SetPlaybackDatasource
(
&
oPlaybackB
);
oPADeviceB
.
SetRecordEnabled
(
true
);
ITAStreamProbe
oRecordStreamProbeB
(
oPADeviceB
.
GetRecordDatasource
(),
sRecordingSignalPathB
);
// --- Run latency measurement ---
// Open
oPADeviceA
.
Open
();
oPADeviceA
.
Open
();
// Start streaming
oPADeviceA
.
Start
();
oPADeviceB
.
Start
();
// Measurement
WriteFromDatasourceToFile
(
&
oRecordStreamProbeA
,
sRecordingSignalPathA
,
oPlaybackA
.
GetFileCapacity
(),
1.0
,
true
,
true
);
WriteFromDatasourceToFile
(
&
oRecordStreamProbeB
,
sRecordingSignalPathA
,
oPlaybackB
.
GetFileCapacity
(),
1.0
,
true
,
true
);
// Stop streaming
oPADeviceA
.
Stop
();
oPADeviceB
.
Stop
();
// Close
oPADeviceA
.
Close
();
oPADeviceB
.
Close
();
// Finalize
oPADeviceA
.
Finalize
();
oPADeviceB
.
Finalize
();
}
catch
(
const
ITAException
&
e
)
{
cerr
<<
e
<<
endl
;
}
return
0
;
}
\ No newline at end of file
Write
Preview
Supports
Markdown
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment