Skip to content
This repository has been archived by the owner on Feb 15, 2024. It is now read-only.

Commit

Permalink
Initial commit
Browse files Browse the repository at this point in the history
  • Loading branch information
ToadKing committed Aug 2, 2020
0 parents commit d28d70d
Show file tree
Hide file tree
Showing 14 changed files with 1,457 additions and 0 deletions.
144 changes: 144 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,144 @@
## Ignore Visual Studio temporary files, build results, and
## files generated by popular Visual Studio add-ons.
##
## Get latest from https://github.com/github/gitignore/blob/master/VisualStudio.gitignore

# User-specific files
*.rsuser
*.suo
*.user
*.userosscache
*.sln.docstates

# User-specific files (MonoDevelop/Xamarin Studio)
*.userprefs

# Mono auto generated files
mono_crash.*

# Build results
[Dd]ebug/
[Dd]ebugPublic/
[Rr]elease/
[Rr]eleases/
x64/
x86/
[Ww][Ii][Nn]32/
[Aa][Rr][Mm]/
[Aa][Rr][Mm]64/
bld/
[Bb]in/
[Oo]bj/
[Ll]og/
[Ll]ogs/

# Visual Studio 2015/2017 cache/options directory
.vs/
# Uncomment if you have tasks that create the project's static files in wwwroot
#wwwroot/

# Visual Studio 2017 auto generated files
Generated\ Files/

# MSTest test Results
[Tt]est[Rr]esult*/
[Bb]uild[Ll]og.*

# NUnit
*.VisualState.xml
TestResult.xml
nunit-*.xml

# Build Results of an ATL Project
[Dd]ebugPS/
[Rr]eleasePS/
dlldata.c

# Benchmark Results
BenchmarkDotNet.Artifacts/

# .NET Core
project.lock.json
project.fragment.lock.json
artifacts/

# ASP.NET Scaffolding
ScaffoldingReadMe.txt

# StyleCop
StyleCopReport.xml

# Files built by Visual Studio
*_i.c
*_p.c
*_h.h
*.ilk
*.meta
*.obj
*.iobj
*.pch
*.pdb
*.ipdb
*.pgc
*.pgd
*.rsp
*.sbr
*.tlb
*.tli
*.tlh
*.tmp
*.tmp_proj
*_wpftmp.csproj
*.log
*.vspscc
*.vssscc
.builds
*.pidb
*.svclog
*.scc

# Chutzpah Test files
_Chutzpah*

# Visual C++ cache files
ipch/
*.aps
*.ncb
*.opendb
*.opensdf
*.sdf
*.cachefile
*.VC.db
*.VC.VC.opendb

# Visual Studio profiler
*.psess
*.vsp
*.vspx
*.sap

# Visual Studio Trace Files
*.e2e

# TFS 2012 Local Workspace
$tf/

# Guidance Automation Toolkit
*.gpState

# ReSharper is a .NET coding add-in
_ReSharper*/
*.[Rr]e[Ss]harper
*.DotSettings.user

# TeamCity is a build add-in
_TeamCity*

# DotCover is a Code Coverage Tool
*.dotCover

