Skip to content

Commit

Permalink
Removed dependency to MediaInfo.Wrapper
Browse files Browse the repository at this point in the history
  • Loading branch information
potchy committed May 24, 2020
1 parent 2574254 commit 2757214
Show file tree
Hide file tree
Showing 18 changed files with 335 additions and 21 deletions.
6 changes: 6 additions & 0 deletions wavtogg.Analyzer/App.config
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.6.1" />
</startup>
</configuration>
78 changes: 78 additions & 0 deletions wavtogg.Analyzer/Program.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
using CsvHelper;
using MediaInfo;
using System;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Text;

namespace wavtogg.Analyzer
{
// this is just a throwaway program I used to collect the sample data.
// I figure it might come in handy again someday.

class Program
{
static readonly byte[] fmt = { 0x66, 0x6d, 0x74 };

static void Main(string[] args)
{
string folder = args[0];

using (var fileStream = File.Create(@"csv.csv"))
using (var streamWriter = new StreamWriter(fileStream, Encoding.Unicode))
using (var csvWriter = new CsvWriter(streamWriter, CultureInfo.InvariantCulture))
{
csvWriter.WriteField("Path");
csvWriter.WriteField("Format");
csvWriter.WriteField("BytesAt0xc");
csvWriter.WriteField("BytesAt0xcSequenceEqual0x66-0x6d-0x74");
csvWriter.WriteField("ByteAt0x14");
csvWriter.WriteField("ByteAt0x14EqualsTo2or17");
csvWriter.WriteField("Match");
csvWriter.NextRecord();

foreach (string wavPath in Directory.EnumerateFiles(folder, "*.wav", SearchOption.AllDirectories))
{
// Path
csvWriter.WriteField(wavPath);

// Format
string format = new MediaInfoWrapper(wavPath).AudioCodec;
csvWriter.WriteField(format);

using (FileStream fs = File.OpenRead(wavPath))
{
// BytesAt0xc
fs.Seek(0xc, SeekOrigin.Begin);
var bytesAt0x0c = new byte[3];
fs.Read(bytesAt0x0c, 0, bytesAt0x0c.Length);

csvWriter.WriteField(BitConverter.ToString(bytesAt0x0c));

// BytesAt0x0SequenceEqual0x66-0x6d-0x74
bool bytesAt0xcSequenceEqual0x66_0x6d_0x74 = bytesAt0x0c.SequenceEqual(fmt);
csvWriter.WriteField(bytesAt0xcSequenceEqual0x66_0x6d_0x74 ? "YES" : "NO");

// ByteAt0x14
fs.Seek(0x14, SeekOrigin.Begin);
int byteAt0x14 = fs.ReadByte();

csvWriter.WriteField(byteAt0x14);

// ByteAt0x14EqualsTo2or17
bool byteAt0x14EqualsTo2or17 = new[] { 2, 17 }.Contains(byteAt0x14);
csvWriter.WriteField(byteAt0x14EqualsTo2or17 ? "YES" : "NO");

// Match
bool match = "ADPCM".Equals(format, StringComparison.OrdinalIgnoreCase) == (bytesAt0xcSequenceEqual0x66_0x6d_0x74 && byteAt0x14EqualsTo2or17);
csvWriter.WriteField(match ? "SUCCESS" : "FAIL");
}

csvWriter.NextRecord();
streamWriter.Flush();
}
}
}
}
}
36 changes: 36 additions & 0 deletions wavtogg.Analyzer/Properties/AssemblyInfo.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;

// General Information about an assembly is controlled through the following
// set of attributes. Change these attribute values to modify the information
// associated with an assembly.
[assembly: AssemblyTitle("wavtogg.Analyzer")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("wavtogg.Analyzer")]
[assembly: AssemblyCopyright("Copyright © 2020")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]

// Setting ComVisible to false makes the types in this assembly not visible
// to COM components. If you need to access a type in this assembly from
// COM, set the ComVisible attribute to true on that type.
[assembly: ComVisible(false)]

// The following GUID is for the ID of the typelib if this project is exposed to COM
[assembly: Guid("407fb3ef-a157-44c0-874b-cc70d203a170")]

