Use PortAudio-Sharp bindings for easier updates

Use COSFunctions for OS-specific stuff
Add dll directories on startup (could be done in the modules itself, but this way it avoids all trouble)
This commit is contained in:
Flamefire committed 2014-03-15 17:15:13 +01:00
1 parent f0fca0baf7
commit 5316d30a7d
12 files changed
+196 -650

No files matched your search

Binary file not shown.
+4
View File
@@ -0,0 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<configuration><startup><supportedRuntime version="v2.0.50727" /></startup>
<dllmap dll="PortAudio.dll" target="libportaudio.so.2" />
</configuration>
File renamed without changes.
File renamed without changes.
+89
View File
@@ -0,0 +1,89 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
namespace Vocaluxe
{
static class COSFunctions
{
#if WIN
private static bool _DefaultDllDirSet;
private static bool _UsePath;
private static bool _UseSetDllDir;
private static class CWindowsFunctions
{
[DllImport("kernel32.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)]
public static extern void AddDllDirectory(string lpPathName);
[DllImport("kernel32.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)]
public static extern void SetDllDirectory(string lpPathName);
[DllImport("user32.dll", CallingConvention = CallingConvention.StdCall)]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool SetForegroundWindow(IntPtr hWnd);
[DllImport("user32.dll", CallingConvention = CallingConvention.StdCall)]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool SetDefaultDllDirectories(int directoryFlags);
// ReSharper disable InconsistentNaming
public const int LOAD_LIBRARY_SEARCH_DEFAULT_DIRS = 0x00001000;
// ReSharper restore InconsistentNaming
}
#endif
public static void AddEnvironmentPath(string path)
{
string newPath = Environment.GetEnvironmentVariable("PATH") ?? string.Empty;
if (newPath.Length > 0)
newPath += ";";
newPath += path;
Environment.SetEnvironmentVariable("PATH", newPath);
}
public static void AddLibrarySearchpath(string path)
{
#if WIN
if (!_DefaultDllDirSet)
{
try
{
CWindowsFunctions.SetDefaultDllDirectories(CWindowsFunctions.LOAD_LIBRARY_SEARCH_DEFAULT_DIRS);
}
catch (Exception)
{
_UsePath = true;
_UseSetDllDir = true;
}
_DefaultDllDirSet = true;
}
if (_UsePath)
AddEnvironmentPath(path);
if (!_UseSetDllDir)
{
try
{
CWindowsFunctions.AddDllDirectory(path);
}
catch (Exception)
{
_UseSetDllDir = true;
}
}
if (_UseSetDllDir)
CWindowsFunctions.SetDllDirectory(path);
#endif
}
public static void SetForegroundWindow(IntPtr hWnd)
{
#if WIN
CWindowsFunctions.SetForegroundWindow(hWnd);
#endif
}
}
}
+15
View File
@@ -17,6 +17,8 @@
using System;
using System.IO;
using System.Reflection;
using System.Runtime.InteropServices;
using System.Security;
using Microsoft.Win32;
using Vocaluxe.Base;
@@ -108,5 +110,18 @@ namespace Vocaluxe
}
return true;
}
public static void Init()
{
#if ARCH_X86
string path = "x86";
#endif
#if ARCH_X64
string path = "x64";
#endif
path = Path.GetDirectoryName(Assembly.GetEntryAssembly().Location) + Path.DirectorySeparatorChar + path;
COSFunctions.AddLibrarySearchpath(path);
COSFunctions.AddLibrarySearchpath(path + Path.DirectorySeparatorChar + "gstreamer");
}
}
}
@@ -26,9 +26,6 @@ namespace Vocaluxe.Lib.Sound.Playback.GstreamerSharp
private readonly Dictionary<int, CGstreamerSharpAudioStream> _Streams = new Dictionary<int, CGstreamerSharpAudioStream>();
private static int _IDCount;
[DllImport("kernel32.dll", CharSet = CharSet.Auto)]
private static extern void SetDllDirectory(string lpPathName);
public bool Init()
{
#if ARCH_X86
@@ -37,7 +34,7 @@ namespace Vocaluxe.Lib.Sound.Playback.GstreamerSharp
#if ARCH_X64
const string path = ".\\x64\\gstreamer";
#endif
SetDllDirectory(path);
//SetDllDirectory(path);
Application.Init();
Registry reg = Registry.Get();
reg.ScanPath(path);
@@ -4,7 +4,6 @@ using System.Runtime.InteropServices;
using System.Threading;
using Vocaluxe.Base;
using Vocaluxe.Lib.Sound.Playback.Decoder;
using Vocaluxe.Lib.Sound.PortAudio;
using VocaluxeLib;
namespace Vocaluxe.Lib.Sound.Playback.PortAudio
@@ -25,12 +24,12 @@ namespace Vocaluxe.Lib.Sound.Playback.PortAudio
private EStreamAction _AfterFadeAction;
private CFading _Fading;
private static CPortAudio.SPaHostApiInfo _ApiInfo;
private static CPortAudio.SPaDeviceInfo _OutputDeviceInfo;
private static PortAudioSharp.PortAudio.PaHostApiInfo _ApiInfo;
private static PortAudioSharp.PortAudio.PaDeviceInfo _OutputDeviceInfo;
private IntPtr _Ptr = new IntPtr(0);
private Closeproc _Closeproc;
private CPortAudio.PaStreamCallbackDelegate _PaStreamCallback;
private PortAudioSharp.PortAudio.PaStreamCallbackDelegate _PaStreamCallback;
private int _StreamID;
private IAudioDecoder _Decoder;
private float _BytesPerSecond;
@@ -202,7 +201,7 @@ namespace Vocaluxe.Lib.Sound.Playback.PortAudio
_AfterFadeAction = EStreamAction.Nothing;
lock (_Mutex)
{
_ErrorCheck("StartStream", CPortAudio.Pa_StartStream(_Ptr));
_ErrorCheck("StartStream", PortAudioSharp.PortAudio.Pa_StartStream(_Ptr));
}
}
@@ -210,7 +209,7 @@ namespace Vocaluxe.Lib.Sound.Playback.PortAudio
{
lock (_Mutex)
{
_ErrorCheck("StopStream (playback)", CPortAudio.Pa_StopStream(_Ptr));
_ErrorCheck("StopStream (playback)", PortAudioSharp.PortAudio.Pa_StopStream(_Ptr));
}
Skip(0f);
}
@@ -241,15 +240,15 @@ namespace Vocaluxe.Lib.Sound.Playback.PortAudio
{
if (!_Initialized)
{
if (_ErrorCheck("Initialize", CPortAudio.Pa_Initialize()))
if (_ErrorCheck("Initialize", PortAudioSharp.PortAudio.Pa_Initialize()))
return -1;
_Initialized = true;
int hostApi = _ApiSelect();
_ApiInfo = CPortAudio.PaGetHostApiInfo(hostApi);
_OutputDeviceInfo = CPortAudio.PaGetDeviceInfo(_ApiInfo.DefaultOutputDevice);
if (_OutputDeviceInfo.DefaultLowOutputLatency < 0.1)
_OutputDeviceInfo.DefaultLowOutputLatency = 0.1;
_ApiInfo = PortAudioSharp.PortAudio.Pa_GetHostApiInfo(hostApi);
_OutputDeviceInfo = PortAudioSharp.PortAudio.Pa_GetDeviceInfo(_ApiInfo.defaultOutputDevice);
if (_OutputDeviceInfo.defaultLowOutputLatency < 0.1)
_OutputDeviceInfo.defaultLowOutputLatency = 0.1;
}
}
@@ -278,24 +277,25 @@ namespace Vocaluxe.Lib.Sound.Playback.PortAudio
var data = new IntPtr(0);
var outputParams = new CPortAudio.SPaStreamParameters
PortAudioSharp.PortAudio.PaStreamParameters? outputParams = new PortAudioSharp.PortAudio.PaStreamParameters
{
ChannelCount = format.ChannelCount,
Device = _ApiInfo.DefaultOutputDevice,
SampleFormat = CPortAudio.EPaSampleFormat.PaInt16,
SuggestedLatency = _OutputDeviceInfo.DefaultLowOutputLatency
channelCount = format.ChannelCount,
device = _ApiInfo.defaultOutputDevice,
sampleFormat = PortAudioSharp.PortAudio.PaSampleFormat.paInt16,
suggestedLatency = _OutputDeviceInfo.defaultLowOutputLatency
};
PortAudioSharp.PortAudio.PaStreamParameters? inputParams = null;
var bufsize = (uint)CConfig.AudioBufferSize;
lock (_Mutex)
{
_ErrorCheck("OpenDefaultStream (playback)", CPortAudio.Pa_OpenStream(
_ErrorCheck("OpenDefaultStream (playback)", PortAudioSharp.PortAudio.Pa_OpenStream(
out _Ptr,
IntPtr.Zero,
ref inputParams,
ref outputParams,
format.SamplesPerSecond,
bufsize,
CPortAudio.EPaStreamFlags.PaNoFlag,
PortAudioSharp.PortAudio.PaStreamFlags.paNoFlag,
_PaStreamCallback,
data));
}
@@ -450,7 +450,7 @@ namespace Vocaluxe.Lib.Sound.Playback.PortAudio
{
lock (_Mutex)
{
CPortAudio.Pa_Terminate();
PortAudioSharp.PortAudio.Pa_Terminate();
_Initialized = false;
}
}
@@ -462,12 +462,12 @@ namespace Vocaluxe.Lib.Sound.Playback.PortAudio
#endregion Threading
#region Callbacks
private CPortAudio.EPaStreamCallbackResult _ProcessNewData(
private PortAudioSharp.PortAudio.PaStreamCallbackResult _ProcessNewData(
IntPtr input,
IntPtr output,
uint frameCount,
ref CPortAudio.SPaStreamCallbackTimeInfo timeInfo,
CPortAudio.EPaStreamCallbackFlags statusFlags,
ref PortAudioSharp.PortAudio.PaStreamCallbackTimeInfo timeInfo,
PortAudioSharp.PortAudio.PaStreamCallbackFlags statusFlags,
IntPtr userData)
{
var buf = new byte[frameCount * _ByteCount];
@@ -482,7 +482,7 @@ namespace Vocaluxe.Lib.Sound.Playback.PortAudio
{
Console.WriteLine(e.ToString());
}
return CPortAudio.EPaStreamCallbackResult.PaContinue;
return PortAudioSharp.PortAudio.PaStreamCallbackResult.paContinue;
}
lock (_LockData)
@@ -534,27 +534,27 @@ namespace Vocaluxe.Lib.Sound.Playback.PortAudio
}
catch (Exception e)
{
CLog.LogError("Error PortAudio.StreamCallback: " + e.Message);
CLog.LogError("Error PortAudio.treamCallback: " + e.Message);
}
return CPortAudio.EPaStreamCallbackResult.PaContinue;
return PortAudioSharp.PortAudio.PaStreamCallbackResult.paContinue;
}
#endregion Callbacks
private bool _ErrorCheck(String action, CPortAudio.EPaError errorCode)
private bool _ErrorCheck(String action, PortAudioSharp.PortAudio.PaError errorCode)
{
if (errorCode != CPortAudio.EPaError.PaNoError)
if (errorCode != PortAudioSharp.PortAudio.PaError.paNoError)
{
if (errorCode == CPortAudio.EPaError.PaStreamIsNotStopped)
if (errorCode == PortAudioSharp.PortAudio.PaError.paStreamIsNotStopped)
return false;
CLog.LogError(action + " error (playback): " + CPortAudio.PaGetErrorText(errorCode));
if (errorCode == CPortAudio.EPaError.PaUnanticipatedHostError)
CLog.LogError(action + " error (playback): " + PortAudioSharp.PortAudio.Pa_GetErrorText(errorCode));
if (errorCode == PortAudioSharp.PortAudio.PaError.paUnanticipatedHostError)
{
CPortAudio.SPaHostErrorInfo errorInfo = CPortAudio.PaGetLastHostErrorInfo();
CLog.LogError("- Host error API type: " + errorInfo.HostApiType);
CLog.LogError("- Host error code: " + errorInfo.ErrorCode);
CLog.LogError("- Host error text: " + errorInfo.ErrorText);
PortAudioSharp.PortAudio.PaHostErrorInfo errorInfo = PortAudioSharp.PortAudio.Pa_GetLastHostErrorInfo();
CLog.LogError("- Host error API type: " + errorInfo.hostApiType);
CLog.LogError("- Host error code: " + errorInfo.errorCode);
CLog.LogError("- Host error text: " + errorInfo.errorText);
}
return true;
}
@@ -567,13 +567,13 @@ namespace Vocaluxe.Lib.Sound.Playback.PortAudio
if (!_Initialized)
return 0;
int selectedHostApi = CPortAudio.Pa_GetDefaultHostApi();
int apiCount = CPortAudio.Pa_GetHostApiCount();
int selectedHostApi = PortAudioSharp.PortAudio.Pa_GetDefaultHostApi();
int apiCount = PortAudioSharp.PortAudio.Pa_GetHostApiCount();
for (int i = 0; i < apiCount; i++)
{
CPortAudio.SPaHostApiInfo apiInfo = CPortAudio.PaGetHostApiInfo(i);
if ((apiInfo.Type == CPortAudio.EPaHostApiTypeId.PaDirectSound)
|| (apiInfo.Type == CPortAudio.EPaHostApiTypeId.PaALSA))
PortAudioSharp.PortAudio.PaHostApiInfo apiInfo = PortAudioSharp.PortAudio.Pa_GetHostApiInfo(i);
if ((apiInfo.type == PortAudioSharp.PortAudio.PaHostApiTypeId.paDirectSound)
|| (apiInfo.type == PortAudioSharp.PortAudio.PaHostApiTypeId.paALSA))
selectedHostApi = i;
}
return selectedHostApi;
-558
View File
@@ -1,558 +0,0 @@
#region license
// This file is part of Vocaluxe.
//
// Vocaluxe 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 3 of the License, or
// (at your option) any later version.
//
// Vocaluxe 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 Vocaluxe. If not, see <http://www.gnu.org/licenses/>.
#endregion
using System;
using System.Runtime.InteropServices;
namespace Vocaluxe.Lib.Sound.PortAudio
{
/**
<summary>
PortAudio v.19 bindings for .NET
</summary>
*/
// ReSharper disable UnusedMember.Global
// ReSharper disable FieldCanBeMadeReadOnly.Global
// ReSharper disable MemberCanBePrivate.Global
public static class CPortAudio
{
#region **** PORTAUDIO CALLBACKS ****
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate EPaStreamCallbackResult PaStreamCallbackDelegate(
IntPtr input,
IntPtr output,
uint frameCount,
ref SPaStreamCallbackTimeInfo timeInfo,
EPaStreamCallbackFlags statusFlags,
IntPtr userData);
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate void PaStreamFinishedCallbackDelegate(IntPtr userData);
#endregion
#region **** PORTAUDIO DATA STRUCTURES ****
[StructLayout(LayoutKind.Sequential)]
public struct SPaDeviceInfo
{
public int StructVersion;
[MarshalAs(UnmanagedType.LPStr)] public string Name;
public int HostApi;
public int MaxInputChannels;
public int MaxOutputChannels;
public double DefaultLowInputLatency;
public double DefaultLowOutputLatency;
public double DefaultHighInputLatency;
public double DefaultHighOutputLatency;
public double DefaultSampleRate;
public override string ToString()
{
return "[" + GetType().Name + "]" + "\n"
+ "name: " + Name + "\n"
+ "hostApi: " + HostApi + "\n"
+ "maxInputChannels: " + MaxInputChannels + "\n"
+ "maxOutputChannels: " + MaxOutputChannels + "\n"
+ "defaultLowInputLatency: " + DefaultLowInputLatency + "\n"
+ "defaultLowOutputLatency: " + DefaultLowOutputLatency + "\n"
+ "defaultHighInputLatency: " + DefaultHighInputLatency + "\n"
+ "defaultHighOutputLatency: " + DefaultHighOutputLatency + "\n"
+ "defaultSampleRate: " + DefaultSampleRate;
}
}
[StructLayout(LayoutKind.Sequential)]
public struct SPaHostApiInfo
{
public int StructVersion;
public EPaHostApiTypeId Type;
[MarshalAs(UnmanagedType.LPStr)] public string Name;
public int DeviceCount;
public int DefaultInputDevice;
public int DefaultOutputDevice;
public override string ToString()
{
return "[" + GetType().Name + "]" + "\n"
+ "structVersion: " + StructVersion + "\n"
+ "type: " + Type + "\n"
+ "name: " + Name + "\n"
+ "deviceCount: " + DeviceCount + "\n"
+ "defaultInputDevice: " + DefaultInputDevice + "\n"
+ "defaultOutputDevice: " + DefaultOutputDevice;
}
}
[StructLayout(LayoutKind.Sequential)]
public struct SPaHostErrorInfo
{
public EPaHostApiTypeId HostApiType;
public int ErrorCode;
[MarshalAs(UnmanagedType.LPStr)] public string ErrorText;
public override string ToString()
{
return "[" + GetType().Name + "]" + "\n"
+ "hostApiType: " + HostApiType + "\n"
+ "errorCode: " + ErrorCode + "\n"
+ "errorText: " + ErrorText;
}
}
[StructLayout(LayoutKind.Sequential)]
public struct SPaStreamCallbackTimeInfo
{
public double InputBufferAdcTime;
public double CurrentTime;
public double OutputBufferDacTime;
public override string ToString()
{
return "[" + GetType().Name + "]" + "\n"
+ "currentTime: " + CurrentTime + "\n"
+ "inputBufferAdcTime: " + InputBufferAdcTime + "\n"
+ "outputBufferDacTime: " + OutputBufferDacTime;
}
}
[StructLayout(LayoutKind.Sequential)]
public struct SPaStreamInfo
{
public int StructVersion;
public double InputLatency;
public double OutputLatency;
public double SampleRate;
public override string ToString()
{
return "[" + GetType().Name + "]" + "\n"
+ "structVersion: " + StructVersion + "\n"
+ "inputLatency: " + InputLatency + "\n"
+ "outputLatency: " + OutputLatency + "\n"
+ "sampleRate: " + SampleRate;
}
}
[StructLayout(LayoutKind.Sequential)]
public struct SPaStreamParameters
{
public int Device;
public int ChannelCount;
public EPaSampleFormat SampleFormat;
public double SuggestedLatency;
internal IntPtr HostApiSpecificStreamInfo;
public override string ToString()
{
return "[" + GetType().Name + "]" + "\n"
+ "device: " + Device + "\n"
+ "channelCount: " + ChannelCount + "\n"
+ "sampleFormat: " + SampleFormat + "\n"
+ "suggestedLatency: " + SuggestedLatency;
}
}
#endregion
#region **** PORTAUDIO DEFINES ****
public enum EPaDeviceIndex
{
PaNoDevice = -1,
PaUseHostApiSpecificDeviceSpecification = -2
}
public enum EPaSampleFormat : uint
{
PaFloat32 = 0x00000001,
PaInt32 = 0x00000002,
PaInt24 = 0x00000004,
PaInt16 = 0x00000008,
PaInt8 = 0x00000010,
PaUInt8 = 0x00000020,
PaCustomFormat = 0x00010000,
PaNonInterleaved = 0x80000000,
}
public const int PaFormatIsSupported = 0;
public const int PaFramesPerBufferUnspecified = 0;
public enum EPaStreamFlags : uint
{
PaNoFlag = 0,
PaClipOff = 0x00000001,
PaDitherOff = 0x00000002,
PaNeverDropInput = 0x00000004,
PaPrimeOutputBuffersUsingStreamCallback = 0x00000008,
PaPlatformSpecificFlags = 0xFFFF0000
}
public enum EPaStreamCallbackFlags : uint
{
PaInputUnderflow = 0x00000001,
PaInputOverflow = 0x00000002,
PaOutputUnderflow = 0x00000004,
PaOutputOverflow = 0x00000008,
PaPrimingOutput = 0x00000010
}
#endregion
#region **** PORTAUDIO ENUMERATIONS ****
public enum EPaError
{
PaNoError = 0,
PaNotInitialized = -10000,
PaUnanticipatedHostError,
PaInvalidChannelCount,
PaInvalidSampleRate,
PaInvalidDevice,
PaInvalidFlag,
PaSampleFormatNotSupported,
PaBadIODeviceCombination,
PaInsufficientMemory,
PaBufferTooBig,
PaBufferTooSmall,
PaNullCallback,
PaBadStreamPtr,
PaTimedOut,
PaInternalError,
PaDeviceUnavailable,
PaIncompatibleHostApiSpecificStreamInfo,
PaStreamIsStopped,
PaStreamIsNotStopped,
PaInputOverflowed,
PaOutputUnderflowed,
PaHostApiNotFound,
PaInvalidHostApi,
PaCanNotReadFromCallbackStream,
PaCanNotWriteToACallbackStream,
PaCanNotReadFromAnOutputOnlyStream,
PaCanNotWriteToAnInputOnlyStream,
PaIncompatibleStreamHostApi,
PaBadBufferPtr
}
public enum EPaHostApiTypeId : uint
{
PaInDevelopment = 0,
PaDirectSound = 1,
PaMME = 2,
PaASIO = 3,
PaSoundManager = 4,
PaCoreAudio = 5,
PaOSS = 7,
PaALSA = 8,
PaAL = 9,
PaBeOS = 10,
PaWDMKS = 11,
PaJACK = 12,
PaWASAPI = 13,
PaAudioScienceHPI = 14
}
public enum EPaStreamCallbackResult : uint
{
PaContinue = 0,
PaComplete = 1,
PaAbort = 2
}
#endregion
#region **** PORTAUDIO FUNCTIONS ****
#if ARCH_X86
#if WIN
private const string _PaDll = "x86\\portaudio_x86.dll";
#endif
#if LINUX
private const string _PaDll = "libportaudio.so.2.0.0";
#endif
#endif
#if ARCH_X64
#if WIN
private const string _PaDll = "x64\\portaudio_x64.dll";
#endif
#if LINUX
private const string _PaDll = "libportaudio.so.2.0.0";
#endif
#endif
[DllImport(_PaDll, CallingConvention = CallingConvention.Cdecl)]
public static extern int Pa_GetVersion();
[DllImport(_PaDll, EntryPoint = "Pa_GetVersionText", CallingConvention = CallingConvention.Cdecl)]
private static extern IntPtr IntPtr_Pa_GetVersionText();
public static string PaGetVersionText()
{
IntPtr strptr = IntPtr_Pa_GetVersionText();
return Marshal.PtrToStringAnsi(strptr);
}
[DllImport(_PaDll, EntryPoint = "Pa_GetErrorText", CallingConvention = CallingConvention.Cdecl)]
public static extern IntPtr IntPtr_Pa_GetErrorText(EPaError errorCode);
public static string PaGetErrorText(EPaError errorCode)
{
IntPtr strptr = IntPtr_Pa_GetErrorText(errorCode);
return Marshal.PtrToStringAnsi(strptr);
}
[DllImport(_PaDll, CallingConvention = CallingConvention.Cdecl)]
public static extern EPaError Pa_Initialize();
[DllImport(_PaDll, CallingConvention = CallingConvention.Cdecl)]
public static extern EPaError Pa_Terminate();
[DllImport(_PaDll, CallingConvention = CallingConvention.Cdecl)]
public static extern int Pa_GetHostApiCount();
[DllImport(_PaDll, CallingConvention = CallingConvention.Cdecl)]
public static extern int Pa_GetDefaultHostApi();
[DllImport(_PaDll, EntryPoint = "Pa_GetHostApiInfo", CallingConvention = CallingConvention.Cdecl)]
public static extern IntPtr IntPtr_Pa_GetHostApiInfo(int hostApi);
public static SPaHostApiInfo PaGetHostApiInfo(int hostApi)
{
IntPtr structptr = IntPtr_Pa_GetHostApiInfo(hostApi);
return (SPaHostApiInfo)Marshal.PtrToStructure(structptr, typeof(SPaHostApiInfo));
}
[DllImport(_PaDll, CallingConvention = CallingConvention.Cdecl)]
public static extern int Pa_HostApiTypeIdToHostApiIndex(EPaHostApiTypeId type);
[DllImport(_PaDll, CallingConvention = CallingConvention.Cdecl)]
public static extern int Pa_HostApiDeviceIndexToDeviceIndex(int hostApi, int hostApiDeviceIndex);
[DllImport(_PaDll, EntryPoint = "Pa_GetLastHostErrorInfo", CallingConvention = CallingConvention.Cdecl)]
public static extern IntPtr IntPtr_Pa_GetLastHostErrorInfo();
public static SPaHostErrorInfo PaGetLastHostErrorInfo()
{
IntPtr structptr = IntPtr_Pa_GetLastHostErrorInfo();
return (SPaHostErrorInfo)Marshal.PtrToStructure(structptr, typeof(SPaHostErrorInfo));
}
[DllImport(_PaDll, CallingConvention = CallingConvention.Cdecl)]
public static extern int Pa_GetDeviceCount();
[DllImport(_PaDll, CallingConvention = CallingConvention.Cdecl)]
public static extern int Pa_GetDefaultInputDevice();
[DllImport(_PaDll, CallingConvention = CallingConvention.Cdecl)]
public static extern int Pa_GetDefaultOutputDevice();
[DllImport(_PaDll, EntryPoint = "Pa_GetDeviceInfo", CallingConvention = CallingConvention.Cdecl)]
public static extern IntPtr IntPtr_Pa_GetDeviceInfo(int device);
public static SPaDeviceInfo PaGetDeviceInfo(int device)
{
IntPtr structptr = IntPtr_Pa_GetDeviceInfo(device);
return (SPaDeviceInfo)Marshal.PtrToStructure(structptr, typeof(SPaDeviceInfo));
}
[DllImport(_PaDll, CallingConvention = CallingConvention.Cdecl)]
public static extern EPaError Pa_IsFormatSupported(
ref SPaStreamParameters inputParameters,
ref SPaStreamParameters outputParameters,
double sampleRate);
[DllImport(_PaDll, CallingConvention = CallingConvention.Cdecl)]
public static extern EPaError Pa_OpenStream(
out IntPtr stream,
ref SPaStreamParameters inputParameters,
ref SPaStreamParameters outputParameters,
double sampleRate,
uint framesPerBuffer,
EPaStreamFlags streamFlags,
PaStreamCallbackDelegate streamCallback,
IntPtr userData);
[DllImport(_PaDll, CallingConvention = CallingConvention.Cdecl)]
public static extern EPaError Pa_OpenStream(
out IntPtr stream,
ref SPaStreamParameters inputParameters,
IntPtr outputParameters,
double sampleRate,
uint framesPerBuffer,
EPaStreamFlags streamFlags,
PaStreamCallbackDelegate streamCallback,
IntPtr userData);
[DllImport(_PaDll, CallingConvention = CallingConvention.Cdecl)]
public static extern EPaError Pa_OpenStream(
out IntPtr stream,
IntPtr inputParameters,
ref SPaStreamParameters outputParameters,
double sampleRate,
uint framesPerBuffer,
EPaStreamFlags streamFlags,
PaStreamCallbackDelegate streamCallback,
IntPtr userData);
[DllImport(_PaDll, CallingConvention = CallingConvention.Cdecl)]
public static extern EPaError Pa_OpenDefaultStream(
out IntPtr stream,
int numInputChannels,
int numOutputChannels,
uint sampleFormat,
double sampleRate,
uint framesPerBuffer,
PaStreamCallbackDelegate streamCallback,
IntPtr userData);
[DllImport(_PaDll, CallingConvention = CallingConvention.Cdecl)]
public static extern EPaError Pa_CloseStream(IntPtr stream);
[DllImport(_PaDll, CallingConvention = CallingConvention.Cdecl)]
public static extern EPaError Pa_SetStreamFinishedCallback(
ref IntPtr stream,
[MarshalAs(UnmanagedType.FunctionPtr)] PaStreamFinishedCallbackDelegate streamFinishedCallback);
[DllImport(_PaDll, CallingConvention = CallingConvention.Cdecl)]
public static extern EPaError Pa_StartStream(IntPtr stream);
[DllImport(_PaDll, CallingConvention = CallingConvention.Cdecl)]
public static extern EPaError Pa_StopStream(IntPtr stream);
[DllImport(_PaDll, CallingConvention = CallingConvention.Cdecl)]
public static extern EPaError Pa_AbortStream(IntPtr stream);
[DllImport(_PaDll, CallingConvention = CallingConvention.Cdecl)]
public static extern EPaError Pa_IsStreamStopped(IntPtr stream);
[DllImport(_PaDll, CallingConvention = CallingConvention.Cdecl)]
public static extern EPaError Pa_IsStreamActive(IntPtr stream);
[DllImport(_PaDll, EntryPoint = "Pa_GetStreamInfo", CallingConvention = CallingConvention.Cdecl)]
public static extern IntPtr IntPtr_Pa_GetStreamInfo(IntPtr stream);
public static SPaStreamInfo PaGetStreamInfo(IntPtr stream)
{
IntPtr structptr = IntPtr_Pa_GetStreamInfo(stream);
return (SPaStreamInfo)Marshal.PtrToStructure(structptr, typeof(SPaStreamInfo));
}
[DllImport(_PaDll, CallingConvention = CallingConvention.Cdecl)]
public static extern double Pa_GetStreamTime(IntPtr stream);
[DllImport(_PaDll, CallingConvention = CallingConvention.Cdecl)]
public static extern double Pa_GetStreamCpuLoad(IntPtr stream);
[DllImport(_PaDll, CallingConvention = CallingConvention.Cdecl)]
public static extern EPaError Pa_ReadStream(
IntPtr stream,
[Out] float[] buffer,
uint frames);
[DllImport(_PaDll, CallingConvention = CallingConvention.Cdecl)]
public static extern EPaError Pa_ReadStream(
IntPtr stream,
[Out] byte[] buffer,
uint frames);
[DllImport(_PaDll, CallingConvention = CallingConvention.Cdecl)]
public static extern EPaError Pa_ReadStream(
IntPtr stream,
[Out] sbyte[] buffer,
uint frames);
[DllImport(_PaDll, CallingConvention = CallingConvention.Cdecl)]
public static extern EPaError Pa_ReadStream(
IntPtr stream,
[Out] ushort[] buffer,
uint frames);
[DllImport(_PaDll, CallingConvention = CallingConvention.Cdecl)]
public static extern EPaError Pa_ReadStream(
IntPtr stream,
[Out] short[] buffer,
uint frames);
[DllImport(_PaDll, CallingConvention = CallingConvention.Cdecl)]
public static extern EPaError Pa_ReadStream(
IntPtr stream,
[Out] uint[] buffer,
uint frames);
[DllImport(_PaDll, CallingConvention = CallingConvention.Cdecl)]
public static extern EPaError Pa_ReadStream(
IntPtr stream,
[Out] int[] buffer,
uint frames);
[DllImport(_PaDll, CallingConvention = CallingConvention.Cdecl)]
public static extern EPaError Pa_WriteStream(
IntPtr stream,
[In] float[] buffer,
uint frames);
[DllImport(_PaDll, CallingConvention = CallingConvention.Cdecl)]
public static extern EPaError Pa_WriteStream(
IntPtr stream,
[In] byte[] buffer,
uint frames);
[DllImport(_PaDll, CallingConvention = CallingConvention.Cdecl)]
public static extern EPaError Pa_WriteStream(
IntPtr stream,
[In] sbyte[] buffer,
uint frames);
[DllImport(_PaDll, CallingConvention = CallingConvention.Cdecl)]
public static extern EPaError Pa_WriteStream(
IntPtr stream,
[In] ushort[] buffer,
uint frames);
[DllImport(_PaDll, CallingConvention = CallingConvention.Cdecl)]
public static extern EPaError Pa_WriteStream(
IntPtr stream,
[In] short[] buffer,
uint frames);
[DllImport(_PaDll, CallingConvention = CallingConvention.Cdecl)]
public static extern EPaError Pa_WriteStream(
IntPtr stream,
[In] uint[] buffer,
uint frames);
[DllImport(_PaDll, CallingConvention = CallingConvention.Cdecl)]
public static extern EPaError Pa_WriteStream(
IntPtr stream,
[In] int[] buffer,
uint frames);
[DllImport(_PaDll, CallingConvention = CallingConvention.Cdecl)]
public static extern int Pa_GetStreamReadAvailable(IntPtr stream);
[DllImport(_PaDll, CallingConvention = CallingConvention.Cdecl)]
public static extern int Pa_GetStreamWriteAvailable(IntPtr stream);
[DllImport(_PaDll, CallingConvention = CallingConvention.Cdecl)]
public static extern EPaError Pa_GetSampleSize(EPaSampleFormat format);
[DllImport(_PaDll, CallingConvention = CallingConvention.Cdecl)]
public static extern void Pa_Sleep(int msec);
#endregion
}
// ReSharper restore UnusedMember.Global
// ReSharper restore FieldCanBeMadeReadOnly.Global
// ReSharper restore MemberCanBePrivate.Global
}
@@ -21,7 +21,6 @@ using System;
using System.Collections.Generic;
using System.Runtime.InteropServices;
using Vocaluxe.Base;
using Vocaluxe.Lib.Sound.PortAudio;
namespace Vocaluxe.Lib.Sound.Record.PortAudio
{
@@ -30,7 +29,7 @@ namespace Vocaluxe.Lib.Sound.Record.PortAudio
private bool _Initialized;
private List<CRecordDevice> _Devices;
private CPortAudio.PaStreamCallbackDelegate _MyRecProc;
private PortAudioSharp.PortAudio.PaStreamCallbackDelegate _MyRecProc;
private IntPtr[] _RecHandle;
private readonly CBuffer[] _Buffer;
@@ -59,19 +58,19 @@ namespace Vocaluxe.Lib.Sound.Record.PortAudio
if (_Initialized)
CloseAll();
if (_ErrorCheck("Initialize", CPortAudio.Pa_Initialize()))
if (_ErrorCheck("Initialize", PortAudioSharp.PortAudio.Pa_Initialize()))
return false;
_Initialized = true;
int hostAPI = _ApiSelect();
int numDevices = CPortAudio.Pa_GetDeviceCount();
int numDevices = PortAudioSharp.PortAudio.Pa_GetDeviceCount();
for (int i = 0; i < numDevices; i++)
{
CPortAudio.SPaDeviceInfo info = CPortAudio.PaGetDeviceInfo(i);
if (info.HostApi == hostAPI && info.MaxInputChannels > 0)
PortAudioSharp.PortAudio.PaDeviceInfo info = PortAudioSharp.PortAudio.Pa_GetDeviceInfo(i);
if (info.hostApi == hostAPI && info.maxInputChannels > 0)
{
var dev = new CRecordDevice( i, info.Name,info.Name + i, info.MaxInputChannels);
var dev = new CRecordDevice(i, info.name, info.name + i, info.maxInputChannels);
_Devices.Add(dev);
}
@@ -108,7 +107,7 @@ namespace Vocaluxe.Lib.Sound.Record.PortAudio
foreach (IntPtr handle in _RecHandle)
{
int waitcount = 0;
while (waitcount < 5 && CPortAudio.Pa_IsStreamStopped(handle) == CPortAudio.EPaError.PaStreamIsNotStopped)
while (waitcount < 5 && PortAudioSharp.PortAudio.Pa_IsStreamStopped(handle) == PortAudioSharp.PortAudio.PaError.paStreamIsNotStopped)
{
Thread.Sleep(1);
waitcount++;
@@ -130,26 +129,26 @@ namespace Vocaluxe.Lib.Sound.Record.PortAudio
{
if (active[i])
{
var inputParams = new CPortAudio.SPaStreamParameters
PortAudioSharp.PortAudio.PaStreamParameters? inputParams = new PortAudioSharp.PortAudio.PaStreamParameters
{
ChannelCount = _Devices[i].Channels,
Device = _Devices[i].ID,
SampleFormat = CPortAudio.EPaSampleFormat.PaInt16,
SuggestedLatency = CPortAudio.PaGetDeviceInfo(_Devices[i].ID).DefaultLowInputLatency
channelCount = _Devices[i].Channels,
device = _Devices[i].ID,
sampleFormat = PortAudioSharp.PortAudio.PaSampleFormat.paInt16,
suggestedLatency = PortAudioSharp.PortAudio.Pa_GetDeviceInfo(_Devices[i].ID).defaultLowInputLatency
};
if (_ErrorCheck("OpenStream (rec)", CPortAudio.Pa_OpenStream(
PortAudioSharp.PortAudio.PaStreamParameters? outputParams = null;
if (_ErrorCheck("OpenStream (rec)", PortAudioSharp.PortAudio.Pa_OpenStream(
out _RecHandle[i],
ref inputParams,
IntPtr.Zero,
ref outputParams,
44100,
882,
CPortAudio.EPaStreamFlags.PaNoFlag,
PortAudioSharp.PortAudio.PaStreamFlags.paNoFlag,
_MyRecProc,
new IntPtr(i))))
return false;
if (_ErrorCheck("Start Stream (rec)", CPortAudio.Pa_StartStream(_RecHandle[i])))
if (_ErrorCheck("Start Stream (rec)", PortAudioSharp.PortAudio.Pa_StartStream(_RecHandle[i])))
return false;
}
}
@@ -166,7 +165,7 @@ namespace Vocaluxe.Lib.Sound.Record.PortAudio
return false;
foreach (IntPtr handle in _RecHandle)
CPortAudio.Pa_StopStream(handle);
PortAudioSharp.PortAudio.Pa_StopStream(handle);
return true;
}
@@ -179,7 +178,7 @@ namespace Vocaluxe.Lib.Sound.Record.PortAudio
if (_Initialized)
{
CPortAudio.Pa_Terminate();
PortAudioSharp.PortAudio.Pa_Terminate();
_Initialized = false;
}
@@ -265,12 +264,12 @@ namespace Vocaluxe.Lib.Sound.Record.PortAudio
return _Devices.AsReadOnly();
}
private CPortAudio.EPaStreamCallbackResult _MyPaStreamCallback(
private PortAudioSharp.PortAudio.PaStreamCallbackResult _MyPaStreamCallback(
IntPtr input,
IntPtr output,
uint frameCount,
ref CPortAudio.SPaStreamCallbackTimeInfo timeInfo,
CPortAudio.EPaStreamCallbackFlags statusFlags,
ref PortAudioSharp.PortAudio.PaStreamCallbackTimeInfo timeInfo,
PortAudioSharp.PortAudio.PaStreamCallbackFlags statusFlags,
IntPtr userData)
{
try
@@ -312,20 +311,20 @@ namespace Vocaluxe.Lib.Sound.Record.PortAudio
CLog.LogError("Error on Stream Callback (rec): " + e);
}
return CPortAudio.EPaStreamCallbackResult.PaContinue;
return PortAudioSharp.PortAudio.PaStreamCallbackResult.paContinue;
}
private bool _ErrorCheck(String action, CPortAudio.EPaError errorCode)
private bool _ErrorCheck(String action, PortAudioSharp.PortAudio.PaError errorCode)
{
if (errorCode != CPortAudio.EPaError.PaNoError)
if (errorCode != PortAudioSharp.PortAudio.PaError.paNoError)
{
CLog.LogError(action + " error (rec): " + CPortAudio.PaGetErrorText(errorCode));
if (errorCode == CPortAudio.EPaError.PaUnanticipatedHostError)
CLog.LogError(action + " error (rec): " + PortAudioSharp.PortAudio.Pa_GetErrorText(errorCode));
if (errorCode == PortAudioSharp.PortAudio.PaError.paUnanticipatedHostError)
{
CPortAudio.SPaHostErrorInfo errorInfo = CPortAudio.PaGetLastHostErrorInfo();
CLog.LogError("- Host error API type: " + errorInfo.HostApiType);
CLog.LogError("- Host error code: " + errorInfo.ErrorCode);
CLog.LogError("- Host error text: " + errorInfo.ErrorText);
PortAudioSharp.PortAudio.PaHostErrorInfo errorInfo = PortAudioSharp.PortAudio.Pa_GetLastHostErrorInfo();
CLog.LogError("- Host error API type: " + errorInfo.hostApiType);
CLog.LogError("- Host error code: " + errorInfo.errorCode);
CLog.LogError("- Host error text: " + errorInfo.errorText);
}
return true;
}
@@ -338,13 +337,13 @@ namespace Vocaluxe.Lib.Sound.Record.PortAudio
if (!_Initialized)
return 0;
int selectedHostApi = CPortAudio.Pa_GetDefaultHostApi();
int apiCount = CPortAudio.Pa_GetHostApiCount();
int selectedHostApi = PortAudioSharp.PortAudio.Pa_GetDefaultHostApi();
int apiCount = PortAudioSharp.PortAudio.Pa_GetHostApiCount();
for (int i = 0; i < apiCount; i++)
{
CPortAudio.SPaHostApiInfo apiInfo = CPortAudio.PaGetHostApiInfo(i);
if ((apiInfo.Type == CPortAudio.EPaHostApiTypeId.PaDirectSound)
|| (apiInfo.Type == CPortAudio.EPaHostApiTypeId.PaALSA))
PortAudioSharp.PortAudio.PaHostApiInfo apiInfo = PortAudioSharp.PortAudio.Pa_GetHostApiInfo(i);
if ((apiInfo.type == PortAudioSharp.PortAudio.PaHostApiTypeId.paDirectSound)
|| (apiInfo.type == PortAudioSharp.PortAudio.PaHostApiTypeId.paALSA))
selectedHostApi = i;
}
return selectedHostApi;
+6 -10
View File
@@ -20,7 +20,6 @@ using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.InteropServices;
using System.Threading;
using System.Windows.Forms;
using Vocaluxe.Base;
@@ -32,12 +31,6 @@ namespace Vocaluxe
{
static class CMainProgram
{
#if WIN
[DllImport("user32.dll")]
[return: MarshalAs(UnmanagedType.Bool)]
private static extern bool SetForegroundWindow(IntPtr hWnd);
#endif
private static CSplashScreen _SplashScreen;
[STAThread, HandleProcessCorruptedStateExceptions]
@@ -85,6 +78,7 @@ namespace Vocaluxe
if (!CProgrammHelper.CheckRequirements())
return;
CProgrammHelper.Init();
CMain.Init();
CSettings.CreateFolders();
@@ -228,13 +222,15 @@ namespace Vocaluxe
{
MessageBox.Show("Error on start up: " + e.Message + e.StackTrace);
CLog.LogError("Error on start up: " + e);
_SplashScreen.Close();
if (_SplashScreen != null)
_SplashScreen.Close();
_CloseProgram();
}
Application.DoEvents();
// Start Main Loop
_SplashScreen.Close();
if (_SplashScreen != null)
_SplashScreen.Close();
CVocaluxeServer.Start();
CDraw.MainLoop();
@@ -332,7 +328,7 @@ namespace Vocaluxe
{
IntPtr wnd = process.MainWindowHandle;
if (wnd != IntPtr.Zero)
SetForegroundWindow(wnd);
COSFunctions.SetForegroundWindow(wnd);
}
#endif
return false;
+5 -1
View File
@@ -199,6 +199,10 @@
<Reference Include="OpenTK.GLControl">
<HintPath>..\Output\OpenTK.GLControl.dll</HintPath>
</Reference>
<Reference Include="PortAudioSharp, Version=0.19.3.27472, Culture=neutral, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
<HintPath>..\Output\PortAudioSharp.dll</HintPath>
</Reference>
<Reference Include="QRCoder, Version=1.0.0.0, Culture=neutral, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
<HintPath>..\Output\QRCoder.dll</HintPath>
@@ -212,6 +216,7 @@
</ItemGroup>
<ItemGroup>
<Compile Include="Base\CBackgroundMusic.cs" />
<Compile Include="COSFunctions.cs" />
<Compile Include="Lib\Sound\Playback\GstreamerSharp\CGstreamerSharpAudioStream.cs" />
<Compile Include="Lib\Sound\Playback\OpenAL\COpenAlStream.cs" />
<Compile Include="Lib\Sound\Playback\PortAudio\CPortAudioStream.cs" />
@@ -327,7 +332,6 @@
<None Include="app.config">
<SubType>Designer</SubType>
</None>
<Compile Include="Lib\Sound\PortAudio\PortAudio.cs" />
<None Include="Doc\SQLite.NET.chm" />
<Content Include="Website\locales\de.json">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>