# AxoCover is a Code Coverage Tool
.axoCover/*
!.axoCover/settings.json

# Coverlet is a free, cross platform Code Coverage Tool
11 changes: 11 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
# mono-to-stereo

Takes a mono input and renders it as if it was an interleaved stereo input. Works on MS2109 capture
devices where the audio input is a 96khz mono stream but in actuality is a 48khz stereo stream with
the left and right channels swapped. In order to support this device better, swapping the left and
right channels is done by default.

Original code based off of [Matthew van Eerde's loopback-capture](https://github.com/mvaneerde/blog/tree/master/loopback-capture)
project.

Run `mono-to-stereo.exe -?` for usage instructions.
28 changes: 28 additions & 0 deletions loopback-capture.sln
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 16
VisualStudioVersion = 16.0.30309.148
MinimumVisualStudioVersion = 10.0.40219.1
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "mono-to-stereo", "mono-to-stereo\mono-to-stereo.vcxproj", "{4463F7EB-16DC-4C5E-A9CB-9B4E5A18E2E9}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Win32 = Debug|Win32
Debug|x64 = Debug|x64
Release|Win32 = Release|Win32
Release|x64 = Release|x64
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{4463F7EB-16DC-4C5E-A9CB-9B4E5A18E2E9}.Debug|Win32.ActiveCfg = Debug|Win32
{4463F7EB-16DC-4C5E-A9CB-9B4E5A18E2E9}.Debug|Win32.Build.0 = Debug|Win32
{4463F7EB-16DC-4C5E-A9CB-9B4E5A18E2E9}.Debug|x64.ActiveCfg = Debug|x64
{4463F7EB-16DC-4C5E-A9CB-9B4E5A18E2E9}.Debug|x64.Build.0 = Debug|x64
{4463F7EB-16DC-4C5E-A9CB-9B4E5A18E2E9}.Release|Win32.ActiveCfg = Release|Win32
{4463F7EB-16DC-4C5E-A9CB-9B4E5A18E2E9}.Release|Win32.Build.0 = Release|Win32
{4463F7EB-16DC-4C5E-A9CB-9B4E5A18E2E9}.Release|x64.ActiveCfg = Release|x64
{4463F7EB-16DC-4C5E-A9CB-9B4E5A18E2E9}.Release|x64.Build.0 = Release|x64
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
EndGlobal
121 changes: 121 additions & 0 deletions mono-to-stereo/cleanup.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,121 @@
// cleanup.h

class AudioClientStopOnExit {
public:
AudioClientStopOnExit(IAudioClient *p) : m_p(p) {}
~AudioClientStopOnExit() {
HRESULT hr = m_p->Stop();
if (FAILED(hr)) {
ERR(L"IAudioClient::Stop failed: hr = 0x%08x", hr);
}
}

private:
IAudioClient *m_p;
};

class AvRevertMmThreadCharacteristicsOnExit {
public:
AvRevertMmThreadCharacteristicsOnExit(HANDLE hTask) : m_hTask(hTask) {}
~AvRevertMmThreadCharacteristicsOnExit() {
if (!AvRevertMmThreadCharacteristics(m_hTask)) {
ERR(L"AvRevertMmThreadCharacteristics failed: last error is %d", GetLastError());
}
}
private:
HANDLE m_hTask;
};

class CancelWaitableTimerOnExit {
public:
CancelWaitableTimerOnExit(HANDLE h) : m_h(h) {}
~CancelWaitableTimerOnExit() {
if (!CancelWaitableTimer(m_h)) {
ERR(L"CancelWaitableTimer failed: last error is %d", GetLastError());
}
}
private:
HANDLE m_h;
};

class CloseHandleOnExit {
public:
CloseHandleOnExit(HANDLE h) : m_h(h) {}
~CloseHandleOnExit() {
if (!CloseHandle(m_h)) {
ERR(L"CloseHandle failed: last error is %d", GetLastError());
}
}

private:
HANDLE m_h;
};

class CoTaskMemFreeOnExit {
public:
CoTaskMemFreeOnExit(PVOID p) : m_p(p) {}
~CoTaskMemFreeOnExit() {
CoTaskMemFree(m_p);
}

private:
PVOID m_p;
};

class CoUninitializeOnExit {
public:
~CoUninitializeOnExit() {
CoUninitialize();
}
};

class PropVariantClearOnExit {
public:
PropVariantClearOnExit(PROPVARIANT *p) : m_p(p) {}
~PropVariantClearOnExit() {
HRESULT hr = PropVariantClear(m_p);
if (FAILED(hr)) {
ERR(L"PropVariantClear failed: hr = 0x%08x", hr);
}
}

private:
PROPVARIANT *m_p;
};

class ReleaseOnExit {
public:
ReleaseOnExit(IUnknown *p) : m_p(p) {}
~ReleaseOnExit() {
m_p->Release();
}

private:
IUnknown *m_p;
};

class SetEventOnExit {
public:
SetEventOnExit(HANDLE h) : m_h(h) {}
~SetEventOnExit() {
if (!SetEvent(m_h)) {
ERR(L"SetEvent failed: last error is %d", GetLastError());
}
}
private:
HANDLE m_h;
};

class WaitForSingleObjectOnExit {
public:
WaitForSingleObjectOnExit(HANDLE h) : m_h(h) {}
~WaitForSingleObjectOnExit() {
DWORD dwWaitResult = WaitForSingleObject(m_h, INFINITE);
if (WAIT_OBJECT_0 != dwWaitResult) {
ERR(L"WaitForSingleObject returned unexpected result 0x%08x, last error is %d", dwWaitResult, GetLastError());
}
}

private:
HANDLE m_h;
};
14 changes: 14 additions & 0 deletions mono-to-stereo/common.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
// common.h

#include <stdio.h>
#include <windows.h>
#include <mmsystem.h>
#include <mmdeviceapi.h>
#include <audioclient.h>
#include <avrt.h>
#include <functiondiscoverykeys_devpkey.h>

#include "log.h"
#include "cleanup.h"
#include "prefs.h"
#include "mono-to-stereo.h"
4 changes: 4 additions & 0 deletions mono-to-stereo/guid.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
// guid.cpp

#include <initguid.h>
#include "common.h"
4 changes: 4 additions & 0 deletions mono-to-stereo/log.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
// log.h

#define LOG(format, ...) wprintf(format L"\n", __VA_ARGS__)
#define ERR(format, ...) LOG(L"Error: " format, __VA_ARGS__)
Loading

0 comments on commit d28d70d

Please sign in to comment.