// Version information for an assembly consists of the following four values:
//
// Major Version
// Minor Version
// Build Number
// Revision
//
// You can specify all the values or you can default the Build and Revision Numbers
// by using the '*' as shown below:
// [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("1.0.0.0")]
[assembly: AssemblyFileVersion("1.0.0.0")]
10 changes: 10 additions & 0 deletions wavtogg.Analyzer/packages.config
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="CsvHelper" version="15.0.5" targetFramework="net461" />
<package id="MediaInfo.Native" version="19.9.0" targetFramework="net461" />
<package id="MediaInfo.Wrapper" version="19.9.2" targetFramework="net461" />
<package id="Microsoft.CSharp" version="4.5.0" targetFramework="net461" />
<package id="System.Runtime.CompilerServices.Unsafe" version="4.5.2" targetFramework="net461" />
<package id="System.Threading.Tasks.Extensions" version="4.5.2" targetFramework="net461" />
<package id="System.ValueTuple" version="4.4.0" targetFramework="net461" />
</packages>
80 changes: 80 additions & 0 deletions wavtogg.Analyzer/wavtogg.Analyzer.csproj
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProjectGuid>{407FB3EF-A157-44C0-874B-CC70D203A170}</ProjectGuid>
<OutputType>Exe</OutputType>
<RootNamespace>wavtogg.Analyzer</RootNamespace>
<AssemblyName>wavtogg.Analyzer</AssemblyName>
<TargetFrameworkVersion>v4.6.1</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
<AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects>
<Deterministic>true</Deterministic>
<NuGetPackageImportStamp>
</NuGetPackageImportStamp>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<PlatformTarget>AnyCPU</PlatformTarget>
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\Debug\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<PlatformTarget>AnyCPU</PlatformTarget>
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\Release\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<ItemGroup>
<Reference Include="CsvHelper, Version=15.0.0.0, Culture=neutral, PublicKeyToken=8c4959082be5c823, processorArchitecture=MSIL">
<HintPath>..\packages\CsvHelper.15.0.5\lib\net45\CsvHelper.dll</HintPath>
</Reference>
<Reference Include="MediaInfo.Wrapper, Version=19.9.2.0, Culture=neutral, processorArchitecture=MSIL">
<HintPath>..\packages\MediaInfo.Wrapper.19.9.2\lib\net45\MediaInfo.Wrapper.dll</HintPath>
</Reference>
<Reference Include="System" />
<Reference Include="System.Core" />
<Reference Include="System.Runtime.CompilerServices.Unsafe, Version=4.0.4.1, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
<HintPath>..\packages\System.Runtime.CompilerServices.Unsafe.4.5.2\lib\netstandard2.0\System.Runtime.CompilerServices.Unsafe.dll</HintPath>
</Reference>
<Reference Include="System.Threading.Tasks.Extensions, Version=4.2.0.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51, processorArchitecture=MSIL">
<HintPath>..\packages\System.Threading.Tasks.Extensions.4.5.2\lib\netstandard2.0\System.Threading.Tasks.Extensions.dll</HintPath>
</Reference>
<Reference Include="System.ValueTuple, Version=4.0.2.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51, processorArchitecture=MSIL">
<HintPath>..\packages\System.ValueTuple.4.4.0\lib\net461\System.ValueTuple.dll</HintPath>
<Private>True</Private>
<Private>True</Private>
</Reference>
<Reference Include="System.Xml.Linq" />
<Reference Include="System.Data.DataSetExtensions" />
<Reference Include="Microsoft.CSharp" />
<Reference Include="System.Data" />
<Reference Include="System.Net.Http" />
<Reference Include="System.Xml" />
</ItemGroup>
<ItemGroup>
<Compile Include="Program.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
</ItemGroup>
<ItemGroup>
<None Include="App.config" />
<None Include="packages.config" />
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<Import Project="..\packages\MediaInfo.Native.19.9.0\build\MediaInfo.Native.targets" Condition="Exists('..\packages\MediaInfo.Native.19.9.0\build\MediaInfo.Native.targets')" />
<Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
<PropertyGroup>
<ErrorText>This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.</ErrorText>
</PropertyGroup>
<Error Condition="!Exists('..\packages\MediaInfo.Native.19.9.0\build\MediaInfo.Native.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\MediaInfo.Native.19.9.0\build\MediaInfo.Native.targets'))" />
</Target>
</Project>
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file added wavtogg.Tests/Samples/Data.xlsx
Binary file not shown.
Binary file not shown.
Binary file not shown.
20 changes: 20 additions & 0 deletions wavtogg.Tests/WavUtilsTests.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
using NUnit.Framework;
using wavtogg.Utils;

