Add WASAPI audio capture

- Add WASAPI audio capture for windows, input and output

 - Check for null pointer in os_dlopen

 - Add exception-safe 'WinHandle' and 'CoTaskMemPtr' helper classes that
   will automatically call CloseHandle on handles and call CoTaskMemFree
   on certain types of memory returned from windows functions

 - Changed the wide <-> MBS/UTF8 conversion functions so that you use
   buffers (like these functions are *supposed* to behave), and changed
   the ones that allocate to a different naming scheme to be safe
This commit is contained in:
jp9000
2014-03-04 07:07:13 -07:00
parent 2fd57ed7f5
commit 348588254c
21 changed files with 1039 additions and 50 deletions

View File

@@ -585,13 +585,13 @@ void dstr_right(struct dstr *dst, const struct dstr *str, const size_t pos)
void dstr_from_mbs(struct dstr *dst, const char *mbstr)
{
dstr_free(dst);
dst->len = os_mbs_to_utf8(mbstr, 0, &dst->array);
dst->len = os_mbs_to_utf8_ptr(mbstr, 0, &dst->array);
}
char *dstr_to_mbs(const struct dstr *str)
{
char *dst;
os_mbs_to_utf8(str->array, str->len, &dst);
os_mbs_to_utf8_ptr(str->array, str->len, &dst);
return dst;
}

View File

