{* UltraStar Deluxe - Karaoke Game * * UltraStar Deluxe is the legal property of its developers, whose names * are too numerous to list here. Please refer to the COPYRIGHT * file distributed with this source distribution. * * 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; see the file COPYING. If not, write to * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * * $URL$ * $Id$ *} program TestPortAudioDevice; {* TestPortAudioDevice does some basic tests of the portaudio libs. * If all works, it lists all audio input and output devices and their * characteristics. Compile and run with simple commands. *} {$IFDEF FPC} {$MODE Delphi} {$ENDIF} uses SysUtils, ctypes, PortAudio in '../src/lib/portaudio/portaudio.pas'; const paDefaultApi = -1; const ApiPreferenceOrder: {$IF Defined(MSWINDOWS)} // Note1: Portmixer has no mixer support for paASIO and paWASAPI at the moment // Note2: Windows Default-API is MME, but DirectSound is faster array[0..0] of TPaHostApiTypeId = ( paDirectSound ); {$ELSEIF Defined(DARWIN)} array[0..0] of TPaHostApiTypeId = ( paDefaultApi ); // paCoreAudio {$ELSEIF Defined(UNIX)} // Note: Portmixer has no mixer support for JACK at the moment array[0..2] of TPaHostApiTypeId = ( paALSA, paJACK, paOSS ); {$ELSE} array[0..0] of TPaHostApiTypeId = ( paDefaultApi ); {$IFEND} var i: integer; PaError: TPaError; paApiIndex: TPaHostApiIndex; paApiInfo: PPaHostApiInfo; deviceIndex: TPaDeviceIndex; deviceInfo: PPaDeviceInfo; inputParameters: PPaStreamParameters; outputParameters: PPaStreamParameters; sampleRate: cdouble; function GetPreferredApiIndex(): TPaHostApiIndex; var i: integer; apiIndex: TPaHostApiIndex; apiInfo: PPaHostApiInfo; begin result := -1; // select preferred sound-API for i:= 0 to High(ApiPreferenceOrder) do begin if (ApiPreferenceOrder[i] <> paDefaultApi) then begin // check if API is available apiIndex := Pa_HostApiTypeIdToHostApiIndex(ApiPreferenceOrder[i]); if (apiIndex >= 0) then begin // we found an API but we must check if it works // (on linux portaudio might detect OSS but does not provide // any devices if ALSA is enabled) apiInfo := Pa_GetHostApiInfo(apiIndex); if (apiInfo^.deviceCount > 0) then begin Result := apiIndex; break; end; end; end; end; // None of the preferred APIs is available -> use default if (result < 0) then begin result := Pa_GetDefaultHostApi(); end; end; begin writeln ('Start: Test of Portaudio libs'); writeln; writeln ('*** Test of Pa_Initialize and Pa_Terminate ***'); PaError := Pa_Initialize; if PaError = paNoError then writeln ('Pa_Initialize: No error') else writeln ('Pa_Initialize: Error No ', PaError); PaError := Pa_Terminate; if PaError = paNoError then writeln ('Pa_Terminate: No error') else writeln ('Pa_Terminate: Error No: ', PaError); writeln; writeln ('*** Test of Pa_GetErrorText ***'); PaError := Pa_Initialize; writeln ('paNoError (0): ', Pa_GetErrorText(PaError)); writeln; writeln ('Code Text'); writeln ('------------------------------------'); i := paNotInitialized; repeat writeln (i:6, ' ', Pa_GetErrorText(i)); i := succ(i); until SameText(Pa_GetErrorText(i), 'Invalid error code') or (i = paNotInitialized + 100); writeln (i:6, ' ', Pa_GetErrorText(i)); PaError := Pa_Terminate; writeln; writeln ('*** Test of Pa_GetVersion and Pa_GetVersionText ***'); PaError := Pa_Initialize; writeln ('Pa_GetVersion: ', Pa_GetVersion); writeln ('Pa_GetVersionText: ', Pa_GetVersionText); PaError := Pa_Terminate; writeln; writeln ('*** Test of Pa_GetDeviceCount ***'); PaError := Pa_Initialize; writeln ('Pa_GetDeviceCount: ', Pa_GetDeviceCount); PaError := Pa_Terminate; writeln; writeln ('*** Test of Pa_GetDefaultInputDevice ***'); PaError := Pa_Initialize; writeln ('Pa_GetDefaultInputDevice: ', Pa_GetDefaultInputDevice); PaError := Pa_Terminate; writeln; writeln ('*** Test of Pa_GetDefaultOutputDevice ***'); PaError := Pa_Initialize; writeln ('Pa_GetDefaultOutputDevice: ', Pa_GetDefaultOutputDevice); PaError := Pa_Terminate; writeln; writeln ('*** Test of GetPreferredApiIndex ***'); PaError := Pa_Initialize; paApiIndex := GetPreferredApiIndex(); if (paApiIndex = -1) then writeln ('GetPreferredApiIndex: No working Audio-API found.') else writeln ('GetPreferredApiIndex: working Audio-API found. No: ', paApiIndex); PaError := Pa_Terminate; writeln; writeln ('*** Test of Pa_GetHostApiInfo ***'); PaError := Pa_Initialize; paApiIndex := GetPreferredApiIndex(); paApiInfo := Pa_GetHostApiInfo(paApiIndex); writeln ('Pa_GetHostApiInfo:'); writeln ('paApiInfo.structVersion: ', paApiInfo.structVersion); writeln ('paApiInfo._type: ', paApiInfo._type); writeln ('paApiInfo.name: ', paApiInfo.name); writeln ('paApiInfo.deviceCount: ', paApiInfo.deviceCount); writeln ('paApiInfo.defaultInputDevice: ', paApiInfo.defaultInputDevice); writeln ('paApiInfo.defaultOutputDevice: ', paApiInfo.defaultOutputDevice); PaError := Pa_Terminate; writeln; writeln ('*** Test of Pa_HostApiDeviceIndexToDeviceIndex ***'); PaError := Pa_Initialize; paApiIndex := GetPreferredApiIndex(); paApiInfo := Pa_GetHostApiInfo(paApiIndex); for i:= 0 to paApiInfo^.deviceCount-1 do begin deviceIndex := Pa_HostApiDeviceIndexToDeviceIndex(paApiIndex, i); writeln ('deviceIndex[', i, ']: ', deviceIndex); end; PaError := Pa_Terminate; writeln; writeln ('*** Test of Pa_GetDeviceInfo ***'); // Note: the fields of deviceInfo can also be used without the '^'. // deviceInfo.name works as well as deviceInfo^.name PaError := Pa_Initialize; paApiIndex := GetPreferredApiIndex(); paApiInfo := Pa_GetHostApiInfo(paApiIndex); for i:= 0 to paApiInfo^.deviceCount - 1 do begin deviceIndex := Pa_HostApiDeviceIndexToDeviceIndex(paApiIndex, i); deviceInfo := Pa_GetDeviceInfo(deviceIndex); writeln ('deviceInfo[', i, '].name: ', deviceInfo^.name); writeln ('deviceInfo[', i, '].structVersion: ', deviceInfo^.structVersion, ' (should be 2)'); writeln ('deviceInfo[', i, '].hostApi: ', deviceInfo^.hostApi); writeln ('deviceInfo[', i, '].maxInputChannels: ', deviceInfo^.maxInputChannels); writeln ('deviceInfo[', i, '].maxOutputChannels: ', deviceInfo^.maxOutputChannels); writeln ('deviceInfo[', i, '].defaultLowInputLatency: ', deviceInfo^.defaultLowInputLatency); writeln ('deviceInfo[', i, '].defaultLowOutputLatency: ', deviceInfo^.defaultLowOutputLatency); writeln ('deviceInfo[', i, '].defaultHighInputLatency: ', deviceInfo^.defaultHighInputLatency); writeln ('deviceInfo[', i, '].defaultHighOutputLatency: ', deviceInfo^.defaultHighOutputLatency); writeln ('deviceInfo[', i, '].defaultSampleRate: ', deviceInfo^.defaultSampleRate:5:0); writeln; end; PaError := Pa_Terminate; writeln ('*** Test of Pa_IsFormatSupported ***'); // Note: the fields of deviceInfo can also be used without the '^'. // deviceInfo.name works as well as deviceInfo^.name PaError := Pa_Initialize; paApiIndex := GetPreferredApiIndex(); paApiInfo := Pa_GetHostApiInfo(paApiIndex); for i:= 0 to paApiInfo^.deviceCount - 1 do begin deviceIndex := Pa_HostApiDeviceIndexToDeviceIndex(paApiIndex, i); deviceInfo := Pa_GetDeviceInfo(deviceIndex); writeln ('Device[', i, '] ', deviceInfo^.name, ':'); New(inputParameters); New(outputParameters); if deviceInfo^.maxInputChannels > 0 then begin inputParameters^.device := deviceIndex; inputParameters^.channelCount := deviceInfo^.maxInputChannels; inputParameters^.sampleFormat := paInt16; inputParameters^.suggestedLatency := deviceInfo^.defaultLowInputLatency; inputParameters^.hostApiSpecificStreamInfo := nil; outputParameters := nil; end else begin inputParameters := nil; outputParameters^.device := deviceIndex; outputParameters^.channelCount := deviceInfo^.maxOutputChannels; outputParameters^.sampleFormat := paInt16; outputParameters^.suggestedLatency := deviceInfo^.defaultLowOutputLatency; outputParameters^.hostApiSpecificStreamInfo := nil; end; sampleRate := deviceInfo^.defaultSampleRate; PaError := Pa_IsFormatSupported(inputParameters, outputParameters, sampleRate); if PaError = paFormatIsSupported then writeln ('Sample rate: ', sampleRate:5:0, ' : supported') else writeln ('Sample rate: ', sampleRate:5:0, ' : Error: ', Pa_GetErrorText(PaError)); { try sampleRate := 48000; PaError := Pa_IsFormatSupported(inputParameters, outputParameters, sampleRate); if PaError = paFormatIsSupported then writeln ('Sample rate: ', sampleRate:5:0, ' : supported') else writeln ('Sample rate: ', sampleRate:5:0, ' : Error: ', PaError); except On EDivByZero do begin writeln ('Division by 0 error with sample rate ', sampleRate:5:0); PaError := Pa_Terminate; PaError := Pa_Initialize; end; end; try sampleRate := 90000; PaError := Pa_IsFormatSupported(inputParameters, outputParameters, sampleRate); if PaError = paFormatIsSupported then writeln ('Sample rate: ', sampleRate:5:0, ' : supported') else writeln ('Sample rate: ', sampleRate:5:0, ' : Error: ', Pa_GetErrorText(PaError)); except On EDivByZero do begin writeln ('Division by 0 error with sample rate ', sampleRate:5:0); PaError := Pa_Terminate; PaError := Pa_Initialize; end; end; } Dispose(inputParameters); Dispose(outputParameters); end; writeln; PaError := Pa_Terminate; writeln ('End: Test of Portaudio libs'); end.