Skip to content

Commit

Permalink
Merge pull request #1 from LAGonauta/volume-meter-and-map-channels
Browse files Browse the repository at this point in the history
Lots of desirable changes
  • Loading branch information
LAGonauta authored Aug 10, 2019
2 parents a376fd3 + 0c929e7 commit 79bc819
Show file tree
Hide file tree
Showing 11 changed files with 824 additions and 204 deletions.
9 changes: 3 additions & 6 deletions ASIORecAndPlay.sln
Original file line number Diff line number Diff line change
Expand Up @@ -8,21 +8,18 @@ EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Debug|x64 = Debug|x64
Release|Any CPU = Release|Any CPU
Release|x64 = Release|x64
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{496F0D9F-591C-4213-B0CC-9489714E2DEB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{496F0D9F-591C-4213-B0CC-9489714E2DEB}.Debug|Any CPU.Build.0 = Debug|Any CPU
{496F0D9F-591C-4213-B0CC-9489714E2DEB}.Debug|x64.ActiveCfg = Debug|x64
{496F0D9F-591C-4213-B0CC-9489714E2DEB}.Debug|x64.Build.0 = Debug|x64
{496F0D9F-591C-4213-B0CC-9489714E2DEB}.Release|Any CPU.ActiveCfg = Release|Any CPU
{496F0D9F-591C-4213-B0CC-9489714E2DEB}.Release|Any CPU.Build.0 = Release|Any CPU
{496F0D9F-591C-4213-B0CC-9489714E2DEB}.Release|x64.ActiveCfg = Release|x64
{496F0D9F-591C-4213-B0CC-9489714E2DEB}.Release|x64.Build.0 = Release|x64
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {24AA2A5E-78C6-4817-8A99-1017A740BE1C}
EndGlobalSection
EndGlobal
30 changes: 26 additions & 4 deletions ASIORecAndPlay/ASIORecAndPlay.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,9 @@
<DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<Prefer32Bit>false</Prefer32Bit>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
<LangVersion>default</LangVersion>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<PlatformTarget>AnyCPU</PlatformTarget>
Expand All @@ -33,6 +36,9 @@
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<Prefer32Bit>false</Prefer32Bit>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
<LangVersion>default</LangVersion>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x64'">
<DebugSymbols>true</DebugSymbols>
Expand All @@ -43,6 +49,8 @@
<ErrorReport>prompt</ErrorReport>
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
<Prefer32Bit>true</Prefer32Bit>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
<LangVersion>default</LangVersion>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x64'">
<OutputPath>bin\x64\Release\</OutputPath>
Expand All @@ -53,14 +61,16 @@
<ErrorReport>prompt</ErrorReport>
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
<Prefer32Bit>true</Prefer32Bit>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
<LangVersion>default</LangVersion>
</PropertyGroup>
<PropertyGroup>
<ApplicationIcon>Graphicloads-Colorful-Long-Shadow-Sound.ico</ApplicationIcon>
</PropertyGroup>
<PropertyGroup>
<StartupObject />
</PropertyGroup>
<ItemGroup>
<Reference Include="NAudio, Version=1.8.4.0, Culture=neutral, processorArchitecture=MSIL">
<HintPath>..\packages\NAudio.1.8.4\lib\net35\NAudio.dll</HintPath>
</Reference>
<Reference Include="System" />
<Reference Include="System.Data" />
<Reference Include="System.Drawing" />
Expand All @@ -80,6 +90,9 @@
<Generator>MSBuild:Compile</Generator>
<SubType>Designer</SubType>
</ApplicationDefinition>
<Compile Include="ChannelMapping.cs" />
<Compile Include="VolumeMeterChannels.cs" />
<Compile Include="Wasapi.cs" />
<Page Include="MainWindow.xaml">
<Generator>MSBuild:Compile</Generator>
<SubType>Designer</SubType>
Expand All @@ -88,6 +101,8 @@
<DependentUpon>App.xaml</DependentUpon>
<SubType>Code</SubType>
</Compile>
<Compile Include="Asio.cs" />
<Compile Include="RecAndPlay.cs" />
<Compile Include="MainWindow.xaml.cs">
<DependentUpon>MainWindow.xaml</DependentUpon>
<SubType>Code</SubType>
Expand All @@ -111,7 +126,6 @@
<Generator>ResXFileCodeGenerator</Generator>
<LastGenOutput>Resources.Designer.cs</LastGenOutput>
</EmbeddedResource>
<None Include="packages.config" />
<None Include="Properties\Settings.settings">
<Generator>SettingsSingleFileGenerator</Generator>
<LastGenOutput>Settings.Designer.cs</LastGenOutput>
Expand All @@ -123,5 +137,13 @@
<ItemGroup>
<Resource Include="Graphicloads-Colorful-Long-Shadow-Sound.ico" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="audio-vu-meter">
<Version>1.0.1</Version>
</PackageReference>
<PackageReference Include="NAudio">
<Version>1.9.0</Version>
</PackageReference>
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
</Project>
49 changes: 49 additions & 0 deletions ASIORecAndPlay/Asio.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
using NAudio.Wave;
using System;
using System.Collections.Generic;

namespace ASIORecAndPlay
{
internal enum ChannelType
{
Input,
Output
}

internal static class Asio
{
public static string[] GetDevices()
{
return AsioOut.GetDriverNames();
}

public static void ShowControlPanel(string device)
{
using (var asio = new AsioOut(device))
{
asio.ShowControlPanel();
}
}

public static string[] GetChannelNames(string device, ChannelType channelType)
{
using (var asio = new AsioOut(device))
{
int count = asio.DriverOutputChannelCount;
Func<int, string> getName = (i) => asio.AsioOutputChannelName(i);
if (channelType == ChannelType.Input)
{
count = asio.DriverInputChannelCount;
getName = (i) => asio.AsioInputChannelName(i);
}

var nameList = new List<string>();
for (int i = 0; i < count; ++i)
{
nameList.Add(getName(i));
}
return nameList.ToArray();
}
}
}
}
94 changes: 94 additions & 0 deletions ASIORecAndPlay/ChannelMapping.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
using System.Collections.Generic;
using System.Linq;

namespace ASIORecAndPlay
{
internal struct Mapping
{
public int inputChannel;
public int outputChannel;
}

internal class ChannelMapping
{
private IDictionary<int, int> channelMapping;
private object _lock = new object();

public IEnumerable<int> InputChannels => channelMapping.Values;

public IEnumerable<int> OutputChannels => channelMapping.Keys;

public ChannelMapping()
{
channelMapping = new Dictionary<int, int>();
}

public ChannelMapping(IDictionary<int, int> outputInputPairs)
{
channelMapping = outputInputPairs;
}

/// <summary>
/// While one input can send to various outputs, one output can receive only from one input.
/// Thus, the output must be unique.
/// </summary>
/// <param name="inputChannel">Input channel number</param>
/// <param name="outputChannel">Output channel number</param>
/// <returns></returns>
public bool Add(int inputChannel, int outputChannel)
{
try
{
lock (_lock)
{
channelMapping.Add(outputChannel, inputChannel);
}

return true;
}
catch
{
return false;
}
}

/// <summary>
/// Remove the mapping to the set output channel.
/// </summary>
/// <param name="outputChannel"></param>
/// <returns></returns>
public bool Remove(int outputChannel)
{
lock (_lock)
{
return channelMapping.Remove(outputChannel);
}
}

/// <summary>
/// Gets an ordered enumerable of a copy the mapping, ordered by input channel.
/// </summary>
/// <returns></returns>
public IEnumerable<Mapping> GetMappingList()
{
lock (_lock)
{
return channelMapping
.Select(e => new Mapping { inputChannel = e.Value, outputChannel = e.Key })
.OrderBy(e => e.inputChannel).ToList();
}
}

/// <summary>
/// Gets a copy of the internal dictionary.
/// </summary>
/// <returns></returns>
public IDictionary<int, int> GetMappingDictionary()
{
lock (_lock)
{
return channelMapping.ToDictionary(e => e.Key, e => e.Value);
}
}
}
}
Loading

0 comments on commit 79bc819

Please sign in to comment.