aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authortobigun <tobigun@b956fd51-792f-4845-bead-9b4dfca2ff2c>2010-04-19 21:40:23 +0000
committertobigun <tobigun@b956fd51-792f-4845-bead-9b4dfca2ff2c>2010-04-19 21:40:23 +0000
commitec49bde7e1919e5a460c05903b6ccafc00be0455 (patch)
tree190870c5c19d1a35e3d0d00567fb16d77f5a782b /src
parentaecd412bef5a839a34617f11ba2fdf247d086584 (diff)
downloadusdx-ec49bde7e1919e5a460c05903b6ccafc00be0455.tar.gz
usdx-ec49bde7e1919e5a460c05903b6ccafc00be0455.tar.xz
usdx-ec49bde7e1919e5a460c05903b6ccafc00be0455.zip
bugfix for crash with portaudio (all platforms):
- UAudioInput_Portaudio: UnifyDeviceNames was called with the wrong index further changes: - BASS input source-names seem to be encoded with local encoding and are converted to UTF8 - Portaudio source and device names encoding is auto-detected and converted to UTF8 - some clean-up git-svn-id: svn://svn.code.sf.net/p/ultrastardx/svn/trunk@2252 b956fd51-792f-4845-bead-9b4dfca2ff2c
Diffstat (limited to 'src')
-rw-r--r--src/base/URecord.pas16
-rw-r--r--src/media/UAudioInput_Bass.pas8
-rw-r--r--src/media/UAudioInput_Portaudio.pas57
3 files changed, 52 insertions, 29 deletions
diff --git a/src/base/URecord.pas b/src/base/URecord.pas
index c4612adb..09ac92de 100644
--- a/src/base/URecord.pas
+++ b/src/base/URecord.pas
@@ -95,7 +95,7 @@ const
type
TAudioInputSource = record
- Name: string;
+ Name: UTF8String;
end;
// soundcard input-devices information
@@ -745,7 +745,7 @@ function TAudioInputBase.UnifyDeviceName(const name: UTF8String; deviceIndex: in
var
count: integer; // count of devices with this name
- function IsDuplicate(const name: string): boolean;
+ function IsDuplicate(const name: UTF8String): boolean;
var
i: integer;
begin
@@ -754,11 +754,13 @@ var
for i := 0 to deviceIndex-1 do
begin
if (AudioInputProcessor.DeviceList[i] <> nil) then
- if (AudioInputProcessor.DeviceList[i].Name = name) then
- begin
- Result := true;
- Break;
- end;
+ begin
+ if (AudioInputProcessor.DeviceList[i].Name = name) then
+ begin
+ Result := true;
+ Break;
+ end;
+ end;
end;
end;
diff --git a/src/media/UAudioInput_Bass.pas b/src/media/UAudioInput_Bass.pas
index e51ba254..b8f914c5 100644
--- a/src/media/UAudioInput_Bass.pas
+++ b/src/media/UAudioInput_Bass.pas
@@ -392,8 +392,8 @@ begin
BassDevice.BassDeviceID := BassDeviceID;
- // bass device name seems to be encoded w/ local encoding
- // to-do : check if this is correct
+ // BASS device names seem to be encoded with local encoding
+ // TODO: works for windows, check Linux + Mac OS X
Descr := DecodeStringUTF8(DeviceInfo.name, encLocale);
BassDevice.Name := UnifyDeviceName(Descr, DeviceIndex);
@@ -463,7 +463,9 @@ begin
break;
SetLength(BassDevice.Source, Length(BassDevice.Source)+1);
- BassDevice.Source[SourceIndex].Name := SourceName;
+ // BASS source names seem to be encoded with local encoding
+ // TODO: works for windows, check Linux + Mac OS X
+ BassDevice.Source[SourceIndex].Name := DecodeStringUTF8(SourceName, encLocale);
// get input-source info
Flags := BASS_RecordGetInput(SourceIndex, PSingle(nil)^);
diff --git a/src/media/UAudioInput_Portaudio.pas b/src/media/UAudioInput_Portaudio.pas
index 95b0f104..26919d42 100644
--- a/src/media/UAudioInput_Portaudio.pas
+++ b/src/media/UAudioInput_Portaudio.pas
@@ -46,6 +46,8 @@ uses
{$ENDIF}
portaudio,
UAudioCore_Portaudio,
+ UUnicodeUtils,
+ UTextEncoding,
UIni,
ULog,
UMain,
@@ -88,6 +90,20 @@ function MicrophoneTestCallback(input: pointer; output: pointer; frameCount: lon
inputDevice: pointer): integer; cdecl; forward;
+{**
+ * Converts a string returned by Portaudio into UTF8.
+ * If the string already is in UTF8 no conversion is performed, otherwise
+ * the local encoding is used.
+ *}
+function ConvertPaStringToUTF8(const Str: RawByteString): UTF8String;
+begin
+ if (IsUTF8String(Str)) then
+ Result := Str
+ else
+ Result := DecodeStringUTF8(Str, encLocale);
+end;
+
+
{ TPortaudioInputDevice }
function TPortaudioInputDevice.Open(): boolean;
@@ -95,6 +111,9 @@ var
Error: TPaError;
inputParams: TPaStreamParameters;
deviceInfo: PPaDeviceInfo;
+ {$IFDEF UsePortmixer}
+ SourceIndex: integer;
+ {$ENDIF}
begin
Result := false;
@@ -269,13 +288,13 @@ end;
function TAudioInput_Portaudio.EnumDevices(): boolean;
var
i: integer;
+ deviceName: UTF8String;
paApiIndex: TPaHostApiIndex;
paApiInfo: PPaHostApiInfo;
- deviceName: UTF8String;
- deviceIndex: TPaDeviceIndex;
- deviceInfo: PPaDeviceInfo;
+ paDeviceIndex:TPaDeviceIndex;
+ paDeviceInfo: PPaDeviceInfo;
channelCnt: integer;
- soundcardCnt: integer;
+ deviceIndex: integer;
err: TPaError;
errMsg: string;
paDevice: TPortaudioInputDevice;
@@ -288,7 +307,7 @@ var
mixer: PPxMixer;
sourceCnt: integer;
sourceIndex: integer;
- sourceName: string;
+ sourceName: UTF8String;
{$ENDIF}
begin
Result := false;
@@ -303,17 +322,17 @@ begin
paApiInfo := Pa_GetHostApiInfo(paApiIndex);
- soundcardCnt := 0;
+ deviceIndex := 0;
// init array-size to max. input-devices count
SetLength(AudioInputProcessor.DeviceList, paApiInfo^.deviceCount);
for i:= 0 to High(AudioInputProcessor.DeviceList) do
begin
// convert API-specific device-index to global index
- deviceIndex := Pa_HostApiDeviceIndexToDeviceIndex(paApiIndex, i);
- deviceInfo := Pa_GetDeviceInfo(deviceIndex);
+ paDeviceIndex := Pa_HostApiDeviceIndexToDeviceIndex(paApiIndex, i);
+ paDeviceInfo := Pa_GetDeviceInfo(paDeviceIndex);
- channelCnt := deviceInfo^.maxInputChannels;
+ channelCnt := paDeviceInfo^.maxInputChannels;
// current device is no input device -> skip
if (channelCnt <= 0) then
@@ -326,25 +345,25 @@ begin
channelCnt := 2;
paDevice := TPortaudioInputDevice.Create();
- AudioInputProcessor.DeviceList[soundCardCnt] := paDevice;
+ AudioInputProcessor.DeviceList[deviceIndex] := paDevice;
// retrieve device-name
- deviceName := deviceInfo^.name;
+ deviceName := ConvertPaStringToUTF8(paDeviceInfo^.name);
paDevice.Name := UnifyDeviceName(deviceName, deviceIndex);
- paDevice.PaDeviceIndex := deviceIndex;
+ paDevice.PaDeviceIndex := paDeviceIndex;
- sampleRate := deviceInfo^.defaultSampleRate;
+ sampleRate := paDeviceInfo^.defaultSampleRate;
// on vista and xp the defaultLowInputLatency may be set to 0 but it works.
// TODO: correct too low latencies (what is a too low latency, maybe < 10ms?)
- latency := deviceInfo^.defaultLowInputLatency;
+ latency := paDeviceInfo^.defaultLowInputLatency;
// setup desired input parameters
// TODO: retry with input-latency set to 20ms (defaultLowInputLatency might
// not be set correctly in OSS)
with inputParams do
begin
- device := deviceIndex;
+ device := paDeviceIndex;
channelCount := channelCnt;
sampleFormat := paInt16;
suggestedLatency := latency;
@@ -421,7 +440,7 @@ begin
for sourceIndex := 1 to sourceCnt do
begin
sourceName := Px_GetInputSourceName(mixer, sourceIndex-1);
- paDevice.Source[sourceIndex].Name := sourceName;
+ paDevice.Source[sourceIndex].Name := ConvertPaStringToUTF8(sourceName);
end;
Px_CloseMixer(mixer);
@@ -430,13 +449,13 @@ begin
// close test-stream
Pa_CloseStream(stream);
- Inc(soundCardCnt);
+ Inc(deviceIndex);
end;
// adjust size to actual input-device count
- SetLength(AudioInputProcessor.DeviceList, soundCardCnt);
+ SetLength(AudioInputProcessor.DeviceList, deviceIndex);
- Log.LogStatus('#Input-Devices: ' + inttostr(soundCardCnt), 'Portaudio');
+ Log.LogStatus('#Input-Devices: ' + inttostr(deviceIndex), 'Portaudio');
Result := true;
end;