Use an al_string vector for winmm device names

Also now gets wchar device names, to properly convert to UTF-8
This commit is contained in:
Chris Robinson 2014-04-07 12:43:19 -07:00
parent c6821e5dd1
commit 4f1104125b
2 changed files with 110 additions and 82 deletions

View File

@ -42,4 +42,7 @@ void al_string_append_range(al_string *str, const al_string_char_type *from, con
void al_string_copy_wcstr(al_string *str, const wchar_t *from); void al_string_copy_wcstr(al_string *str, const wchar_t *from);
#endif #endif
DECL_VECTOR(al_string)
#endif /* ALSTRING_H */ #endif /* ALSTRING_H */

View File

@ -56,87 +56,103 @@ typedef struct {
} WinMMData; } WinMMData;
static ALCchar **PlaybackDeviceList; static vector_al_string PlaybackDevices;
static ALuint NumPlaybackDevices; static vector_al_string CaptureDevices;
static ALCchar **CaptureDeviceList;
static ALuint NumCaptureDevices;
static void ProbePlaybackDevices(void) static void ProbePlaybackDevices(void)
{ {
al_string *iter, *end;
ALuint numdevs;
ALuint i; ALuint i;
for(i = 0;i < NumPlaybackDevices;i++) iter = VECTOR_ITER_BEGIN(PlaybackDevices);
free(PlaybackDeviceList[i]); end = VECTOR_ITER_END(PlaybackDevices);
for(;iter != end;iter++)
AL_STRING_DEINIT(*iter);
VECTOR_RESIZE(PlaybackDevices, 0);
NumPlaybackDevices = waveOutGetNumDevs(); numdevs = waveOutGetNumDevs();
PlaybackDeviceList = realloc(PlaybackDeviceList, sizeof(ALCchar*) * NumPlaybackDevices); VECTOR_RESERVE(PlaybackDevices, numdevs);
for(i = 0;i < NumPlaybackDevices;i++) for(i = 0;i < numdevs;i++)
{ {
WAVEOUTCAPS WaveCaps; WAVEOUTCAPSW WaveCaps;
al_string dname;
PlaybackDeviceList[i] = NULL; AL_STRING_INIT(dname);
if(waveOutGetDevCaps(i, &WaveCaps, sizeof(WaveCaps)) == MMSYSERR_NOERROR) if(waveOutGetDevCapsW(i, &WaveCaps, sizeof(WaveCaps)) == MMSYSERR_NOERROR)
{ {
char name[1024]; ALuint count = 0;
ALuint count, j;
count = 0;
do { do {
if(count == 0) al_string_copy_wcstr(&dname, WaveCaps.szPname);
snprintf(name, sizeof(name), "%s", WaveCaps.szPname); if(count != 0)
else {
snprintf(name, sizeof(name), "%s #%d", WaveCaps.szPname, count+1); char str[64];
snprintf(str, sizeof(str), " #%d", count+1);
al_string_append_cstr(&dname, str);
}
count++; count++;
for(j = 0;j < i;j++) iter = VECTOR_ITER_BEGIN(PlaybackDevices);
end = VECTOR_ITER_END(PlaybackDevices);
for(;iter != end;iter++)
{ {
if(strcmp(name, PlaybackDeviceList[j]) == 0) if(al_string_cmp(*iter, dname) == 0)
break; break;
} }
} while(j != i); } while(iter != end);
PlaybackDeviceList[i] = strdup(name); TRACE("Got device \"%s\", ID %u\n", al_string_get_cstr(dname), i);
} }
VECTOR_PUSH_BACK(PlaybackDevices, dname);
} }
} }
static void ProbeCaptureDevices(void) static void ProbeCaptureDevices(void)
{ {
al_string *iter, *end;
ALuint numdevs;
ALuint i; ALuint i;
for(i = 0;i < NumCaptureDevices;i++) iter = VECTOR_ITER_BEGIN(CaptureDevices);
free(CaptureDeviceList[i]); end = VECTOR_ITER_END(CaptureDevices);
for(;iter != end;iter++)
AL_STRING_DEINIT(*iter);
VECTOR_RESIZE(CaptureDevices, 0);
NumCaptureDevices = waveInGetNumDevs(); numdevs = waveInGetNumDevs();
CaptureDeviceList = realloc(CaptureDeviceList, sizeof(ALCchar*) * NumCaptureDevices); VECTOR_RESERVE(CaptureDevices, numdevs);
for(i = 0;i < NumCaptureDevices;i++) for(i = 0;i < numdevs;i++)
{ {
WAVEINCAPS WaveInCaps; WAVEINCAPSW WaveCaps;
al_string dname;
CaptureDeviceList[i] = NULL; AL_STRING_INIT(dname);
if(waveInGetDevCaps(i, &WaveInCaps, sizeof(WAVEINCAPS)) == MMSYSERR_NOERROR) if(waveInGetDevCapsW(i, &WaveCaps, sizeof(WaveCaps)) == MMSYSERR_NOERROR)
{ {
char name[1024]; ALuint count = 0;
ALuint count, j;
count = 0;
do { do {
if(count == 0) al_string_copy_wcstr(&dname, WaveCaps.szPname);
snprintf(name, sizeof(name), "%s", WaveInCaps.szPname); if(count != 0)
else {
snprintf(name, sizeof(name), "%s #%d", WaveInCaps.szPname, count+1); char str[64];
snprintf(str, sizeof(str), " #%d", count+1);
al_string_append_cstr(&dname, str);
}
count++; count++;
for(j = 0;j < i;j++) iter = VECTOR_ITER_BEGIN(CaptureDevices);
end = VECTOR_ITER_END(CaptureDevices);
for(;iter != end;iter++)
{ {
if(strcmp(name, CaptureDeviceList[j]) == 0) if(al_string_cmp(*iter, dname) == 0)
break; break;
} }
} while(j != i); } while(iter != end);
CaptureDeviceList[i] = strdup(name); TRACE("Got device \"%s\", ID %u\n", al_string_get_cstr(dname), i);
} }
VECTOR_PUSH_BACK(CaptureDevices, dname);
} }
} }
@ -270,24 +286,26 @@ static DWORD WINAPI CaptureThreadProc(LPVOID param)
static ALCenum WinMMOpenPlayback(ALCdevice *Device, const ALCchar *deviceName) static ALCenum WinMMOpenPlayback(ALCdevice *Device, const ALCchar *deviceName)
{ {
WinMMData *data = NULL; WinMMData *data = NULL;
UINT DeviceID = 0; const al_string *iter, *end;
UINT DeviceID = -1u;
MMRESULT res; MMRESULT res;
ALuint i = 0;
if(!PlaybackDeviceList) if(VECTOR_SIZE(PlaybackDevices) == 0)
ProbePlaybackDevices(); ProbePlaybackDevices();
// Find the Device ID matching the deviceName if valid // Find the Device ID matching the deviceName if valid
for(i = 0;i < NumPlaybackDevices;i++) iter = VECTOR_ITER_BEGIN(PlaybackDevices);
end = VECTOR_ITER_END(PlaybackDevices);
for(;iter != end;iter++)
{ {
if(PlaybackDeviceList[i] && if(!al_string_empty(*iter) &&
(!deviceName || strcmp(deviceName, PlaybackDeviceList[i]) == 0)) (!deviceName || al_string_cmp_cstr(*iter, deviceName) == 0))
{ {
DeviceID = i; DeviceID = (UINT)(iter - VECTOR_ITER_BEGIN(PlaybackDevices));
break; break;
} }
} }
if(i == NumPlaybackDevices) if(DeviceID == -1u)
return ALC_INVALID_VALUE; return ALC_INVALID_VALUE;
data = calloc(1, sizeof(*data)); data = calloc(1, sizeof(*data));
@ -336,7 +354,7 @@ retry_open:
goto failure; goto failure;
} }
al_string_copy_cstr(&Device->DeviceName, PlaybackDeviceList[DeviceID]); al_string_copy(&Device->DeviceName, VECTOR_ELEM(PlaybackDevices, DeviceID));
return ALC_NO_ERROR; return ALC_NO_ERROR;
failure: failure:
@ -485,28 +503,31 @@ static void WinMMStopPlayback(ALCdevice *device)
static ALCenum WinMMOpenCapture(ALCdevice *Device, const ALCchar *deviceName) static ALCenum WinMMOpenCapture(ALCdevice *Device, const ALCchar *deviceName)
{ {
const al_string *iter, *end;
ALbyte *BufferData = NULL; ALbyte *BufferData = NULL;
DWORD CapturedDataSize; DWORD CapturedDataSize;
WinMMData *data = NULL; WinMMData *data = NULL;
UINT DeviceID = 0; UINT DeviceID = -1u;
ALint BufferSize; ALint BufferSize;
MMRESULT res; MMRESULT res;
ALuint i; ALuint i;
if(!CaptureDeviceList) if(VECTOR_SIZE(CaptureDevices) == 0)
ProbeCaptureDevices(); ProbeCaptureDevices();
// Find the Device ID matching the deviceName if valid // Find the Device ID matching the deviceName if valid
for(i = 0;i < NumCaptureDevices;i++) iter = VECTOR_ITER_BEGIN(CaptureDevices);
end = VECTOR_ITER_END(CaptureDevices);
for(;iter != end;iter++)
{ {
if(CaptureDeviceList[i] && if(!al_string_empty(*iter) &&
(!deviceName || strcmp(deviceName, CaptureDeviceList[i]) == 0)) (!deviceName || al_string_cmp_cstr(*iter, deviceName) == 0))
{ {
DeviceID = i; DeviceID = (UINT)(iter - VECTOR_ITER_BEGIN(CaptureDevices));
break; break;
} }
} }
if(i == NumCaptureDevices) if(DeviceID == -1u)
return ALC_INVALID_VALUE; return ALC_INVALID_VALUE;
switch(Device->FmtChans) switch(Device->FmtChans)
@ -606,7 +627,7 @@ static ALCenum WinMMOpenCapture(ALCdevice *Device, const ALCchar *deviceName)
if (data->WaveThread == NULL) if (data->WaveThread == NULL)
goto failure; goto failure;
al_string_copy_cstr(&Device->DeviceName, CaptureDeviceList[DeviceID]); al_string_copy(&Device->DeviceName, VECTOR_ELEM(CaptureDevices, DeviceID));
return ALC_NO_ERROR; return ALC_NO_ERROR;
failure: failure:
@ -718,51 +739,55 @@ static const BackendFuncs WinMMFuncs = {
ALCboolean alcWinMMInit(BackendFuncs *FuncList) ALCboolean alcWinMMInit(BackendFuncs *FuncList)
{ {
VECTOR_INIT(PlaybackDevices);
VECTOR_INIT(CaptureDevices);
*FuncList = WinMMFuncs; *FuncList = WinMMFuncs;
return ALC_TRUE; return ALC_TRUE;
} }
void alcWinMMDeinit() void alcWinMMDeinit()
{ {
ALuint i; al_string *iter, *end;
for(i = 0;i < NumPlaybackDevices;i++) iter = VECTOR_ITER_BEGIN(PlaybackDevices);
free(PlaybackDeviceList[i]); end = VECTOR_ITER_END(PlaybackDevices);
free(PlaybackDeviceList); for(;iter != end;iter++)
PlaybackDeviceList = NULL; AL_STRING_DEINIT(*iter);
VECTOR_DEINIT(PlaybackDevices);
NumPlaybackDevices = 0; iter = VECTOR_ITER_BEGIN(CaptureDevices);
end = VECTOR_ITER_END(CaptureDevices);
for(;iter != end;iter++)
for(i = 0;i < NumCaptureDevices;i++) AL_STRING_DEINIT(*iter);
free(CaptureDeviceList[i]); VECTOR_DEINIT(CaptureDevices);
free(CaptureDeviceList);
CaptureDeviceList = NULL;
NumCaptureDevices = 0;
} }
void alcWinMMProbe(enum DevProbe type) void alcWinMMProbe(enum DevProbe type)
{ {
ALuint i; const al_string *iter, *end;
switch(type) switch(type)
{ {
case ALL_DEVICE_PROBE: case ALL_DEVICE_PROBE:
ProbePlaybackDevices(); ProbePlaybackDevices();
for(i = 0;i < NumPlaybackDevices;i++) iter = VECTOR_ITER_BEGIN(PlaybackDevices);
end = VECTOR_ITER_END(PlaybackDevices);
for(;iter != end;iter++)
{ {
if(PlaybackDeviceList[i]) if(!al_string_empty(*iter))
AppendAllDevicesList(PlaybackDeviceList[i]); AppendAllDevicesList(al_string_get_cstr(*iter));
} }
break; break;
case CAPTURE_DEVICE_PROBE: case CAPTURE_DEVICE_PROBE:
ProbeCaptureDevices(); ProbeCaptureDevices();
for(i = 0;i < NumCaptureDevices;i++) iter = VECTOR_ITER_BEGIN(CaptureDevices);
end = VECTOR_ITER_END(CaptureDevices);
for(;iter != end;iter++)
{ {
if(CaptureDeviceList[i]) if(!al_string_empty(*iter))
AppendCaptureDeviceList(CaptureDeviceList[i]); AppendCaptureDeviceList(al_string_get_cstr(*iter));
} }
break; break;
} }