namespace wavtogg.Tests
{
[TestFixture]
public class WavUtilsTests
{
[TestCase(@"Samples\beatmania IIDX.IIDX19 Lincle.Kagachi.02.wav", true)]
[TestCase(@"Samples\BeMusicSeeker difficulty tables BMS PACK.Ende.SFK.WAV", true)]
[TestCase(@"Samples\BeMusicSeeker difficulty tables BMS PACK.Kern Typhoon.Bass 01.wav", true)]
[TestCase(@"Samples\beatmania IIDX.IIDX23 copula.STARLIGHT DANCEHALL.008V.wav", false)]
[TestCase(@"Samples\BeMusicSeeker difficulty tables BMS PACK.Coexistence.bgm3.wav", false)]
public void IsAdpcm(string path, bool expectedResult)
{
bool actualResult = WavUtils.IsAdpcm(path);
Assert.AreEqual(expectedResult, actualResult);
}
}
}
39 changes: 39 additions & 0 deletions wavtogg.Tests/wavtogg.Tests.csproj
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>netcoreapp3.1</TargetFramework>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.6.1" />
<PackageReference Include="NUnit" Version="3.12.0" />
<PackageReference Include="NUnit3TestAdapter" Version="3.16.1">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
</ItemGroup>

<ItemGroup>
<ProjectReference Include="..\wavtogg\wavtogg.csproj" />
</ItemGroup>

<ItemGroup>
<None Update="Samples\beatmania IIDX.IIDX19 Lincle.Kagachi.02.wav">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Update="Samples\beatmania IIDX.IIDX23 copula.STARLIGHT DANCEHALL.008V.wav">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Update="Samples\BeMusicSeeker difficulty tables BMS PACK.Coexistence.bgm3.wav">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Update="Samples\BeMusicSeeker difficulty tables BMS PACK.Ende.SFK.WAV">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Update="Samples\BeMusicSeeker difficulty tables BMS PACK.Kern Typhoon.Bass 01.wav">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
</ItemGroup>

</Project>
12 changes: 12 additions & 0 deletions wavtogg.sln
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,10 @@ VisualStudioVersion = 16.0.29806.167
MinimumVisualStudioVersion = 10.0.40219.1
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "wavtogg", "wavtogg\wavtogg.csproj", "{5AFFA553-8706-46AA-A168-42425EE28EDF}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "wavtogg.Tests", "wavtogg.Tests\wavtogg.Tests.csproj", "{28541EF7-F5A2-4017-8177-29BC2061CC12}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "wavtogg.Analyzer", "wavtogg.Analyzer\wavtogg.Analyzer.csproj", "{407FB3EF-A157-44C0-874B-CC70D203A170}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Expand All @@ -15,6 +19,14 @@ Global
{5AFFA553-8706-46AA-A168-42425EE28EDF}.Debug|Any CPU.Build.0 = Debug|Any CPU
{5AFFA553-8706-46AA-A168-42425EE28EDF}.Release|Any CPU.ActiveCfg = Release|Any CPU
{5AFFA553-8706-46AA-A168-42425EE28EDF}.Release|Any CPU.Build.0 = Release|Any CPU
{28541EF7-F5A2-4017-8177-29BC2061CC12}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{28541EF7-F5A2-4017-8177-29BC2061CC12}.Debug|Any CPU.Build.0 = Debug|Any CPU
{28541EF7-F5A2-4017-8177-29BC2061CC12}.Release|Any CPU.ActiveCfg = Release|Any CPU
{28541EF7-F5A2-4017-8177-29BC2061CC12}.Release|Any CPU.Build.0 = Release|Any CPU
{407FB3EF-A157-44C0-874B-CC70D203A170}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{407FB3EF-A157-44C0-874B-CC70D203A170}.Debug|Any CPU.Build.0 = Debug|Any CPU
{407FB3EF-A157-44C0-874B-CC70D203A170}.Release|Any CPU.ActiveCfg = Release|Any CPU
{407FB3EF-A157-44C0-874B-CC70D203A170}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
Expand Down
49 changes: 49 additions & 0 deletions wavtogg/Utils/WavUtils.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
using System.IO;
using System.Linq;