@@ -33,6 +33,10 @@
void *os_dlopen(const char *path)
{
struct dstr dylib_name;
if (!path)
return NULL;
dstr_init_copy(&dylib_name, path);
if (!dstr_find(&dylib_name, ".so"))
dstr_cat(&dylib_name, ".so");

View File

@@ -28,6 +28,10 @@
void *os_dlopen(const char *path)
{
struct dstr dylib_name;
if (!path)
return NULL;
dstr_init_copy(&dylib_name, path);
if (!dstr_find(&dylib_name, ".so"))
dstr_cat(&dylib_name, ".so");

View File

@@ -52,11 +52,14 @@ void *os_dlopen(const char *path)
wchar_t *wpath;
HMODULE h_library = NULL;
if (!path)
return NULL;
dstr_init_copy(&dll_name, path);
if (!dstr_find(&dll_name, ".dll"))
dstr_cat(&dll_name, ".dll");
os_utf8_to_wcs(dll_name.array, 0, &wpath);
os_utf8_to_wcs_ptr(dll_name.array, 0, &wpath);
h_library = LoadLibraryW(wpath);
bfree(wpath);
dstr_free(&dll_name);
@@ -139,7 +142,7 @@ char *os_get_config_path(const char *name)
SHGetFolderPathW(NULL, CSIDL_APPDATA, NULL, SHGFP_TYPE_CURRENT,
path_utf16);
os_wcs_to_utf8(path_utf16, 0, &ptr);
os_wcs_to_utf8_ptr(path_utf16, 0, &ptr);
dstr_init_move_array(&path, ptr);
dstr_cat(&path, "\\");
dstr_cat(&path, name);
@@ -152,7 +155,7 @@ bool os_file_exists(const char *path)
HANDLE hFind;
wchar_t *path_utf16;
if (!os_utf8_to_wcs(path, 0, &path_utf16))
if (!os_utf8_to_wcs_ptr(path, 0, &path_utf16))
return false;
hFind = FindFirstFileW(path_utf16, &wfd);
@@ -168,7 +171,7 @@ int os_mkdir(const char *path)
wchar_t *path_utf16;
BOOL success;
if (!os_utf8_to_wcs(path, 0, &path_utf16))
if (!os_utf8_to_wcs_ptr(path, 0, &path_utf16))
return MKDIR_ERROR;
success = CreateDirectory(path_utf16, NULL);

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2013 Hugh Bailey <obs.jim@gmail.com>
* Copyright (c) 2013-2014 Hugh Bailey <obs.jim@gmail.com>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
@@ -28,13 +28,13 @@ FILE *os_wfopen(const wchar_t *path, const char *mode)
#ifdef _MSC_VER
wchar_t *wcs_mode;
os_utf8_to_wcs(mode, 0, &wcs_mode);
os_utf8_to_wcs_ptr(mode, 0, &wcs_mode);
file = _wfopen(path, wcs_mode);
bfree(wcs_mode);
#else
char *mbs_path;
os_wcs_to_utf8(path, 0, &mbs_path);
os_wcs_to_utf8_ptr(path, 0, &mbs_path);
file = fopen(mbs_path, mode);
bfree(mbs_path);
#endif
@@ -46,7 +46,7 @@ FILE *os_fopen(const char *path, const char *mode)
#ifdef _WIN32
wchar_t *wpath = NULL;
FILE *file = NULL;
os_utf8_to_wcs(path, 0, &wpath);
os_utf8_to_wcs_ptr(path, 0, &wpath);
file = os_wfopen(wpath, mode);
bfree(wpath);
@@ -95,7 +95,7 @@ size_t os_fread_mbs(FILE *file, char **pstr)
}
mbstr[size] = 0;
len = os_mbs_to_utf8(mbstr, size, pstr);
len = os_mbs_to_utf8_ptr(mbstr, size, pstr);
bfree(mbstr);
}
@@ -180,7 +180,7 @@ bool os_quick_write_mbs_file(const char *path, const char *str, size_t len)
if (!f)
return false;
mbs_len = os_utf8_to_mbs(str, len, &mbs);
mbs_len = os_utf8_to_mbs_ptr(str, len, &mbs);
if (mbs_len)
fwrite(mbs, 1, mbs_len, f);
bfree(mbs);
@@ -205,74 +205,93 @@ bool os_quick_write_utf8_file(const char *path, const char *str, size_t len,
return true;
}
size_t os_mbs_to_wcs(const char *str, size_t len, wchar_t **pstr)
size_t os_mbs_to_wcs(const char *str, size_t len, wchar_t *dst)
{
size_t out_len = mbstowcs(NULL, str, len);
wchar_t *dst = NULL;
size_t out_len = dst ? len : mbstowcs(NULL, str, len);
if (len) {
dst = bmalloc((out_len+1) * sizeof(wchar_t));
if (len && dst) {
mbstowcs(dst, str, out_len+1);
dst[out_len] = 0;
}
*pstr = dst;
return out_len;
}
size_t os_utf8_to_wcs(const char *str, size_t len, wchar_t **pstr)
size_t os_utf8_to_wcs(const char *str, size_t len, wchar_t *dst)
{
size_t in_len = len ? len : strlen(str);
size_t out_len = utf8_to_wchar(str, in_len, NULL, 0, 0);
wchar_t *dst = NULL;
size_t out_len = dst ? len : utf8_to_wchar(str, in_len, NULL, 0, 0);
if (out_len) {
dst = bmalloc((out_len+1) * sizeof(wchar_t));
if (out_len && dst) {
utf8_to_wchar(str, in_len, dst, out_len+1, 0);
dst[out_len] = 0;
}
*pstr = dst;
return out_len;
}
size_t os_wcs_to_mbs(const wchar_t *str, size_t len, char **pstr)
size_t os_wcs_to_mbs(const wchar_t *str, size_t len, char *dst)
{
size_t out_len = wcstombs(NULL, str, len);
char *dst = NULL;
size_t out_len = dst ? len : wcstombs(NULL, str, len);
if (len) {
dst = bmalloc(out_len+1);
if (len && dst) {
wcstombs(dst, str, out_len+1);
dst[out_len] = 0;
}
*pstr = dst;
return out_len;
}
size_t os_wcs_to_utf8(const wchar_t *str, size_t len, char **pstr)
size_t os_wcs_to_utf8(const wchar_t *str, size_t len, char *dst)
{
size_t in_len = (len != 0) ? len : wcslen(str);
size_t out_len = wchar_to_utf8(str, in_len, NULL, 0, 0);
char *dst = NULL;
size_t out_len = dst ? len : wchar_to_utf8(str, in_len, NULL, 0, 0);
if (out_len) {
dst = bmalloc(out_len+1);
if (out_len && dst) {
wchar_to_utf8(str, in_len, dst, out_len+1, 0);
dst[out_len] = 0;
}
*pstr = dst;
return out_len;
}
size_t os_utf8_to_mbs(const char *str, size_t len, char **pstr)
size_t os_mbs_to_wcs_ptr(const char *str, size_t len, wchar_t **pstr)
{
size_t out_len = os_mbs_to_wcs(str, len, NULL);
*pstr = bmalloc((out_len+1) * sizeof(wchar_t));
return os_mbs_to_wcs(str, out_len, *pstr);
}
size_t os_utf8_to_wcs_ptr(const char *str, size_t len, wchar_t **pstr)
{
size_t out_len = os_utf8_to_wcs(str, len, NULL);
*pstr = bmalloc((out_len+1) * sizeof(wchar_t));
return os_utf8_to_wcs(str, out_len, *pstr);
}
size_t os_wcs_to_mbs_ptr(const wchar_t *str, size_t len, char **pstr)
{
size_t out_len = os_wcs_to_mbs(str, len, NULL);
*pstr = bmalloc((out_len+1) * sizeof(char));
return os_wcs_to_mbs(str, out_len, *pstr);
}
size_t os_wcs_to_utf8_ptr(const wchar_t *str, size_t len, char **pstr)
{
size_t out_len = os_wcs_to_utf8(str, len, NULL);
*pstr = bmalloc((out_len+1) * sizeof(char));
return os_wcs_to_utf8(str, out_len, *pstr);
}
size_t os_utf8_to_mbs_ptr(const char *str, size_t len, char **pstr)
{
wchar_t *wstr = NULL;
char *dst = NULL;
size_t wlen = os_utf8_to_wcs(str, len, &wstr);
size_t out_len = os_wcs_to_mbs(wstr, wlen, &dst);
size_t wlen = os_utf8_to_wcs_ptr(str, len, &wstr);
size_t out_len = os_wcs_to_mbs_ptr(wstr, wlen, &dst);
bfree(wstr);
*pstr = dst;
@@ -280,12 +299,12 @@ size_t os_utf8_to_mbs(const char *str, size_t len, char **pstr)
return out_len;
}
size_t os_mbs_to_utf8(const char *str, size_t len, char **pstr)
size_t os_mbs_to_utf8_ptr(const char *str, size_t len, char **pstr)
{
wchar_t *wstr = NULL;
char *dst = NULL;
size_t wlen = os_mbs_to_wcs(str, len, &wstr);
size_t out_len = os_wcs_to_utf8(wstr, wlen, &dst);
size_t wlen = os_mbs_to_wcs_ptr(str, len, &wstr);
size_t out_len = os_wcs_to_utf8_ptr(wstr, wlen, &dst);
bfree(wstr);
*pstr = dst;

View File

@@ -45,13 +45,18 @@ EXPORT char *os_quick_read_mbs_file(const char *path);
EXPORT bool os_quick_write_mbs_file(const char *path, const char *str,
size_t len);
EXPORT size_t os_mbs_to_wcs(const char *str, size_t len, wchar_t **pstr);
EXPORT size_t os_utf8_to_wcs(const char *str, size_t len, wchar_t **pstr);
EXPORT size_t os_wcs_to_mbs(const wchar_t *str, size_t len, char **pstr);
EXPORT size_t os_wcs_to_utf8(const wchar_t *str, size_t len, char **pstr);
EXPORT size_t os_mbs_to_wcs(const char *str, size_t len, wchar_t *dst);
EXPORT size_t os_utf8_to_wcs(const char *str, size_t len, wchar_t *dst);
EXPORT size_t os_wcs_to_mbs(const wchar_t *str, size_t len, char *dst);
EXPORT size_t os_wcs_to_utf8(const wchar_t *str, size_t len, char *dst);
EXPORT size_t os_utf8_to_mbs(const char *str, size_t len, char **pstr);
EXPORT size_t os_mbs_to_utf8(const char *str, size_t len, char **pstr);
EXPORT size_t os_mbs_to_wcs_ptr(const char *str, size_t len, wchar_t **pstr);
EXPORT size_t os_utf8_to_wcs_ptr(const char *str, size_t len, wchar_t **pstr);
EXPORT size_t os_wcs_to_mbs_ptr(const wchar_t *str, size_t len, char **pstr);
EXPORT size_t os_wcs_to_utf8_ptr(const wchar_t *str, size_t len, char **pstr);
EXPORT size_t os_utf8_to_mbs_ptr(const char *str, size_t len, char **pstr);
EXPORT size_t os_mbs_to_utf8_ptr(const char *str, size_t len, char **pstr);
EXPORT void *os_dlopen(const char *path);
EXPORT void *os_dlsym(void *module, const char *func);

View File

@@ -0,0 +1,43 @@
/*
* Copyright (c) 2014 Hugh Bailey <obs.jim@gmail.com>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#pragma once
template<typename T> class CoTaskMemPtr {
T *ptr;
inline void Clear() {if (ptr) CoTaskMemFree(ptr);}
public:
inline CoTaskMemPtr() : ptr(NULL) {}
inline CoTaskMemPtr(T *ptr_) : ptr(ptr_) {}
inline ~CoTaskMemPtr() {Clear();}
inline operator T*() const {return ptr;}
inline CoTaskMemPtr& operator=(T* val)
{
Clear();
ptr = val;
}
inline T** operator&()
{
Clear();
ptr = NULL;
return &ptr;
}
};

View File

@@ -0,0 +1,56 @@
/*
* Copyright (c) 2014 Hugh Bailey <obs.jim@gmail.com>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#pragma once
class WinHandle {
HANDLE handle;
inline void Clear()
{
if (handle && handle != INVALID_HANDLE_VALUE)
CloseHandle(handle);
}
public:
inline WinHandle() : handle(NULL) {}
inline WinHandle(HANDLE handle_) : handle(handle_) {}
inline ~WinHandle() {Clear();}
inline operator HANDLE() const {return handle;}
inline WinHandle& operator=(HANDLE handle_)
{
if (handle_ != handle) {
Clear();
handle = handle_;
}
return *this;
}
inline HANDLE* operator&()
{
Clear();
handle = NULL;
return &handle;
}
inline bool Valid() const
{
return handle && handle != INVALID_HANDLE_VALUE;
}
};