namespace wavtogg.Utils
{
public static class WavUtils
{
// reference:
// http://soundfile.sapp.org/doc/WaveFormat/
// https://mh-nexus.de/en/hxd/
private const byte FormatChunkOffset = 0xc;
private static readonly byte[] FormatChunkExpectedContent = { 0x66, 0x6d, 0x74 };

// https://github.com/tpn/winddk-8.1/blob/f6e6e4da7d1894536cf1fa774911df1218ef912e/Include/shared/mmreg.h#L2393
private const int WFormatTagOffset = 0x14;

// https://github.com/tpn/winddk-8.1/blob/f6e6e4da7d1894536cf1fa774911df1218ef912e/Include/shared/mmreg.h#L2109
private const int WAVE_FORMAT_ADPCM = 0x0002;
private const int WAVE_FORMAT_DVI_ADPCM = 0x0011; // 17
private static readonly int[] WFormatTagExpectedContent = {WAVE_FORMAT_ADPCM, WAVE_FORMAT_DVI_ADPCM};

/// <remarks>
/// I actually don't know much about WAV headers, so I'm sure this algorithm is very very naive.
///
/// I ran it across a sample size of 1.347.475 files, compared its results to MediaInfo's
/// but I didn't get not even 1 false positive/negative, so I think it suits the purposes of this application pretty well.
/// You can find the sample data in the test project.
/// </remarks>
public static bool IsAdpcm(string path)
{
using (var fs = new FileStream(path, FileMode.Open, FileAccess.Read, FileShare.Read))
{
// format chunk check
fs.Seek(FormatChunkOffset, SeekOrigin.Begin);
var formatChunkContent = new byte[FormatChunkExpectedContent.Length];
fs.Read(formatChunkContent, 0, formatChunkContent.Length);

if (!formatChunkContent.SequenceEqual(FormatChunkExpectedContent))
return false;

// wFormatTag check
fs.Seek(WFormatTagOffset, SeekOrigin.Begin);
int wFormatTagContent = fs.ReadByte();

return WFormatTagExpectedContent.Contains(wFormatTagContent);
}
}
}
}
13 changes: 4 additions & 9 deletions wavtogg/Verbs/Convert/ConvertImpl.cs
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
using System;
using System.Diagnostics;
using System.IO;
using MediaInfo;
using wavtogg.Logging;
using wavtogg.Utils;

namespace wavtogg.Verbs.Convert
{
Expand Down Expand Up @@ -31,15 +31,10 @@ void Convert(string folder)
{
logger.Start("Converting", wavPath);

if (_options.AdpcmOnly)
if (_options.AdpcmOnly && !WavUtils.IsAdpcm(wavPath))
{
var mediaInfo = new MediaInfoWrapper(wavPath);

if (!string.Equals(mediaInfo.AudioCodec, "ADPCM", StringComparison.OrdinalIgnoreCase))
{
logger.Skip("Not ADPCM encoded.");
continue;
}
logger.Skip("Not ADPCM encoded.");
continue;
}

string oggPath = Path.ChangeExtension(wavPath, ".ogg");
Expand Down
2 changes: 0 additions & 2 deletions wavtogg/packages.config
Original file line number Diff line number Diff line change
@@ -1,6 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="CommandLineParser" version="2.8.0" targetFramework="net461" />
<package id="MediaInfo.Native" version="19.9.0" targetFramework="net461" />
<package id="MediaInfo.Wrapper" version="19.9.2" targetFramework="net461" />
</packages>
Loading

0 comments on commit 2757214

Please sign in to comment.