Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
1a0fdefcab | ||
|
|
aea6e7ff30 | ||
|
|
8ee60bee2a | ||
|
|
3a2854fafe | ||
|
|
bdc06d137d | ||
|
|
47b55a3774 | ||
|
|
063241068f | ||
|
|
837dc018bd | ||
|
|
1705898b5a | ||
|
|
704e205e94 | ||
|
|
772a79ffad | ||
|
|
27497c92ba | ||
|
|
076e86b643 | ||
|
|
d9a72132a0 | ||
|
|
23883e46b6 | ||
|
|
bfa9f8f791 | ||
|
|
e695203087 | ||
|
|
85d3f63c50 | ||
|
|
89db842aa2 | ||
|
|
679ca8c130 | ||
|
|
8f67e6498c | ||
|
|
51231b2e2e | ||
|
|
b56900d6c7 | ||
|
|
64b1be61c9 | ||
|
|
d5106d3030 | ||
|
|
84a1248234 | ||
|
|
a6be9e759a | ||
|
|
cd29218fc8 | ||
|
|
8d0b39774e | ||
|
|
971285d0aa | ||
|
|
b725ff2f00 | ||
|
|
230b77fb4a | ||
|
|
110a87afff | ||
|
|
c02af77870 | ||
|
|
0ebb186d60 | ||
|
|
f6235bfbb6 | ||
|
|
1b2178ffdf | ||
|
|
c2ca4862c5 | ||
|
|
399b925cb9 | ||
|
|
0691c7135d | ||
|
|
e455065915 | ||
|
|
d7cc20d96f | ||
|
|
0156e36bfc | ||
|
|
92e4122499 | ||
|
|
8731159e32 | ||
|
|
5cdbc48b7a | ||
|
|
535cb9cbdc | ||
|
|
23a6d01cac | ||
|
|
dc7e6dc275 | ||
|
|
2f5247989f | ||
|
|
8fc7f6550e | ||
|
|
afc86e9c46 | ||
|
|
ee44c908e7 | ||
|
|
f4ef160668 | ||
|
|
0c43c85d63 | ||
|
|
a056082027 | ||
|
|
641074edf2 | ||
|
|
34ef4c594c | ||
|
|
3dfdec27c6 | ||
|
|
3ffec77d01 | ||
|
|
5ff2ae2fd8 | ||
|
|
c59d034f48 | ||
|
|
a7f1d6ca48 | ||
|
|
6f865cb34e | ||
|
|
bd950e4720 | ||
|
|
b01bb90e6c | ||
|
|
ddfd154412 | ||
|
|
4d1fdf9bde | ||
|
|
31c1f1043f | ||
|
|
b27ea27e7f | ||
|
|
bf6be18d69 | ||
|
|
9997e57d3b | ||
|
|
ab44197e0d | ||
|
|
60ff39e1b7 | ||
|
|
7662088225 | ||
|
|
687846c04d | ||
|
|
d4ebe976fc | ||
|
|
0f49f0f277 | ||
|
|
28d05cf2d7 | ||
|
|
01199f7133 | ||
|
|
8ecd0b6df0 | ||
|
|
9e48bd9f97 | ||
|
|
75449f4f54 | ||
|
|
75927decb7 | ||
|
|
c6e94fd82e | ||
|
|
ff47d1d75c | ||
|
|
9d2ad26176 | ||
|
|
8d64b3afa7 | ||
|
|
5ead805191 | ||
|
|
e0abc89450 | ||
|
|
70513c0a36 | ||
|
|
215f13793c | ||
|
|
3f173e43c7 | ||
|
|
f3d41d5634 | ||
|
|
64e3b2d62b | ||
|
|
66c5dba042 | ||
|
|
1b9c9f009b | ||
|
|
02b6955caa | ||
|
|
5c77cde4a1 | ||
|
|
3600c0aecd | ||
|
|
8d9bed6744 | ||
|
|
8f887a770a | ||
|
|
8cb19fbc58 | ||
|
|
5742a312e0 | ||
|
|
9f7f79fb6d | ||
|
|
324f7f7af7 | ||
|
|
5bfe317c1e | ||
|
|
5534e757b7 |
@@ -0,0 +1,37 @@
|
||||
name: build-validation
|
||||
|
||||
on:
|
||||
push:
|
||||
pull_request:
|
||||
branches: [ main ]
|
||||
paths:
|
||||
- '**.cs'
|
||||
- '**.csproj'
|
||||
|
||||
|
||||
env:
|
||||
DOTNET_VERSION: '6.x'
|
||||
|
||||
jobs:
|
||||
build:
|
||||
name: build-windows
|
||||
runs-on: [ windows-latest ]
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- name: Setup .NET Core
|
||||
uses: actions/setup-dotnet@v3
|
||||
with:
|
||||
dotnet-version: ${{ env.DOTNET_VERSION }}
|
||||
|
||||
- name: Install dependencies
|
||||
run: dotnet restore
|
||||
|
||||
- name: Build
|
||||
run: dotnet build --configuration Release --no-restore
|
||||
|
||||
- name: Publish artifacts
|
||||
uses: actions/upload-artifact@v1
|
||||
with:
|
||||
name: build
|
||||
path: BAKKA-Editor\bin\Release\net6.0-windows\
|
||||
@@ -1,31 +0,0 @@
|
||||
|
||||
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||
# Visual Studio Version 16
|
||||
VisualStudioVersion = 16.0.32126.315
|
||||
MinimumVisualStudioVersion = 10.0.40219.1
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "BAKKA Editor", "BAKKA Editor\BAKKA Editor.vcxproj", "{459EC852-D323-45B0-8A85-D6F4B030F5A4}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|x64 = Debug|x64
|
||||
Debug|x86 = Debug|x86
|
||||
Release|x64 = Release|x64
|
||||
Release|x86 = Release|x86
|
||||
EndGlobalSection
|
||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||
{459EC852-D323-45B0-8A85-D6F4B030F5A4}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{459EC852-D323-45B0-8A85-D6F4B030F5A4}.Debug|x64.Build.0 = Debug|x64
|
||||
{459EC852-D323-45B0-8A85-D6F4B030F5A4}.Debug|x86.ActiveCfg = Debug|Win32
|
||||
{459EC852-D323-45B0-8A85-D6F4B030F5A4}.Debug|x86.Build.0 = Debug|Win32
|
||||
{459EC852-D323-45B0-8A85-D6F4B030F5A4}.Release|x64.ActiveCfg = Release|x64
|
||||
{459EC852-D323-45B0-8A85-D6F4B030F5A4}.Release|x64.Build.0 = Release|x64
|
||||
{459EC852-D323-45B0-8A85-D6F4B030F5A4}.Release|x86.ActiveCfg = Release|Win32
|
||||
{459EC852-D323-45B0-8A85-D6F4B030F5A4}.Release|x86.Build.0 = Release|Win32
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
EndGlobalSection
|
||||
GlobalSection(ExtensibilityGlobals) = postSolution
|
||||
SolutionGuid = {469EEAFF-2D80-4D14-A10D-95AE6CB493DA}
|
||||
EndGlobalSection
|
||||
EndGlobal
|
||||
@@ -1,71 +0,0 @@
|
||||
// Microsoft Visual C++ generated resource script.
|
||||
//
|
||||
#include "resource.h"
|
||||
|
||||
#define APSTUDIO_READONLY_SYMBOLS
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Generated from the TEXTINCLUDE 2 resource.
|
||||
//
|
||||
#include "winres.h"
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
#undef APSTUDIO_READONLY_SYMBOLS
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// English (United States) resources
|
||||
|
||||
#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
|
||||
LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
|
||||
#pragma code_page(1252)
|
||||
|
||||
#ifdef APSTUDIO_INVOKED
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// TEXTINCLUDE
|
||||
//
|
||||
|
||||
1 TEXTINCLUDE
|
||||
BEGIN
|
||||
"resource.h\0"
|
||||
END
|
||||
|
||||
2 TEXTINCLUDE
|
||||
BEGIN
|
||||
"#include ""winres.h""\r\n"
|
||||
"\0"
|
||||
END
|
||||
|
||||
3 TEXTINCLUDE
|
||||
BEGIN
|
||||
"\r\n"
|
||||
"\0"
|
||||
END
|
||||
|
||||
#endif // APSTUDIO_INVOKED
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Icon
|
||||
//
|
||||
|
||||
// Icon with lowest ID value placed first to ensure application icon
|
||||
// remains consistent on all systems.
|
||||
IDI_ICON1 ICON "exeIcon.ico"
|
||||
|
||||
#endif // English (United States) resources
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
|
||||
#ifndef APSTUDIO_INVOKED
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Generated from the TEXTINCLUDE 3 resource.
|
||||
//
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
#endif // not APSTUDIO_INVOKED
|
||||
|
||||
@@ -1,176 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup Label="ProjectConfigurations">
|
||||
<ProjectConfiguration Include="Debug|Win32">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|Win32">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Debug|x64">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|x64">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
</ProjectConfiguration>
|
||||
</ItemGroup>
|
||||
<PropertyGroup Label="Globals">
|
||||
<VCProjectVersion>16.0</VCProjectVersion>
|
||||
<ProjectGuid>{459EC852-D323-45B0-8A85-D6F4B030F5A4}</ProjectGuid>
|
||||
<TargetFrameworkVersion>v4.7.2</TargetFrameworkVersion>
|
||||
<Keyword>ManagedCProj</Keyword>
|
||||
<RootNamespace>BAKKAEditor</RootNamespace>
|
||||
<WindowsTargetPlatformVersion>10.0</WindowsTargetPlatformVersion>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
<PlatformToolset>v142</PlatformToolset>
|
||||
<CLRSupport>true</CLRSupport>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<PlatformToolset>v142</PlatformToolset>
|
||||
<CLRSupport>true</CLRSupport>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
<PlatformToolset>v142</PlatformToolset>
|
||||
<CLRSupport>true</CLRSupport>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<PlatformToolset>v142</PlatformToolset>
|
||||
<CLRSupport>true</CLRSupport>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
||||
<ImportGroup Label="ExtensionSettings">
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="Shared">
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<PropertyGroup Label="UserMacros" />
|
||||
<PropertyGroup />
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<ClCompile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<PreprocessorDefinitions>WIN32;_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<AdditionalDependencies />
|
||||
<SubSystem>Windows</SubSystem>
|
||||
<EntryPointSymbol>main</EntryPointSymbol>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<ClCompile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<AdditionalIncludeDirectories>C:\Users\otaku\source\repos\BAKKA Editor\BAKKA Editor\irrKlang-64bit-1.6.0\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
</ClCompile>
|
||||
<Link />
|
||||
<Link>
|
||||
<AdditionalDependencies>irrKlang.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<AdditionalLibraryDirectories>C:\Users\otaku\source\repos\BAKKA Editor\BAKKA Editor\irrKlang-64bit-1.6.0\lib\Winx64-visualStudio;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
<EntryPointSymbol>main</EntryPointSymbol>
|
||||
</Link>
|
||||
<Manifest>
|
||||
<EnableDpiAwareness>false</EnableDpiAwareness>
|
||||
</Manifest>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<ClCompile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<PreprocessorDefinitions>WIN32;NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<AdditionalDependencies />
|
||||
<EntryPointSymbol>main</EntryPointSymbol>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<ClCompile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<AdditionalIncludeDirectories>C:\Users\otaku\source\repos\BAKKA Editor\BAKKA Editor\irrKlang-64bit-1.6.0\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
</ClCompile>
|
||||
<Link />
|
||||
<Link>
|
||||
<AdditionalDependencies>irrKlang.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<AdditionalLibraryDirectories>C:\Users\otaku\source\repos\BAKKA Editor\BAKKA Editor\irrKlang-64bit-1.6.0\lib\Winx64-visualStudio;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
<EntryPointSymbol>main</EntryPointSymbol>
|
||||
</Link>
|
||||
<Manifest>
|
||||
<EnableDpiAwareness>false</EnableDpiAwareness>
|
||||
</Manifest>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemGroup>
|
||||
<Reference Include="irrKlang.NET4">
|
||||
<HintPath>O:\Wacca_Stuff\Charting\irrKlang-64bit-1.6.0\bin\dotnet-4-64\irrKlang.NET4.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System" />
|
||||
<Reference Include="System.Data" />
|
||||
<Reference Include="System.Drawing" />
|
||||
<Reference Include="System.Windows.Forms" />
|
||||
<Reference Include="System.Windows.Forms.DataVisualization" />
|
||||
<Reference Include="System.Xml" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="MyForm.cpp" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="Chart.h" />
|
||||
<ClInclude Include="MyForm.h">
|
||||
<FileType>CppForm</FileType>
|
||||
</ClInclude>
|
||||
<ClInclude Include="resource.h" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<EmbeddedResource Include="MyForm.en-US.resx">
|
||||
<DependentUpon>MyForm.h</DependentUpon>
|
||||
</EmbeddedResource>
|
||||
<EmbeddedResource Include="MyForm.resx">
|
||||
<DependentUpon>MyForm.h</DependentUpon>
|
||||
<SubType>Designer</SubType>
|
||||
</EmbeddedResource>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ResourceCompile Include="BAKKA Editor.rc" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Image Include="exeIcon.ico" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="..\README.md" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
<ImportGroup Label="ExtensionTargets">
|
||||
</ImportGroup>
|
||||
</Project>
|
||||
@@ -1,48 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup>
|
||||
<Filter Include="Source Files">
|
||||
<UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
|
||||
<Extensions>cpp;c;cc;cxx;c++;cppm;ixx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
|
||||
</Filter>
|
||||
<Filter Include="Header Files">
|
||||
<UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
|
||||
<Extensions>h;hh;hpp;hxx;h++;hm;inl;inc;ipp;xsd</Extensions>
|
||||
</Filter>
|
||||
<Filter Include="Resource Files">
|
||||
<UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
|
||||
<Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>
|
||||
</Filter>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="MyForm.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="MyForm.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="Chart.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="resource.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ResourceCompile Include="BAKKA Editor.rc">
|
||||
<Filter>Resource Files</Filter>
|
||||
</ResourceCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Image Include="exeIcon.ico">
|
||||
<Filter>Resource Files</Filter>
|
||||
</Image>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="..\README.md">
|
||||
<Filter>Source Files</Filter>
|
||||
</None>
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
@@ -1,35 +0,0 @@
|
||||
#pragma once
|
||||
#include <iostream>
|
||||
#include <iterator>
|
||||
#include <list>
|
||||
|
||||
struct NotesNode {
|
||||
int beat;
|
||||
int subBeat;
|
||||
int noteType;
|
||||
int position;
|
||||
int size;
|
||||
int holdChange;
|
||||
int BGType;
|
||||
std::list<NotesNode>::iterator nextNode;
|
||||
std::list<NotesNode>::iterator prevNode;
|
||||
};
|
||||
|
||||
struct PreChartNode {
|
||||
int beat;
|
||||
int subBeat;
|
||||
int type;
|
||||
double BPM; //2
|
||||
int beatDiv1; //3
|
||||
int beatDiv2; //3
|
||||
double hiSpeed; //5
|
||||
//6-10 have no extra info
|
||||
};
|
||||
|
||||
struct Chart {
|
||||
std::list<NotesNode> Notes;
|
||||
std::list<PreChartNode> PreChart;
|
||||
double offset;
|
||||
double movieOffset;
|
||||
std::string songFileName;
|
||||
};
|
||||
@@ -1,14 +0,0 @@
|
||||
#include "MyForm.h"
|
||||
|
||||
|
||||
using namespace System;
|
||||
using namespace System::Windows::Forms;
|
||||
[STAThread]
|
||||
|
||||
void main(array<String^>^ args)
|
||||
{
|
||||
Application::EnableVisualStyles();
|
||||
Application::SetCompatibleTextRenderingDefault(false);
|
||||
BAKKAEditor::MyForm form;
|
||||
Application::Run(% form);
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
Binary file not shown.
|
Before Width: | Height: | Size: 19 KiB |
@@ -1,780 +0,0 @@
|
||||
|
||||
irrKlang 1.6
|
||||
|
||||
- stopped support for .NET 1.1, please use the versions for .NET 2 or .NET 4 instead,
|
||||
or an older version of irrKlang if you still need .NET 1 support
|
||||
|
||||
- irrKlang for .NET 4 now needs version 4.5 at miminum
|
||||
|
||||
- there is now a new function stopAllSoundsOfSoundSource() to stop all sounds of a specific sound source
|
||||
|
||||
- irrKlang.NET for .NET 4 now also has a strong name (it is now a signed assembly)
|
||||
|
||||
- irrklang for gcc now supports gcc 5.1
|
||||
|
||||
- irrKlang 1.5 for windows was depending on the MSVC runtime dll, this is now
|
||||
no longer the case with irrKlang 1.6
|
||||
|
||||
- fixed a bug causing duplicated DirectSound buffers to share the playbackSpeed sometimes, causing
|
||||
some sounds to have a wrong frequency when played.
|
||||
|
||||
- fixed update() problem in single threaded mode
|
||||
if you run irrKlang in single threaded mode, you can now call irrKlang::update as often and
|
||||
fast as you want. This was supposed to be called only about once every second prevousliy, and
|
||||
could cause irrklang to stall previously if called too often.
|
||||
|
||||
- added support for Visual Studio 2017
|
||||
|
||||
|
||||
------------------------------------------------------------------------
|
||||
|
||||
irrKlang 1.5
|
||||
|
||||
- Added support for unicode file names.
|
||||
irrKlang now uses UTF8 internally on all operating systems. If you are running it on Windows, and want to use
|
||||
wchar_t types, you can use the irrKlang provided function makeUTF8fromUTF16string() to convert your wchar_t* string to
|
||||
a char* string.
|
||||
In the .NET version of irrKlang, the API hasn't changed, but irrklang now supports unicode
|
||||
file names there automatically as well.
|
||||
|
||||
- Added 64 bit support.
|
||||
There is now a separate irrKlang SDK for 64 bit builds
|
||||
|
||||
- Added support for playing back 24 bit flac files
|
||||
|
||||
- Uses less resources on linux now: PCM handles are now closed as soon as possible, freeing resources much earlier.
|
||||
|
||||
------------------------------------------------------------------------
|
||||
|
||||
|
||||
irrKlang 1.4.1
|
||||
|
||||
- irrKlang now loads the alsa lib from the correct directory on previously unsupported linux systems.
|
||||
|
||||
------------------------------------------------------------------------
|
||||
|
||||
irrKlang 1.4.0
|
||||
|
||||
- Fixed a potential crash in the windows version, when using DirectSound8
|
||||
|
||||
- Improved speed of the Windows version of irrKlang by about 20%
|
||||
|
||||
- irrKlang now also works with newer Linux distributions (like Ubuntu 12),
|
||||
which moved the ALSA lib file into a new directory.
|
||||
|
||||
- Cleared up some inconsistencies in the documentation
|
||||
|
||||
- Removed a very small memory leak in Linux and Mac OS X
|
||||
|
||||
---------------------------------------------------------------------
|
||||
|
||||
irrKlang 1.3.0b
|
||||
|
||||
- Added support for .NET framework 4.
|
||||
|
||||
- Fixed a problem with audio recording: GUIDs were not correctly
|
||||
decoded for some devices, causing manual device selection to fail
|
||||
on Windows.
|
||||
|
||||
---------------------------------------------------------------------
|
||||
|
||||
irrKlang 1.3.0
|
||||
|
||||
- There is now the possibility to capture the mixed output audio data
|
||||
from irrKlang, using the ISoundMixedOutputReceiver interface.
|
||||
Can be used to store the sound output as .wav file or for creating
|
||||
an Oscillograph and similar.
|
||||
|
||||
- The movement speed of 3d sound listeners has been ignored in previous
|
||||
releases for 3d sound doppler effects, this has been corrected now.
|
||||
|
||||
- irrKlang now also runs on 64 bit linux systems. It previously
|
||||
looked for the alsa lib in /usr/lib/libasound.so, but on 64 bit
|
||||
system this is located in /usr/lib32/libasound.so. This is fixed now.
|
||||
|
||||
---------------------------------------------------------------------
|
||||
|
||||
irrKlang 1.2.0
|
||||
|
||||
- Added .flac file playback support. Implemented as plugin, ikpFlac.dll.
|
||||
|
||||
- Fixed a bug causing the volume of 3D sounds not to be set correctly
|
||||
when using DirectSound8 and playing more than one 3D sound of the
|
||||
same file at the same time.
|
||||
|
||||
- File formats with unknown extensions are now loaded by Plugins only
|
||||
if they could not be loaded by the internal decoders.
|
||||
|
||||
- Several API documentation updates and improvements.
|
||||
|
||||
- C++ documentation now has search functionality
|
||||
|
||||
- Replaced .chm documentation files now with plain .html files
|
||||
|
||||
-----------------------------------------------------------------------
|
||||
|
||||
irrKlang 1.1.3c
|
||||
|
||||
- [This update only changes the implementation, the interfaces all remain the
|
||||
same, so only the irrKlang.dll file needs to be replaced since version 1.1.3.]
|
||||
|
||||
- Fixed a bug causing irrKlang to crash when playing looped, streamed sounds in 3D
|
||||
under special circumstances.
|
||||
|
||||
-----------------------------------------------------------------------
|
||||
|
||||
irrKlang 1.1.3b
|
||||
|
||||
- [This update only changes the implementation, the interfaces all remain the
|
||||
same, so only the irrKlang.dll file needs to be replaced since version 1.1.3.]
|
||||
|
||||
- Small bug fix for the DirectSound drivers: Looped streamed sounds sometimes
|
||||
restarted with a small pause (~10 ms) in between.
|
||||
|
||||
- The ISound and ISoundSource classes in irrKlang.NET now implement the
|
||||
IDisposable interface, so it is now easily possible to free their resources
|
||||
manually.
|
||||
|
||||
- The .NET version now uses less memory (earlier unmanaged resource disposal).
|
||||
|
||||
-----------------------------------------------------------------------
|
||||
|
||||
irrKlang 1.1.3
|
||||
|
||||
- Added support for multichannel audio recording. When starting audio recording using
|
||||
startRecordingBufferedAudio() or startRecordingCustomHandledAudio(),
|
||||
set the new last parameter to the amount of channels you want to record audio data.
|
||||
|
||||
- Reduced latency of the Linux version (ALSA).
|
||||
|
||||
- Improved Mac OS X performance (CoreAudio), irrKlang now performs better on computers
|
||||
with slow hardware.
|
||||
|
||||
- Added two VisualBasic.NET examples
|
||||
|
||||
- ForcedStreamingThreshold property of ISound now also available in
|
||||
the .NET verion of irrKlang.
|
||||
|
||||
- IAudioRecoder::IsRecording now returns the correct value in the .NET
|
||||
version of irrKlang.
|
||||
|
||||
- IAudioRecorder now correctly returns a SampleFormat data with a lenght of 0 if
|
||||
nothing has been recorded before.
|
||||
|
||||
- In irrKlang.NET, IAudioRecorder.RecordedAudioData does not throw an
|
||||
OutOfMemoryException anymore if nothing has been recorded yet.
|
||||
|
||||
- ISoundSource::getForcedStreamingForceThreshold has been renamed to
|
||||
ISoundSource::getForcedStreamingThreshold
|
||||
|
||||
-----------------------------------------------------------------------
|
||||
|
||||
irrKlang 1.1.2b
|
||||
|
||||
- Added support for (external) multichannel sound hardware on MacOSX.
|
||||
|
||||
-----------------------------------------------------------------------
|
||||
|
||||
irrKlang 1.1.2
|
||||
|
||||
- Added support to play back 24 bit wave files.
|
||||
|
||||
- The DirectSound drivers now use more aggressive sound buffer sharing,
|
||||
causing irrKlang to use a lot less memory and also speeding it up a lot
|
||||
when playing a lot of big sounds.
|
||||
|
||||
- There is now a way to access the internal used audio interfaces (ALSA, DirectSound,
|
||||
DirectSound8, WinMM, CoreAudio) using ISoundEngine::getInternalAudioInterface().
|
||||
|
||||
- There are now two .NET versions of irrKlang available, one for the .NET CLR 1.1
|
||||
and one for .NET CLR 2.0 (.NET Framework 2, 3 and 3.5). Of course, you can still
|
||||
use every version with every project, this is mainly to reduce the size of installers.
|
||||
See details in readme.txt
|
||||
|
||||
- It is now possible in the .NET version to access the decoded sample audio data of
|
||||
non-streamed sounds using ISound.SampleData
|
||||
|
||||
- It is now possible in the .NET version to access the recorded audio data directly
|
||||
using IAudioRecorder.RecordedAudioData
|
||||
|
||||
- Fixed a bug in the .NET version of the method EnableCompressorSoundEffect()
|
||||
which totally skrewed up its parameters.
|
||||
|
||||
- Fixed a bug causing the AudioRecorder only to work for one recording session
|
||||
in DirectSound.
|
||||
|
||||
- Fixed a bug causing the irrklang DirectSound driver to start playing the sound when
|
||||
it changing its 'looped' flag when the sound is paused.
|
||||
|
||||
- There is now a new example for C# available which shows how to use irrKlang with
|
||||
Windows.Forms.
|
||||
|
||||
- The forced streaming treshold has been adjusted to 2MB
|
||||
|
||||
- Fixed some documentation mistakes in ISoundEngine::addSoundSourceFromPCMData
|
||||
|
||||
-----------------------------------------------------------------------
|
||||
|
||||
irrKlang 1.1.0
|
||||
|
||||
- Several speed optimizations and memory usage improvments.
|
||||
|
||||
- It is now possible to directly access the decoded PCM sample data of
|
||||
every loaded sound source.
|
||||
Use ISoundSource::getSampleData() for this.
|
||||
|
||||
- Fixed a bug causing the UserData object and other resources not to be garbage
|
||||
collected when using ISoundStopEventReceiver in the .NET version of irrKlang.
|
||||
|
||||
- Fixed a bug causing the sudden end of sound loops under very rare circumstances.
|
||||
|
||||
- The 'Could not init COM' warning was senseless and has been removed.
|
||||
|
||||
-----------------------------------------------------------------------
|
||||
irrKlang 1.0.4
|
||||
|
||||
- irrKlang is now able to record audio. Use createIrrKlangAudioRecorder() to create an
|
||||
audio recorder object. It currently only works in Windows and with DirectSound (subject to change).
|
||||
|
||||
- A new method ISoundEngine::addSoundSourceFromPCMData() now adds to possibility to use sound
|
||||
source from pure PCM data.
|
||||
|
||||
- The three method overloads of addSoundSource() have now been renamed to
|
||||
addSoundSourceFromFile(), addSoundSourceFromMemoryFile(), and addSoundSourceAlias().
|
||||
|
||||
-----------------------------------------------------------------------
|
||||
irrKlang 1.0.3
|
||||
|
||||
- irrKlang now supports Power PCs (PPC). All features and file formats except
|
||||
Module playback (.mod, .it, .xm, .s3m) are now supported on this platform.
|
||||
|
||||
- There is now a function to enumerate available audio devices. Select a device ID from this list to
|
||||
let irrKlang use a specific audio device. You can create this list using
|
||||
irrklang::ISoundDeviceList* list = createSoundDeviceList();
|
||||
or in .NET (C#):
|
||||
IrrKlang.ISoundDeviceList list = new IrrKlang.ISoundDeviceList();
|
||||
|
||||
- The sound stop event receiver now has an additional parameter, describing the reason why the
|
||||
sound has been stopped. The signature of the method is now
|
||||
virtual void OnSoundStopped(ISound* sound, E_STOP_EVENT_CAUSE reason, void* userData) = 0;
|
||||
or in .NET (C#):
|
||||
public void OnSoundStopped(IrrKlang.ISound sound, IrrKlang.StopEventCause reason, object userData);
|
||||
|
||||
- irrKlang.NET is now a signed assembly to work around some security hassle Microsoft introduced on Vista.
|
||||
|
||||
- On newer linux versions (such as Ubuntu 7.10), irrKlang sometimes would play sound too fast or with
|
||||
a lot of noise, this is repaired now.
|
||||
|
||||
- The Linux version of irrKlang shared object file is now named
|
||||
libirrKlang.so instead of previously irrKlang.so
|
||||
|
||||
- ALSA driver latency highly improved
|
||||
|
||||
- IrrKlang.NET now supports retrieving the audio format of a sound, using ISoundSource::AudioFormat.
|
||||
|
||||
- IrrKlang can now optionally be told which sound device to use for sound output. In addition using
|
||||
this feature, it is now possible to define an ALSA device name to be used for alsa output when calling
|
||||
createIrrKlangDevice().
|
||||
|
||||
- irrKlang ignored the new flag ESEO_PRINT_DEBUG_INFO_TO_STDOUT on unix based operation systems,
|
||||
this is fixed now.
|
||||
|
||||
-----------------------------------------------------------------------
|
||||
irrKlang 1.0.2
|
||||
|
||||
- Breaking interface changes:
|
||||
- All interfaces are now located in one single, new namespace named 'irrklang'.
|
||||
- vector3df is now named vec3df
|
||||
- IReadFile is now named IFileReader
|
||||
- IReferenceCounted is now named IRefCounted and IVirtualReferenceCounted now IVirtualRefCounted
|
||||
- primitive types now have the prefix ik_
|
||||
- all header files have now the prefix ik_
|
||||
- IFileFactory::createAndOpenFile() is now named createFileReader().
|
||||
These changes where necessary to simplify and clean up the interface, as well as to make irrklang independent
|
||||
of future changes of the Irrlicht Engine.
|
||||
|
||||
- It is now possible to change the play position of a sound using ISound::setPlayPosition().
|
||||
|
||||
- Software devices such as ALSA, WinMM and CoreAudio also support teh setPlaybackSpeed() functionality now.
|
||||
|
||||
- Max values of 3D sound now behave differently: They won't mute the sound anymore when
|
||||
the max distance is reached. This should not affect if you set your 3D sound min/max values
|
||||
correctly before: The audible radius of a sound is only influenced by the minimum value,
|
||||
the maximum should be set to a extremely high value usually (such as 1mio) which is the
|
||||
default. If the maximum value is set to a small value, the sound won't attenuate anymore
|
||||
after this distance and stay audible from then on.
|
||||
In short: In nearly all cases, it is not necessary to change the max value of the sound
|
||||
if not in linear rolloff mode. Details can be found in the documentation.
|
||||
|
||||
- It is now possible to retrieve the audio format of sound sources. Informations
|
||||
like channel count (mono/stereo), frame count, sample rate, etc are possible to
|
||||
be retrieved using ISoundSource::getAudioFormat()
|
||||
|
||||
- The internals of irrKlang has been refactored: irrKlang.dll/.so/.dylib files are now smaller, use
|
||||
an improved thread locking mechanism and should run a bit faster.
|
||||
|
||||
- irrKlang now supports a RollOff factor for 3D sounds. Use ISoundEngine::setRolloffFactor() for this.
|
||||
|
||||
- it is now possible to get the name of the used sound driver by calling ISoundEngine::getDriverName();
|
||||
|
||||
- irrKlang now only prints status messages to stdout if ESEO_PRINT_DEBUG_INFO_TO_STDOUT was set when
|
||||
creating the device (which is the default).
|
||||
|
||||
- There is a new example application included in the SDK: A music player.
|
||||
|
||||
- ISound::getPlayPosition() didn't return 100% accurate positions in all cases, this is fixed now.
|
||||
|
||||
- irrKlang won't touch files anymore for preloading when streaming was specified.
|
||||
|
||||
- ISoundSource::getIsSeekingSupported() now returns if the sound supports seeking using
|
||||
ISound::setPlayPosition().
|
||||
|
||||
- Fixed a problem with 3D sounds: On some sound boards on windows operating systems older than Vista,
|
||||
the 3D sound would not stop at the maximum 3D distance when using DirectSound.
|
||||
|
||||
- Using ISoundEngine::setDefault3DSoundMaxDistance() had a small bug, which caused the max distance
|
||||
not to work in all cases, this is fixed now.
|
||||
|
||||
-----------------------------------------------------------------------
|
||||
irrKlang 1.0.1
|
||||
|
||||
- Removed the deprecated header ESoundEffects.h
|
||||
|
||||
- Fixed a rarely happening bug causing irrKlang to crash when stopping streamed sounds in the software devices
|
||||
at disadvantageous times.
|
||||
|
||||
- Fixed a rarely happening bug which could have caused a deadlock when stopping a huge
|
||||
amount of streamed at the same time sounds.
|
||||
|
||||
- Documentation fixes
|
||||
|
||||
-----------------------------------------------------------------------
|
||||
irrKlang 1.0
|
||||
|
||||
- Added ISound::setIsLooped(), to make it possible to change the loop mode of sounds during runtime.
|
||||
|
||||
- It is now possible to preload sounds when using the addSoundSource() method, by
|
||||
setting the parameter 'preload' to true. If this flag is set to false (which is default)
|
||||
the sound engine will not try to load the sound file when calling this method,
|
||||
but only when play() is called with this sound source as parameter.
|
||||
|
||||
- Plugins can now be loaded manually from a custom path using ISoundEngine::loadPlugins();
|
||||
|
||||
- The listener position is now set to a default value when starting up irrKlang.
|
||||
Previously, when playing 3D sounds without changing or setting the listener position at all,
|
||||
3D sounds would sound differently based on the chosen audio driver.
|
||||
|
||||
- Fixed a bug of the Linux version of irrKlang, causing ALSA to crash on
|
||||
some very few systems (known as the '!snd_interval_empty(i)'-problem).
|
||||
|
||||
- Resampling mono sounds in all devices except directSound (it was ok there already)
|
||||
now uses only half the memory as before.
|
||||
|
||||
- To reduce name clashes with the windows headers for people not using namespaces,
|
||||
the Interface IUnknown has been renamed to IRefCounted.
|
||||
|
||||
- IrrKlang can now be used easily together with the latest 6 versions of
|
||||
Irrlicht (header compatibility).
|
||||
|
||||
- Fixed a small bug in the .NET version which could return 'false' instead of 'true' under
|
||||
special circumstances when calling isCurrentlyPlaying() (Microsoft compiler bug).
|
||||
|
||||
- The documentation has been updated and extended with lots of examples.
|
||||
|
||||
- Examples now also include project files for visual studio 6.0
|
||||
|
||||
-----------------------------------------------------------------------
|
||||
irrKlang 1.0-RC1
|
||||
|
||||
- irrKlang now supports MacOSX, using CoreAudio.
|
||||
There is a new sound output driver enumeration literal, named ESOD_CORE_AUDIO, which
|
||||
will be chosen automaticly when using ESOD_AUTO_DETECT on MacOsX.
|
||||
Please note that irrKlang is a universal binary for both x86 and ppc, but
|
||||
only x86 hardware is supported yet, altough some few features might work with the
|
||||
ppc irrKlang version.
|
||||
|
||||
- This version is release candiate 1 for version 1.0. There are now known bugs in irrKlang
|
||||
currently, and if no major bugs will be found, version 1.0 will be released after some time.
|
||||
We are already working on new user requested features which will be integrated after the
|
||||
1.0 release.
|
||||
|
||||
- irrKlang.NET is now able to override the file access just like the C++ version. There is
|
||||
a tutorial in examples.net\CSharp.04.OverrideFileAccess demonstrating this.
|
||||
Use IFileFactory with ISoundEngine::addFileFactory for this.
|
||||
|
||||
- Added a method to irrKlang.NET, making it possible to add System::IO::Streams as sound
|
||||
sources. Note that the stream is totally read into memory when adding the sound source.
|
||||
If you want irrKlang to dynamically open and close custom file streams without loading
|
||||
everything into memory, use the addFileFactory with your own IFileFactory implementation.
|
||||
|
||||
- Documentation improvements for the .NET version.
|
||||
|
||||
-----------------------------------------------------------------------
|
||||
irrKlang 0.9.1
|
||||
|
||||
- License change: All of the irrKlang Pro features (except static linking and signed assembly)
|
||||
are now available for non-commercial use too. Please take a closer look at the new
|
||||
license and the website for details.
|
||||
The license was changed because of lots of user requests, so that free and open
|
||||
source projects are now able to use irrKlang pro's features as well. To compensate this,
|
||||
this means that irrKlang is no more free for commercial use.
|
||||
|
||||
- Mp3 files with ID3 v2 or later tags in it have not been played correctly in irrKlang, this is
|
||||
fixed now.
|
||||
|
||||
- It is now possible to add sound source aliases for an existing sound source.
|
||||
This is useful if you want to play multiple sounds but each sound isn't necessarily one single file.
|
||||
Also useful if you want to or play the same sound using different names, volumes or min and max 3D distances.
|
||||
Use the now existing third overload of ISoundEngine::addSoundSource() which takes another
|
||||
sound source as parameter for this.
|
||||
|
||||
- added ISound::PlayLength property to irrKlang.NET to retrieve the length of sounds in milliseconds.
|
||||
|
||||
- irrKlang.NET now needs a lower amount of memory every time a sound is played and also
|
||||
frees the memory used by these sounds earlier.
|
||||
|
||||
- irrKlang.NET now supports sound sources just as the irrKlang C++ version does,
|
||||
which means better access and possibility to influence sounds.
|
||||
|
||||
- irrKlang.NET now also supports default 3D min and max distances.
|
||||
|
||||
- irrKlang.NET now supports playing sounds directly from custom memory areas,
|
||||
byte arrays (byte[]). Use ISoundEngine.addSoundSource(yourMemoryArray, someName) for this.
|
||||
|
||||
- Using irrKlang.NET, streamed sound files have not been closed on some systems. This is fixed now.
|
||||
|
||||
- It is now possible to set the wanted stream mode for sound sources using
|
||||
ISoundSource::setStreamMode().
|
||||
|
||||
- Reduced the file size of the irrKlang library again a bit.
|
||||
|
||||
- There are two new tutorials for irrKlang.NET in C# available now.
|
||||
|
||||
-----------------------------------------------------------------------
|
||||
|
||||
irrKlang 0.9
|
||||
|
||||
- irrKlang is now available in two editions:
|
||||
- irrKlang which is still free, also for commercial use
|
||||
- irrKlang Pro, for a small license fee (see details on http://ambiera.com)
|
||||
Some of the new features added in this version are only available in
|
||||
irrKlang Pro (see website for details). The 'pro' features can be accessed
|
||||
and tested with the free version as well, but the audio engine will start playing
|
||||
additional sounds (female voice saying 'irrKlang pro') from time to time once
|
||||
a pro feature has been used.
|
||||
|
||||
- irrKlang now supports DirectSound8 as additional sound output driver.
|
||||
Note that the E_SOUND_OUTPUT_DRIVER enumeration has a new member now:
|
||||
ESOD_DIRECT_SOUND_8. The ESOD_DIRECT_SOUND is still available.
|
||||
|
||||
- Doppler effects are now supported (with the DirectSound drivers at least).
|
||||
Use ISound::setVelocity to set a sounds velocity, ISoundEngine::setListenerPosition()
|
||||
to set the listeners velocity and ISoundEngine::setDopplerEffectParameters() to
|
||||
adjust two parameters influencing the doppler effects intensity.
|
||||
|
||||
- There are now sound stop events: Events which are called when a sound has finished
|
||||
playback. Use the new interface ISoundStopEventReciever for this.
|
||||
The interface has only one method to be implemented by the user: OnSoundStopped().
|
||||
Implement this interface and set it via ISound::setSoundStopEventReciever().
|
||||
The sound stop event is guaranteed to be called when a sound or sound stream is finished,
|
||||
either because the sound reached its playback end, its sound source was removed,
|
||||
ISoundEngine::stopAllSounds() has been called or the whole engine was deleted.
|
||||
|
||||
- Sound effects are now usable when using the ESOD_DIRECT_SOUND_8
|
||||
driver (default). Available sound effects are:
|
||||
- Chorus
|
||||
- Compressor
|
||||
- Distortion
|
||||
- Echo
|
||||
- Flanger
|
||||
- Gargle
|
||||
- 3DL2Reverb
|
||||
- ParamEq
|
||||
- WavesReverb
|
||||
Those effects can be accessed via ISound::getSoundEffectControl(), if the
|
||||
'enableSoundEffects' flag was set to true when starting the sound with
|
||||
play2D() or play3D().
|
||||
|
||||
- There is now the option to change the play back speed and the frequency
|
||||
of a sound. Use ISound::setPlaybackSpeed() for this.
|
||||
|
||||
- It is now possible to set a default volume for every sound source via
|
||||
ISoundSource::setDefaultVolume().
|
||||
|
||||
- There is now a statically linkable version of irrKlang available (currently
|
||||
windows and irrKlang pro only).
|
||||
Just #Define IRRKLANG_STATIC in your project settings or before including the
|
||||
irrKlang headers to use the static lib version of irrKlang.
|
||||
Note that you need to use multi threaded runtime libraries in your project
|
||||
when using irrKlang as static lib, other wise you will get linker errors
|
||||
(like "__getmbcp already defined in LIBC.lib(mbctype.obj)") or random crashes.
|
||||
In Visual Studio, this setting can be found in
|
||||
Project Settings -> C++ -> Code Generation -> Runtime Library.
|
||||
|
||||
- Memory sound sources are now copied by default, so the memory block can be discarded after
|
||||
calling ISoundEngine::addSoundSource(). There is a new parameter 'copyMemory' which
|
||||
can be set to false to make the engine use the old, non memory copying behavior.
|
||||
|
||||
- ISoundEngine::getSoundSource() now has a second parameter making it possible
|
||||
to only retrieve a already added sound source without loading it.
|
||||
|
||||
- There is a new example available showing how to use sound effects.
|
||||
|
||||
- Refactored a lot of internal code, reducing the file size of the
|
||||
irrKlang binaries.
|
||||
|
||||
- Fixed a possible synchronization problem (possible crash)
|
||||
|
||||
-----------------------------------------------------------------------
|
||||
|
||||
irrKlang 0.8.1
|
||||
|
||||
- There was a serious bug in the WAV file reader which read over the end of files,
|
||||
when streamed, causing a short 'click' sound. Fixed now.
|
||||
|
||||
- 8 Bit sound streams don't produce a click when stopped anymore.
|
||||
|
||||
- Audio stream readers which report a wrong amount of frames in the stream now
|
||||
don't get clipped before playing the end of the sound anymore.
|
||||
|
||||
-----------------------------------------------------------------------
|
||||
|
||||
irrKlang 0.8
|
||||
|
||||
- There are now two ways to set default min and max distances for 3D sounds:
|
||||
ISoundEngine::setDefault3DSoundMinDistance(), ISoundEngine::setDefault3DSoundMaxDistance
|
||||
for global min/max control, as well as
|
||||
ISoundSource::setDefaultMinDistance(), ISoundSource::setDefaultMaxDistance().
|
||||
to influence the default min/max value based on the sound source.
|
||||
|
||||
- Some documentation updates
|
||||
|
||||
- The short 'click'/'pop' sound which sometimes has been played on streamed, non looped sounds
|
||||
when using the DirectSound device is now removed.
|
||||
|
||||
- The ALSA driver now also works with sound hardware not supporting power of two buffer sizes.
|
||||
|
||||
- License change: irrKlang.so file may also be redistributed.
|
||||
|
||||
-----------------------------------------------------------------------
|
||||
|
||||
irrKlang 0.7
|
||||
|
||||
- Added possibility to remove sound sources (selective or all at once).
|
||||
See ISoundEngine::removeSoundSource() (two overloads) and
|
||||
ISoundEngine::removeAllSoundSources().
|
||||
|
||||
- There is now the possibility to get the length of any sound source or playing sound.
|
||||
See ISound::getPlayLength() and ISoundSource::getPlayLength().
|
||||
|
||||
- Resources of finished played sounds are now freed much earlier, causing smaller memory usage.
|
||||
|
||||
- When stream playback is paused, the play position returned by ISound::getPlayPosition()
|
||||
won't advance forward anymore in DirectSound, this was a bug which is now fixed.
|
||||
|
||||
- Fixed a bug which caused ISound::isFinished() to be returned incorrect values when
|
||||
using the DirectSound driver.
|
||||
|
||||
- Fixed a bug causing a wrong value being reported using getPlayPosition() when playing
|
||||
very long streams using the WinMM or the ALSA driver.
|
||||
|
||||
-----------------------------------------------------------------------
|
||||
|
||||
irrKlang 0.6
|
||||
|
||||
- There are some new supported file formats: MOD, XM, IT and S3M. Implemented using the
|
||||
excellent Dynamic Universal Music Bibliotheque.
|
||||
|
||||
- irrKlang now is available for .NET languages (C#, VisualBasic.NET,
|
||||
IronPhyton, Boo, Delphi.NET etc).
|
||||
See /bin/dotnet for the binary, and /examples.net for some examples.
|
||||
|
||||
- irrKlang now chooses sound drivers in a more intelligent way when running in
|
||||
driver auto detect mode (ESOD_AUTO_DETECT).
|
||||
For example when DirectSound is available but fails starting up (for whatever reason),
|
||||
irrKlang will select the winMM driver instead of not playing any sound.
|
||||
|
||||
- It is now possible to influence or disable the threshold where irrKlang desides
|
||||
to stream a file regardless of the user specified setting.
|
||||
Use ISoundSource::setForcedStreamingThreshold for this.
|
||||
|
||||
- irrKlang is now compatible with Irrlicht 1.3, the IFileReader interface has been
|
||||
updated. Meaning you can use the same IFileReader interfaces between those two
|
||||
engines and for example make irrKlang read files using Irrlicht's file system.
|
||||
|
||||
- irrKlang now needs even less memory when playing a lot of short soundfiles at the same time,
|
||||
achieved through a nicer internal (de)allocation scheme.
|
||||
|
||||
- When using software 3d sound (using winMM or ALSA), the left and right speaker were swapped.
|
||||
This is fixed now.
|
||||
|
||||
- Failed COM initialization is now only a warning, and irrKlang will not abort with an error.
|
||||
|
||||
- Under some circumstances (bad windows scheduling, cpu intensive applications etc) it could
|
||||
happen that looped, streamed sound filed played via DirectSound in irrKlang would play
|
||||
strange noises after the first repeat. This has been corrected now.
|
||||
|
||||
- On some hardware under Linux, irrKlang wasn't able to set the wanted buffer size,
|
||||
this has been improved now.
|
||||
|
||||
- Removed a bug causing visual studio 2005 projects not to compile when using irrKlang without
|
||||
a WIN32 define.
|
||||
|
||||
-----------------------------------------------------------------------
|
||||
|
||||
irrKlang 0.5
|
||||
|
||||
- Linux is now supported as platform. irrKlang uses ALSA as output target here by default.
|
||||
|
||||
- irrKlang now supports winMM as output driver next to DirectSound in Windows.
|
||||
|
||||
- added a new method to pause/unpause all sounds:
|
||||
ISoundEngine::setAllSoundsPaused( bool bPaused = true )
|
||||
|
||||
- The flag ESEO_LOAD_PLUGINS now correctly prevents loading of plugins if
|
||||
not set. This was not working before.
|
||||
|
||||
- ISoundEngine::stopAllSounds() didn't work with the DirectSound output driver correctly,
|
||||
this has been corrected now.
|
||||
|
||||
- irrKlang can now be used as static lib. Just #Define IRRKLANG_STATIC in your project
|
||||
settings or before including the irrKlang headers to use the static lib version
|
||||
of irrKlang. Note that you need to use multi threaded runtime libraries in your project
|
||||
when using irrKlang as static lib, other wise you will get linker errors
|
||||
(like "__getmbcp already defined in LIBC.lib(mbctype.obj)") or random crashes.
|
||||
In Visual Studio, this setting can be found in
|
||||
Project Settings -> C++ -> Code Generation -> Runtime Library.
|
||||
(If the static library isn't released in this package it may come as separate archive)
|
||||
|
||||
-----------------------------------------------------------------------
|
||||
|
||||
irrKlang 0.4
|
||||
|
||||
- Added support for the GCC compiler
|
||||
|
||||
- Added the possibility to load sounds directly from memory.
|
||||
For this, two overloaded methods to the ISoundEngine interface have been added:
|
||||
ISoundSource* addSoundSource(void* memory, ik_s32 sizeInBytes, const ik_c8* soundName);
|
||||
ISoundSource* addSoundSource(const ik_c8* fileName, E_STREAM_MODE mode=SM_AUTO_DETECT);
|
||||
|
||||
- Added possibility to override file access easily.
|
||||
|
||||
- Added two tutorials: MemoryPlayback and OverrideFileAccess.
|
||||
|
||||
- Added support for the Code::Blocks IDE
|
||||
|
||||
- Removed streamMode parameter from getSoundSource(). If you needed this, please use
|
||||
addSoundSource() now instead.
|
||||
|
||||
- Sounds are now loaded correctly independent of their file extension.
|
||||
|
||||
- irrKlang no longer crashes if more than one instance of it is created.
|
||||
|
||||
-----------------------------------------------------------------------
|
||||
|
||||
irrKlang 0.3
|
||||
|
||||
- Added the option to play mp3 files. This functionality is available as plugin and
|
||||
works when the file ikpMP3.dll is available. Simply remove it if you don't want
|
||||
or need mp3 support for your software. Please note that if you are using mp3
|
||||
files in your application, you might need to pay a license fee to Thompson for
|
||||
their patent (This is nothing irrKlang specific, every application needs to do
|
||||
this today if Thompson wants it to.)
|
||||
The ikpMP3.dll decoder is available as full source in the \plugins directory
|
||||
and licensed under the LGPL.
|
||||
|
||||
- Added plugin support. Create a .dll which starts with ikp (for IrrKlangPlugin)
|
||||
including a function looking like this:
|
||||
__declspec(dllexport) void __stdcall irrKlangPluginInit(
|
||||
ISoundEngine* engine, const char* version) { // your code here }
|
||||
irrKlang will load the dll and invoke that function. There is an example plugin
|
||||
with full source code in the \plugins directory which enhances irrKlang
|
||||
to decode mp3 files.
|
||||
|
||||
- IrrKlang now supports 3D buffers (enabled by default). Previously, they have been
|
||||
emulated. By not specifying the ESEO_USE_3D_BUFFERS flag when calling
|
||||
createIrrKlangDevice(), irrKlang will not use 3D buffers.
|
||||
|
||||
- Added the possibility to write debug info to any windows debugger supporting
|
||||
OutputDebugString() (like VisualStudio). This is pretty useful if your application
|
||||
does not capture any console output. Use ESEO_PRINT_DEBUG_INFO_TO_DEBUGGER to
|
||||
enable this feature when calling createIrrKlangDevice().
|
||||
|
||||
- irrKlang now supports multiple rolloff models. 3D sounds are now played back with
|
||||
a logarithmic rolloff by default. In previous versions, irrKlang used a linear rolloff
|
||||
model. Use ESEO_LINEAR_ROLLOFF when calling createIrrKlangDevice() to switch
|
||||
to the linear rolloff model.
|
||||
|
||||
- The createIrrKlangDevice() function now accepts several options as flags. Note that
|
||||
the C++ compiler automaticly converts bools to this flags so if you used a previous
|
||||
version of the engine you might want to check if your parameters are correctly set.
|
||||
|
||||
- Added the method ISound::getPlayPosition() which returns the current play position of
|
||||
the sound in milliseconds.
|
||||
|
||||
- Fixed a possible crash when stopping a streamed sound manually at the same time
|
||||
it also stopped automaticly.
|
||||
|
||||
- Fixed playback of looped streamed sounds causing artifacts under several circumstances.
|
||||
|
||||
-----------------------------------------------------------------------
|
||||
|
||||
irrKlang 0.2
|
||||
|
||||
- Fixed 3d positioning of sounds
|
||||
|
||||
- Fixed a bug in ik_ISound.h causing irrKlang header not to compile with some strict compiler settings.
|
||||
|
||||
- Added some internal performance improvements
|
||||
|
||||
-----------------------------------------------------------------------
|
||||
|
||||
irrKlang 0.1
|
||||
|
||||
Initial release.
|
||||
|
||||
Although this is the first release, irrKlang already has some features:
|
||||
|
||||
- Support for .WAV and .OGG files (MP3, FLAC, SPEEX support planned and
|
||||
coming soon)
|
||||
|
||||
- Buffered and streamed audio playback
|
||||
|
||||
- Seamless 2D and 3D audio: It is possible to play short simple stereo
|
||||
sounds as well multiple large streamed sound files in 3D space at the
|
||||
same time for example.
|
||||
|
||||
- High level autodetection: The engine can do everything for you. Just
|
||||
tell it to play a sound file, and it will load, cache and/or stream
|
||||
sound data for you automaticly, depending on what is best for
|
||||
performance and memory usage. But if you want to specify how the engine
|
||||
should handle this, you can specify this as well.
|
||||
|
||||
- Extendable: Possibility to write own file format readers/decoders to
|
||||
extend the engine with it.
|
||||
|
||||
- Multi/Singlethreaded modes: The engine can run both multithreaded or
|
||||
singlethreaded in the same thread as your application, to make it
|
||||
possible to debug your application easier for example.
|
||||
|
||||
- Low level audio output manipulation: Before starting to play a sound
|
||||
or even during it is already playing, it is possible of course to alter
|
||||
any aspect of it like panning, volume and 3d position.
|
||||
|
||||
- Fast 3D audio on low end hardware: Because some low end audio hardware
|
||||
is not able to play 3D sounds without significant performance loss or
|
||||
some don't support 3d audio buffers at all, irrEdit has a high
|
||||
performance 3d sound buffer emulator built-in, causing a sound
|
||||
experience nearly as it was a real 3d sound buffer.
|
||||
|
||||
- Separate music and sound control: As most applications want to
|
||||
separate between sound and music playback, the engine offers to control
|
||||
them separately, like for example via a master volume control. No need
|
||||
to manage alls your playing sounds just to change the volume of all
|
||||
sounds. (The control of the 'music' part in the API is not available in
|
||||
version 0.1 yet, but can be used via normal sounds already)
|
||||
|
||||
- Full playback control: Play any sound and forget about it if you want.
|
||||
Then later, you can query at any time which sound is currently playing
|
||||
and influene this if you want.
|
||||
|
||||
@@ -1,78 +0,0 @@
|
||||
// Copyright (C) 2002-2018 Nikolaus Gebhardt
|
||||
// This file is part of the "irrKlang" library.
|
||||
// For conditions of distribution and use, see copyright notice in irrKlang.h
|
||||
|
||||
#ifndef __E_IRRKLANG_SOUND_ENGINE_OPTIONS_H_INCLUDED__
|
||||
#define __E_IRRKLANG_SOUND_ENGINE_OPTIONS_H_INCLUDED__
|
||||
|
||||
namespace irrklang
|
||||
{
|
||||
//! An enumeration for all options for starting up the sound engine
|
||||
/** When using createIrrKlangDevice, use a combination of this these
|
||||
as 'options' parameter to start up the engine. By default, irrKlang
|
||||
uses ESEO_DEFAULT_OPTIONS, which is set to the combination
|
||||
ESEO_MULTI_THREADED | ESEO_LOAD_PLUGINS | ESEO_USE_3D_BUFFERS | ESEO_PRINT_DEBUG_INFO_TO_DEBUGGER | ESEO_PRINT_DEBUG_INFO_TO_STDOUT. */
|
||||
enum E_SOUND_ENGINE_OPTIONS
|
||||
{
|
||||
//! If specified (default), it will make irrKlang run in a separate thread.
|
||||
/** Using this flag, irrKlang will update
|
||||
all streams, sounds, 3d positions and whatever automaticly. You also don't need to call ISoundEngine::update()
|
||||
if irrKlang is running multithreaded. However, if you want to run irrKlang in the same thread
|
||||
as your application (for easier debugging for example), don't set this. But you need to call ISoundEngine::update()
|
||||
as often as you can (at least about 2-3 times per second) to make irrKlang update everything correctly then. */
|
||||
ESEO_MULTI_THREADED = 0x01,
|
||||
|
||||
//! If the window of the application doesn't have the focus, irrKlang will be silent if this has been set.
|
||||
/** This will only work when irrKlang is using the DirectSound output driver. */
|
||||
ESEO_MUTE_IF_NOT_FOCUSED = 0x02,
|
||||
|
||||
//! Automaticly loads external plugins when starting up.
|
||||
/** Plugins usually are .dll, .so or .dylib
|
||||
files named for example ikpMP3.dll (= short for irrKlangPluginMP3) which are executed
|
||||
after the startup of the sound engine and modify it for example to make it possible
|
||||
to play back mp3 files. Plugins are being loaded from the current working directory
|
||||
as well as from the position where the .exe using the irrKlang library resides.
|
||||
It is also possible to load the plugins after the engine has started up using
|
||||
ISoundEngine::loadPlugins(). */
|
||||
ESEO_LOAD_PLUGINS = 0x04,
|
||||
|
||||
//! Uses 3D sound buffers instead of emulating them when playing 3d sounds (default).
|
||||
/** If this flag is not specified, all buffers will by created
|
||||
in 2D only and 3D positioning will be emulated in software, making the engine run
|
||||
faster if hardware 3d audio is slow on the system. */
|
||||
ESEO_USE_3D_BUFFERS = 0x08,
|
||||
|
||||
//! Prints debug messages to the debugger window.
|
||||
/** irrKlang will print debug info and status messages to any windows debugger supporting
|
||||
OutputDebugString() (like VisualStudio).
|
||||
This is useful if your application does not capture any console output (see ESEO_PRINT_DEBUG_INFO_TO_STDOUT). */
|
||||
ESEO_PRINT_DEBUG_INFO_TO_DEBUGGER = 0x10,
|
||||
|
||||
//! Prints debug messages to stdout (the ConsoleWindow).
|
||||
/** irrKlang will print debug info and status messages stdout, the console window in Windows. */
|
||||
ESEO_PRINT_DEBUG_INFO_TO_STDOUT = 0x20,
|
||||
|
||||
//! Uses linear rolloff for 3D sound.
|
||||
/** If specified, instead of the default logarithmic one, irrKlang will
|
||||
use a linear rolloff model which influences the attenuation
|
||||
of the sounds over distance. The volume is interpolated linearly between the MinDistance
|
||||
and MaxDistance, making it possible to adjust sounds more easily although this is not
|
||||
physically correct.
|
||||
Note that this option may not work when used together with the ESEO_USE_3D_BUFFERS
|
||||
option when using Direct3D for example, irrKlang will then turn off ESEO_USE_3D_BUFFERS
|
||||
automaticly to be able to use this option and write out a warning. */
|
||||
ESEO_LINEAR_ROLLOFF = 0x40,
|
||||
|
||||
//! Default parameters when starting up the engine.
|
||||
ESEO_DEFAULT_OPTIONS = ESEO_MULTI_THREADED | ESEO_LOAD_PLUGINS | ESEO_USE_3D_BUFFERS | ESEO_PRINT_DEBUG_INFO_TO_DEBUGGER | ESEO_PRINT_DEBUG_INFO_TO_STDOUT,
|
||||
|
||||
//! Never used, it only forces the compiler to compile these enumeration values to 32 bit.
|
||||
/** Don't use this. */
|
||||
ESEO_FORCE_32_BIT = 0x7fffffff
|
||||
};
|
||||
|
||||
} // end namespace irrklang
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1,59 +0,0 @@
|
||||
// Copyright (C) 2002-2018 Nikolaus Gebhardt
|
||||
// This file is part of the "irrKlang" library.
|
||||
// For conditions of distribution and use, see copyright notice in irrKlang.h
|
||||
|
||||
#ifndef __E_IRRKLANG_SOUND_OUTPUT_DRIVERS_H_INCLUDED__
|
||||
#define __E_IRRKLANG_SOUND_OUTPUT_DRIVERS_H_INCLUDED__
|
||||
|
||||
namespace irrklang
|
||||
{
|
||||
//! An enumeration for all types of supported sound drivers
|
||||
/** Values of this enumeration can be used as parameter when calling createIrrKlangDevice(). */
|
||||
enum E_SOUND_OUTPUT_DRIVER
|
||||
{
|
||||
//! Autodetects the best sound driver for the system
|
||||
ESOD_AUTO_DETECT = 0,
|
||||
|
||||
//! DirectSound8 sound output driver, windows only.
|
||||
/** In contrast to ESOD_DIRECT_SOUND, this supports sophisticated sound effects
|
||||
but may not be available on old windows versions. It behaves very similar
|
||||
to ESOD_DIRECT_SOUND but also supports DX8 sound effects.*/
|
||||
ESOD_DIRECT_SOUND_8,
|
||||
|
||||
//! DirectSound sound output driver, windows only.
|
||||
/** This uses DirectSound 3 or above, if available. If DX8 sound effects
|
||||
are needed, use ESOD_DIRECT_SOUND_8 instead. The
|
||||
ESOD_DIRECT_SOUND driver may be available on more and older windows
|
||||
versions than ESOD_DIRECT_SOUND_8.*/
|
||||
ESOD_DIRECT_SOUND,
|
||||
|
||||
//! WinMM sound output driver, windows only.
|
||||
/** Supports the ISoundMixedOutputReceiver interface using setMixedDataOutputReceiver. */
|
||||
ESOD_WIN_MM,
|
||||
|
||||
//! ALSA sound output driver, linux only.
|
||||
/** When using ESOD_ALSA in createIrrKlangDevice(), it is possible to set the third parameter,
|
||||
'deviceID' to the name of specific ALSA pcm device, to the irrKlang force to use this one.
|
||||
Set it to 'default', or 'plug:hw' or whatever you need it to be.
|
||||
Supports the ISoundMixedOutputReceiver interface using setMixedDataOutputReceiver. */
|
||||
ESOD_ALSA,
|
||||
|
||||
//! Core Audio sound output driver, mac os only.
|
||||
/** Supports the ISoundMixedOutputReceiver interface using setMixedDataOutputReceiver. */
|
||||
ESOD_CORE_AUDIO,
|
||||
|
||||
//! Null driver, creating no sound output
|
||||
ESOD_NULL,
|
||||
|
||||
//! Amount of built-in sound output drivers
|
||||
ESOD_COUNT,
|
||||
|
||||
//! This enumeration literal is never used, it only forces the compiler to
|
||||
//! compile these enumeration values to 32 bit.
|
||||
ESOD_FORCE_32_BIT = 0x7fffffff
|
||||
};
|
||||
|
||||
} // end namespace irrklang
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1,31 +0,0 @@
|
||||
// Copyright (C) 2002-2018 Nikolaus Gebhardt
|
||||
// This file is part of the "irrKlang" library.
|
||||
// For conditions of distribution and use, see copyright notice in irrKlang.h
|
||||
|
||||
#ifndef __E_IRRKLANG_STREAM_MODES_H_INCLUDED__
|
||||
#define __E_IRRKLANG_STREAM_MODES_H_INCLUDED__
|
||||
|
||||
namespace irrklang
|
||||
{
|
||||
//! An enumeration for all types of supported stream modes
|
||||
enum E_STREAM_MODE
|
||||
{
|
||||
//! Autodetects the best stream mode for a specified audio data.
|
||||
ESM_AUTO_DETECT = 0,
|
||||
|
||||
//! Streams the audio data when needed.
|
||||
ESM_STREAMING,
|
||||
|
||||
//! Loads the whole audio data into the memory.
|
||||
ESM_NO_STREAMING,
|
||||
|
||||
//! This enumeration literal is never used, it only forces the compiler to
|
||||
//! compile these enumeration values to 32 bit.
|
||||
ESM_FORCE_32_BIT = 0x7fffffff
|
||||
};
|
||||
|
||||
} // end namespace irrklang
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1,110 +0,0 @@
|
||||
// Copyright (C) 2002-2018 Nikolaus Gebhardt
|
||||
// This file is part of the "irrKlang" library.
|
||||
// For conditions of distribution and use, see copyright notice in irrKlang.h
|
||||
|
||||
#ifndef __I_IRRKLANG_AUDIO_RECORDER_H_INCLUDED__
|
||||
#define __I_IRRKLANG_AUDIO_RECORDER_H_INCLUDED__
|
||||
|
||||
#include "ik_IRefCounted.h"
|
||||
#include "ik_ISoundSource.h"
|
||||
|
||||
|
||||
namespace irrklang
|
||||
{
|
||||
class ICapturedAudioDataReceiver;
|
||||
|
||||
//! Interface to an audio recorder. Create it using the createIrrKlangAudioRecorder() function.
|
||||
/** It creates sound sources into an ISoundEngine which then can be played there.
|
||||
See @ref recordingAudio for an example on how to use this. */
|
||||
class IAudioRecorder : public virtual IRefCounted
|
||||
{
|
||||
public:
|
||||
|
||||
//! Starts recording audio.
|
||||
/** Clears all possibly previously recorded buffered audio data and starts to record.
|
||||
When finished recording audio data, call stopRecordingAudio().
|
||||
All recorded audio data gets stored into an internal audio buffer, which
|
||||
can then be accessed for example using addSoundSourceFromRecordedAudio() or
|
||||
getRecordedAudioData(). For recording audio data not into an internal audio
|
||||
buffer, use startRecordingCustomHandledAudio().
|
||||
\param sampleRate: Sample rate of the recorded audio.
|
||||
\param sampleFormat: Sample format of the recorded audio.
|
||||
\param channelCount: Amount of audio channels.
|
||||
\return Returns true if successfully started recording and false if not.*/
|
||||
virtual bool startRecordingBufferedAudio(ik_s32 sampleRate=22000,
|
||||
ESampleFormat sampleFormat=ESF_S16,
|
||||
ik_s32 channelCount=1) = 0;
|
||||
|
||||
//! Starts recording audio.
|
||||
/** Clears all possibly previously recorded buffered audio data and starts to record
|
||||
audio data, which is delivered to a custom user callback interface.
|
||||
When finished recording audio data, call stopRecordingAudio(). If instead of
|
||||
recording the data to the receiver interface recording into a managed buffer
|
||||
is wished, use startRecordingBufferedAudio() instead.
|
||||
\param receiver: Interface to be implemented by the user, gets called once for each
|
||||
captured audio data chunk.
|
||||
\param sampleRate: Sample rate of the recorded audio.
|
||||
\param sampleFormat: Sample format of the recorded audio.
|
||||
\param channelCount: Amount of audio channels.
|
||||
\return Returns true if successfully started recording and false if not. */
|
||||
virtual bool startRecordingCustomHandledAudio(ICapturedAudioDataReceiver* receiver,
|
||||
ik_s32 sampleRate=22000,
|
||||
ESampleFormat sampleFormat=ESF_S16,
|
||||
ik_s32 channelCount=1) = 0;
|
||||
|
||||
//! Stops recording audio.
|
||||
virtual void stopRecordingAudio() = 0;
|
||||
|
||||
//! Creates a sound source for the recorded audio data.
|
||||
/** The returned sound source pointer then can be used to play back the recorded audio data
|
||||
using ISoundEngine::play2D(). This method only will succeed if the audio was recorded using
|
||||
startRecordingBufferedAudio() and audio recording is currently stopped.
|
||||
\param soundName Name of the virtual sound file (e.g. "someRecordedAudio"). You can also use this
|
||||
name when calling play3D() or play2D(). */
|
||||
virtual ISoundSource* addSoundSourceFromRecordedAudio(const char* soundName) = 0;
|
||||
|
||||
//! Clears recorded audio data buffer, freeing memory.
|
||||
/** This method will only succeed if audio recording is currently stopped. */
|
||||
virtual void clearRecordedAudioDataBuffer() = 0;
|
||||
|
||||
//! Returns if the recorder is currently recording audio.
|
||||
virtual bool isRecording() = 0;
|
||||
|
||||
//! Returns the audio format of the recorded audio data.
|
||||
/** Also contains informations about the length of the recorded audio stream. */
|
||||
virtual SAudioStreamFormat getAudioFormat() = 0;
|
||||
|
||||
//! Returns a pointer to the recorded audio data.
|
||||
/** This method will only succeed if audio recording is currently stopped and
|
||||
something was recorded previously using startRecordingBufferedAudio().
|
||||
The lenght of the buffer can be retrieved using
|
||||
getAudioFormat().getSampleDataSize(). Note that the pointer is only valid
|
||||
as long as not clearRecordedAudioDataBuffer() is called or another sample is
|
||||
recorded.*/
|
||||
virtual void* getRecordedAudioData() = 0;
|
||||
|
||||
//! returns the name of the sound driver, like 'ALSA' for the alsa device.
|
||||
/** Possible returned strings are "NULL", "ALSA", "CoreAudio", "winMM",
|
||||
"DirectSound" and "DirectSound8". */
|
||||
virtual const char* getDriverName() = 0;
|
||||
};
|
||||
|
||||
|
||||
//! Interface to be implemented by the user if access to the recorded audio data is needed.
|
||||
/** Is used as parameter in IAudioRecorder::startRecordingCustomHandledAudio. */
|
||||
class ICapturedAudioDataReceiver : public IRefCounted
|
||||
{
|
||||
public:
|
||||
|
||||
//! Gets called once for each captured audio data chunk.
|
||||
/** See IAudioRecorder::startRecordingCustomHandledAudio for details.
|
||||
\param audioData: Pointer to a part of the recorded audio data
|
||||
\param lengthInBytes: Amount of bytes in the audioData buffer.*/
|
||||
virtual void OnReceiveAudioDataStreamChunk(unsigned char* audioData, unsigned long lengthInBytes) = 0;
|
||||
};
|
||||
|
||||
|
||||
} // end namespace irrklang
|
||||
|
||||
|
||||
#endif
|
||||
@@ -1,49 +0,0 @@
|
||||
// Copyright (C) 2002-2018 Nikolaus Gebhardt
|
||||
// This file is part of the "irrKlang" library.
|
||||
// For conditions of distribution and use, see copyright notice in irrKlang.h
|
||||
|
||||
#ifndef __I_IRRKLANG_AUDIO_STREAM_H_INCLUDED__
|
||||
#define __I_IRRKLANG_AUDIO_STREAM_H_INCLUDED__
|
||||
|
||||
#include "ik_IRefCounted.h"
|
||||
#include "ik_SAudioStreamFormat.h"
|
||||
|
||||
namespace irrklang
|
||||
{
|
||||
|
||||
|
||||
//! Reads and decodes audio data into an usable audio stream for the ISoundEngine
|
||||
class IAudioStream : public IRefCounted
|
||||
{
|
||||
public:
|
||||
|
||||
//! destructor
|
||||
virtual ~IAudioStream() {};
|
||||
|
||||
//! returns format of the audio stream
|
||||
virtual SAudioStreamFormat getFormat() = 0;
|
||||
|
||||
//! sets the position of the audio stream.
|
||||
/** For example to let the stream be read from the beginning of the file again,
|
||||
setPosition(0) would be called. This is usually done be the sound engine to
|
||||
loop a stream after if has reached the end. Return true if sucessful and 0 if not.
|
||||
\param pos: Position in frames.*/
|
||||
virtual bool setPosition(ik_s32 pos) = 0;
|
||||
|
||||
//! returns true if the audio stream is seekable
|
||||
/* Some file formats like (MODs) don't support seeking */
|
||||
virtual bool getIsSeekingSupported() { return true; }
|
||||
|
||||
//! tells the audio stream to read frameCountToRead audio frames into the specified buffer
|
||||
/** \param target: Target data buffer to the method will write the read frames into. The
|
||||
specified buffer will be at least getFormat().getFrameSize()*frameCountToRead bytes big.
|
||||
\param frameCountToRead: amount of frames to be read.
|
||||
\returns Returns amount of frames really read. Should be frameCountToRead in most cases. */
|
||||
virtual ik_s32 readFrames(void* target, ik_s32 frameCountToRead) = 0;
|
||||
};
|
||||
|
||||
|
||||
} // end namespace irrklang
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1,40 +0,0 @@
|
||||
// Copyright (C) 2002-2018 Nikolaus Gebhardt
|
||||
// This file is part of the "irrKlang" library.
|
||||
// For conditions of distribution and use, see copyright notice in irrKlang.h
|
||||
|
||||
#ifndef __I_IRRKLANG_AUDIO_STREAM_LOADER_H_INCLUDED__
|
||||
#define __I_IRRKLANG_AUDIO_STREAM_LOADER_H_INCLUDED__
|
||||
|
||||
#include "ik_IRefCounted.h"
|
||||
#include "ik_IFileReader.h"
|
||||
|
||||
namespace irrklang
|
||||
{
|
||||
|
||||
class IAudioStream;
|
||||
|
||||
//! Class which is able to create an audio file stream from a file.
|
||||
class IAudioStreamLoader : public IRefCounted
|
||||
{
|
||||
public:
|
||||
|
||||
//! destructor
|
||||
virtual ~IAudioStreamLoader() {};
|
||||
|
||||
//! Returns true if the file maybe is able to be loaded by this class.
|
||||
/** This decision should be based only on the file extension (e.g. ".wav"). The given
|
||||
filename string is guaranteed to be lower case. */
|
||||
virtual bool isALoadableFileExtension(const ik_c8* fileName) = 0;
|
||||
|
||||
//! Creates an audio file input stream from a file
|
||||
/** \return Pointer to the created audio stream. Returns 0 if loading failed.
|
||||
If you no longer need the stream, you should call IAudioFileStream::drop().
|
||||
See IRefCounted::drop() for more information. */
|
||||
virtual IAudioStream* createAudioStream(IFileReader* file) = 0;
|
||||
};
|
||||
|
||||
|
||||
} // end namespace irrklang
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1,41 +0,0 @@
|
||||
// Copyright (C) 2002-2018 Nikolaus Gebhardt
|
||||
// This file is part of the "irrKlang" library.
|
||||
// For conditions of distribution and use, see copyright notice in irrKlang.h
|
||||
|
||||
#ifndef __I_IRRKLANG_FILE_FACTORY_H_INCLUDED__
|
||||
#define __I_IRRKLANG_FILE_FACTORY_H_INCLUDED__
|
||||
|
||||
#include "ik_IRefCounted.h"
|
||||
|
||||
namespace irrklang
|
||||
{
|
||||
class IFileReader;
|
||||
|
||||
//! Interface to overwrite file access in irrKlang.
|
||||
/** Derive your own class from IFileFactory, overwrite the createFileReader()
|
||||
method and return your own implemented IFileReader to overwrite file access of irrKlang.
|
||||
Use ISoundEngine::addFileFactory() to let irrKlang know about your class.
|
||||
Example code can be found in the tutorial 04.OverrideFileAccess.
|
||||
*/
|
||||
class IFileFactory : public virtual IRefCounted
|
||||
{
|
||||
public:
|
||||
|
||||
virtual ~IFileFactory() {};
|
||||
|
||||
//! Opens a file for read access.
|
||||
/** Derive your own class from IFileFactory, overwrite this
|
||||
method and return your own implemented IFileReader to overwrite file access of irrKlang.
|
||||
Use ISoundEngine::addFileFactory() to let irrKlang know about your class.
|
||||
Example code can be found in the tutorial 04.OverrideFileAccess.
|
||||
\param filename Name of file to open.
|
||||
\return Returns a pointer to the created file interface.
|
||||
The returned pointer should be dropped when no longer needed.
|
||||
See IRefCounted::drop() for more information. Returns 0 if file cannot be opened. */
|
||||
virtual IFileReader* createFileReader(const ik_c8* filename) = 0;
|
||||
};
|
||||
|
||||
} // end namespace irrklang
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1,50 +0,0 @@
|
||||
// Copyright (C) 2002-2018 Nikolaus Gebhardt
|
||||
// This file is part of the "irrKlang" library.
|
||||
// For conditions of distribution and use, see copyright notice in irrKlang.h
|
||||
|
||||
#ifndef __I_IRRKLANG_READ_FILE_H_INCLUDED__
|
||||
#define __I_IRRKLANG_READ_FILE_H_INCLUDED__
|
||||
|
||||
#include "ik_IRefCounted.h"
|
||||
|
||||
namespace irrklang
|
||||
{
|
||||
|
||||
//! Interface providing read acess to a file.
|
||||
class IFileReader : public virtual IRefCounted
|
||||
{
|
||||
public:
|
||||
|
||||
virtual ~IFileReader() {};
|
||||
|
||||
//! Reads an amount of bytes from the file.
|
||||
//! \param buffer: Pointer to buffer where to read bytes will be written to.
|
||||
//! \param sizeToRead: Amount of bytes to read from the file.
|
||||
//! \return Returns how much bytes were read.
|
||||
virtual ik_s32 read(void* buffer, ik_u32 sizeToRead) = 0;
|
||||
|
||||
//! Changes position in file, returns true if successful.
|
||||
//! \param finalPos: Destination position in the file.
|
||||
//! \param relativeMovement: If set to true, the position in the file is
|
||||
//! changed relative to current position. Otherwise the position is changed
|
||||
//! from beginning of file.
|
||||
//! \return Returns true if successful, otherwise false.
|
||||
virtual bool seek(ik_s32 finalPos, bool relativeMovement = false) = 0;
|
||||
|
||||
//! Returns size of file.
|
||||
//! \return Returns the size of the file in bytes.
|
||||
virtual ik_s32 getSize() = 0;
|
||||
|
||||
//! Returns the current position in the file.
|
||||
//! \return Returns the current position in the file in bytes.
|
||||
virtual ik_s32 getPos() = 0;
|
||||
|
||||
//! Returns name of file.
|
||||
//! \return Returns the file name as zero terminated character string.
|
||||
virtual const ik_c8* getFileName() = 0;
|
||||
};
|
||||
|
||||
} // end namespace irrklang
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1,119 +0,0 @@
|
||||
// Copyright (C) 2002-2018 Nikolaus Gebhardt
|
||||
// This file is part of the "irrKlang" library.
|
||||
// For conditions of distribution and use, see copyright notice in irrKlang.h
|
||||
|
||||
#ifndef __I_IRRKLANG_IREFERENCE_COUNTED_H_INCLUDED__
|
||||
#define __I_IRRKLANG_IREFERENCE_COUNTED_H_INCLUDED__
|
||||
|
||||
#include "ik_irrKlangTypes.h"
|
||||
|
||||
namespace irrklang
|
||||
{
|
||||
//! Base class of most objects of the irrKlang.
|
||||
/** This class provides reference counting through the methods grab() and drop().
|
||||
It also is able to store a debug string for every instance of an object.
|
||||
Most objects of irrKlang are derived from IRefCounted, and so they are reference counted.
|
||||
|
||||
When you receive an object in irrKlang (for example an ISound using play2D() or
|
||||
play3D()), and you no longer need the object, you have
|
||||
to call drop(). This will destroy the object, if grab() was not called
|
||||
in another part of you program, because this part still needs the object.
|
||||
Note, that you only don't need to call drop() for all objects you receive, it
|
||||
will be explicitely noted in the documentation.
|
||||
|
||||
A simple example:
|
||||
|
||||
If you want to play a sound, you may want to call the method
|
||||
ISoundEngine::play2D. You call
|
||||
ISound* mysound = engine->play2D("foobar.mp3", false, false true);
|
||||
If you no longer need the sound interface, call mysound->drop(). The
|
||||
sound may still play on after this because the engine still has a reference
|
||||
to that sound, but you can be sure that it's memory will be released as soon
|
||||
the sound is no longer used.
|
||||
|
||||
If you want to add a sound source, you may want to call a method
|
||||
ISoundEngine::addSoundSourceFromFile. You do this like
|
||||
ISoundSource* mysource = engine->addSoundSourceFromFile("example.jpg");
|
||||
You will not have to drop the pointer to the source, because
|
||||
sound sources are managed by the engine (it will live as long as the sound engine) and
|
||||
the documentation says so.
|
||||
*/
|
||||
class IRefCounted
|
||||
{
|
||||
public:
|
||||
|
||||
//! Constructor.
|
||||
IRefCounted()
|
||||
: ReferenceCounter(1)
|
||||
{
|
||||
}
|
||||
|
||||
//! Destructor.
|
||||
virtual ~IRefCounted()
|
||||
{
|
||||
}
|
||||
|
||||
//! Grabs the object. Increments the reference counter by one.
|
||||
//! Someone who calls grab() to an object, should later also call
|
||||
//! drop() to it. If an object never gets as much drop() as grab()
|
||||
//! calls, it will never be destroyed.
|
||||
//! The IRefCounted class provides a basic reference counting mechanism
|
||||
//! with its methods grab() and drop(). Most objects of irrklang
|
||||
//! are derived from IRefCounted, and so they are reference counted.
|
||||
//!
|
||||
//! When you receive an object in irrKlang (for example an ISound using play2D() or
|
||||
//! play3D()), and you no longer need the object, you have
|
||||
//! to call drop(). This will destroy the object, if grab() was not called
|
||||
//! in another part of you program, because this part still needs the object.
|
||||
//! Note, that you only don't need to call drop() for all objects you receive, it
|
||||
//! will be explicitely noted in the documentation.
|
||||
//!
|
||||
//! A simple example:
|
||||
//!
|
||||
//! If you want to play a sound, you may want to call the method
|
||||
//! ISoundEngine::play2D. You call
|
||||
//! ISound* mysound = engine->play2D("foobar.mp3", false, false true);
|
||||
//! If you no longer need the sound interface, call mysound->drop(). The
|
||||
//! sound may still play on after this because the engine still has a reference
|
||||
//! to that sound, but you can be sure that it's memory will be released as soon
|
||||
//! the sound is no longer used.
|
||||
void grab() { ++ReferenceCounter; }
|
||||
|
||||
//! When you receive an object in irrKlang (for example an ISound using play2D() or
|
||||
//! play3D()), and you no longer need the object, you have
|
||||
//! to call drop(). This will destroy the object, if grab() was not called
|
||||
//! in another part of you program, because this part still needs the object.
|
||||
//! Note, that you only don't need to call drop() for all objects you receive, it
|
||||
//! will be explicitely noted in the documentation.
|
||||
//!
|
||||
//! A simple example:
|
||||
//!
|
||||
//! If you want to play a sound, you may want to call the method
|
||||
//! ISoundEngine::play2D. You call
|
||||
//! ISound* mysound = engine->play2D("foobar.mp3", false, false true);
|
||||
//! If you no longer need the sound interface, call mysound->drop(). The
|
||||
//! sound may still play on after this because the engine still has a reference
|
||||
//! to that sound, but you can be sure that it's memory will be released as soon
|
||||
//! the sound is no longer used.
|
||||
bool drop()
|
||||
{
|
||||
--ReferenceCounter;
|
||||
|
||||
if (!ReferenceCounter)
|
||||
{
|
||||
delete this;
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
ik_s32 ReferenceCounter;
|
||||
};
|
||||
|
||||
} // end namespace irr
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1,194 +0,0 @@
|
||||
// Copyright (C) 2002-2018 Nikolaus Gebhardt
|
||||
// This file is part of the "irrKlang" library.
|
||||
// For conditions of distribution and use, see copyright notice in irrKlang.h
|
||||
|
||||
#ifndef __I_IRRKLANG_SOUND_H_INCLUDED__
|
||||
#define __I_IRRKLANG_SOUND_H_INCLUDED__
|
||||
|
||||
#include "ik_IVirtualRefCounted.h"
|
||||
#include "ik_ISoundEffectControl.h"
|
||||
#include "ik_vec3d.h"
|
||||
|
||||
|
||||
namespace irrklang
|
||||
{
|
||||
class ISoundSource;
|
||||
class ISoundStopEventReceiver;
|
||||
|
||||
//! Represents a sound which is currently played.
|
||||
/** The sound can be stopped, its volume or pan changed, effects added/removed
|
||||
and similar using this interface.
|
||||
Creating sounds is done using ISoundEngine::play2D() or ISoundEngine::play3D().
|
||||
More informations about the source of a sound can be obtained from the ISoundSource
|
||||
interface. */
|
||||
class ISound : public IVirtualRefCounted
|
||||
{
|
||||
public:
|
||||
|
||||
//! returns source of the sound which stores the filename and other informations about that sound
|
||||
/** \return Returns the sound source poitner of this sound. May return 0 if the sound source
|
||||
has been removed.*/
|
||||
virtual ISoundSource* getSoundSource() = 0;
|
||||
|
||||
//! returns if the sound is paused
|
||||
virtual void setIsPaused( bool paused = true) = 0;
|
||||
|
||||
//! returns if the sound is paused
|
||||
virtual bool getIsPaused() = 0;
|
||||
|
||||
//! Will stop the sound and free its resources.
|
||||
/** If you just want to pause the sound, use setIsPaused().
|
||||
After calling stop(), isFinished() will usually return true.
|
||||
Be sure to also call ->drop() once you are done.*/
|
||||
virtual void stop() = 0;
|
||||
|
||||
//! returns volume of the sound, a value between 0 (mute) and 1 (full volume).
|
||||
/** (this volume gets multiplied with the master volume of the sound engine
|
||||
and other parameters like distance to listener when played as 3d sound) */
|
||||
virtual ik_f32 getVolume() = 0;
|
||||
|
||||
//! sets the volume of the sound, a value between 0 (mute) and 1 (full volume).
|
||||
/** This volume gets multiplied with the master volume of the sound engine
|
||||
and other parameters like distance to listener when played as 3d sound. */
|
||||
virtual void setVolume(ik_f32 volume) = 0;
|
||||
|
||||
//! sets the pan of the sound. Takes a value between -1 and 1, 0 is center.
|
||||
virtual void setPan(ik_f32 pan) = 0;
|
||||
|
||||
//! returns the pan of the sound. Takes a value between -1 and 1, 0 is center.
|
||||
virtual ik_f32 getPan() = 0;
|
||||
|
||||
//! returns if the sound has been started to play looped
|
||||
virtual bool isLooped() = 0;
|
||||
|
||||
//! changes the loop mode of the sound.
|
||||
/** If the sound is playing looped and it is changed to not-looped, then it
|
||||
will stop playing after the loop has finished.
|
||||
If it is not looped and changed to looped, the sound will start repeating to be
|
||||
played when it reaches its end.
|
||||
Invoking this method will not have an effect when the sound already has stopped. */
|
||||
virtual void setIsLooped(bool looped) = 0;
|
||||
|
||||
//! returns if the sound has finished playing.
|
||||
/** Don't mix this up with isPaused(). isFinished() returns if the sound has been
|
||||
finished playing. If it has, is maybe already have been removed from the playing list of the
|
||||
sound engine and calls to any other of the methods of ISound will not have any result.
|
||||
If you call stop() to a playing sound will result that this function will return true
|
||||
when invoked. */
|
||||
virtual bool isFinished() = 0;
|
||||
|
||||
//! Sets the minimal distance if this is a 3D sound.
|
||||
/** Changes the distance at which the 3D sound stops getting louder. This works
|
||||
like this: As a listener approaches a 3D sound source, the sound gets louder.
|
||||
Past a certain point, it is not reasonable for the volume to continue to increase.
|
||||
Either the maximum (zero) has been reached, or the nature of the sound source
|
||||
imposes a logical limit. This is the minimum distance for the sound source.
|
||||
Similarly, the maximum distance for a sound source is the distance beyond
|
||||
which the sound does not get any quieter.
|
||||
The default minimum distance is 1, the default max distance is a huge number like 1000000000.0f. */
|
||||
virtual void setMinDistance(ik_f32 min) = 0;
|
||||
|
||||
//! Returns the minimal distance if this is a 3D sound.
|
||||
/** See setMinDistance() for details. */
|
||||
virtual ik_f32 getMinDistance() = 0;
|
||||
|
||||
//! Sets the maximal distance if this is a 3D sound.
|
||||
/** Changing this value is usually not necessary. Use setMinDistance() instead.
|
||||
Don't change this value if you don't know what you are doing: This value causes the sound
|
||||
to stop attenuating after it reaches the max distance. Most people think that this sets the
|
||||
volume of the sound to 0 after this distance, but this is not true. Only change the
|
||||
minimal distance (using for example setMinDistance()) to influence this.
|
||||
The maximum distance for a sound source is the distance beyond which the sound does not get any quieter.
|
||||
The default minimum distance is 1, the default max distance is a huge number like 1000000000.0f. */
|
||||
virtual void setMaxDistance(ik_f32 max) = 0;
|
||||
|
||||
//! Returns the maximal distance if this is a 3D sound.
|
||||
/** See setMaxDistance() for details. */
|
||||
virtual ik_f32 getMaxDistance() = 0;
|
||||
|
||||
//! sets the position of the sound in 3d space
|
||||
virtual void setPosition(vec3df position) = 0;
|
||||
|
||||
//! returns the position of the sound in 3d space
|
||||
virtual vec3df getPosition() = 0;
|
||||
|
||||
//! sets the position of the sound in 3d space, needed for Doppler effects.
|
||||
/** To use doppler effects use ISound::setVelocity to set a sounds velocity,
|
||||
ISoundEngine::setListenerPosition() to set the listeners velocity and
|
||||
ISoundEngine::setDopplerEffectParameters() to adjust two parameters influencing
|
||||
the doppler effects intensity. */
|
||||
virtual void setVelocity(vec3df vel) = 0;
|
||||
|
||||
//! returns the velocity of the sound in 3d space, needed for Doppler effects.
|
||||
/** To use doppler effects use ISound::setVelocity to set a sounds velocity,
|
||||
ISoundEngine::setListenerPosition() to set the listeners velocity and
|
||||
ISoundEngine::setDopplerEffectParameters() to adjust two parameters influencing
|
||||
the doppler effects intensity. */
|
||||
virtual vec3df getVelocity() = 0;
|
||||
|
||||
//! returns the current play position of the sound in milliseconds.
|
||||
/** \return Returns -1 if not implemented or possible for this sound for example
|
||||
because it already has been stopped and freed internally or similar. */
|
||||
virtual ik_u32 getPlayPosition() = 0;
|
||||
|
||||
//! sets the current play position of the sound in milliseconds.
|
||||
/** \param pos Position in milliseconds. Must be between 0 and the value returned
|
||||
by getPlayPosition().
|
||||
\return Returns true successful. False is returned for example if the sound already finished
|
||||
playing and is stopped or the audio source is not seekable, for example if it
|
||||
is an internet stream or a a file format not supporting seeking (a .MOD file for example).
|
||||
A file can be tested if it can bee seeking using ISoundSource::getIsSeekingSupported(). */
|
||||
virtual bool setPlayPosition(ik_u32 pos) = 0;
|
||||
|
||||
//! Sets the playback speed (frequency) of the sound.
|
||||
/** Plays the sound at a higher or lower speed, increasing or decreasing its
|
||||
frequency which makes it sound lower or higher.
|
||||
Note that this feature is not available on all sound output drivers (it is on the
|
||||
DirectSound drivers at least), and it does not work together with the
|
||||
'enableSoundEffects' parameter of ISoundEngine::play2D and ISoundEngine::play3D when
|
||||
using DirectSound.
|
||||
\param speed Factor of the speed increase or decrease. 2 is twice as fast,
|
||||
0.5 is only half as fast. The default is 1.0.
|
||||
\return Returns true if sucessful, false if not. The current sound driver might not
|
||||
support changing the playBack speed, or the sound was started with the
|
||||
'enableSoundEffects' parameter. */
|
||||
virtual bool setPlaybackSpeed(ik_f32 speed = 1.0f) = 0;
|
||||
|
||||
//! Returns the playback speed set by setPlaybackSpeed(). Default: 1.0f.
|
||||
/** See setPlaybackSpeed() for details */
|
||||
virtual ik_f32 getPlaybackSpeed() = 0;
|
||||
|
||||
//! returns the play length of the sound in milliseconds.
|
||||
/** Returns -1 if not known for this sound for example because its decoder
|
||||
does not support length reporting or it is a file stream of unknown size.
|
||||
Note: You can also use ISoundSource::getPlayLength() to get the length of
|
||||
a sound without actually needing to play it. */
|
||||
virtual ik_u32 getPlayLength() = 0;
|
||||
|
||||
//! Returns the sound effect control interface for this sound.
|
||||
/** Sound effects such as Chorus, Distorsions, Echo, Reverb and similar can
|
||||
be controlled using this. The interface pointer is only valid as long as the ISound pointer is valid.
|
||||
If the ISound pointer gets dropped (IVirtualRefCounted::drop()), the ISoundEffects
|
||||
may not be used any more.
|
||||
\return Returns a pointer to the sound effects interface if available. The sound
|
||||
has to be started via ISoundEngine::play2D() or ISoundEngine::play3D(),
|
||||
with the flag enableSoundEffects=true, otherwise 0 will be returned. Note that
|
||||
if the output driver does not support sound effects, 0 will be returned as well.*/
|
||||
virtual ISoundEffectControl* getSoundEffectControl() = 0;
|
||||
|
||||
//! Sets the sound stop event receiver, an interface which gets called if a sound has finished playing.
|
||||
/** This event is guaranteed to be called when the sound or sound stream is finished,
|
||||
either because the sound reached its playback end, its sound source was removed,
|
||||
ISoundEngine::stopAllSounds() has been called or the whole engine was deleted.
|
||||
There is an example on how to use events in irrklang at @ref events .
|
||||
\param receiver Interface to a user implementation of the sound receiver. This interface
|
||||
should be as long valid as the sound exists or another stop event receiver is set.
|
||||
Set this to null to set no sound stop event receiver.
|
||||
\param userData: A iser data pointer, can be null. */
|
||||
virtual void setSoundStopEventReceiver(ISoundStopEventReceiver* reciever, void* userData=0) = 0;
|
||||
};
|
||||
|
||||
} // end namespace irrklang
|
||||
|
||||
|
||||
#endif
|
||||
@@ -1,41 +0,0 @@
|
||||
// Copyright (C) 2002-2018 Nikolaus Gebhardt
|
||||
// This file is part of the "irrKlang" library.
|
||||
// For conditions of distribution and use, see copyright notice in irrKlang.h
|
||||
|
||||
#ifndef __I_IRRKLANG_SOUND_DEVICE_LIST_H_INCLUDED__
|
||||
#define __I_IRRKLANG_SOUND_DEVICE_LIST_H_INCLUDED__
|
||||
|
||||
#include "ik_IRefCounted.h"
|
||||
|
||||
namespace irrklang
|
||||
{
|
||||
|
||||
//! A list of sound devices for a sound driver. Use irrklang::createSoundDeviceList() to create this list.
|
||||
/** The function createIrrKlangDevice() has a parameter 'deviceID' which takes the value returned by
|
||||
ISoundDeviceList::getDeviceID() and uses that device then.
|
||||
The list of devices in ISoundDeviceList usually also includes the default device which is the first
|
||||
entry and has an empty deviceID string ("") and the description "default device".
|
||||
There is some example code on how to use the ISoundDeviceList in @ref enumeratingDevices.*/
|
||||
class ISoundDeviceList : public IRefCounted
|
||||
{
|
||||
public:
|
||||
|
||||
//! Returns amount of enumerated devices in the list.
|
||||
virtual ik_s32 getDeviceCount() = 0;
|
||||
|
||||
//! Returns the ID of the device. Use this string to identify this device in createIrrKlangDevice().
|
||||
/** \param index Index of the device, a value between 0 and ISoundDeviceList::getDeviceCount()-1.
|
||||
\return Returns a pointer to a string identifying the device. The string will only as long valid
|
||||
as long as the ISoundDeviceList exists. */
|
||||
virtual const char* getDeviceID(ik_s32 index) = 0;
|
||||
|
||||
//! Returns description of the device.
|
||||
/** \param index Index of the device, a value between 0 and ISoundDeviceList::getDeviceCount()-1. */
|
||||
virtual const char* getDeviceDescription(ik_s32 index) = 0;
|
||||
};
|
||||
|
||||
|
||||
} // end namespace irrklang
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1,243 +0,0 @@
|
||||
// Copyright (C) 2002-2018 Nikolaus Gebhardt
|
||||
// This file is part of the "irrKlang" library.
|
||||
// For conditions of distribution and use, see copyright notice in irrKlang.h
|
||||
|
||||
#ifndef __I_IRRKLANG_SOUND_EFFECT_CONTROL_H_INCLUDED__
|
||||
#define __I_IRRKLANG_SOUND_EFFECT_CONTROL_H_INCLUDED__
|
||||
|
||||
#include "ik_IVirtualRefCounted.h"
|
||||
#include "ik_vec3d.h"
|
||||
|
||||
|
||||
namespace irrklang
|
||||
{
|
||||
//! Interface to control the active sound effects (echo, reverb,...) of an ISound object, a playing sound.
|
||||
/** Sound effects such as chorus, distorsions, echo, reverb and similar can
|
||||
be controlled using this. An instance of this interface can be obtained via
|
||||
ISound::getSoundEffectControl(). The sound containing this interface has to be started via
|
||||
ISoundEngine::play2D() or ISoundEngine::play3D() with the flag enableSoundEffects=true,
|
||||
otherwise no acccess to this interface will be available.
|
||||
For the DirectSound driver, these are effects available since DirectSound8. For most
|
||||
effects, sounds should have a sample rate of 44 khz and should be at least
|
||||
150 milli seconds long for optimal quality when using the DirectSound driver.
|
||||
Note that the interface pointer is only valid as long as
|
||||
the ISound pointer is valid. If the ISound pointer gets dropped (IVirtualRefCounted::drop()),
|
||||
the ISoundEffects may not be used any more. */
|
||||
class ISoundEffectControl
|
||||
{
|
||||
public:
|
||||
|
||||
//! Disables all active sound effects
|
||||
virtual void disableAllEffects() = 0;
|
||||
|
||||
//! Enables the chorus sound effect or adjusts its values.
|
||||
/** Chorus is a voice-doubling effect created by echoing the
|
||||
original sound with a slight delay and slightly modulating the delay of the echo.
|
||||
If this sound effect is already enabled, calling this only modifies the parameters of the active effect.
|
||||
\param fWetDryMix Ratio of wet (processed) signal to dry (unprocessed) signal. Minimal Value:0, Maximal Value:100.0f;
|
||||
\param fDepth Percentage by which the delay time is modulated by the low-frequency oscillator, in hundredths of a percentage point. Minimal Value:0, Maximal Value:100.0f;
|
||||
\param fFeedback Percentage of output signal to feed back into the effect's input. Minimal Value:-99, Maximal Value:99.0f;
|
||||
\param fFrequency Frequency of the LFO. Minimal Value:0, Maximal Value:10.0f;
|
||||
\param sinusWaveForm True for sinus wave form, false for triangle.
|
||||
\param fDelay Number of milliseconds the input is delayed before it is played back. Minimal Value:0, Maximal Value:20.0f;
|
||||
\param lPhase Phase differential between left and right LFOs. Possible values:
|
||||
-180, -90, 0, 90, 180
|
||||
\return Returns true if successful. */
|
||||
virtual bool enableChorusSoundEffect(ik_f32 fWetDryMix = 50,
|
||||
ik_f32 fDepth = 10,
|
||||
ik_f32 fFeedback = 25,
|
||||
ik_f32 fFrequency = 1.1,
|
||||
bool sinusWaveForm = true,
|
||||
ik_f32 fDelay = 16,
|
||||
ik_s32 lPhase = 90) = 0;
|
||||
|
||||
//! removes the sound effect from the sound
|
||||
virtual void disableChorusSoundEffect() = 0;
|
||||
|
||||
//! returns if the sound effect is active on the sound
|
||||
virtual bool isChorusSoundEffectEnabled() = 0;
|
||||
|
||||
//! Enables the Compressor sound effect or adjusts its values.
|
||||
/** Compressor is a reduction in the fluctuation of a signal above a certain amplitude.
|
||||
If this sound effect is already enabled, calling this only modifies the parameters of the active effect.
|
||||
\param fGain Output gain of signal after Compressor. Minimal Value:-60, Maximal Value:60.0f;
|
||||
\param fAttack Time before Compressor reaches its full value. Minimal Value:0.01, Maximal Value:500.0f;
|
||||
\param fRelease Speed at which Compressor is stopped after input drops below fThreshold. Minimal Value:50, Maximal Value:3000.0f;
|
||||
\param fThreshold Point at which Compressor begins, in decibels. Minimal Value:-60, Maximal Value:0.0f;
|
||||
\param fRatio Compressor ratio. Minimal Value:1, Maximal Value:100.0f;
|
||||
\param fPredelay Time after lThreshold is reached before attack phase is started, in milliseconds. Minimal Value:0, Maximal Value:4.0f;
|
||||
\return Returns true if successful. */
|
||||
virtual bool enableCompressorSoundEffect( ik_f32 fGain = 0,
|
||||
ik_f32 fAttack = 10,
|
||||
ik_f32 fRelease = 200,
|
||||
ik_f32 fThreshold = -20,
|
||||
ik_f32 fRatio = 3,
|
||||
ik_f32 fPredelay = 4) = 0;
|
||||
|
||||
//! removes the sound effect from the sound
|
||||
virtual void disableCompressorSoundEffect() = 0;
|
||||
|
||||
//! returns if the sound effect is active on the sound
|
||||
virtual bool isCompressorSoundEffectEnabled() = 0;
|
||||
|
||||
//! Enables the Distortion sound effect or adjusts its values.
|
||||
/** Distortion is achieved by adding harmonics to the signal in such a way that,
|
||||
If this sound effect is already enabled, calling this only modifies the parameters of the active effect.
|
||||
as the level increases, the top of the waveform becomes squared off or clipped.
|
||||
\param fGain Amount of signal change after distortion. Minimal Value:-60, Maximal Value:0;
|
||||
\param fEdge Percentage of distortion intensity. Minimal Value:0, Maximal Value:100;
|
||||
\param fPostEQCenterFrequency Center frequency of harmonic content addition. Minimal Value:100, Maximal Value:8000;
|
||||
\param fPostEQBandwidth Width of frequency band that determines range of harmonic content addition. Minimal Value:100, Maximal Value:8000;
|
||||
\param fPreLowpassCutoff Filter cutoff for high-frequency harmonics attenuation. Minimal Value:100, Maximal Value:8000;
|
||||
\return Returns true if successful. */
|
||||
virtual bool enableDistortionSoundEffect(ik_f32 fGain = -18,
|
||||
ik_f32 fEdge = 15,
|
||||
ik_f32 fPostEQCenterFrequency = 2400,
|
||||
ik_f32 fPostEQBandwidth = 2400,
|
||||
ik_f32 fPreLowpassCutoff = 8000) = 0;
|
||||
|
||||
//! removes the sound effect from the sound
|
||||
virtual void disableDistortionSoundEffect() = 0;
|
||||
|
||||
//! returns if the sound effect is active on the sound
|
||||
virtual bool isDistortionSoundEffectEnabled() = 0;
|
||||
|
||||
//! Enables the Echo sound effect or adjusts its values.
|
||||
/** An echo effect causes an entire sound to be repeated after a fixed delay.
|
||||
If this sound effect is already enabled, calling this only modifies the parameters of the active effect.
|
||||
\param fWetDryMix Ratio of wet (processed) signal to dry (unprocessed) signal. Minimal Value:0, Maximal Value:100.0f;
|
||||
\param fFeedback Percentage of output fed back into input. Minimal Value:0, Maximal Value:100.0f;
|
||||
\param fLeftDelay Delay for left channel, in milliseconds. Minimal Value:1, Maximal Value:2000.0f;
|
||||
\param fRightDelay Delay for right channel, in milliseconds. Minimal Value:1, Maximal Value:2000.0f;
|
||||
\param lPanDelay Value that specifies whether to swap left and right delays with each successive echo. Minimal Value:0, Maximal Value:1;
|
||||
\return Returns true if successful. */
|
||||
virtual bool enableEchoSoundEffect(ik_f32 fWetDryMix = 50,
|
||||
ik_f32 fFeedback = 50,
|
||||
ik_f32 fLeftDelay = 500,
|
||||
ik_f32 fRightDelay = 500,
|
||||
ik_s32 lPanDelay = 0) = 0;
|
||||
|
||||
//! removes the sound effect from the sound
|
||||
virtual void disableEchoSoundEffect() = 0;
|
||||
|
||||
//! returns if the sound effect is active on the sound
|
||||
virtual bool isEchoSoundEffectEnabled() = 0;
|
||||
|
||||
//! Enables the Flanger sound effect or adjusts its values.
|
||||
/** Flange is an echo effect in which the delay between the original
|
||||
signal and its echo is very short and varies over time. The result is
|
||||
sometimes referred to as a sweeping sound. The term flange originated
|
||||
with the practice of grabbing the flanges of a tape reel to change the speed.
|
||||
If this sound effect is already enabled, calling this only modifies the parameters of the active effect.
|
||||
\param fWetDryMix Ratio of wet (processed) signal to dry (unprocessed) signal. Minimal Value:0, Maximal Value:100.0f;
|
||||
\param fDepth Percentage by which the delay time is modulated by the low-frequency oscillator, in hundredths of a percentage point. Minimal Value:0, Maximal Value:100.0f;
|
||||
\param fFeedback Percentage of output signal to feed back into the effect's input. Minimal Value:-99, Maximal Value:99.0f;
|
||||
\param fFrequency Frequency of the LFO. Minimal Value:0, Maximal Value:10.0f;
|
||||
\param triangleWaveForm True for triangle wave form, false for square.
|
||||
\param fDelay Number of milliseconds the input is delayed before it is played back. Minimal Value:0, Maximal Value:20.0f;
|
||||
\param lPhase Phase differential between left and right LFOs. Possible values:
|
||||
-180, -90, 0, 90, 180
|
||||
\return Returns true if successful. */
|
||||
virtual bool enableFlangerSoundEffect(ik_f32 fWetDryMix = 50,
|
||||
ik_f32 fDepth = 100,
|
||||
ik_f32 fFeedback = -50,
|
||||
ik_f32 fFrequency = 0.25f,
|
||||
bool triangleWaveForm = true,
|
||||
ik_f32 fDelay = 2,
|
||||
ik_s32 lPhase = 0) = 0;
|
||||
|
||||
//! removes the sound effect from the sound
|
||||
virtual void disableFlangerSoundEffect() = 0;
|
||||
|
||||
//! returns if the sound effect is active on the sound
|
||||
virtual bool isFlangerSoundEffectEnabled() = 0;
|
||||
|
||||
//! Enables the Gargle sound effect or adjusts its values.
|
||||
/** The gargle effect modulates the amplitude of the signal.
|
||||
If this sound effect is already enabled, calling this only modifies the parameters of the active effect.
|
||||
\param rateHz Rate of modulation, in Hertz. Minimal Value:1, Maximal Value:1000
|
||||
\param sinusWaveForm True for sinus wave form, false for triangle.
|
||||
\return Returns true if successful. */
|
||||
virtual bool enableGargleSoundEffect(ik_s32 rateHz = 20, bool sinusWaveForm = true) = 0;
|
||||
|
||||
//! removes the sound effect from the sound
|
||||
virtual void disableGargleSoundEffect() = 0;
|
||||
|
||||
//! returns if the sound effect is active on the sound
|
||||
virtual bool isGargleSoundEffectEnabled() = 0;
|
||||
|
||||
//! Enables the Interactive 3D Level 2 reverb sound effect or adjusts its values.
|
||||
/** An implementation of the listener properties in the I3DL2 specification. Source properties are not supported.
|
||||
If this sound effect is already enabled, calling this only modifies the parameters of the active effect.
|
||||
\param lRoom Attenuation of the room effect, in millibels (mB). Interval: [-10000, 0] Default: -1000 mB
|
||||
\param lRoomHF Attenuation of the room high-frequency effect. Interval: [-10000, 0] default: 0 mB
|
||||
\param flRoomRolloffFactor Rolloff factor for the reflected signals. Interval: [0.0, 10.0] default: 0.0
|
||||
\param flDecayTime Decay time, in seconds. Interval: [0.1, 20.0] default: 1.49s
|
||||
\param flDecayHFRatio Ratio of the decay time at high frequencies to the decay time at low frequencies. Interval: [0.1, 2.0] default: 0.83
|
||||
\param lReflections Attenuation of early reflections relative to lRoom. Interval: [-10000, 1000] default: -2602 mB
|
||||
\param flReflectionsDelay Delay time of the first reflection relative to the direct path in seconds. Interval: [0.0, 0.3] default: 0.007 s
|
||||
\param lReverb Attenuation of late reverberation relative to lRoom, in mB. Interval: [-10000, 2000] default: 200 mB
|
||||
\param flReverbDelay Time limit between the early reflections and the late reverberation relative to the time of the first reflection. Interval: [0.0, 0.1] default: 0.011 s
|
||||
\param flDiffusion Echo density in the late reverberation decay in percent. Interval: [0.0, 100.0] default: 100.0 %
|
||||
\param flDensity Modal density in the late reverberation decay, in percent. Interval: [0.0, 100.0] default: 100.0 %
|
||||
\param flHFReference Reference high frequency, in hertz. Interval: [20.0, 20000.0] default: 5000.0 Hz
|
||||
\return Returns true if successful. */
|
||||
virtual bool enableI3DL2ReverbSoundEffect(ik_s32 lRoom = -1000,
|
||||
ik_s32 lRoomHF = -100,
|
||||
ik_f32 flRoomRolloffFactor = 0,
|
||||
ik_f32 flDecayTime = 1.49f,
|
||||
ik_f32 flDecayHFRatio = 0.83f,
|
||||
ik_s32 lReflections = -2602,
|
||||
ik_f32 flReflectionsDelay = 0.007f,
|
||||
ik_s32 lReverb = 200,
|
||||
ik_f32 flReverbDelay = 0.011f,
|
||||
ik_f32 flDiffusion = 100.0f,
|
||||
ik_f32 flDensity = 100.0f,
|
||||
ik_f32 flHFReference = 5000.0f ) = 0;
|
||||
|
||||
//! removes the sound effect from the sound
|
||||
virtual void disableI3DL2ReverbSoundEffect() = 0;
|
||||
|
||||
//! returns if the sound effect is active on the sound
|
||||
virtual bool isI3DL2ReverbSoundEffectEnabled() = 0;
|
||||
|
||||
//! Enables the ParamEq sound effect or adjusts its values.
|
||||
/** Parametric equalizer amplifies or attenuates signals of a given frequency.
|
||||
If this sound effect is already enabled, calling this only modifies the parameters of the active effect.
|
||||
\param fCenter Center frequency, in hertz, The default value is 8000. Minimal Value:80, Maximal Value:16000.0f
|
||||
\param fBandwidth Bandwidth, in semitones, The default value is 12. Minimal Value:1.0f, Maximal Value:36.0f
|
||||
\param fGain Gain, default value is 0. Minimal Value:-15.0f, Maximal Value:15.0f
|
||||
\return Returns true if successful. */
|
||||
virtual bool enableParamEqSoundEffect(ik_f32 fCenter = 8000,
|
||||
ik_f32 fBandwidth = 12,
|
||||
ik_f32 fGain = 0) = 0;
|
||||
|
||||
//! removes the sound effect from the sound
|
||||
virtual void disableParamEqSoundEffect() = 0;
|
||||
|
||||
//! returns if the sound effect is active on the sound
|
||||
virtual bool isParamEqSoundEffectEnabled() = 0;
|
||||
|
||||
//! Enables the Waves Reverb sound effect or adjusts its values.
|
||||
/** \param fInGain Input gain of signal, in decibels (dB). Min/Max: [-96.0,0.0] Default: 0.0 dB.
|
||||
If this sound effect is already enabled, calling this only modifies the parameters of the active effect.
|
||||
\param fReverbMix Reverb mix, in dB. Min/Max: [-96.0,0.0] Default: 0.0 dB
|
||||
\param fReverbTime Reverb time, in milliseconds. Min/Max: [0.001,3000.0] Default: 1000.0 ms
|
||||
\param fHighFreqRTRatio High-frequency reverb time ratio. Min/Max: [0.001,0.999] Default: 0.001
|
||||
\return Returns true if successful. */
|
||||
virtual bool enableWavesReverbSoundEffect(ik_f32 fInGain = 0,
|
||||
ik_f32 fReverbMix = 0,
|
||||
ik_f32 fReverbTime = 1000,
|
||||
ik_f32 fHighFreqRTRatio = 0.001f) = 0;
|
||||
|
||||
//! removes the sound effect from the sound
|
||||
virtual void disableWavesReverbSoundEffect() = 0;
|
||||
|
||||
//! returns if the sound effect is active on the sound
|
||||
virtual bool isWavesReverbSoundEffectEnabled() = 0;
|
||||
};
|
||||
|
||||
} // end namespace irrklang
|
||||
|
||||
|
||||
#endif
|
||||
@@ -1,436 +0,0 @@
|
||||
// Copyright (C) 2002-2018 Nikolaus Gebhardt
|
||||
// This file is part of the "irrKlang" library.
|
||||
// For conditions of distribution and use, see copyright notice in irrKlang.h
|
||||
|
||||
#ifndef __I_IRRKLANG_SOUND_ENGINE_H_INCLUDED__
|
||||
#define __I_IRRKLANG_SOUND_ENGINE_H_INCLUDED__
|
||||
|
||||
#include "ik_IRefCounted.h"
|
||||
#include "ik_vec3d.h"
|
||||
#include "ik_ISoundSource.h"
|
||||
#include "ik_ISound.h"
|
||||
#include "ik_EStreamModes.h"
|
||||
#include "ik_IFileFactory.h"
|
||||
#include "ik_ISoundMixedOutputReceiver.h"
|
||||
|
||||
|
||||
namespace irrklang
|
||||
{
|
||||
class IAudioStreamLoader;
|
||||
struct SInternalAudioInterface;
|
||||
|
||||
//! Interface to the sound engine, for playing 3d and 2d sound and music.
|
||||
/** This is the main interface of irrKlang. You usually would create this using
|
||||
the createIrrKlangDevice() function.
|
||||
*/
|
||||
class ISoundEngine : public virtual irrklang::IRefCounted
|
||||
{
|
||||
public:
|
||||
|
||||
//! returns the name of the sound driver, like 'ALSA' for the alsa device
|
||||
/** Possible returned strings are "NULL", "ALSA", "CoreAudio", "winMM",
|
||||
"DirectSound" and "DirectSound8". */
|
||||
virtual const char* getDriverName() = 0;
|
||||
|
||||
//! loads a sound source (if not loaded already) from a file and plays it.
|
||||
/** \param sourceFileName Filename of sound, like "sounds/test.wav" or "foobar.ogg".
|
||||
\param playLooped plays the sound in loop mode. If set to 'false', the sound is played once, then stopped and deleted from the internal playing list. Calls to
|
||||
ISound have no effect after such a non looped sound has been stopped automaticly.
|
||||
\param startPaused starts the sound paused. This implies that track=true. Use this if you want to modify some of the playing
|
||||
parameters before the sound actually plays. Usually you would set this parameter to true, then use the ISound interface to
|
||||
modify some of the sound parameters and then call ISound::setPaused(false);
|
||||
Note: You need to call ISound::drop() when setting this parameter to true and you don't need the ISound
|
||||
object anymore. See 'return' for details.
|
||||
\param track Makes it possible to track the sound. Causes the method to return an ISound interface. See 'return' for details.
|
||||
\param streamMode Specifies if the file should be streamed or loaded completely into memory for playing.
|
||||
ESM_AUTO_DETECT sets this to autodetection. Note: if the sound has been loaded or played before into the
|
||||
engine, this parameter has no effect.
|
||||
\param enableSoundEffects Makes it possible to use sound effects such as chorus, distorsions, echo,
|
||||
reverb and similar for this sound. Sound effects can then be controlled via ISound::getSoundEffectControl().
|
||||
Only enable if necessary.
|
||||
\return Only returns a pointer to an ISound if the parameters 'track', 'startPaused' or
|
||||
'enableSoundEffects' have been set to true. Note: if this method returns an ISound as result,
|
||||
you HAVE to call ISound::drop() after you don't need the ISound interface anymore. Otherwise this
|
||||
will cause memory waste. This method also may return 0 altough 'track', 'startPaused' or
|
||||
'enableSoundEffects' have been set to true, if the sound could not be played.*/
|
||||
virtual ISound* play2D(const char* soundFileName,
|
||||
bool playLooped = false,
|
||||
bool startPaused = false,
|
||||
bool track = false,
|
||||
E_STREAM_MODE streamMode = ESM_AUTO_DETECT,
|
||||
bool enableSoundEffects = false) = 0;
|
||||
|
||||
//! Plays a sound source as 2D sound with its default settings stored in ISoundSource.
|
||||
/** An ISoundSource object will be created internally when playing a sound the first time,
|
||||
or can be added with getSoundSource().
|
||||
\param source The sound source, specifiying sound file source and default settings for this file.
|
||||
Use the other ISoundEngine::play2D() overloads if you want to specify a filename string instead of this.
|
||||
\param playLooped plays the sound in loop mode. If set to 'false', the sound is played once, then stopped and deleted from the internal playing list. Calls to
|
||||
ISound have no effect after such a non looped sound has been stopped automaticly.
|
||||
\param startPaused starts the sound paused. This implies that track=true. Use this if you want to modify some of the playing
|
||||
parameters before the sound actually plays. Usually you would set this parameter to true, then use the ISound interface to
|
||||
modify some of the sound parameters and then call ISound::setPaused(false);
|
||||
Note: You need to call ISound::drop() when setting this parameter to true and you don't need the ISound
|
||||
object anymore. See 'return' for details.
|
||||
\param track Makes it possible to track the sound. Causes the method to return an ISound interface. See 'return' for details.
|
||||
\param enableSoundEffects Makes it possible to use sound effects such as chorus, distorsions, echo,
|
||||
reverb and similar for this sound. Sound effects can then be controlled via ISound::getSoundEffectControl().
|
||||
Only enable if necessary.
|
||||
\return Only returns a pointer to an ISound if the parameters 'track', 'startPaused' or
|
||||
'enableSoundEffects' have been set to true. Note: if this method returns an ISound as result,
|
||||
you HAVE to call ISound::drop() after you don't need the ISound interface anymore. Otherwise this
|
||||
will cause memory waste. This method also may return 0 altough 'track', 'startPaused' or
|
||||
'enableSoundEffects' have been set to true, if the sound could not be played.*/
|
||||
virtual ISound* play2D(ISoundSource* source,
|
||||
bool playLooped = false,
|
||||
bool startPaused = false,
|
||||
bool track = false,
|
||||
bool enableSoundEffects = false) = 0;
|
||||
|
||||
//! Loads a sound source (if not loaded already) from a file and plays it as 3D sound.
|
||||
/** There is some example code on how to work with 3D sound at @ref sound3d.
|
||||
\param sourceFileName Filename of sound, like "sounds/test.wav" or "foobar.ogg".
|
||||
\param pos Position of the 3D sound.
|
||||
\param playLooped plays the sound in loop mode. If set to 'false', the sound is played once, then stopped and deleted from the internal playing list. Calls to
|
||||
ISound have no effect after such a non looped sound has been stopped automaticly.
|
||||
\param startPaused starts the sound paused. This implies that track=true. Use this if you want to modify some of the playing
|
||||
parameters before the sound actually plays. Usually you would set this parameter to true, then use the ISound interface to
|
||||
modify some of the sound parameters and then call ISound::setPaused(false);
|
||||
Note: You need to call ISound::drop() when setting this parameter to true and you don't need the ISound
|
||||
object anymore. See 'return' for details.
|
||||
\param track Makes it possible to track the sound. Causes the method to return an ISound interface. See 'return' for details.
|
||||
\param streamMode Specifies if the file should be streamed or loaded completely into memory for playing.
|
||||
ESM_AUTO_DETECT sets this to autodetection. Note: if the sound has been loaded or played before into the
|
||||
engine, this parameter has no effect.
|
||||
\param enableSoundEffects Makes it possible to use sound effects such as chorus, distorsions, echo,
|
||||
reverb and similar for this sound. Sound effects can then be controlled via ISound::getSoundEffectControl().
|
||||
Only enable if necessary.
|
||||
\return Only returns a pointer to an ISound if the parameters 'track', 'startPaused' or
|
||||
'enableSoundEffects' have been set to true. Note: if this method returns an ISound as result,
|
||||
you HAVE to call ISound::drop() after you don't need the ISound interface anymore. Otherwise this
|
||||
will cause memory waste. This method also may return 0 altough 'track', 'startPaused' or
|
||||
'enableSoundEffects' have been set to true, if the sound could not be played.*/
|
||||
virtual ISound* play3D(const char* soundFileName, vec3df pos,
|
||||
bool playLooped = false,
|
||||
bool startPaused = false,
|
||||
bool track = false,
|
||||
E_STREAM_MODE streamMode = ESM_AUTO_DETECT,
|
||||
bool enableSoundEffects = false) = 0;
|
||||
|
||||
//! Plays a sound source as 3D sound with its default settings stored in ISoundSource.
|
||||
/** An ISoundSource object will be created internally when playing a sound the first time,
|
||||
or can be added with getSoundSource(). There is some example code on how to work with 3D sound @ref sound3d.
|
||||
\param source The sound source, specifiying sound file source and default settings for this file.
|
||||
Use the other ISoundEngine::play2D() overloads if you want to specify a filename string instead of this.
|
||||
\param pos Position of the 3D sound.
|
||||
\param playLooped plays the sound in loop mode. If set to 'false', the sound is played once, then stopped and deleted from the internal playing list. Calls to
|
||||
ISound have no effect after such a non looped sound has been stopped automaticly.
|
||||
\param startPaused starts the sound paused. This implies that track=true. Use this if you want to modify some of the playing
|
||||
parameters before the sound actually plays. Usually you would set this parameter to true, then use the ISound interface to
|
||||
modify some of the sound parameters and then call ISound::setPaused(false);
|
||||
Note: You need to call ISound::drop() when setting this parameter to true and you don't need the ISound
|
||||
object anymore. See 'return' for details.
|
||||
\param track Makes it possible to track the sound. Causes the method to return an ISound interface. See 'return' for details.
|
||||
\param enableSoundEffects Makes it possible to use sound effects such as chorus, distorsions, echo,
|
||||
reverb and similar for this sound. Sound effects can then be controlled via ISound::getSoundEffectControl().
|
||||
Only enable if necessary.
|
||||
\return Only returns a pointer to an ISound if the parameters 'track', 'startPaused' or
|
||||
'enableSoundEffects' have been set to true. Note: if this method returns an ISound as result,
|
||||
you HAVE to call ISound::drop() after you don't need the ISound interface anymore. Otherwise this
|
||||
will cause memory waste. This method also may return 0 altough 'track', 'startPaused' or
|
||||
'enableSoundEffects' have been set to true, if the sound could not be played.*/
|
||||
virtual ISound* play3D(ISoundSource* source, vec3df pos,
|
||||
bool playLooped = false,
|
||||
bool startPaused = false,
|
||||
bool track = false,
|
||||
bool enableSoundEffects = false) = 0;
|
||||
|
||||
//! Stops all currently playing sounds.
|
||||
virtual void stopAllSounds() = 0;
|
||||
|
||||
//! Pauses or unpauses all currently playing sounds.
|
||||
virtual void setAllSoundsPaused( bool bPaused = true ) = 0;
|
||||
|
||||
//! Gets a sound source by sound name. Adds the sound source as file into the sound engine if not loaded already.
|
||||
/** Please note: For performance reasons most ISoundEngine implementations will
|
||||
not try to load the sound when calling this method, but only when play() is called
|
||||
with this sound source as parameter.
|
||||
\param addIfNotFound if 'true' adds the sound source to the list and returns the interface to it
|
||||
if it cannot be found in the sound source list. If 'false', returns 0 if the sound
|
||||
source is not in the list and does not modify the list. Default value: true.
|
||||
\return Returns the sound source or 0 if not available.
|
||||
Note: Don't call drop() to this pointer, it will be managed by irrKlang and
|
||||
exist as long as you don't delete irrKlang or call removeSoundSource(). However,
|
||||
you are free to call grab() if you want and drop() it then later of course. */
|
||||
virtual ISoundSource* getSoundSource(const ik_c8* soundName, bool addIfNotFound=true) = 0;
|
||||
|
||||
//! Returns a sound source by index.
|
||||
/** \param idx: Index of the loaded sound source, must by smaller than getSoundSourceCount().
|
||||
\return Returns the sound source or 0 if not available.
|
||||
Note: Don't call drop() to this pointer, it will be managed by irrKlang and
|
||||
exist as long as you don't delete irrKlang or call removeSoundSource(). However,
|
||||
you are free to call grab() if you want and drop() it then later of course. */
|
||||
virtual ISoundSource* getSoundSource(ik_s32 index) = 0;
|
||||
|
||||
//! Returns amount of loaded sound sources.
|
||||
virtual ik_s32 getSoundSourceCount() = 0;
|
||||
|
||||
//! Adds sound source into the sound engine as file.
|
||||
/** \param fileName Name of the sound file (e.g. "sounds/something.mp3"). You can also use this
|
||||
name when calling play3D() or play2D().
|
||||
\param mode Streaming mode for this sound source
|
||||
\param preload If this flag is set to false (which is default) the sound engine will
|
||||
not try to load the sound file when calling this method, but only when play() is called
|
||||
with this sound source as parameter. Otherwise the sound will be preloaded.
|
||||
\return Returns the pointer to the added sound source or 0 if not sucessful because for
|
||||
example a sound already existed with that name. If not successful, the reason will be printed
|
||||
into the log. Note: Don't call drop() to this pointer, it will be managed by irrKlang and
|
||||
exist as long as you don't delete irrKlang or call removeSoundSource(). However,
|
||||
you are free to call grab() if you want and drop() it then later of course. */
|
||||
virtual ISoundSource* addSoundSourceFromFile(const ik_c8* fileName, E_STREAM_MODE mode=ESM_AUTO_DETECT,
|
||||
bool preload=false) = 0;
|
||||
|
||||
//! Adds a sound source into the sound engine as memory source.
|
||||
/** Note: This method only accepts a file (.wav, .ogg, etc) which is totally loaded into memory.
|
||||
If you want to add a sound source from decoded plain PCM data in memory, use addSoundSourceFromPCMData() instead.
|
||||
\param memory Pointer to the memory to be treated as loaded sound file.
|
||||
\param sizeInBytes Size of the memory chunk, in bytes.
|
||||
\param soundName Name of the virtual sound file (e.g. "sounds/something.mp3"). You can also use this
|
||||
name when calling play3D() or play2D(). Hint: If you include the extension of the original file
|
||||
like .ogg, .mp3 or .wav at the end of the filename, irrKlang will be able to decide better what
|
||||
file format it is and might be able to start playback faster.
|
||||
\param copyMemory If set to true which is default, the memory block is copied
|
||||
and stored in the engine, after calling addSoundSourceFromMemory() the memory pointer can be deleted
|
||||
savely. If set to false, the memory is not copied and the user takes the responsibility that
|
||||
the memory block pointed to remains there as long as the sound engine or at least this sound
|
||||
source exists.
|
||||
\return Returns the pointer to the added sound source or 0 if not sucessful because for example a sound already
|
||||
existed with that name. If not successful, the reason will be printed into the log.
|
||||
Note: Don't call drop() to this pointer, it will be managed by irrKlang and exist as long as you don't
|
||||
delete irrKlang or call removeSoundSource(). However, you are free to call grab() if you
|
||||
want and drop() it then later of course. */
|
||||
virtual ISoundSource* addSoundSourceFromMemory(void* memory, ik_s32 sizeInBytes, const ik_c8* soundName,
|
||||
bool copyMemory=true) = 0;
|
||||
|
||||
|
||||
//! Adds a sound source into the sound engine from plain PCM data in memory.
|
||||
/** \param memory Pointer to the memory to be treated as loaded sound file.
|
||||
\param sizeInBytes Size of the memory chunk, in bytes.
|
||||
\param soundName Name of the virtual sound file (e.g. "sounds/something.mp3"). You can also use this
|
||||
name when calling play3D() or play2D().
|
||||
\param copyMemory If set to true which is default, the memory block is copied
|
||||
and stored in the engine, after calling addSoundSourceFromPCMData() the memory pointer can be deleted
|
||||
savely. If set to true, the memory is not copied and the user takes the responsibility that
|
||||
the memory block pointed to remains there as long as the sound engine or at least this sound
|
||||
source exists.
|
||||
\return Returns the pointer to the added sound source or 0 if not sucessful because for
|
||||
example a sound already existed with that name. If not successful, the reason will be printed
|
||||
into the log. */
|
||||
virtual ISoundSource* addSoundSourceFromPCMData(void* memory, ik_s32 sizeInBytes,
|
||||
const ik_c8* soundName, SAudioStreamFormat format,
|
||||
bool copyMemory=true) = 0;
|
||||
|
||||
//! Adds a sound source as alias for an existing sound source, but with a different name or optional different default settings.
|
||||
/** This is useful if you want to play multiple sounds but each sound isn't necessarily one single file.
|
||||
Also useful if you want to or play the same sound using different names, volumes or min and max 3D distances.
|
||||
\param baseSource The sound source where this sound source should be based on. This sound
|
||||
source will use the baseSource as base to access the file and similar, but it will have its
|
||||
own name and its own default settings.
|
||||
\param soundName Name of the new sound source to be added.
|
||||
\return Returns the pointer to the added sound source or 0 if not sucessful because for
|
||||
example a sound already existed with that name. If not successful, the reason will be printed
|
||||
into the log.*/
|
||||
virtual ISoundSource* addSoundSourceAlias(ISoundSource* baseSource, const ik_c8* soundName) = 0;
|
||||
|
||||
//! Removes a sound source from the engine, freeing the memory it occupies.
|
||||
/** This will also cause all currently playing sounds of this source to be stopped.
|
||||
Also note that if the source has been removed successfully, the value returned
|
||||
by getSoundSourceCount() will have been decreased by one.
|
||||
Removing sound sources is only necessary if you know you won't use a lot of non-streamed
|
||||
sounds again. Sound sources of streamed sounds do not cost a lot of memory.*/
|
||||
virtual void removeSoundSource(ISoundSource* source) = 0;
|
||||
|
||||
//! Removes a sound source from the engine, freeing the memory it occupies.
|
||||
/** This will also cause all currently playing sounds of this source to be stopped.
|
||||
Also note that if the source has been removed successfully, the value returned
|
||||
by getSoundSourceCount() will have been decreased by one.
|
||||
Removing sound sources is only necessary if you know you won't use a lot of non-streamed
|
||||
sounds again. Sound sources of streamed sounds do not cost a lot of memory. */
|
||||
virtual void removeSoundSource(const ik_c8* name) = 0;
|
||||
|
||||
//! Removes all sound sources from the engine
|
||||
/** This will also cause all sounds to be stopped.
|
||||
Removing sound sources is only necessary if you know you won't use a lot of non-streamed
|
||||
sounds again. Sound sources of streamed sounds do not cost a lot of memory. */
|
||||
virtual void removeAllSoundSources() = 0;
|
||||
|
||||
//! Sets master sound volume. This value is multiplied with all sounds played.
|
||||
/** \param volume 0 (silent) to 1.0f (full volume) */
|
||||
virtual void setSoundVolume(ik_f32 volume) = 0;
|
||||
|
||||
//! Returns master sound volume.
|
||||
/* A value between 0.0 and 1.0. Default is 1.0. Can be changed using setSoundVolume(). */
|
||||
virtual ik_f32 getSoundVolume() = 0;
|
||||
|
||||
//! Sets the current listener 3d position.
|
||||
/** When playing sounds in 3D, updating the position of the listener every frame should be
|
||||
done using this function.
|
||||
\param pos Position of the camera or listener.
|
||||
\param lookdir Direction vector where the camera or listener is looking into. If you have a
|
||||
camera position and a target 3d point where it is looking at, this would be cam->getTarget() - cam->getAbsolutePosition().
|
||||
\param velPerSecond The velocity per second describes the speed of the listener and
|
||||
is only needed for doppler effects.
|
||||
\param upvector Vector pointing 'up', so the engine can decide where is left and right.
|
||||
This vector is usually (0,1,0).*/
|
||||
virtual void setListenerPosition(const vec3df& pos,
|
||||
const vec3df& lookdir,
|
||||
const vec3df& velPerSecond = vec3df(0,0,0),
|
||||
const vec3df& upVector = vec3df(0,1,0)) = 0;
|
||||
|
||||
//! Updates the audio engine. This should be called several times per frame if irrKlang was started in single thread mode.
|
||||
/** This updates the 3d positions of the sounds as well as their volumes, effects,
|
||||
streams and other stuff. Call this several times per frame (the more the better) if you
|
||||
specified irrKlang to run single threaded. Otherwise it is not necessary to use this method.
|
||||
This method is being called by the scene manager automaticly if you are using one, so
|
||||
you might want to ignore this. */
|
||||
virtual void update() = 0;
|
||||
|
||||
//! Returns if a sound with the specified name is currently playing.
|
||||
virtual bool isCurrentlyPlaying(const char* soundName) = 0;
|
||||
|
||||
//! Returns if a sound with the specified source is currently playing.
|
||||
virtual bool isCurrentlyPlaying(ISoundSource* source) = 0;
|
||||
|
||||
//! Stops all sounds of a specific sound source
|
||||
virtual void stopAllSoundsOfSoundSource(ISoundSource* source) = 0;
|
||||
|
||||
//! Registers a new audio stream loader in the sound engine.
|
||||
/** Use this to enhance the audio engine to support other or new file formats.
|
||||
To do this, implement your own IAudioStreamLoader interface and register it
|
||||
with this method */
|
||||
virtual void registerAudioStreamLoader(IAudioStreamLoader* loader) = 0;
|
||||
|
||||
//! Returns if irrKlang is running in the same thread as the application or is using multithreading.
|
||||
/** This basicly returns the flag set by the user when creating the sound engine.*/
|
||||
virtual bool isMultiThreaded() const = 0;
|
||||
|
||||
//! Adds a file factory to the sound engine, making it possible to override file access of the sound engine.
|
||||
/** Derive your own class from IFileFactory, overwrite the createFileReader()
|
||||
method and return your own implemented IFileReader to overwrite file access of irrKlang. */
|
||||
virtual void addFileFactory(IFileFactory* fileFactory) = 0;
|
||||
|
||||
//! Sets the default minimal distance for 3D sounds.
|
||||
/** This value influences how loud a sound is heard based on its distance.
|
||||
See ISound::setMinDistance() for details about what the min distance is.
|
||||
It is also possible to influence this default value for every sound file
|
||||
using ISoundSource::setDefaultMinDistance().
|
||||
This method only influences the initial distance value of sounds. For changing the
|
||||
distance after the sound has been started to play, use ISound::setMinDistance() and ISound::setMaxDistance().
|
||||
\param minDistance Default minimal distance for 3d sounds. The default value is 1.0f.*/
|
||||
virtual void setDefault3DSoundMinDistance(ik_f32 minDistance) = 0;
|
||||
|
||||
//! Returns the default minimal distance for 3D sounds.
|
||||
/** This value influences how loud a sound is heard based on its distance.
|
||||
You can change it using setDefault3DSoundMinDistance().
|
||||
See ISound::setMinDistance() for details about what the min distance is.
|
||||
It is also possible to influence this default value for every sound file
|
||||
using ISoundSource::setDefaultMinDistance().
|
||||
\return Default minimal distance for 3d sounds. The default value is 1.0f. */
|
||||
virtual ik_f32 getDefault3DSoundMinDistance() = 0;
|
||||
|
||||
//! Sets the default maximal distance for 3D sounds.
|
||||
/** Changing this value is usually not necessary. Use setDefault3DSoundMinDistance() instead.
|
||||
Don't change this value if you don't know what you are doing: This value causes the sound
|
||||
to stop attenuating after it reaches the max distance. Most people think that this sets the
|
||||
volume of the sound to 0 after this distance, but this is not true. Only change the
|
||||
minimal distance (using for example setDefault3DSoundMinDistance()) to influence this.
|
||||
See ISound::setMaxDistance() for details about what the max distance is.
|
||||
It is also possible to influence this default value for every sound file
|
||||
using ISoundSource::setDefaultMaxDistance().
|
||||
This method only influences the initial distance value of sounds. For changing the
|
||||
distance after the sound has been started to play, use ISound::setMinDistance() and ISound::setMaxDistance().
|
||||
\param maxDistance Default maximal distance for 3d sounds. The default value is 1000000000.0f. */
|
||||
virtual void setDefault3DSoundMaxDistance(ik_f32 maxDistance) = 0;
|
||||
|
||||
//! Returns the default maximal distance for 3D sounds.
|
||||
/** This value influences how loud a sound is heard based on its distance.
|
||||
You can change it using setDefault3DSoundmaxDistance(), but
|
||||
changing this value is usually not necessary. This value causes the sound
|
||||
to stop attenuating after it reaches the max distance. Most people think that this sets the
|
||||
volume of the sound to 0 after this distance, but this is not true. Only change the
|
||||
minimal distance (using for example setDefault3DSoundMinDistance()) to influence this.
|
||||
See ISound::setMaxDistance() for details about what the max distance is.
|
||||
It is also possible to influence this default value for every sound file
|
||||
using ISoundSource::setDefaultMaxDistance().
|
||||
\return Default maximal distance for 3d sounds. The default value is 1000000000.0f. */
|
||||
virtual ik_f32 getDefault3DSoundMaxDistance() = 0;
|
||||
|
||||
//! Sets a rolloff factor which influences the amount of attenuation that is applied to 3D sounds.
|
||||
/** The rolloff factor can range from 0.0 to 10.0, where 0 is no rolloff. 1.0 is the default
|
||||
rolloff factor set, the value which we also experience in the real world. A value of 2 would mean
|
||||
twice the real-world rolloff. */
|
||||
virtual void setRolloffFactor(ik_f32 rolloff) = 0;
|
||||
|
||||
//! Sets parameters affecting the doppler effect.
|
||||
/** \param dopplerFactor is a value between 0 and 10 which multiplies the doppler
|
||||
effect. Default value is 1.0, which is the real world doppler effect, and 10.0f
|
||||
would be ten times the real world doppler effect.
|
||||
\param distanceFactor is the number of meters in a vector unit. The default value
|
||||
is 1.0. Doppler effects are calculated in meters per second, with this parameter,
|
||||
this can be changed, all velocities and positions are influenced by this. If
|
||||
the measurement should be in foot instead of meters, set this value to 0.3048f
|
||||
for example.*/
|
||||
virtual void setDopplerEffectParameters(ik_f32 dopplerFactor=1.0f, ik_f32 distanceFactor=1.0f) = 0;
|
||||
|
||||
//! Loads irrKlang plugins from a custom path.
|
||||
/** Plugins usually are .dll, .so or .dylib
|
||||
files named for example ikpMP3.dll (= short for irrKlangPluginMP3) which
|
||||
make it possible to play back mp3 files. Plugins are being
|
||||
loaded from the current working directory at startup of the sound engine
|
||||
if the parameter ESEO_LOAD_PLUGINS is set (which it is by default), but
|
||||
using this method, it is possible to load plugins from a custom path in addition.
|
||||
\param path Path to the plugin directory, like "C:\games\somegamegame\irrklangplugins".
|
||||
\return returns true if sucessful or fals if not, for example because the path could
|
||||
not be found. */
|
||||
virtual bool loadPlugins(const ik_c8* path) = 0;
|
||||
|
||||
//! Returns a pointer to internal sound engine pointers, like the DirectSound interface.
|
||||
/** Use this with caution. This is only exposed to make it possible for other libraries
|
||||
such as Video playback packages to extend or use the sound driver irrklang uses. */
|
||||
virtual const SInternalAudioInterface& getInternalAudioInterface() = 0;
|
||||
|
||||
//! Sets the OutputMixedDataReceiver, so you can receive the pure mixed output audio data while it is being played.
|
||||
/** This can be used to store the sound output as .wav file or for creating a Oscillograph or similar.
|
||||
This works only with software based audio drivers, that is ESOD_WIN_MM, ESOD_ALSA, and ESOD_CORE_AUDIO.
|
||||
Returns true if sucessful and fals if the current audio driver doesn't support this feature. Set this to null
|
||||
again once you don't need it anymore. */
|
||||
virtual bool setMixedDataOutputReceiver(ISoundMixedOutputReceiver* receiver) = 0;
|
||||
};
|
||||
|
||||
|
||||
//! structure for returning pointers to the internal audio interface.
|
||||
/** Use ISoundEngine::getInternalAudioInterface() to get this. */
|
||||
struct SInternalAudioInterface
|
||||
{
|
||||
//! IDirectSound interface, this is not null when using the ESOD_DIRECT_SOUND audio driver
|
||||
void* pIDirectSound;
|
||||
|
||||
//! IDirectSound8 interface, this is not null when using the ESOD_DIRECT_SOUND8 audio driver
|
||||
void* pIDirectSound8;
|
||||
|
||||
//! HWaveout interface, this is not null when using the ESOD_WIN_MM audio driver
|
||||
void* pWinMM_HWaveOut;
|
||||
|
||||
//! ALSA PCM Handle interface, this is not null when using the ESOD_ALSA audio driver
|
||||
void* pALSA_SND_PCM;
|
||||
|
||||
//! AudioDeviceID handle, this is not null when using the ESOD_CORE_AUDIO audio driver
|
||||
ik_u32 pCoreAudioDeciceID;
|
||||
};
|
||||
|
||||
|
||||
|
||||
} // end namespace irrklang
|
||||
|
||||
|
||||
#endif
|
||||
@@ -1,46 +0,0 @@
|
||||
// Copyright (C) 2002-2018 Nikolaus Gebhardt
|
||||
// This file is part of the "irrKlang" library.
|
||||
// For conditions of distribution and use, see copyright notice in irrKlang.h
|
||||
|
||||
#ifndef __I_IRRKLANG_SOUND_MIXED_OUTPUT_RECEIVER_H_INCLUDED__
|
||||
#define __I_IRRKLANG_SOUND_MIXED_OUTPUT_RECEIVER_H_INCLUDED__
|
||||
|
||||
#include "ik_IRefCounted.h"
|
||||
#include "ik_SAudioStreamFormat.h"
|
||||
|
||||
|
||||
namespace irrklang
|
||||
{
|
||||
|
||||
|
||||
//! Interface to be implemented by the user, which recieves the mixed output when it it played by the sound engine.
|
||||
/** This can be used to store the sound output as .wav file or for creating a Oscillograph or similar.
|
||||
Simply implement your own class derived from ISoundMixedOutputReceiver and use ISoundEngine::setMixedDataOutputReceiver
|
||||
to let the audio driver know about it. */
|
||||
class ISoundMixedOutputReceiver
|
||||
{
|
||||
public:
|
||||
|
||||
//! destructor
|
||||
virtual ~ISoundMixedOutputReceiver() {};
|
||||
|
||||
//! Called when a chunk of sound has been mixed and is about to be played.
|
||||
/** Note: This is called from the playing thread of the sound library, so you need to
|
||||
make everything you are doing in this method thread safe. Additionally, it would
|
||||
be a good idea to do nothing complicated in your implementation and return as fast as possible,
|
||||
otherwise sound output may be stuttering.
|
||||
\param data representing the sound frames which just have been mixed. Sound data always
|
||||
consists of two interleaved sound channels at 16bit per frame.
|
||||
\param byteCount Amount of bytes of the data
|
||||
\param playbackrate The playback rate at samples per second (usually something like 44000).
|
||||
This value will not change and always be the same for an instance of an ISoundEngine. */
|
||||
virtual void OnAudioDataReady(const void* data, int byteCount, int playbackrate) = 0;
|
||||
|
||||
};
|
||||
|
||||
|
||||
} // end namespace irrklang
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1,167 +0,0 @@
|
||||
// Copyright (C) 2002-2018 Nikolaus Gebhardt
|
||||
// This file is part of the "irrKlang" library.
|
||||
// For conditions of distribution and use, see copyright notice in irrKlang.h
|
||||
|
||||
#ifndef __I_IRRKLANG_IRR_SOUND_SOURCE_H_INCLUDED__
|
||||
#define __I_IRRKLANG_IRR_SOUND_SOURCE_H_INCLUDED__
|
||||
|
||||
#include "ik_IVirtualRefCounted.h"
|
||||
#include "ik_vec3d.h"
|
||||
#include "ik_EStreamModes.h"
|
||||
#include "ik_SAudioStreamFormat.h"
|
||||
|
||||
|
||||
namespace irrklang
|
||||
{
|
||||
|
||||
//! A sound source describes an input file (.ogg, .mp3, .wav or similar) and its default settings.
|
||||
/** It provides some informations about the sound source like the play lenght and
|
||||
can have default settings for volume, distances for 3d etc. There is some example code on how
|
||||
to use Sound sources at @ref soundSources.*/
|
||||
class ISoundSource : public IVirtualRefCounted
|
||||
{
|
||||
public:
|
||||
|
||||
//! Returns the name of the sound source (usually, this is the file name)
|
||||
virtual const ik_c8* getName() = 0;
|
||||
|
||||
//! Sets the stream mode which should be used for a sound played from this source.
|
||||
/** Note that if this is set to ESM_NO_STREAMING, the engine still might decide
|
||||
to stream the sound if it is too big. The threashold for this can be
|
||||
adjusted using ISoundSource::setForcedStreamingThreshold(). */
|
||||
virtual void setStreamMode(E_STREAM_MODE mode) = 0;
|
||||
|
||||
//! Returns the detected or set type of the sound with wich the sound will be played.
|
||||
/** Note: If the returned type is ESM_AUTO_DETECT, this mode will change after the
|
||||
sound has been played the first time. */
|
||||
virtual E_STREAM_MODE getStreamMode() = 0;
|
||||
|
||||
//! Returns the play length of the sound in milliseconds.
|
||||
/** Returns -1 if not known for this sound for example because its decoder
|
||||
does not support lenght reporting or it is a file stream of unknown size.
|
||||
Note: If the sound never has been played before, the sound engine will have to open
|
||||
the file and try to get the play lenght from there, so this call could take a bit depending
|
||||
on the type of file. */
|
||||
virtual ik_u32 getPlayLength() = 0;
|
||||
|
||||
//! Returns informations about the sound source: channel count (mono/stereo), frame count, sample rate, etc.
|
||||
/** \return Returns the structure filled with 0 or negative values if not known for this sound for example because
|
||||
because the file could not be opened or similar.
|
||||
Note: If the sound never has been played before, the sound engine will have to open
|
||||
the file and try to get the play lenght from there, so this call could take a bit depending
|
||||
on the type of file. */
|
||||
virtual SAudioStreamFormat getAudioFormat() = 0;
|
||||
|
||||
//! Returns if sounds played from this source will support seeking via ISound::setPlayPosition().
|
||||
/* If a sound is seekable depends on the file type and the audio format. For example MOD files
|
||||
cannot be seeked currently.
|
||||
\return Returns true of the sound source supports setPlayPosition() and false if not.
|
||||
Note: If the sound never has been played before, the sound engine will have to open
|
||||
the file and try to get the information from there, so this call could take a bit depending
|
||||
on the type of file. */
|
||||
virtual bool getIsSeekingSupported() = 0;
|
||||
|
||||
//! Sets the default volume for a sound played from this source.
|
||||
/** The default value of this is 1.0f.
|
||||
Note that the default volume is being multiplied with the master volume
|
||||
of ISoundEngine, change this via ISoundEngine::setSoundVolume().
|
||||
//! \param volume 0 (silent) to 1.0f (full volume). Default value is 1.0f. */
|
||||
virtual void setDefaultVolume(ik_f32 volume=1.0f) = 0;
|
||||
|
||||
//! Returns the default volume for a sound played from this source.
|
||||
/** You can influence this default volume value using setDefaultVolume().
|
||||
Note that the default volume is being multiplied with the master volume
|
||||
of ISoundEngine, change this via ISoundEngine::setSoundVolume().
|
||||
//! \return 0 (silent) to 1.0f (full volume). Default value is 1.0f. */
|
||||
virtual ik_f32 getDefaultVolume() = 0;
|
||||
|
||||
//! sets the default minimal distance for 3D sounds played from this source.
|
||||
/** This value influences how loud a sound is heard based on its distance.
|
||||
See ISound::setMinDistance() for details about what the min distance is.
|
||||
This method only influences the initial distance value of sounds. For changing the
|
||||
distance while the sound is playing, use ISound::setMinDistance() and ISound::setMaxDistance().
|
||||
\param minDistance: Default minimal distance for 3D sounds from this source. Set it to a negative
|
||||
value to let sounds of this source use the engine level default min distance, which
|
||||
can be set via ISoundEngine::setDefault3DSoundMinDistance(). Default value is -1, causing
|
||||
the default min distance of the sound engine to take effect. */
|
||||
virtual void setDefaultMinDistance(ik_f32 minDistance) = 0;
|
||||
|
||||
//! Returns the default minimal distance for 3D sounds played from this source.
|
||||
/** This value influences how loud a sound is heard based on its distance.
|
||||
See ISound::setMinDistance() for details about what the minimal distance is.
|
||||
\return Default minimal distance for 3d sounds from this source. If setDefaultMinDistance()
|
||||
was set to a negative value, it will return the default value set in the engine,
|
||||
using ISoundEngine::setDefault3DSoundMinDistance(). Default value is -1, causing
|
||||
the default min distance of the sound engine to take effect. */
|
||||
virtual ik_f32 getDefaultMinDistance() = 0;
|
||||
|
||||
//! Sets the default maximal distance for 3D sounds played from this source.
|
||||
/** Changing this value is usually not necessary. Use setDefaultMinDistance() instead.
|
||||
Don't change this value if you don't know what you are doing: This value causes the sound
|
||||
to stop attenuating after it reaches the max distance. Most people think that this sets the
|
||||
volume of the sound to 0 after this distance, but this is not true. Only change the
|
||||
minimal distance (using for example setDefaultMinDistance()) to influence this.
|
||||
See ISound::setMaxDistance() for details about what the max distance is.
|
||||
This method only influences the initial distance value of sounds. For changing the
|
||||
distance while the sound is played, use ISound::setMinDistance()
|
||||
and ISound::setMaxDistance().
|
||||
\param maxDistance Default maximal distance for 3D sounds from this source. Set it to a negative
|
||||
value to let sounds of this source use the engine level default max distance, which
|
||||
can be set via ISoundEngine::setDefault3DSoundMaxDistance(). Default value is -1, causing
|
||||
the default max distance of the sound engine to take effect. */
|
||||
virtual void setDefaultMaxDistance(ik_f32 maxDistance) = 0;
|
||||
|
||||
//! returns the default maxmial distance for 3D sounds played from this source.
|
||||
/** This value influences how loud a sound is heard based on its distance.
|
||||
Changing this value is usually not necessary. Use setDefaultMinDistance() instead.
|
||||
Don't change this value if you don't know what you are doing: This value causes the sound
|
||||
to stop attenuating after it reaches the max distance. Most people think that this sets the
|
||||
volume of the sound to 0 after this distance, but this is not true. Only change the
|
||||
minimal distance (using for example setDefaultMinDistance()) to influence this.
|
||||
See ISound::setMaxDistance() for details about what the max distance is.
|
||||
\return Default maximal distance for 3D sounds from this source. If setDefaultMaxDistance()
|
||||
was set to a negative value, it will return the default value set in the engine,
|
||||
using ISoundEngine::setDefault3DSoundMaxDistance(). Default value is -1, causing
|
||||
the default max distance of the sound engine to take effect. */
|
||||
virtual ik_f32 getDefaultMaxDistance() = 0;
|
||||
|
||||
//! Forces the sound to be reloaded at next replay.
|
||||
/** Sounds which are not played as streams are buffered to make it possible to
|
||||
replay them without much overhead. If the sound file is altered after the sound
|
||||
has been played the first time, the engine won't play the changed file then.
|
||||
Calling this method makes the engine reload the file before the file is played
|
||||
the next time.*/
|
||||
virtual void forceReloadAtNextUse() = 0;
|
||||
|
||||
//! Sets the threshold size where irrKlang decides to force streaming a file independent of the user specified setting.
|
||||
/** When specifying ESM_NO_STREAMING for playing back a sound file, irrKlang will
|
||||
ignore this setting if the file is bigger than this threshold and stream the file
|
||||
anyway. Please note that if an audio format loader is not able to return the
|
||||
size of a sound source and returns -1 as length, this will be ignored as well
|
||||
and streaming has to be forced.
|
||||
\param threshold: New threshold. The value is specified in uncompressed bytes and its default value is
|
||||
about one Megabyte. Set to 0 or a negative value to disable stream forcing. */
|
||||
virtual void setForcedStreamingThreshold(ik_s32 thresholdBytes) = 0;
|
||||
|
||||
//! Returns the threshold size where irrKlang decides to force streaming a file independent of the user specified setting.
|
||||
/** The value is specified in uncompressed bytes and its default value is
|
||||
about one Megabyte. See setForcedStreamingThreshold() for details. */
|
||||
virtual ik_s32 getForcedStreamingThreshold() = 0;
|
||||
|
||||
//! Returns a pointer to the loaded and decoded sample data.
|
||||
/** \return Returns a pointer to the sample data. The data is provided in decoded PCM data. The
|
||||
exact format can be retrieved using getAudioFormat(). Use getAudioFormat().getSampleDataSize()
|
||||
for getting the amount of bytes. The returned pointer will only be valid as long as the sound
|
||||
source exists.
|
||||
This function will only return a pointer to the data if the
|
||||
audio file is not streamed, namely ESM_NO_STREAMING. Otherwise this function will return 0.
|
||||
Note: If the sound never has been played before, the sound engine will have to open
|
||||
the file and decode audio data from there, so this call could take a bit depending
|
||||
on the type of the file.*/
|
||||
virtual void* getSampleData() = 0;
|
||||
};
|
||||
|
||||
} // end namespace irrklang
|
||||
|
||||
|
||||
#endif
|
||||
@@ -1,72 +0,0 @@
|
||||
// Copyright (C) 2002-2018 Nikolaus Gebhardt
|
||||
// This file is part of the "irrKlang" library.
|
||||
// For conditions of distribution and use, see copyright notice in irrKlang.h
|
||||
|
||||
#ifndef __I_IRRKLANG_SOUND_STOP_EVENT_RECEIVER_H_INCLUDED__
|
||||
#define __I_IRRKLANG_SOUND_STOP_EVENT_RECEIVER_H_INCLUDED__
|
||||
|
||||
#include "ik_IRefCounted.h"
|
||||
#include "ik_SAudioStreamFormat.h"
|
||||
|
||||
|
||||
namespace irrklang
|
||||
{
|
||||
|
||||
|
||||
//! An enumeration listing all reasons for a fired sound stop event
|
||||
enum E_STOP_EVENT_CAUSE
|
||||
{
|
||||
//! The sound stop event was fired because the sound finished playing
|
||||
ESEC_SOUND_FINISHED_PLAYING = 0,
|
||||
|
||||
//! The sound stop event was fired because the sound was stopped by the user, calling ISound::stop().
|
||||
ESEC_SOUND_STOPPED_BY_USER,
|
||||
|
||||
//! The sound stop event was fired because the source of the sound was removed, for example
|
||||
//! because irrKlang was shut down or the user called ISoundEngine::removeSoundSource().
|
||||
ESEC_SOUND_STOPPED_BY_SOURCE_REMOVAL,
|
||||
|
||||
//! This enumeration literal is never used, it only forces the compiler to
|
||||
//! compile these enumeration values to 32 bit.
|
||||
ESEC_FORCE_32_BIT = 0x7fffffff
|
||||
};
|
||||
|
||||
|
||||
//! Interface to be implemented by the user, which recieves sound stop events.
|
||||
/** The interface has only one method to be implemented by the user: OnSoundStopped().
|
||||
Implement this interface and set it via ISound::setSoundStopEventReceiver().
|
||||
The sound stop event is guaranteed to be called when a sound or sound stream is finished,
|
||||
either because the sound reached its playback end, its sound source was removed,
|
||||
ISoundEngine::stopAllSounds() has been called or the whole engine was deleted. */
|
||||
class ISoundStopEventReceiver
|
||||
{
|
||||
public:
|
||||
|
||||
//! destructor
|
||||
virtual ~ISoundStopEventReceiver() {};
|
||||
|
||||
//! Called when a sound has stopped playing.
|
||||
/** This is the only method to be implemented by the user.
|
||||
The sound stop event is guaranteed to be called when a sound or sound stream is finished,
|
||||
either because the sound reached its playback end, its sound source was removed,
|
||||
ISoundEngine::stopAllSounds() has been called or the whole engine was deleted.
|
||||
Please note: Sound events will occur in a different thread when the engine runs in
|
||||
multi threaded mode (default). In single threaded mode, the event will happen while
|
||||
the user thread is calling ISoundEngine::update().
|
||||
\param sound: Sound which has been stopped.
|
||||
\param reason: The reason why the sound stop event was fired. Usually, this will be ESEC_SOUND_FINISHED_PLAYING.
|
||||
When the sound was aborded by calling ISound::stop() or ISoundEngine::stopAllSounds();, this would be
|
||||
ESEC_SOUND_STOPPED_BY_USER. If irrKlang was deleted or the sound source was removed, the value is
|
||||
ESEC_SOUND_STOPPED_BY_SOURCE_REMOVAL.
|
||||
\param userData: userData pointer set by the user when registering the interface
|
||||
via ISound::setSoundStopEventReceiver(). */
|
||||
virtual void OnSoundStopped(ISound* sound, E_STOP_EVENT_CAUSE reason, void* userData) = 0;
|
||||
|
||||
};
|
||||
|
||||
|
||||
} // end namespace irrklang
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1,48 +0,0 @@
|
||||
// Copyright (C) 2002-2018 Nikolaus Gebhardt
|
||||
// This file is part of the "irrKlang" library.
|
||||
// For conditions of distribution and use, see copyright notice in irrKlang.h
|
||||
|
||||
#ifndef __I_IRRKLANG_VIRTUAL_UNKNOWN_H_INCLUDED__
|
||||
#define __I_IRRKLANG_VIRTUAL_UNKNOWN_H_INCLUDED__
|
||||
|
||||
#include "ik_irrKlangTypes.h"
|
||||
|
||||
|
||||
namespace irrklang
|
||||
{
|
||||
|
||||
//! Reference counting base class for objects in the Irrlicht Engine similar to IRefCounted.
|
||||
/** See IRefCounted for the basics of this class.
|
||||
The difference to IRefCounted is that the class has to implement reference counting
|
||||
for itself.
|
||||
*/
|
||||
class IVirtualRefCounted
|
||||
{
|
||||
public:
|
||||
|
||||
//! Destructor.
|
||||
virtual ~IVirtualRefCounted()
|
||||
{
|
||||
}
|
||||
|
||||
//! Grabs the object. Increments the reference counter by one.
|
||||
/** To be implemented by the derived class. If you don't want to
|
||||
implement this, use the class IRefCounted instead. See IRefCounted::grab() for details
|
||||
of this method. */
|
||||
virtual void grab() = 0;
|
||||
|
||||
//! Drops the object. Decrements the reference counter by one.
|
||||
/** To be implemented by the derived class. If you don't want to
|
||||
implement this, use the class IRefCounted instead. See IRefCounted::grab() for details
|
||||
of this method. */
|
||||
virtual bool drop() = 0;
|
||||
};
|
||||
|
||||
|
||||
|
||||
} // end namespace irrklang
|
||||
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1,71 +0,0 @@
|
||||
// Copyright (C) 2002-2018 Nikolaus Gebhardt
|
||||
// This file is part of the "irrKlang" library.
|
||||
// For conditions of distribution and use, see copyright notice in irrKlang.h
|
||||
|
||||
#ifndef __S_IRRKLANG_AUDIO_STREAM_FORMAT_H_INCLUDED__
|
||||
#define __S_IRRKLANG_AUDIO_STREAM_FORMAT_H_INCLUDED__
|
||||
|
||||
#include "ik_IRefCounted.h"
|
||||
|
||||
|
||||
namespace irrklang
|
||||
{
|
||||
|
||||
//! audio sample data format enumeration for supported formats
|
||||
enum ESampleFormat
|
||||
{
|
||||
//! one unsigned byte (0;255)
|
||||
ESF_U8,
|
||||
|
||||
//! 16 bit, signed (-32k;32k)
|
||||
ESF_S16
|
||||
};
|
||||
|
||||
|
||||
//! structure describing an audio stream format with helper functions
|
||||
struct SAudioStreamFormat
|
||||
{
|
||||
//! channels, 1 for mono, 2 for stereo
|
||||
ik_s32 ChannelCount;
|
||||
|
||||
//! amount of frames in the sample data or stream.
|
||||
/** If the stream has an unknown lenght, this is -1 */
|
||||
ik_s32 FrameCount;
|
||||
|
||||
//! samples per second
|
||||
ik_s32 SampleRate;
|
||||
|
||||
//! format of the sample data
|
||||
ESampleFormat SampleFormat;
|
||||
|
||||
//! returns the size of a sample of the data described by the stream data in bytes
|
||||
inline ik_s32 getSampleSize() const
|
||||
{
|
||||
return (SampleFormat == ESF_U8) ? 1 : 2;
|
||||
}
|
||||
|
||||
//! returns the frame size of the stream data in bytes
|
||||
inline ik_s32 getFrameSize() const
|
||||
{
|
||||
return ChannelCount * getSampleSize();
|
||||
}
|
||||
|
||||
//! returns the size of the sample data in bytes
|
||||
/* Returns an invalid negative value when the stream has an unknown lenght */
|
||||
inline ik_s32 getSampleDataSize() const
|
||||
{
|
||||
return getFrameSize() * FrameCount;
|
||||
}
|
||||
|
||||
//! returns amount of bytes per second
|
||||
inline ik_s32 getBytesPerSecond() const
|
||||
{
|
||||
return getFrameSize() * SampleRate;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
} // end namespace irrklang
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1,96 +0,0 @@
|
||||
// Copyright (C) 2002-2018 Nikolaus Gebhardt
|
||||
// This file is part of the "irrKlang" library.
|
||||
// For conditions of distribution and use, see copyright notice in irrKlang.h
|
||||
|
||||
#ifndef __IRRKLANG_TYPES_H_INCLUDED__
|
||||
#define __IRRKLANG_TYPES_H_INCLUDED__
|
||||
|
||||
|
||||
namespace irrklang
|
||||
{
|
||||
|
||||
//! 8 bit unsigned variable.
|
||||
/** This is a typedef for unsigned char, it ensures portability of the engine. */
|
||||
typedef unsigned char ik_u8;
|
||||
|
||||
//! 8 bit signed variable.
|
||||
/** This is a typedef for signed char, it ensures portability of the engine. */
|
||||
typedef signed char ik_s8;
|
||||
|
||||
//! 8 bit character variable.
|
||||
/** This is a typedef for char, it ensures portability of the engine. */
|
||||
typedef char ik_c8;
|
||||
|
||||
|
||||
|
||||
//! 16 bit unsigned variable.
|
||||
/** This is a typedef for unsigned short, it ensures portability of the engine. */
|
||||
typedef unsigned short ik_u16;
|
||||
|
||||
//! 16 bit signed variable.
|
||||
/** This is a typedef for signed short, it ensures portability of the engine. */
|
||||
typedef signed short ik_s16;
|
||||
|
||||
|
||||
|
||||
//! 32 bit unsigned variable.
|
||||
/** This is a typedef for unsigned int, it ensures portability of the engine. */
|
||||
typedef unsigned int ik_u32;
|
||||
|
||||
//! 32 bit signed variable.
|
||||
/** This is a typedef for signed int, it ensures portability of the engine. */
|
||||
typedef signed int ik_s32;
|
||||
|
||||
|
||||
|
||||
//! 32 bit floating point variable.
|
||||
/** This is a typedef for float, it ensures portability of the engine. */
|
||||
typedef float ik_f32;
|
||||
|
||||
//! 64 bit floating point variable.
|
||||
/** This is a typedef for double, it ensures portability of the engine. */
|
||||
typedef double ik_f64;
|
||||
|
||||
|
||||
|
||||
// some constants
|
||||
|
||||
const ik_f32 IK_ROUNDING_ERROR_32 = 0.000001f;
|
||||
const ik_f64 IK_PI64 = 3.1415926535897932384626433832795028841971693993751;
|
||||
const ik_f32 IK_PI32 = 3.14159265359f;
|
||||
const ik_f32 IK_RADTODEG = 180.0f / IK_PI32;
|
||||
const ik_f32 IK_DEGTORAD = IK_PI32 / 180.0f;
|
||||
const ik_f64 IK_RADTODEG64 = 180.0 / IK_PI64;
|
||||
const ik_f64 IK_DEGTORAD64 = IK_PI64 / 180.0;
|
||||
|
||||
//! returns if a float equals the other one, taking floating
|
||||
//! point rounding errors into account
|
||||
inline bool equalsfloat(const ik_f32 a, const ik_f32 b, const ik_f32 tolerance = IK_ROUNDING_ERROR_32)
|
||||
{
|
||||
return (a + tolerance > b) && (a - tolerance < b);
|
||||
}
|
||||
|
||||
} // end irrklang namespace
|
||||
|
||||
// ensure wchar_t type is existing for unicode support
|
||||
#include <wchar.h>
|
||||
|
||||
// define the wchar_t type if not already built in.
|
||||
#ifdef _MSC_VER // microsoft compiler
|
||||
#ifndef _WCHAR_T_DEFINED
|
||||
//! A 16 bit wide character type.
|
||||
/**
|
||||
Defines the wchar_t-type.
|
||||
In VS6, its not possible to tell
|
||||
the standard compiler to treat wchar_t as a built-in type, and
|
||||
sometimes we just don't want to include the huge stdlib.h or wchar.h,
|
||||
so we'll use this.
|
||||
*/
|
||||
typedef unsigned short wchar_t;
|
||||
#define _WCHAR_T_DEFINED
|
||||
#endif // wchar is not defined
|
||||
#endif // microsoft compiler
|
||||
|
||||
|
||||
#endif // __IRR_TYPES_H_INCLUDED__
|
||||
|
||||
@@ -1,261 +0,0 @@
|
||||
// Copyright (C) 2002-2018 Nikolaus Gebhardt
|
||||
// This file is part of the "irrKlang" library.
|
||||
// For conditions of distribution and use, see copyright notice in irrKlang.h
|
||||
|
||||
#ifndef __IRR_IRRKLANG_VEC_3D_H_INCLUDED__
|
||||
#define __IRR_IRRKLANG_VEC_3D_H_INCLUDED__
|
||||
|
||||
#include <math.h>
|
||||
#include "ik_irrKlangTypes.h"
|
||||
|
||||
|
||||
namespace irrklang
|
||||
{
|
||||
|
||||
//! a 3d vector template class for representing vectors and points in 3d
|
||||
template <class T>
|
||||
class vec3d
|
||||
{
|
||||
public:
|
||||
|
||||
vec3d(): X(0), Y(0), Z(0) {};
|
||||
vec3d(T nx, T ny, T nz) : X(nx), Y(ny), Z(nz) {};
|
||||
vec3d(const vec3d<T>& other) :X(other.X), Y(other.Y), Z(other.Z) {};
|
||||
|
||||
//! constructor creating an irrklang vec3d from an irrlicht vector.
|
||||
#ifdef __IRR_POINT_3D_H_INCLUDED__
|
||||
template<class B>
|
||||
vec3d(const B& other) :X(other.X), Y(other.Y), Z(other.Z) {};
|
||||
#endif // __IRR_POINT_3D_H_INCLUDED__
|
||||
|
||||
// operators
|
||||
|
||||
vec3d<T> operator-() const { return vec3d<T>(-X, -Y, -Z); }
|
||||
|
||||
vec3d<T>& operator=(const vec3d<T>& other) { X = other.X; Y = other.Y; Z = other.Z; return *this; }
|
||||
|
||||
vec3d<T> operator+(const vec3d<T>& other) const { return vec3d<T>(X + other.X, Y + other.Y, Z + other.Z); }
|
||||
vec3d<T>& operator+=(const vec3d<T>& other) { X+=other.X; Y+=other.Y; Z+=other.Z; return *this; }
|
||||
|
||||
vec3d<T> operator-(const vec3d<T>& other) const { return vec3d<T>(X - other.X, Y - other.Y, Z - other.Z); }
|
||||
vec3d<T>& operator-=(const vec3d<T>& other) { X-=other.X; Y-=other.Y; Z-=other.Z; return *this; }
|
||||
|
||||
vec3d<T> operator*(const vec3d<T>& other) const { return vec3d<T>(X * other.X, Y * other.Y, Z * other.Z); }
|
||||
vec3d<T>& operator*=(const vec3d<T>& other) { X*=other.X; Y*=other.Y; Z*=other.Z; return *this; }
|
||||
vec3d<T> operator*(const T v) const { return vec3d<T>(X * v, Y * v, Z * v); }
|
||||
vec3d<T>& operator*=(const T v) { X*=v; Y*=v; Z*=v; return *this; }
|
||||
|
||||
vec3d<T> operator/(const vec3d<T>& other) const { return vec3d<T>(X / other.X, Y / other.Y, Z / other.Z); }
|
||||
vec3d<T>& operator/=(const vec3d<T>& other) { X/=other.X; Y/=other.Y; Z/=other.Z; return *this; }
|
||||
vec3d<T> operator/(const T v) const { T i=(T)1.0/v; return vec3d<T>(X * i, Y * i, Z * i); }
|
||||
vec3d<T>& operator/=(const T v) { T i=(T)1.0/v; X*=i; Y*=i; Z*=i; return *this; }
|
||||
|
||||
bool operator<=(const vec3d<T>&other) const { return X<=other.X && Y<=other.Y && Z<=other.Z;};
|
||||
bool operator>=(const vec3d<T>&other) const { return X>=other.X && Y>=other.Y && Z>=other.Z;};
|
||||
|
||||
bool operator==(const vec3d<T>& other) const { return other.X==X && other.Y==Y && other.Z==Z; }
|
||||
bool operator!=(const vec3d<T>& other) const { return other.X!=X || other.Y!=Y || other.Z!=Z; }
|
||||
|
||||
// functions
|
||||
|
||||
//! returns if this vector equalsfloat the other one, taking floating point rounding errors into account
|
||||
bool equals(const vec3d<T>& other)
|
||||
{
|
||||
return equalsfloat(X, other.X) &&
|
||||
equalsfloat(Y, other.Y) &&
|
||||
equalsfloat(Z, other.Z);
|
||||
}
|
||||
|
||||
void set(const T nx, const T ny, const T nz) {X=nx; Y=ny; Z=nz; }
|
||||
void set(const vec3d<T>& p) { X=p.X; Y=p.Y; Z=p.Z;}
|
||||
|
||||
//! Returns length of the vector.
|
||||
ik_f64 getLength() const { return sqrt(X*X + Y*Y + Z*Z); }
|
||||
|
||||
//! Returns squared length of the vector.
|
||||
/** This is useful because it is much faster then
|
||||
getLength(). */
|
||||
ik_f64 getLengthSQ() const { return X*X + Y*Y + Z*Z; }
|
||||
|
||||
//! Returns the dot product with another vector.
|
||||
T dotProduct(const vec3d<T>& other) const
|
||||
{
|
||||
return X*other.X + Y*other.Y + Z*other.Z;
|
||||
}
|
||||
|
||||
//! Returns distance from an other point.
|
||||
/** Here, the vector is interpreted as point in 3 dimensional space. */
|
||||
ik_f64 getDistanceFrom(const vec3d<T>& other) const
|
||||
{
|
||||
ik_f64 vx = X - other.X; ik_f64 vy = Y - other.Y; ik_f64 vz = Z - other.Z;
|
||||
return sqrt(vx*vx + vy*vy + vz*vz);
|
||||
}
|
||||
|
||||
//! Returns squared distance from an other point.
|
||||
/** Here, the vector is interpreted as point in 3 dimensional space. */
|
||||
ik_f32 getDistanceFromSQ(const vec3d<T>& other) const
|
||||
{
|
||||
ik_f32 vx = X - other.X; ik_f32 vy = Y - other.Y; ik_f32 vz = Z - other.Z;
|
||||
return (vx*vx + vy*vy + vz*vz);
|
||||
}
|
||||
|
||||
//! Calculates the cross product with another vector
|
||||
vec3d<T> crossProduct(const vec3d<T>& p) const
|
||||
{
|
||||
return vec3d<T>(Y * p.Z - Z * p.Y, Z * p.X - X * p.Z, X * p.Y - Y * p.X);
|
||||
}
|
||||
|
||||
//! Returns if this vector interpreted as a point is on a line between two other points.
|
||||
/** It is assumed that the point is on the line. */
|
||||
bool isBetweenPoints(const vec3d<T>& begin, const vec3d<T>& end) const
|
||||
{
|
||||
ik_f32 f = (ik_f32)(end - begin).getLengthSQ();
|
||||
return (ik_f32)getDistanceFromSQ(begin) < f &&
|
||||
(ik_f32)getDistanceFromSQ(end) < f;
|
||||
}
|
||||
|
||||
//! Normalizes the vector.
|
||||
vec3d<T>& normalize()
|
||||
{
|
||||
T l = (T)getLength();
|
||||
if (l == 0)
|
||||
return *this;
|
||||
|
||||
l = (T)1.0 / l;
|
||||
X *= l;
|
||||
Y *= l;
|
||||
Z *= l;
|
||||
return *this;
|
||||
}
|
||||
|
||||
//! Sets the lenght of the vector to a new value
|
||||
void setLength(T newlength)
|
||||
{
|
||||
normalize();
|
||||
*this *= newlength;
|
||||
}
|
||||
|
||||
//! Inverts the vector.
|
||||
void invert()
|
||||
{
|
||||
X *= -1.0f;
|
||||
Y *= -1.0f;
|
||||
Z *= -1.0f;
|
||||
}
|
||||
|
||||
//! Rotates the vector by a specified number of degrees around the Y
|
||||
//! axis and the specified center.
|
||||
//! \param degrees: Number of degrees to rotate around the Y axis.
|
||||
//! \param center: The center of the rotation.
|
||||
void rotateXZBy(ik_f64 degrees, const vec3d<T>& center)
|
||||
{
|
||||
degrees *= IK_DEGTORAD64;
|
||||
T cs = (T)cos(degrees);
|
||||
T sn = (T)sin(degrees);
|
||||
X -= center.X;
|
||||
Z -= center.Z;
|
||||
set(X*cs - Z*sn, Y, X*sn + Z*cs);
|
||||
X += center.X;
|
||||
Z += center.Z;
|
||||
}
|
||||
|
||||
//! Rotates the vector by a specified number of degrees around the Z
|
||||
//! axis and the specified center.
|
||||
//! \param degrees: Number of degrees to rotate around the Z axis.
|
||||
//! \param center: The center of the rotation.
|
||||
void rotateXYBy(ik_f64 degrees, const vec3d<T>& center)
|
||||
{
|
||||
degrees *= IK_DEGTORAD64;
|
||||
T cs = (T)cos(degrees);
|
||||
T sn = (T)sin(degrees);
|
||||
X -= center.X;
|
||||
Y -= center.Y;
|
||||
set(X*cs - Y*sn, X*sn + Y*cs, Z);
|
||||
X += center.X;
|
||||
Y += center.Y;
|
||||
}
|
||||
|
||||
//! Rotates the vector by a specified number of degrees around the X
|
||||
//! axis and the specified center.
|
||||
//! \param degrees: Number of degrees to rotate around the X axis.
|
||||
//! \param center: The center of the rotation.
|
||||
void rotateYZBy(ik_f64 degrees, const vec3d<T>& center)
|
||||
{
|
||||
degrees *= IK_DEGTORAD64;
|
||||
T cs = (T)cos(degrees);
|
||||
T sn = (T)sin(degrees);
|
||||
Z -= center.Z;
|
||||
Y -= center.Y;
|
||||
set(X, Y*cs - Z*sn, Y*sn + Z*cs);
|
||||
Z += center.Z;
|
||||
Y += center.Y;
|
||||
}
|
||||
|
||||
//! Returns interpolated vector.
|
||||
/** \param other: other vector to interpolate between
|
||||
\param d: value between 0.0f and 1.0f. */
|
||||
vec3d<T> getInterpolated(const vec3d<T>& other, ik_f32 d) const
|
||||
{
|
||||
ik_f32 inv = 1.0f - d;
|
||||
return vec3d<T>(other.X*inv + X*d,
|
||||
other.Y*inv + Y*d,
|
||||
other.Z*inv + Z*d);
|
||||
}
|
||||
|
||||
//! Gets the Y and Z rotations of a vector.
|
||||
/** Thanks to Arras on the Irrlicht forums to add this method.
|
||||
\return A vector representing the rotation in degrees of
|
||||
this vector. The Z component of the vector will always be 0. */
|
||||
vec3d<T> getHorizontalAngle()
|
||||
{
|
||||
vec3d<T> angle;
|
||||
|
||||
angle.Y = (T)atan2(X, Z);
|
||||
angle.Y *= (ik_f32)IK_RADTODEG;
|
||||
|
||||
if (angle.Y < 0.0f) angle.Y += 360.0f;
|
||||
if (angle.Y >= 360.0f) angle.Y -= 360.0f;
|
||||
|
||||
ik_f32 z1 = (T)sqrt(X*X + Z*Z);
|
||||
|
||||
angle.X = (T)atan2(z1, Y);
|
||||
angle.X *= (ik_f32)IK_RADTODEG;
|
||||
angle.X -= 90.0f;
|
||||
|
||||
if (angle.X < 0.0f) angle.X += 360.0f;
|
||||
if (angle.X >= 360) angle.X -= 360.0f;
|
||||
|
||||
return angle;
|
||||
}
|
||||
|
||||
//! Fills an array of 4 values with the vector data (usually floats).
|
||||
/** Useful for setting in shader constants for example. The fourth value
|
||||
will always be 0. */
|
||||
void getAs4Values(T* array)
|
||||
{
|
||||
array[0] = X;
|
||||
array[1] = Y;
|
||||
array[2] = Z;
|
||||
array[3] = 0;
|
||||
}
|
||||
|
||||
|
||||
// member variables
|
||||
|
||||
T X, Y, Z;
|
||||
};
|
||||
|
||||
|
||||
//! Typedef for a ik_f32 3d vector, a vector using floats for X, Y and Z
|
||||
typedef vec3d<ik_f32> vec3df;
|
||||
|
||||
//! Typedef for an integer 3d vector, a vector using ints for X, Y and Z
|
||||
typedef vec3d<ik_s32> vec3di;
|
||||
|
||||
template<class S, class T> vec3d<T> operator*(const S scalar, const vec3d<T>& vector) { return vector*scalar; }
|
||||
|
||||
} // end namespace irrklang
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
Binary file not shown.
Binary file not shown.
@@ -1,42 +0,0 @@
|
||||
// Copyright (C) 2002-2007 Nikolaus Gebhardt
|
||||
// This file is part of the "irrKlang" library.
|
||||
// For conditions of distribution and use, see copyright notice in irrKlang.h
|
||||
|
||||
#include "CIrrKlangAudioStreamLoaderMP3.h"
|
||||
#include "CIrrKlangAudioStreamMP3.h"
|
||||
#include <string.h>
|
||||
|
||||
|
||||
namespace irrklang
|
||||
{
|
||||
|
||||
|
||||
CIrrKlangAudioStreamLoaderMP3::CIrrKlangAudioStreamLoaderMP3()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
//! Returns true if the file maybe is able to be loaded by this class.
|
||||
bool CIrrKlangAudioStreamLoaderMP3::isALoadableFileExtension(const ik_c8* fileName)
|
||||
{
|
||||
return strstr(fileName, ".mp3") != 0;
|
||||
}
|
||||
|
||||
|
||||
//! Creates an audio file input stream from a file
|
||||
IAudioStream* CIrrKlangAudioStreamLoaderMP3::createAudioStream(irrklang::IFileReader* file)
|
||||
{
|
||||
CIrrKlangAudioStreamMP3* stream = new CIrrKlangAudioStreamMP3(file);
|
||||
|
||||
if (stream && !stream->isOK())
|
||||
{
|
||||
stream->drop();
|
||||
stream = 0;
|
||||
}
|
||||
|
||||
return stream;
|
||||
}
|
||||
|
||||
|
||||
} // end namespace irrklang
|
||||
|
||||
@@ -1,32 +0,0 @@
|
||||
// Copyright (C) 2002-2007 Nikolaus Gebhardt
|
||||
// This file is part of the "irrKlang" library.
|
||||
// For conditions of distribution and use, see copyright notice in irrKlang.h
|
||||
|
||||
#ifndef __C_IRRKLANG_AUDIO_STREAM_LOADER_MP3_H_INCLUDED__
|
||||
#define __C_IRRKLANG_AUDIO_STREAM_LOADER_MP3_H_INCLUDED__
|
||||
|
||||
#include <ik_IAudioStreamLoader.h>
|
||||
|
||||
namespace irrklang
|
||||
{
|
||||
//! Class which is able to create an audio file stream from a file.
|
||||
class CIrrKlangAudioStreamLoaderMP3 : public IAudioStreamLoader
|
||||
{
|
||||
public:
|
||||
|
||||
CIrrKlangAudioStreamLoaderMP3();
|
||||
|
||||
//! Returns true if the file maybe is able to be loaded by this class.
|
||||
/** This decision should be based only on the file extension (e.g. ".wav") */
|
||||
virtual bool isALoadableFileExtension(const ik_c8* fileName);
|
||||
|
||||
//! Creates an audio file input stream from a file
|
||||
/** \return Pointer to the created audio stream. Returns 0 if loading failed.
|
||||
If you no longer need the stream, you should call IAudioFileStream::drop().
|
||||
See IRefCounted::drop() for more information. */
|
||||
virtual IAudioStream* createAudioStream(irrklang::IFileReader* file);
|
||||
};
|
||||
|
||||
} // end namespace irrklang
|
||||
|
||||
#endif
|
||||
@@ -1,397 +0,0 @@
|
||||
// Copyright (C) 2002-2007 Nikolaus Gebhardt
|
||||
// Part of the code for this plugin for irrKlang is based on:
|
||||
// MP3 input for Audiere by Matt Campbell <mattcampbell@pobox.com>, based on
|
||||
// libavcodec from ffmpeg (http://ffmpeg.sourceforge.net/).
|
||||
// See license.txt for license details of this plugin.
|
||||
|
||||
#include "CIrrKlangAudioStreamMP3.h"
|
||||
#include <memory.h>
|
||||
#include <stdlib.h> // free, malloc and realloc
|
||||
#include <string.h>
|
||||
|
||||
namespace irrklang
|
||||
{
|
||||
|
||||
CIrrKlangAudioStreamMP3::CIrrKlangAudioStreamMP3(IFileReader* file)
|
||||
: File(file), TheMPAuDecContext(0), InputPosition(0), InputLength(0),
|
||||
DecodeBuffer(0), FirstFrameRead(false), EndOfFileReached(0),
|
||||
FileBegin(0), Position(0)
|
||||
{
|
||||
if (File)
|
||||
{
|
||||
File->grab();
|
||||
|
||||
TheMPAuDecContext = new MPAuDecContext();
|
||||
|
||||
if (!TheMPAuDecContext || mpaudec_init(TheMPAuDecContext) < 0)
|
||||
{
|
||||
File->drop();
|
||||
File = 0;
|
||||
delete TheMPAuDecContext;
|
||||
TheMPAuDecContext = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
// init, get format
|
||||
|
||||
DecodeBuffer = new ik_u8[MPAUDEC_MAX_AUDIO_FRAME_SIZE];
|
||||
|
||||
if (File->getSize()>0)
|
||||
{
|
||||
// seekable file, now parse file to get size
|
||||
// (needed to make it possible for the engine to loop a stream correctly)
|
||||
|
||||
skipID3IfNecessary();
|
||||
|
||||
TheMPAuDecContext->parse_only = 1;
|
||||
Format.FrameCount = 0;
|
||||
|
||||
while(!EndOfFileReached)
|
||||
{
|
||||
if (!decodeFrame())
|
||||
break;
|
||||
|
||||
Format.FrameCount += TheMPAuDecContext->frame_size;
|
||||
|
||||
if (!EndOfFileReached /*&& File->isSeekable()*/ )
|
||||
{
|
||||
// to be able to seek in the stream, store offsets and sizes
|
||||
|
||||
SFramePositionData data;
|
||||
data.size = TheMPAuDecContext->frame_size;
|
||||
data.offset = File->getPos() - (InputLength - InputPosition) - TheMPAuDecContext->coded_frame_size;
|
||||
|
||||
FramePositionData.push_back(data);
|
||||
}
|
||||
}
|
||||
|
||||
TheMPAuDecContext->parse_only = 0;
|
||||
setPosition(0);
|
||||
}
|
||||
else
|
||||
decodeFrame(); // decode first frame to read audio format
|
||||
|
||||
if (!TheMPAuDecContext->channels ||
|
||||
!TheMPAuDecContext->sample_rate )
|
||||
{
|
||||
File->drop();
|
||||
File = 0;
|
||||
delete TheMPAuDecContext;
|
||||
TheMPAuDecContext = 0;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
CIrrKlangAudioStreamMP3::~CIrrKlangAudioStreamMP3()
|
||||
{
|
||||
if (File)
|
||||
File->drop();
|
||||
|
||||
if (TheMPAuDecContext)
|
||||
{
|
||||
mpaudec_clear(TheMPAuDecContext);
|
||||
delete TheMPAuDecContext;
|
||||
}
|
||||
|
||||
delete [] DecodeBuffer;
|
||||
}
|
||||
|
||||
|
||||
|
||||
//! returns format of the audio stream
|
||||
SAudioStreamFormat CIrrKlangAudioStreamMP3::getFormat()
|
||||
{
|
||||
return Format;
|
||||
}
|
||||
|
||||
|
||||
//! tells the audio stream to read n audio frames into the specified buffer
|
||||
ik_s32 CIrrKlangAudioStreamMP3::readFrames(void* target, ik_s32 frameCountToRead)
|
||||
{
|
||||
const int frameSize = Format.getFrameSize();
|
||||
|
||||
int framesRead = 0;
|
||||
ik_u8* out = (ik_u8*)target;
|
||||
|
||||
while (framesRead < frameCountToRead)
|
||||
{
|
||||
// no more samples? ask the MP3 for more
|
||||
if (DecodedQueue.getSize() < frameSize)
|
||||
{
|
||||
if (!decodeFrame() || EndOfFileReached)
|
||||
return framesRead;
|
||||
|
||||
// if the buffer is still empty, we are done
|
||||
if (DecodedQueue.getSize() < frameSize)
|
||||
return framesRead;
|
||||
}
|
||||
|
||||
const int framesLeft = frameCountToRead - framesRead;
|
||||
const int dequeSize = DecodedQueue.getSize() / frameSize;
|
||||
const int framesToRead = framesLeft < dequeSize ? framesLeft : dequeSize;
|
||||
|
||||
DecodedQueue.read(out, framesToRead * frameSize);
|
||||
|
||||
out += framesToRead * frameSize;
|
||||
framesRead += framesToRead;
|
||||
Position += framesToRead;
|
||||
}
|
||||
|
||||
return framesRead;
|
||||
}
|
||||
|
||||
|
||||
|
||||
bool CIrrKlangAudioStreamMP3::decodeFrame()
|
||||
{
|
||||
int outputSize = 0;
|
||||
|
||||
while (!outputSize)
|
||||
{
|
||||
if (InputPosition == InputLength)
|
||||
{
|
||||
InputPosition = 0;
|
||||
InputLength = File->read(InputBuffer, IKP_MP3_INPUT_BUFFER_SIZE);
|
||||
|
||||
if (InputLength == 0)
|
||||
{
|
||||
EndOfFileReached = true;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
int rv = mpaudec_decode_frame( TheMPAuDecContext, (ik_s16*)DecodeBuffer,
|
||||
&outputSize,
|
||||
(ik_u8*)InputBuffer + InputPosition,
|
||||
InputLength - InputPosition);
|
||||
|
||||
if (rv < 0)
|
||||
return false;
|
||||
|
||||
InputPosition += rv;
|
||||
} // end while
|
||||
|
||||
if (!FirstFrameRead)
|
||||
{
|
||||
Format.ChannelCount = TheMPAuDecContext->channels;
|
||||
Format.SampleRate = TheMPAuDecContext->sample_rate;
|
||||
Format.SampleFormat = ESF_S16;
|
||||
Format.FrameCount = -1; // unknown lenght
|
||||
|
||||
FirstFrameRead = true;
|
||||
}
|
||||
else
|
||||
if (TheMPAuDecContext->channels != Format.ChannelCount ||
|
||||
TheMPAuDecContext->sample_rate != Format.SampleRate)
|
||||
{
|
||||
// Can't handle format changes mid-stream.
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!TheMPAuDecContext->parse_only)
|
||||
{
|
||||
if (outputSize < 0)
|
||||
{
|
||||
// Couldn't decode this frame. Too bad, already lost it.
|
||||
// This should only happen when seeking.
|
||||
|
||||
outputSize = TheMPAuDecContext->frame_size;
|
||||
memset(DecodeBuffer, 0, outputSize * Format.getFrameSize());
|
||||
}
|
||||
|
||||
DecodedQueue.write(DecodeBuffer, outputSize);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
|
||||
//! sets the position of the audio stream.
|
||||
/** For example to let the stream be read from the beginning of the file again,
|
||||
setPosition(0) would be called. This is usually done be the sound engine to
|
||||
loop a stream after if has reached the end. Return true if sucessful and 0 if not. */
|
||||
bool CIrrKlangAudioStreamMP3::setPosition(ik_s32 pos)
|
||||
{
|
||||
if (!File || !TheMPAuDecContext)
|
||||
return false;
|
||||
|
||||
if (pos == 0)
|
||||
{
|
||||
// usually done for looping, just reset to start
|
||||
|
||||
File->seek(FileBegin); // skip possible ID3 header
|
||||
|
||||
EndOfFileReached = false;
|
||||
|
||||
DecodedQueue.clear();
|
||||
|
||||
MPAuDecContext oldContext = *TheMPAuDecContext;
|
||||
|
||||
mpaudec_clear(TheMPAuDecContext);
|
||||
mpaudec_init(TheMPAuDecContext);
|
||||
|
||||
TheMPAuDecContext->bit_rate = oldContext.bit_rate;
|
||||
TheMPAuDecContext->channels = oldContext.channels;
|
||||
TheMPAuDecContext->frame_size = oldContext.frame_size;
|
||||
TheMPAuDecContext->sample_rate = oldContext.sample_rate;
|
||||
|
||||
InputPosition = 0;
|
||||
InputLength = 0;
|
||||
Position = 0;
|
||||
CurrentFramePosition = 0;
|
||||
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
// user wants to seek in the stream, so do this here
|
||||
|
||||
int scan_position = 0;
|
||||
int target_frame = 0;
|
||||
int frame_count = (int)FramePositionData.size();
|
||||
|
||||
while (target_frame < frame_count)
|
||||
{
|
||||
int frame_size = FramePositionData[target_frame].size;
|
||||
|
||||
if (pos <= scan_position + frame_size)
|
||||
break;
|
||||
else
|
||||
{
|
||||
scan_position += frame_size;
|
||||
target_frame++;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
const int MAX_FRAME_DEPENDENCY = 10;
|
||||
target_frame = std::max(0, target_frame - MAX_FRAME_DEPENDENCY);
|
||||
setPosition(0);
|
||||
|
||||
File->seek(FramePositionData[target_frame].offset, false);
|
||||
|
||||
int i;
|
||||
for (i = 0; i < target_frame; i++)
|
||||
{
|
||||
if (i>=(int)FramePositionData.size())
|
||||
{
|
||||
// internal error
|
||||
setPosition(0);
|
||||
return false;
|
||||
}
|
||||
|
||||
Position += FramePositionData[i].size;
|
||||
}
|
||||
|
||||
if (!decodeFrame() || EndOfFileReached)
|
||||
{
|
||||
setPosition(0);
|
||||
return false;
|
||||
}
|
||||
|
||||
int frames_to_consume = pos - Position; // PCM frames now
|
||||
if (frames_to_consume > 0)
|
||||
{
|
||||
ik_u8 *buf = new ik_u8[frames_to_consume * Format.getFrameSize()];
|
||||
readFrames(buf, frames_to_consume);
|
||||
delete[] buf;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
CIrrKlangAudioStreamMP3::QueueBuffer::QueueBuffer()
|
||||
{
|
||||
Capacity = 256;
|
||||
Size = 0;
|
||||
|
||||
Buffer = (ik_u8*)malloc(Capacity);
|
||||
}
|
||||
|
||||
|
||||
CIrrKlangAudioStreamMP3::QueueBuffer::~QueueBuffer()
|
||||
{
|
||||
free(Buffer);
|
||||
}
|
||||
|
||||
int CIrrKlangAudioStreamMP3::QueueBuffer::getSize()
|
||||
{
|
||||
return Size;
|
||||
}
|
||||
|
||||
void CIrrKlangAudioStreamMP3::QueueBuffer::write(const void* buffer, int size)
|
||||
{
|
||||
bool needRealloc = false;
|
||||
|
||||
while (size + Size > Capacity)
|
||||
{
|
||||
Capacity *= 2;
|
||||
needRealloc = true;
|
||||
}
|
||||
|
||||
if (needRealloc)
|
||||
{
|
||||
Buffer = (ik_u8*)realloc(Buffer, Capacity);
|
||||
}
|
||||
|
||||
memcpy(Buffer + Size, buffer, size);
|
||||
Size += size;
|
||||
}
|
||||
|
||||
|
||||
int CIrrKlangAudioStreamMP3::QueueBuffer::read(void* buffer, int size)
|
||||
{
|
||||
int toRead = size < Size ? size : Size;
|
||||
|
||||
memcpy(buffer, Buffer, toRead);
|
||||
memmove(Buffer, Buffer + toRead, Size - toRead);
|
||||
|
||||
Size -= toRead;
|
||||
return toRead;
|
||||
}
|
||||
|
||||
|
||||
void CIrrKlangAudioStreamMP3::QueueBuffer::clear()
|
||||
{
|
||||
Size = 0;
|
||||
}
|
||||
|
||||
|
||||
void CIrrKlangAudioStreamMP3::skipID3IfNecessary()
|
||||
{
|
||||
char header[10];
|
||||
int read = File->read(&header, 10);
|
||||
|
||||
if (read == 10 &&
|
||||
header[0] == 'I' && header[1] == 'D' && header[2] == '3')
|
||||
{
|
||||
int versionMajor = header[3];
|
||||
int versionMinor = header[4];
|
||||
int flags = header[5];
|
||||
|
||||
// IDv2 size looks like the following: ID3v2 size 4 * %0xxxxxxx.
|
||||
// Sick, but that's how it works.
|
||||
|
||||
int size = 0;
|
||||
size = (header[6] & 0x7f) << (3*7);
|
||||
size |= (header[7] & 0x7f) << (2*7);
|
||||
size |= (header[8] & 0x7f) << (1*7);
|
||||
size |= (header[9] & 0x7f) ;
|
||||
|
||||
size += 10; // header size
|
||||
|
||||
FileBegin = size;
|
||||
File->seek(FileBegin);
|
||||
}
|
||||
else
|
||||
File->seek(0);
|
||||
}
|
||||
|
||||
|
||||
} // end namespace irrklang
|
||||
@@ -1,106 +0,0 @@
|
||||
// Copyright (C) 2002-2007 Nikolaus Gebhardt
|
||||
// Part of the code for this plugin for irrKlang is based on:
|
||||
// MP3 input for Audiere by Matt Campbell <mattcampbell@pobox.com>, based on
|
||||
// libavcodec from ffmpeg (http://ffmpeg.sourceforge.net/).
|
||||
// See license.txt for license details of this plugin.
|
||||
|
||||
#ifndef __C_IRRKLANG_AUDIO_STREAM_MP3_H_INCLUDED__
|
||||
#define __C_IRRKLANG_AUDIO_STREAM_MP3_H_INCLUDED__
|
||||
|
||||
#include <ik_IAudioStream.h>
|
||||
#include <ik_IFileReader.h>
|
||||
#include <vector>
|
||||
#include "decoder/mpaudec.h"
|
||||
|
||||
namespace irrklang
|
||||
{
|
||||
const int IKP_MP3_INPUT_BUFFER_SIZE = 4096;
|
||||
|
||||
//! Reads and decodes audio data into an usable audio stream for the ISoundEngine
|
||||
/** To extend irrKlang with new audio format decoders, the only thing needed to do
|
||||
is implementing the IAudioStream interface. All the code available in this class is only for
|
||||
mp3 decoding and may make this class look a bit more complicated then it actually is. */
|
||||
class CIrrKlangAudioStreamMP3 : public IAudioStream
|
||||
{
|
||||
public:
|
||||
|
||||
CIrrKlangAudioStreamMP3(IFileReader* file);
|
||||
~CIrrKlangAudioStreamMP3();
|
||||
|
||||
//! returns format of the audio stream
|
||||
virtual SAudioStreamFormat getFormat();
|
||||
|
||||
//! tells the audio stream to read n audio frames into the specified buffer
|
||||
/** \param target: Target data buffer to the method will write the read frames into. The
|
||||
specified buffer will be getFormat().getFrameSize()*frameCount big.
|
||||
\param frameCount: amount of frames to be read.
|
||||
\returns Returns amount of frames really read. Should be frameCountToRead in most cases. */
|
||||
virtual ik_s32 readFrames(void* target, ik_s32 frameCountToRead);
|
||||
|
||||
//! sets the position of the audio stream.
|
||||
/** For example to let the stream be read from the beginning of the file again,
|
||||
setPosition(0) would be called. This is usually done be the sound engine to
|
||||
loop a stream after if has reached the end. Return true if sucessful and 0 if not. */
|
||||
virtual bool setPosition(ik_s32 pos);
|
||||
|
||||
// just for the CIrrKlangAudioStreamLoaderMP3 to let him know if loading worked
|
||||
bool isOK() { return File != 0; }
|
||||
|
||||
protected:
|
||||
|
||||
ik_s32 readFrameForMP3(void* target, ik_s32 frameCountToRead, bool parseOnly=false);
|
||||
bool decodeFrame();
|
||||
void skipID3IfNecessary();
|
||||
|
||||
irrklang::IFileReader* File;
|
||||
SAudioStreamFormat Format;
|
||||
|
||||
// mpaudec specific
|
||||
MPAuDecContext* TheMPAuDecContext;
|
||||
|
||||
ik_u8 InputBuffer[IKP_MP3_INPUT_BUFFER_SIZE];
|
||||
|
||||
int InputPosition;
|
||||
int InputLength;
|
||||
int Position;
|
||||
ik_u8* DecodeBuffer;
|
||||
ik_s32 FileBegin;
|
||||
ik_u32 CurrentFramePosition;
|
||||
|
||||
bool FirstFrameRead;
|
||||
bool EndOfFileReached;
|
||||
|
||||
// helper class for managing the streaming decoded audio data
|
||||
class QueueBuffer
|
||||
{
|
||||
public:
|
||||
|
||||
QueueBuffer();
|
||||
~QueueBuffer();
|
||||
|
||||
int getSize();
|
||||
void write(const void* buffer, int size);
|
||||
int read(void* buffer, int size);
|
||||
void clear();
|
||||
|
||||
private:
|
||||
|
||||
ik_u8* Buffer;
|
||||
int Capacity;
|
||||
int Size;
|
||||
};
|
||||
|
||||
struct SFramePositionData
|
||||
{
|
||||
int offset;
|
||||
int size;
|
||||
};
|
||||
|
||||
std::vector<SFramePositionData> FramePositionData;
|
||||
QueueBuffer DecodedQueue;
|
||||
};
|
||||
|
||||
|
||||
} // end namespace irrklang
|
||||
|
||||
#endif
|
||||
@@ -1,273 +0,0 @@
|
||||
/*
|
||||
* Common bit i/o utils
|
||||
* Copyright (c) 2000, 2001 Fabrice Bellard.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
* Modified by Matt Campbell <mattcampbell@pobox.com> for the stand-alone
|
||||
* mpaudec library. Based on common.c from libavcodec.
|
||||
*/
|
||||
|
||||
#include "internal.h"
|
||||
|
||||
/**
|
||||
* init GetBitContext.
|
||||
* @param buffer bitstream buffer
|
||||
* @param bit_size the size of the buffer in bits
|
||||
*/
|
||||
void init_get_bits(GetBitContext *s,
|
||||
const uint8_t *buffer, int bit_size)
|
||||
{
|
||||
s->buffer= buffer;
|
||||
s->size_in_bits= bit_size;
|
||||
s->index=0;
|
||||
}
|
||||
|
||||
unsigned int show_bits(const GetBitContext *s, int n)
|
||||
{
|
||||
int i;
|
||||
unsigned int result = 0;
|
||||
assert(s->size_in_bits - s->index >= n);
|
||||
for (i = s->index; i < s->index + n; i++) {
|
||||
int byte_index = i / 8;
|
||||
unsigned int right_shift = 7 - (i % 8);
|
||||
uint8_t byte = s->buffer[byte_index];
|
||||
uint8_t bit;
|
||||
result <<= 1;
|
||||
if (right_shift == 0)
|
||||
bit = byte & 0x1;
|
||||
else
|
||||
bit = (byte >> right_shift) & 0x1;
|
||||
result |= (unsigned int)bit;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
void skip_bits(GetBitContext *s, int n)
|
||||
{
|
||||
s->index += n;
|
||||
}
|
||||
|
||||
unsigned int get_bits(GetBitContext *s, int n)
|
||||
{
|
||||
unsigned int result = show_bits(s, n);
|
||||
skip_bits(s, n);
|
||||
return result;
|
||||
}
|
||||
|
||||
int get_bits_count(const GetBitContext *s)
|
||||
{
|
||||
return s->index;
|
||||
}
|
||||
|
||||
/* VLC decoding */
|
||||
|
||||
/*#define DEBUG_VLC*/
|
||||
|
||||
#define GET_DATA(v, table, i, wrap, size) \
|
||||
{\
|
||||
const uint8_t *ptr = (const uint8_t *)table + i * wrap;\
|
||||
switch(size) {\
|
||||
case 1:\
|
||||
v = *(const uint8_t *)ptr;\
|
||||
break;\
|
||||
case 2:\
|
||||
v = *(const uint16_t *)ptr;\
|
||||
break;\
|
||||
default:\
|
||||
v = *(const uint32_t *)ptr;\
|
||||
break;\
|
||||
}\
|
||||
}
|
||||
|
||||
|
||||
static int alloc_table(VLC *vlc, int size)
|
||||
{
|
||||
int index;
|
||||
index = vlc->table_size;
|
||||
vlc->table_size += size;
|
||||
if (vlc->table_size > vlc->table_allocated) {
|
||||
vlc->table_allocated += (1 << vlc->bits);
|
||||
vlc->table = realloc(vlc->table,
|
||||
sizeof(VLC_TYPE) * 2 * vlc->table_allocated);
|
||||
if (!vlc->table)
|
||||
return -1;
|
||||
}
|
||||
return index;
|
||||
}
|
||||
|
||||
static int build_table(VLC *vlc, int table_nb_bits,
|
||||
int nb_codes,
|
||||
const void *bits, int bits_wrap, int bits_size,
|
||||
const void *codes, int codes_wrap, int codes_size,
|
||||
uint32_t code_prefix, int n_prefix)
|
||||
{
|
||||
int i, j, k, n, table_size, table_index, nb, n1, index;
|
||||
uint32_t code;
|
||||
VLC_TYPE (*table)[2];
|
||||
|
||||
table_size = 1 << table_nb_bits;
|
||||
table_index = alloc_table(vlc, table_size);
|
||||
#ifdef DEBUG_VLC
|
||||
printf("new table index=%d size=%d code_prefix=%x n=%d\n",
|
||||
table_index, table_size, code_prefix, n_prefix);
|
||||
#endif
|
||||
if (table_index < 0)
|
||||
return -1;
|
||||
table = &vlc->table[table_index];
|
||||
|
||||
for(i=0;i<table_size;i++) {
|
||||
table[i][1] = 0; /*bits*/
|
||||
table[i][0] = -1; /*codes*/
|
||||
}
|
||||
|
||||
/* first pass: map codes and compute auxillary table sizes */
|
||||
for(i=0;i<nb_codes;i++) {
|
||||
GET_DATA(n, bits, i, bits_wrap, bits_size);
|
||||
GET_DATA(code, codes, i, codes_wrap, codes_size);
|
||||
/* we accept tables with holes */
|
||||
if (n <= 0)
|
||||
continue;
|
||||
#if defined(DEBUG_VLC) && 0
|
||||
printf("i=%d n=%d code=0x%x\n", i, n, code);
|
||||
#endif
|
||||
/* if code matches the prefix, it is in the table */
|
||||
n -= n_prefix;
|
||||
if (n > 0 && (code >> n) == code_prefix) {
|
||||
if (n <= table_nb_bits) {
|
||||
/* no need to add another table */
|
||||
j = (code << (table_nb_bits - n)) & (table_size - 1);
|
||||
nb = 1 << (table_nb_bits - n);
|
||||
for(k=0;k<nb;k++) {
|
||||
#ifdef DEBUG_VLC
|
||||
printf("%4x: code=%d n=%d\n",
|
||||
j, i, n);
|
||||
#endif
|
||||
assert(table[j][1] /*bits*/ == 0);
|
||||
table[j][1] = n; /*bits*/
|
||||
table[j][0] = i; /*code*/
|
||||
j++;
|
||||
}
|
||||
} else {
|
||||
n -= table_nb_bits;
|
||||
j = (code >> n) & ((1 << table_nb_bits) - 1);
|
||||
#ifdef DEBUG_VLC
|
||||
printf("%4x: n=%d (subtable)\n",
|
||||
j, n);
|
||||
#endif
|
||||
/* compute table size */
|
||||
n1 = -table[j][1]; /*bits*/
|
||||
if (n > n1)
|
||||
n1 = n;
|
||||
table[j][1] = -n1; /*bits*/
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* second pass : fill auxillary tables recursively */
|
||||
for(i=0;i<table_size;i++) {
|
||||
n = table[i][1]; /*bits*/
|
||||
if (n < 0) {
|
||||
n = -n;
|
||||
if (n > table_nb_bits) {
|
||||
n = table_nb_bits;
|
||||
table[i][1] = -n; /*bits*/
|
||||
}
|
||||
index = build_table(vlc, n, nb_codes,
|
||||
bits, bits_wrap, bits_size,
|
||||
codes, codes_wrap, codes_size,
|
||||
(code_prefix << table_nb_bits) | i,
|
||||
n_prefix + table_nb_bits);
|
||||
if (index < 0)
|
||||
return -1;
|
||||
/* note: realloc has been done, so reload tables */
|
||||
table = &vlc->table[table_index];
|
||||
table[i][0] = index; /*code*/
|
||||
}
|
||||
}
|
||||
return table_index;
|
||||
}
|
||||
|
||||
|
||||
/* Build VLC decoding tables suitable for use with get_vlc().
|
||||
|
||||
'nb_bits' set thee decoding table size (2^nb_bits) entries. The
|
||||
bigger it is, the faster is the decoding. But it should not be too
|
||||
big to save memory and L1 cache. '9' is a good compromise.
|
||||
|
||||
'nb_codes' : number of vlcs codes
|
||||
|
||||
'bits' : table which gives the size (in bits) of each vlc code.
|
||||
|
||||
'codes' : table which gives the bit pattern of of each vlc code.
|
||||
|
||||
'xxx_wrap' : give the number of bytes between each entry of the
|
||||
'bits' or 'codes' tables.
|
||||
|
||||
'xxx_size' : gives the number of bytes of each entry of the 'bits'
|
||||
or 'codes' tables.
|
||||
|
||||
'wrap' and 'size' allows to use any memory configuration and types
|
||||
(byte/word/long) to store the 'bits' and 'codes' tables.
|
||||
*/
|
||||
int init_vlc(VLC *vlc, int nb_bits, int nb_codes,
|
||||
const void *bits, int bits_wrap, int bits_size,
|
||||
const void *codes, int codes_wrap, int codes_size)
|
||||
{
|
||||
vlc->bits = nb_bits;
|
||||
vlc->table = NULL;
|
||||
vlc->table_allocated = 0;
|
||||
vlc->table_size = 0;
|
||||
#ifdef DEBUG_VLC
|
||||
printf("build table nb_codes=%d\n", nb_codes);
|
||||
#endif
|
||||
|
||||
if (build_table(vlc, nb_bits, nb_codes,
|
||||
bits, bits_wrap, bits_size,
|
||||
codes, codes_wrap, codes_size,
|
||||
0, 0) < 0) {
|
||||
free(vlc->table);
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
void free_vlc(VLC *vlc)
|
||||
{
|
||||
free(vlc->table);
|
||||
}
|
||||
|
||||
int get_vlc(GetBitContext *s, const VLC *vlc)
|
||||
{
|
||||
int code = 0;
|
||||
int depth = 0, max_depth = 3;
|
||||
int n, index, bits = vlc->bits;
|
||||
|
||||
do {
|
||||
index = show_bits(s, bits) + code;
|
||||
code = vlc->table[index][0];
|
||||
n = vlc->table[index][1];
|
||||
depth++;
|
||||
|
||||
if (n < 0 && depth < max_depth) {
|
||||
skip_bits(s, bits);
|
||||
bits = -n;
|
||||
}
|
||||
} while (n < 0 && depth < max_depth);
|
||||
|
||||
skip_bits(s, n);
|
||||
return code;
|
||||
}
|
||||
@@ -1,86 +0,0 @@
|
||||
/* Based on common.h from libavcodec. Modified extensively by Matt Campbell
|
||||
<mattcampbell@pobox.com> for the stand-alone mpaudec library. */
|
||||
|
||||
#ifndef INTERNAL_H
|
||||
#define INTERNAL_H
|
||||
|
||||
#if defined(_WIN32) && !defined(__MINGW32__) && !defined(__CYGWIN__)
|
||||
# define CONFIG_WIN32
|
||||
#endif
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <ctype.h>
|
||||
#include <math.h>
|
||||
#include <stddef.h>
|
||||
#include "mpaudec.h"
|
||||
|
||||
#ifndef M_PI
|
||||
#define M_PI 3.14159265358979323846
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_WIN32
|
||||
|
||||
/* windows */
|
||||
|
||||
typedef unsigned short uint16_t;
|
||||
typedef signed short int16_t;
|
||||
typedef unsigned char uint8_t;
|
||||
typedef unsigned int uint32_t;
|
||||
typedef unsigned __int64 uint64_t;
|
||||
typedef signed char int8_t;
|
||||
typedef signed int int32_t;
|
||||
typedef signed __int64 int64_t;
|
||||
|
||||
# ifdef _DEBUG
|
||||
# define DEBUG
|
||||
# endif
|
||||
|
||||
/* CONFIG_WIN32 end */
|
||||
#else
|
||||
|
||||
/* unix */
|
||||
|
||||
#include <inttypes.h>
|
||||
|
||||
#endif /* !CONFIG_WIN32 */
|
||||
|
||||
/* debug stuff */
|
||||
|
||||
#if !defined(DEBUG) && !defined(NDEBUG)
|
||||
# define NDEBUG
|
||||
#endif
|
||||
#include <assert.h>
|
||||
|
||||
/* bit input */
|
||||
|
||||
typedef struct GetBitContext {
|
||||
const uint8_t *buffer;
|
||||
int index;
|
||||
int size_in_bits;
|
||||
} GetBitContext;
|
||||
|
||||
int get_bits_count(const GetBitContext *s);
|
||||
|
||||
#define VLC_TYPE int16_t
|
||||
|
||||
typedef struct VLC {
|
||||
int bits;
|
||||
VLC_TYPE (*table)[2];
|
||||
int table_size, table_allocated;
|
||||
} VLC;
|
||||
|
||||
unsigned int get_bits(GetBitContext *s, int n);
|
||||
unsigned int show_bits(const GetBitContext *s, int n);
|
||||
void skip_bits(GetBitContext *s, int n);
|
||||
void init_get_bits(GetBitContext *s,
|
||||
const uint8_t *buffer, int buffer_size);
|
||||
|
||||
int init_vlc(VLC *vlc, int nb_bits, int nb_codes,
|
||||
const void *bits, int bits_wrap, int bits_size,
|
||||
const void *codes, int codes_wrap, int codes_size);
|
||||
void free_vlc(VLC *vlc);
|
||||
int get_vlc(GetBitContext *s, const VLC *vlc);
|
||||
|
||||
#endif /* INTERNAL_H */
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,34 +0,0 @@
|
||||
/* Portions based on avcodec.h from libavcodec. */
|
||||
|
||||
#ifndef MPAUDEC_H
|
||||
#define MPAUDEC_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* in bytes */
|
||||
#define MPAUDEC_MAX_AUDIO_FRAME_SIZE 4608
|
||||
|
||||
typedef struct MPAuDecContext {
|
||||
int bit_rate;
|
||||
int layer;
|
||||
int sample_rate;
|
||||
int channels;
|
||||
int frame_size;
|
||||
void *priv_data;
|
||||
int parse_only;
|
||||
int coded_frame_size;
|
||||
} MPAuDecContext;
|
||||
|
||||
int mpaudec_init(MPAuDecContext *mpctx);
|
||||
int mpaudec_decode_frame(MPAuDecContext * mpctx,
|
||||
void *data, int *data_size,
|
||||
const unsigned char * buf, int buf_size);
|
||||
void mpaudec_clear(MPAuDecContext *mpctx);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* MPAUDEC_H */
|
||||
@@ -1,772 +0,0 @@
|
||||
/* Modified slightly by Matt Campbell <mattcampbell@pobox.com> for the
|
||||
stand-alone mpaudec library. Based on mpegaudiodectab.h from libavcodec. */
|
||||
|
||||
static const uint16_t mpa_bitrate_tab[2][3][15] = {
|
||||
{ {0, 32, 64, 96, 128, 160, 192, 224, 256, 288, 320, 352, 384, 416, 448 },
|
||||
{0, 32, 48, 56, 64, 80, 96, 112, 128, 160, 192, 224, 256, 320, 384 },
|
||||
{0, 32, 40, 48, 56, 64, 80, 96, 112, 128, 160, 192, 224, 256, 320 } },
|
||||
{ {0, 32, 48, 56, 64, 80, 96, 112, 128, 144, 160, 176, 192, 224, 256},
|
||||
{0, 8, 16, 24, 32, 40, 48, 56, 64, 80, 96, 112, 128, 144, 160},
|
||||
{0, 8, 16, 24, 32, 40, 48, 56, 64, 80, 96, 112, 128, 144, 160}
|
||||
}
|
||||
};
|
||||
|
||||
static const uint16_t mpa_freq_tab[3] = { 44100, 48000, 32000 };
|
||||
|
||||
/*******************************************************/
|
||||
/* half mpeg encoding window (full precision) */
|
||||
static const int32_t mpa_enwindow[257] = {
|
||||
0, -1, -1, -1, -1, -1, -1, -2,
|
||||
-2, -2, -2, -3, -3, -4, -4, -5,
|
||||
-5, -6, -7, -7, -8, -9, -10, -11,
|
||||
-13, -14, -16, -17, -19, -21, -24, -26,
|
||||
-29, -31, -35, -38, -41, -45, -49, -53,
|
||||
-58, -63, -68, -73, -79, -85, -91, -97,
|
||||
-104, -111, -117, -125, -132, -139, -147, -154,
|
||||
-161, -169, -176, -183, -190, -196, -202, -208,
|
||||
213, 218, 222, 225, 227, 228, 228, 227,
|
||||
224, 221, 215, 208, 200, 189, 177, 163,
|
||||
146, 127, 106, 83, 57, 29, -2, -36,
|
||||
-72, -111, -153, -197, -244, -294, -347, -401,
|
||||
-459, -519, -581, -645, -711, -779, -848, -919,
|
||||
-991, -1064, -1137, -1210, -1283, -1356, -1428, -1498,
|
||||
-1567, -1634, -1698, -1759, -1817, -1870, -1919, -1962,
|
||||
-2001, -2032, -2057, -2075, -2085, -2087, -2080, -2063,
|
||||
2037, 2000, 1952, 1893, 1822, 1739, 1644, 1535,
|
||||
1414, 1280, 1131, 970, 794, 605, 402, 185,
|
||||
-45, -288, -545, -814, -1095, -1388, -1692, -2006,
|
||||
-2330, -2663, -3004, -3351, -3705, -4063, -4425, -4788,
|
||||
-5153, -5517, -5879, -6237, -6589, -6935, -7271, -7597,
|
||||
-7910, -8209, -8491, -8755, -8998, -9219, -9416, -9585,
|
||||
-9727, -9838, -9916, -9959, -9966, -9935, -9863, -9750,
|
||||
-9592, -9389, -9139, -8840, -8492, -8092, -7640, -7134,
|
||||
6574, 5959, 5288, 4561, 3776, 2935, 2037, 1082,
|
||||
70, -998, -2122, -3300, -4533, -5818, -7154, -8540,
|
||||
-9975,-11455,-12980,-14548,-16155,-17799,-19478,-21189,
|
||||
-22929,-24694,-26482,-28289,-30112,-31947,-33791,-35640,
|
||||
-37489,-39336,-41176,-43006,-44821,-46617,-48390,-50137,
|
||||
-51853,-53534,-55178,-56778,-58333,-59838,-61289,-62684,
|
||||
-64019,-65290,-66494,-67629,-68692,-69679,-70590,-71420,
|
||||
-72169,-72835,-73415,-73908,-74313,-74630,-74856,-74992,
|
||||
75038,
|
||||
};
|
||||
|
||||
/*******************************************************/
|
||||
/* layer 2 tables */
|
||||
|
||||
static const int sblimit_table[5] = { 27 , 30 , 8, 12 , 30 };
|
||||
|
||||
static const int quant_steps[17] = {
|
||||
3, 5, 7, 9, 15,
|
||||
31, 63, 127, 255, 511,
|
||||
1023, 2047, 4095, 8191, 16383,
|
||||
32767, 65535
|
||||
};
|
||||
|
||||
/* we use a negative value if grouped */
|
||||
static const int quant_bits[17] = {
|
||||
-5, -7, 3, -10, 4,
|
||||
5, 6, 7, 8, 9,
|
||||
10, 11, 12, 13, 14,
|
||||
15, 16
|
||||
};
|
||||
|
||||
/* encoding tables which give the quantization index. Note how it is
|
||||
possible to store them efficiently ! */
|
||||
static const unsigned char alloc_table_0[] = {
|
||||
4, 0, 2, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16,
|
||||
4, 0, 2, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16,
|
||||
4, 0, 2, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16,
|
||||
4, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 16,
|
||||
4, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 16,
|
||||
4, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 16,
|
||||
4, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 16,
|
||||
4, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 16,
|
||||
4, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 16,
|
||||
4, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 16,
|
||||
4, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 16,
|
||||
3, 0, 1, 2, 3, 4, 5, 16,
|
||||
3, 0, 1, 2, 3, 4, 5, 16,
|
||||
3, 0, 1, 2, 3, 4, 5, 16,
|
||||
3, 0, 1, 2, 3, 4, 5, 16,
|
||||
3, 0, 1, 2, 3, 4, 5, 16,
|
||||
3, 0, 1, 2, 3, 4, 5, 16,
|
||||
3, 0, 1, 2, 3, 4, 5, 16,
|
||||
3, 0, 1, 2, 3, 4, 5, 16,
|
||||
3, 0, 1, 2, 3, 4, 5, 16,
|
||||
3, 0, 1, 2, 3, 4, 5, 16,
|
||||
3, 0, 1, 2, 3, 4, 5, 16,
|
||||
3, 0, 1, 2, 3, 4, 5, 16,
|
||||
2, 0, 1, 16,
|
||||
2, 0, 1, 16,
|
||||
2, 0, 1, 16,
|
||||
2, 0, 1, 16,
|
||||
};
|
||||
|
||||
static const unsigned char alloc_table_1[] = {
|
||||
4, 0, 2, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16,
|
||||
4, 0, 2, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16,
|
||||
4, 0, 2, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16,
|
||||
4, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 16,
|
||||
4, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 16,
|
||||
4, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 16,
|
||||
4, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 16,
|
||||
4, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 16,
|
||||
4, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 16,
|
||||
4, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 16,
|
||||
4, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 16,
|
||||
3, 0, 1, 2, 3, 4, 5, 16,
|
||||
3, 0, 1, 2, 3, 4, 5, 16,
|
||||
3, 0, 1, 2, 3, 4, 5, 16,
|
||||
3, 0, 1, 2, 3, 4, 5, 16,
|
||||
3, 0, 1, 2, 3, 4, 5, 16,
|
||||
3, 0, 1, 2, 3, 4, 5, 16,
|
||||
3, 0, 1, 2, 3, 4, 5, 16,
|
||||
3, 0, 1, 2, 3, 4, 5, 16,
|
||||
3, 0, 1, 2, 3, 4, 5, 16,
|
||||
3, 0, 1, 2, 3, 4, 5, 16,
|
||||
3, 0, 1, 2, 3, 4, 5, 16,
|
||||
3, 0, 1, 2, 3, 4, 5, 16,
|
||||
2, 0, 1, 16,
|
||||
2, 0, 1, 16,
|
||||
2, 0, 1, 16,
|
||||
2, 0, 1, 16,
|
||||
2, 0, 1, 16,
|
||||
2, 0, 1, 16,
|
||||
2, 0, 1, 16,
|
||||
};
|
||||
|
||||
static const unsigned char alloc_table_2[] = {
|
||||
4, 0, 1, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
|
||||
4, 0, 1, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
|
||||
3, 0, 1, 3, 4, 5, 6, 7,
|
||||
3, 0, 1, 3, 4, 5, 6, 7,
|
||||
3, 0, 1, 3, 4, 5, 6, 7,
|
||||
3, 0, 1, 3, 4, 5, 6, 7,
|
||||
3, 0, 1, 3, 4, 5, 6, 7,
|
||||
3, 0, 1, 3, 4, 5, 6, 7,
|
||||
};
|
||||
|
||||
static const unsigned char alloc_table_3[] = {
|
||||
4, 0, 1, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
|
||||
4, 0, 1, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
|
||||
3, 0, 1, 3, 4, 5, 6, 7,
|
||||
3, 0, 1, 3, 4, 5, 6, 7,
|
||||
3, 0, 1, 3, 4, 5, 6, 7,
|
||||
3, 0, 1, 3, 4, 5, 6, 7,
|
||||
3, 0, 1, 3, 4, 5, 6, 7,
|
||||
3, 0, 1, 3, 4, 5, 6, 7,
|
||||
3, 0, 1, 3, 4, 5, 6, 7,
|
||||
3, 0, 1, 3, 4, 5, 6, 7,
|
||||
3, 0, 1, 3, 4, 5, 6, 7,
|
||||
3, 0, 1, 3, 4, 5, 6, 7,
|
||||
};
|
||||
|
||||
static const unsigned char alloc_table_4[] = {
|
||||
4, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
|
||||
4, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
|
||||
4, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
|
||||
4, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
|
||||
3, 0, 1, 3, 4, 5, 6, 7,
|
||||
3, 0, 1, 3, 4, 5, 6, 7,
|
||||
3, 0, 1, 3, 4, 5, 6, 7,
|
||||
3, 0, 1, 3, 4, 5, 6, 7,
|
||||
3, 0, 1, 3, 4, 5, 6, 7,
|
||||
3, 0, 1, 3, 4, 5, 6, 7,
|
||||
3, 0, 1, 3, 4, 5, 6, 7,
|
||||
2, 0, 1, 3,
|
||||
2, 0, 1, 3,
|
||||
2, 0, 1, 3,
|
||||
2, 0, 1, 3,
|
||||
2, 0, 1, 3,
|
||||
2, 0, 1, 3,
|
||||
2, 0, 1, 3,
|
||||
2, 0, 1, 3,
|
||||
2, 0, 1, 3,
|
||||
2, 0, 1, 3,
|
||||
2, 0, 1, 3,
|
||||
2, 0, 1, 3,
|
||||
2, 0, 1, 3,
|
||||
2, 0, 1, 3,
|
||||
2, 0, 1, 3,
|
||||
2, 0, 1, 3,
|
||||
2, 0, 1, 3,
|
||||
2, 0, 1, 3,
|
||||
2, 0, 1, 3,
|
||||
};
|
||||
|
||||
static const unsigned char *alloc_tables[5] =
|
||||
{ alloc_table_0, alloc_table_1, alloc_table_2, alloc_table_3, alloc_table_4, };
|
||||
|
||||
/*******************************************************/
|
||||
/* layer 3 tables */
|
||||
|
||||
/* layer3 scale factor size */
|
||||
static const uint8_t slen_table[2][16] = {
|
||||
{ 0, 0, 0, 0, 3, 1, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4 },
|
||||
{ 0, 1, 2, 3, 0, 1, 2, 3, 1, 2, 3, 1, 2, 3, 2, 3 },
|
||||
};
|
||||
|
||||
/* number of lsf scale factors for a given size */
|
||||
static const uint8_t lsf_nsf_table[6][3][4] = {
|
||||
{ { 6, 5, 5, 5 }, { 9, 9, 9, 9 }, { 6, 9, 9, 9 } },
|
||||
{ { 6, 5, 7, 3 }, { 9, 9, 12, 6 }, { 6, 9, 12, 6 } },
|
||||
{ { 11, 10, 0, 0 }, { 18, 18, 0, 0 }, { 15, 18, 0, 0 } },
|
||||
{ { 7, 7, 7, 0 }, { 12, 12, 12, 0 }, { 6, 15, 12, 0 } },
|
||||
{ { 6, 6, 6, 3 }, { 12, 9, 9, 6 }, { 6, 12, 9, 6 } },
|
||||
{ { 8, 8, 5, 0 }, { 15, 12, 9, 0 }, { 6, 18, 9, 0 } },
|
||||
};
|
||||
|
||||
/* mpegaudio layer 3 huffman tables */
|
||||
|
||||
static const uint16_t mpa_huffcodes_1[4] = {
|
||||
0x0001, 0x0001, 0x0001, 0x0000,
|
||||
};
|
||||
|
||||
static const uint8_t mpa_huffbits_1[4] = {
|
||||
1, 3, 2, 3,
|
||||
};
|
||||
|
||||
static const uint16_t mpa_huffcodes_2[9] = {
|
||||
0x0001, 0x0002, 0x0001, 0x0003, 0x0001, 0x0001, 0x0003, 0x0002,
|
||||
0x0000,
|
||||
};
|
||||
|
||||
static const uint8_t mpa_huffbits_2[9] = {
|
||||
1, 3, 6, 3, 3, 5, 5, 5,
|
||||
6,
|
||||
};
|
||||
|
||||
static const uint16_t mpa_huffcodes_3[9] = {
|
||||
0x0003, 0x0002, 0x0001, 0x0001, 0x0001, 0x0001, 0x0003, 0x0002,
|
||||
0x0000,
|
||||
};
|
||||
|
||||
static const uint8_t mpa_huffbits_3[9] = {
|
||||
2, 2, 6, 3, 2, 5, 5, 5,
|
||||
6,
|
||||
};
|
||||
|
||||
static const uint16_t mpa_huffcodes_5[16] = {
|
||||
0x0001, 0x0002, 0x0006, 0x0005, 0x0003, 0x0001, 0x0004, 0x0004,
|
||||
0x0007, 0x0005, 0x0007, 0x0001, 0x0006, 0x0001, 0x0001, 0x0000,
|
||||
};
|
||||
|
||||
static const uint8_t mpa_huffbits_5[16] = {
|
||||
1, 3, 6, 7, 3, 3, 6, 7,
|
||||
6, 6, 7, 8, 7, 6, 7, 8,
|
||||
};
|
||||
|
||||
static const uint16_t mpa_huffcodes_6[16] = {
|
||||
0x0007, 0x0003, 0x0005, 0x0001, 0x0006, 0x0002, 0x0003, 0x0002,
|
||||
0x0005, 0x0004, 0x0004, 0x0001, 0x0003, 0x0003, 0x0002, 0x0000,
|
||||
};
|
||||
|
||||
static const uint8_t mpa_huffbits_6[16] = {
|
||||
3, 3, 5, 7, 3, 2, 4, 5,
|
||||
4, 4, 5, 6, 6, 5, 6, 7,
|
||||
};
|
||||
|
||||
static const uint16_t mpa_huffcodes_7[36] = {
|
||||
0x0001, 0x0002, 0x000a, 0x0013, 0x0010, 0x000a, 0x0003, 0x0003,
|
||||
0x0007, 0x000a, 0x0005, 0x0003, 0x000b, 0x0004, 0x000d, 0x0011,
|
||||
0x0008, 0x0004, 0x000c, 0x000b, 0x0012, 0x000f, 0x000b, 0x0002,
|
||||
0x0007, 0x0006, 0x0009, 0x000e, 0x0003, 0x0001, 0x0006, 0x0004,
|
||||
0x0005, 0x0003, 0x0002, 0x0000,
|
||||
};
|
||||
|
||||
static const uint8_t mpa_huffbits_7[36] = {
|
||||
1, 3, 6, 8, 8, 9, 3, 4,
|
||||
6, 7, 7, 8, 6, 5, 7, 8,
|
||||
8, 9, 7, 7, 8, 9, 9, 9,
|
||||
7, 7, 8, 9, 9, 10, 8, 8,
|
||||
9, 10, 10, 10,
|
||||
};
|
||||
|
||||
static const uint16_t mpa_huffcodes_8[36] = {
|
||||
0x0003, 0x0004, 0x0006, 0x0012, 0x000c, 0x0005, 0x0005, 0x0001,
|
||||
0x0002, 0x0010, 0x0009, 0x0003, 0x0007, 0x0003, 0x0005, 0x000e,
|
||||
0x0007, 0x0003, 0x0013, 0x0011, 0x000f, 0x000d, 0x000a, 0x0004,
|
||||
0x000d, 0x0005, 0x0008, 0x000b, 0x0005, 0x0001, 0x000c, 0x0004,
|
||||
0x0004, 0x0001, 0x0001, 0x0000,
|
||||
};
|
||||
|
||||
static const uint8_t mpa_huffbits_8[36] = {
|
||||
2, 3, 6, 8, 8, 9, 3, 2,
|
||||
4, 8, 8, 8, 6, 4, 6, 8,
|
||||
8, 9, 8, 8, 8, 9, 9, 10,
|
||||
8, 7, 8, 9, 10, 10, 9, 8,
|
||||
9, 9, 11, 11,
|
||||
};
|
||||
|
||||
static const uint16_t mpa_huffcodes_9[36] = {
|
||||
0x0007, 0x0005, 0x0009, 0x000e, 0x000f, 0x0007, 0x0006, 0x0004,
|
||||
0x0005, 0x0005, 0x0006, 0x0007, 0x0007, 0x0006, 0x0008, 0x0008,
|
||||
0x0008, 0x0005, 0x000f, 0x0006, 0x0009, 0x000a, 0x0005, 0x0001,
|
||||
0x000b, 0x0007, 0x0009, 0x0006, 0x0004, 0x0001, 0x000e, 0x0004,
|
||||
0x0006, 0x0002, 0x0006, 0x0000,
|
||||
};
|
||||
|
||||
static const uint8_t mpa_huffbits_9[36] = {
|
||||
3, 3, 5, 6, 8, 9, 3, 3,
|
||||
4, 5, 6, 8, 4, 4, 5, 6,
|
||||
7, 8, 6, 5, 6, 7, 7, 8,
|
||||
7, 6, 7, 7, 8, 9, 8, 7,
|
||||
8, 8, 9, 9,
|
||||
};
|
||||
|
||||
static const uint16_t mpa_huffcodes_10[64] = {
|
||||
0x0001, 0x0002, 0x000a, 0x0017, 0x0023, 0x001e, 0x000c, 0x0011,
|
||||
0x0003, 0x0003, 0x0008, 0x000c, 0x0012, 0x0015, 0x000c, 0x0007,
|
||||
0x000b, 0x0009, 0x000f, 0x0015, 0x0020, 0x0028, 0x0013, 0x0006,
|
||||
0x000e, 0x000d, 0x0016, 0x0022, 0x002e, 0x0017, 0x0012, 0x0007,
|
||||
0x0014, 0x0013, 0x0021, 0x002f, 0x001b, 0x0016, 0x0009, 0x0003,
|
||||
0x001f, 0x0016, 0x0029, 0x001a, 0x0015, 0x0014, 0x0005, 0x0003,
|
||||
0x000e, 0x000d, 0x000a, 0x000b, 0x0010, 0x0006, 0x0005, 0x0001,
|
||||
0x0009, 0x0008, 0x0007, 0x0008, 0x0004, 0x0004, 0x0002, 0x0000,
|
||||
};
|
||||
|
||||
static const uint8_t mpa_huffbits_10[64] = {
|
||||
1, 3, 6, 8, 9, 9, 9, 10,
|
||||
3, 4, 6, 7, 8, 9, 8, 8,
|
||||
6, 6, 7, 8, 9, 10, 9, 9,
|
||||
7, 7, 8, 9, 10, 10, 9, 10,
|
||||
8, 8, 9, 10, 10, 10, 10, 10,
|
||||
9, 9, 10, 10, 11, 11, 10, 11,
|
||||
8, 8, 9, 10, 10, 10, 11, 11,
|
||||
9, 8, 9, 10, 10, 11, 11, 11,
|
||||
};
|
||||
|
||||
static const uint16_t mpa_huffcodes_11[64] = {
|
||||
0x0003, 0x0004, 0x000a, 0x0018, 0x0022, 0x0021, 0x0015, 0x000f,
|
||||
0x0005, 0x0003, 0x0004, 0x000a, 0x0020, 0x0011, 0x000b, 0x000a,
|
||||
0x000b, 0x0007, 0x000d, 0x0012, 0x001e, 0x001f, 0x0014, 0x0005,
|
||||
0x0019, 0x000b, 0x0013, 0x003b, 0x001b, 0x0012, 0x000c, 0x0005,
|
||||
0x0023, 0x0021, 0x001f, 0x003a, 0x001e, 0x0010, 0x0007, 0x0005,
|
||||
0x001c, 0x001a, 0x0020, 0x0013, 0x0011, 0x000f, 0x0008, 0x000e,
|
||||
0x000e, 0x000c, 0x0009, 0x000d, 0x000e, 0x0009, 0x0004, 0x0001,
|
||||
0x000b, 0x0004, 0x0006, 0x0006, 0x0006, 0x0003, 0x0002, 0x0000,
|
||||
};
|
||||
|
||||
static const uint8_t mpa_huffbits_11[64] = {
|
||||
2, 3, 5, 7, 8, 9, 8, 9,
|
||||
3, 3, 4, 6, 8, 8, 7, 8,
|
||||
5, 5, 6, 7, 8, 9, 8, 8,
|
||||
7, 6, 7, 9, 8, 10, 8, 9,
|
||||
8, 8, 8, 9, 9, 10, 9, 10,
|
||||
8, 8, 9, 10, 10, 11, 10, 11,
|
||||
8, 7, 7, 8, 9, 10, 10, 10,
|
||||
8, 7, 8, 9, 10, 10, 10, 10,
|
||||
};
|
||||
|
||||
static const uint16_t mpa_huffcodes_12[64] = {
|
||||
0x0009, 0x0006, 0x0010, 0x0021, 0x0029, 0x0027, 0x0026, 0x001a,
|
||||
0x0007, 0x0005, 0x0006, 0x0009, 0x0017, 0x0010, 0x001a, 0x000b,
|
||||
0x0011, 0x0007, 0x000b, 0x000e, 0x0015, 0x001e, 0x000a, 0x0007,
|
||||
0x0011, 0x000a, 0x000f, 0x000c, 0x0012, 0x001c, 0x000e, 0x0005,
|
||||
0x0020, 0x000d, 0x0016, 0x0013, 0x0012, 0x0010, 0x0009, 0x0005,
|
||||
0x0028, 0x0011, 0x001f, 0x001d, 0x0011, 0x000d, 0x0004, 0x0002,
|
||||
0x001b, 0x000c, 0x000b, 0x000f, 0x000a, 0x0007, 0x0004, 0x0001,
|
||||
0x001b, 0x000c, 0x0008, 0x000c, 0x0006, 0x0003, 0x0001, 0x0000,
|
||||
};
|
||||
|
||||
static const uint8_t mpa_huffbits_12[64] = {
|
||||
4, 3, 5, 7, 8, 9, 9, 9,
|
||||
3, 3, 4, 5, 7, 7, 8, 8,
|
||||
5, 4, 5, 6, 7, 8, 7, 8,
|
||||
6, 5, 6, 6, 7, 8, 8, 8,
|
||||
7, 6, 7, 7, 8, 8, 8, 9,
|
||||
8, 7, 8, 8, 8, 9, 8, 9,
|
||||
8, 7, 7, 8, 8, 9, 9, 10,
|
||||
9, 8, 8, 9, 9, 9, 9, 10,
|
||||
};
|
||||
|
||||
static const uint16_t mpa_huffcodes_13[256] = {
|
||||
0x0001, 0x0005, 0x000e, 0x0015, 0x0022, 0x0033, 0x002e, 0x0047,
|
||||
0x002a, 0x0034, 0x0044, 0x0034, 0x0043, 0x002c, 0x002b, 0x0013,
|
||||
0x0003, 0x0004, 0x000c, 0x0013, 0x001f, 0x001a, 0x002c, 0x0021,
|
||||
0x001f, 0x0018, 0x0020, 0x0018, 0x001f, 0x0023, 0x0016, 0x000e,
|
||||
0x000f, 0x000d, 0x0017, 0x0024, 0x003b, 0x0031, 0x004d, 0x0041,
|
||||
0x001d, 0x0028, 0x001e, 0x0028, 0x001b, 0x0021, 0x002a, 0x0010,
|
||||
0x0016, 0x0014, 0x0025, 0x003d, 0x0038, 0x004f, 0x0049, 0x0040,
|
||||
0x002b, 0x004c, 0x0038, 0x0025, 0x001a, 0x001f, 0x0019, 0x000e,
|
||||
0x0023, 0x0010, 0x003c, 0x0039, 0x0061, 0x004b, 0x0072, 0x005b,
|
||||
0x0036, 0x0049, 0x0037, 0x0029, 0x0030, 0x0035, 0x0017, 0x0018,
|
||||
0x003a, 0x001b, 0x0032, 0x0060, 0x004c, 0x0046, 0x005d, 0x0054,
|
||||
0x004d, 0x003a, 0x004f, 0x001d, 0x004a, 0x0031, 0x0029, 0x0011,
|
||||
0x002f, 0x002d, 0x004e, 0x004a, 0x0073, 0x005e, 0x005a, 0x004f,
|
||||
0x0045, 0x0053, 0x0047, 0x0032, 0x003b, 0x0026, 0x0024, 0x000f,
|
||||
0x0048, 0x0022, 0x0038, 0x005f, 0x005c, 0x0055, 0x005b, 0x005a,
|
||||
0x0056, 0x0049, 0x004d, 0x0041, 0x0033, 0x002c, 0x002b, 0x002a,
|
||||
0x002b, 0x0014, 0x001e, 0x002c, 0x0037, 0x004e, 0x0048, 0x0057,
|
||||
0x004e, 0x003d, 0x002e, 0x0036, 0x0025, 0x001e, 0x0014, 0x0010,
|
||||
0x0035, 0x0019, 0x0029, 0x0025, 0x002c, 0x003b, 0x0036, 0x0051,
|
||||
0x0042, 0x004c, 0x0039, 0x0036, 0x0025, 0x0012, 0x0027, 0x000b,
|
||||
0x0023, 0x0021, 0x001f, 0x0039, 0x002a, 0x0052, 0x0048, 0x0050,
|
||||
0x002f, 0x003a, 0x0037, 0x0015, 0x0016, 0x001a, 0x0026, 0x0016,
|
||||
0x0035, 0x0019, 0x0017, 0x0026, 0x0046, 0x003c, 0x0033, 0x0024,
|
||||
0x0037, 0x001a, 0x0022, 0x0017, 0x001b, 0x000e, 0x0009, 0x0007,
|
||||
0x0022, 0x0020, 0x001c, 0x0027, 0x0031, 0x004b, 0x001e, 0x0034,
|
||||
0x0030, 0x0028, 0x0034, 0x001c, 0x0012, 0x0011, 0x0009, 0x0005,
|
||||
0x002d, 0x0015, 0x0022, 0x0040, 0x0038, 0x0032, 0x0031, 0x002d,
|
||||
0x001f, 0x0013, 0x000c, 0x000f, 0x000a, 0x0007, 0x0006, 0x0003,
|
||||
0x0030, 0x0017, 0x0014, 0x0027, 0x0024, 0x0023, 0x0035, 0x0015,
|
||||
0x0010, 0x0017, 0x000d, 0x000a, 0x0006, 0x0001, 0x0004, 0x0002,
|
||||
0x0010, 0x000f, 0x0011, 0x001b, 0x0019, 0x0014, 0x001d, 0x000b,
|
||||
0x0011, 0x000c, 0x0010, 0x0008, 0x0001, 0x0001, 0x0000, 0x0001,
|
||||
};
|
||||
|
||||
static const uint8_t mpa_huffbits_13[256] = {
|
||||
1, 4, 6, 7, 8, 9, 9, 10,
|
||||
9, 10, 11, 11, 12, 12, 13, 13,
|
||||
3, 4, 6, 7, 8, 8, 9, 9,
|
||||
9, 9, 10, 10, 11, 12, 12, 12,
|
||||
6, 6, 7, 8, 9, 9, 10, 10,
|
||||
9, 10, 10, 11, 11, 12, 13, 13,
|
||||
7, 7, 8, 9, 9, 10, 10, 10,
|
||||
10, 11, 11, 11, 11, 12, 13, 13,
|
||||
8, 7, 9, 9, 10, 10, 11, 11,
|
||||
10, 11, 11, 12, 12, 13, 13, 14,
|
||||
9, 8, 9, 10, 10, 10, 11, 11,
|
||||
11, 11, 12, 11, 13, 13, 14, 14,
|
||||
9, 9, 10, 10, 11, 11, 11, 11,
|
||||
11, 12, 12, 12, 13, 13, 14, 14,
|
||||
10, 9, 10, 11, 11, 11, 12, 12,
|
||||
12, 12, 13, 13, 13, 14, 16, 16,
|
||||
9, 8, 9, 10, 10, 11, 11, 12,
|
||||
12, 12, 12, 13, 13, 14, 15, 15,
|
||||
10, 9, 10, 10, 11, 11, 11, 13,
|
||||
12, 13, 13, 14, 14, 14, 16, 15,
|
||||
10, 10, 10, 11, 11, 12, 12, 13,
|
||||
12, 13, 14, 13, 14, 15, 16, 17,
|
||||
11, 10, 10, 11, 12, 12, 12, 12,
|
||||
13, 13, 13, 14, 15, 15, 15, 16,
|
||||
11, 11, 11, 12, 12, 13, 12, 13,
|
||||
14, 14, 15, 15, 15, 16, 16, 16,
|
||||
12, 11, 12, 13, 13, 13, 14, 14,
|
||||
14, 14, 14, 15, 16, 15, 16, 16,
|
||||
13, 12, 12, 13, 13, 13, 15, 14,
|
||||
14, 17, 15, 15, 15, 17, 16, 16,
|
||||
12, 12, 13, 14, 14, 14, 15, 14,
|
||||
15, 15, 16, 16, 19, 18, 19, 16,
|
||||
};
|
||||
|
||||
static const uint16_t mpa_huffcodes_15[256] = {
|
||||
0x0007, 0x000c, 0x0012, 0x0035, 0x002f, 0x004c, 0x007c, 0x006c,
|
||||
0x0059, 0x007b, 0x006c, 0x0077, 0x006b, 0x0051, 0x007a, 0x003f,
|
||||
0x000d, 0x0005, 0x0010, 0x001b, 0x002e, 0x0024, 0x003d, 0x0033,
|
||||
0x002a, 0x0046, 0x0034, 0x0053, 0x0041, 0x0029, 0x003b, 0x0024,
|
||||
0x0013, 0x0011, 0x000f, 0x0018, 0x0029, 0x0022, 0x003b, 0x0030,
|
||||
0x0028, 0x0040, 0x0032, 0x004e, 0x003e, 0x0050, 0x0038, 0x0021,
|
||||
0x001d, 0x001c, 0x0019, 0x002b, 0x0027, 0x003f, 0x0037, 0x005d,
|
||||
0x004c, 0x003b, 0x005d, 0x0048, 0x0036, 0x004b, 0x0032, 0x001d,
|
||||
0x0034, 0x0016, 0x002a, 0x0028, 0x0043, 0x0039, 0x005f, 0x004f,
|
||||
0x0048, 0x0039, 0x0059, 0x0045, 0x0031, 0x0042, 0x002e, 0x001b,
|
||||
0x004d, 0x0025, 0x0023, 0x0042, 0x003a, 0x0034, 0x005b, 0x004a,
|
||||
0x003e, 0x0030, 0x004f, 0x003f, 0x005a, 0x003e, 0x0028, 0x0026,
|
||||
0x007d, 0x0020, 0x003c, 0x0038, 0x0032, 0x005c, 0x004e, 0x0041,
|
||||
0x0037, 0x0057, 0x0047, 0x0033, 0x0049, 0x0033, 0x0046, 0x001e,
|
||||
0x006d, 0x0035, 0x0031, 0x005e, 0x0058, 0x004b, 0x0042, 0x007a,
|
||||
0x005b, 0x0049, 0x0038, 0x002a, 0x0040, 0x002c, 0x0015, 0x0019,
|
||||
0x005a, 0x002b, 0x0029, 0x004d, 0x0049, 0x003f, 0x0038, 0x005c,
|
||||
0x004d, 0x0042, 0x002f, 0x0043, 0x0030, 0x0035, 0x0024, 0x0014,
|
||||
0x0047, 0x0022, 0x0043, 0x003c, 0x003a, 0x0031, 0x0058, 0x004c,
|
||||
0x0043, 0x006a, 0x0047, 0x0036, 0x0026, 0x0027, 0x0017, 0x000f,
|
||||
0x006d, 0x0035, 0x0033, 0x002f, 0x005a, 0x0052, 0x003a, 0x0039,
|
||||
0x0030, 0x0048, 0x0039, 0x0029, 0x0017, 0x001b, 0x003e, 0x0009,
|
||||
0x0056, 0x002a, 0x0028, 0x0025, 0x0046, 0x0040, 0x0034, 0x002b,
|
||||
0x0046, 0x0037, 0x002a, 0x0019, 0x001d, 0x0012, 0x000b, 0x000b,
|
||||
0x0076, 0x0044, 0x001e, 0x0037, 0x0032, 0x002e, 0x004a, 0x0041,
|
||||
0x0031, 0x0027, 0x0018, 0x0010, 0x0016, 0x000d, 0x000e, 0x0007,
|
||||
0x005b, 0x002c, 0x0027, 0x0026, 0x0022, 0x003f, 0x0034, 0x002d,
|
||||
0x001f, 0x0034, 0x001c, 0x0013, 0x000e, 0x0008, 0x0009, 0x0003,
|
||||
0x007b, 0x003c, 0x003a, 0x0035, 0x002f, 0x002b, 0x0020, 0x0016,
|
||||
0x0025, 0x0018, 0x0011, 0x000c, 0x000f, 0x000a, 0x0002, 0x0001,
|
||||
0x0047, 0x0025, 0x0022, 0x001e, 0x001c, 0x0014, 0x0011, 0x001a,
|
||||
0x0015, 0x0010, 0x000a, 0x0006, 0x0008, 0x0006, 0x0002, 0x0000,
|
||||
};
|
||||
|
||||
static const uint8_t mpa_huffbits_15[256] = {
|
||||
3, 4, 5, 7, 7, 8, 9, 9,
|
||||
9, 10, 10, 11, 11, 11, 12, 13,
|
||||
4, 3, 5, 6, 7, 7, 8, 8,
|
||||
8, 9, 9, 10, 10, 10, 11, 11,
|
||||
5, 5, 5, 6, 7, 7, 8, 8,
|
||||
8, 9, 9, 10, 10, 11, 11, 11,
|
||||
6, 6, 6, 7, 7, 8, 8, 9,
|
||||
9, 9, 10, 10, 10, 11, 11, 11,
|
||||
7, 6, 7, 7, 8, 8, 9, 9,
|
||||
9, 9, 10, 10, 10, 11, 11, 11,
|
||||
8, 7, 7, 8, 8, 8, 9, 9,
|
||||
9, 9, 10, 10, 11, 11, 11, 12,
|
||||
9, 7, 8, 8, 8, 9, 9, 9,
|
||||
9, 10, 10, 10, 11, 11, 12, 12,
|
||||
9, 8, 8, 9, 9, 9, 9, 10,
|
||||
10, 10, 10, 10, 11, 11, 11, 12,
|
||||
9, 8, 8, 9, 9, 9, 9, 10,
|
||||
10, 10, 10, 11, 11, 12, 12, 12,
|
||||
9, 8, 9, 9, 9, 9, 10, 10,
|
||||
10, 11, 11, 11, 11, 12, 12, 12,
|
||||
10, 9, 9, 9, 10, 10, 10, 10,
|
||||
10, 11, 11, 11, 11, 12, 13, 12,
|
||||
10, 9, 9, 9, 10, 10, 10, 10,
|
||||
11, 11, 11, 11, 12, 12, 12, 13,
|
||||
11, 10, 9, 10, 10, 10, 11, 11,
|
||||
11, 11, 11, 11, 12, 12, 13, 13,
|
||||
11, 10, 10, 10, 10, 11, 11, 11,
|
||||
11, 12, 12, 12, 12, 12, 13, 13,
|
||||
12, 11, 11, 11, 11, 11, 11, 11,
|
||||
12, 12, 12, 12, 13, 13, 12, 13,
|
||||
12, 11, 11, 11, 11, 11, 11, 12,
|
||||
12, 12, 12, 12, 13, 13, 13, 13,
|
||||
};
|
||||
|
||||
static const uint16_t mpa_huffcodes_16[256] = {
|
||||
0x0001, 0x0005, 0x000e, 0x002c, 0x004a, 0x003f, 0x006e, 0x005d,
|
||||
0x00ac, 0x0095, 0x008a, 0x00f2, 0x00e1, 0x00c3, 0x0178, 0x0011,
|
||||
0x0003, 0x0004, 0x000c, 0x0014, 0x0023, 0x003e, 0x0035, 0x002f,
|
||||
0x0053, 0x004b, 0x0044, 0x0077, 0x00c9, 0x006b, 0x00cf, 0x0009,
|
||||
0x000f, 0x000d, 0x0017, 0x0026, 0x0043, 0x003a, 0x0067, 0x005a,
|
||||
0x00a1, 0x0048, 0x007f, 0x0075, 0x006e, 0x00d1, 0x00ce, 0x0010,
|
||||
0x002d, 0x0015, 0x0027, 0x0045, 0x0040, 0x0072, 0x0063, 0x0057,
|
||||
0x009e, 0x008c, 0x00fc, 0x00d4, 0x00c7, 0x0183, 0x016d, 0x001a,
|
||||
0x004b, 0x0024, 0x0044, 0x0041, 0x0073, 0x0065, 0x00b3, 0x00a4,
|
||||
0x009b, 0x0108, 0x00f6, 0x00e2, 0x018b, 0x017e, 0x016a, 0x0009,
|
||||
0x0042, 0x001e, 0x003b, 0x0038, 0x0066, 0x00b9, 0x00ad, 0x0109,
|
||||
0x008e, 0x00fd, 0x00e8, 0x0190, 0x0184, 0x017a, 0x01bd, 0x0010,
|
||||
0x006f, 0x0036, 0x0034, 0x0064, 0x00b8, 0x00b2, 0x00a0, 0x0085,
|
||||
0x0101, 0x00f4, 0x00e4, 0x00d9, 0x0181, 0x016e, 0x02cb, 0x000a,
|
||||
0x0062, 0x0030, 0x005b, 0x0058, 0x00a5, 0x009d, 0x0094, 0x0105,
|
||||
0x00f8, 0x0197, 0x018d, 0x0174, 0x017c, 0x0379, 0x0374, 0x0008,
|
||||
0x0055, 0x0054, 0x0051, 0x009f, 0x009c, 0x008f, 0x0104, 0x00f9,
|
||||
0x01ab, 0x0191, 0x0188, 0x017f, 0x02d7, 0x02c9, 0x02c4, 0x0007,
|
||||
0x009a, 0x004c, 0x0049, 0x008d, 0x0083, 0x0100, 0x00f5, 0x01aa,
|
||||
0x0196, 0x018a, 0x0180, 0x02df, 0x0167, 0x02c6, 0x0160, 0x000b,
|
||||
0x008b, 0x0081, 0x0043, 0x007d, 0x00f7, 0x00e9, 0x00e5, 0x00db,
|
||||
0x0189, 0x02e7, 0x02e1, 0x02d0, 0x0375, 0x0372, 0x01b7, 0x0004,
|
||||
0x00f3, 0x0078, 0x0076, 0x0073, 0x00e3, 0x00df, 0x018c, 0x02ea,
|
||||
0x02e6, 0x02e0, 0x02d1, 0x02c8, 0x02c2, 0x00df, 0x01b4, 0x0006,
|
||||
0x00ca, 0x00e0, 0x00de, 0x00da, 0x00d8, 0x0185, 0x0182, 0x017d,
|
||||
0x016c, 0x0378, 0x01bb, 0x02c3, 0x01b8, 0x01b5, 0x06c0, 0x0004,
|
||||
0x02eb, 0x00d3, 0x00d2, 0x00d0, 0x0172, 0x017b, 0x02de, 0x02d3,
|
||||
0x02ca, 0x06c7, 0x0373, 0x036d, 0x036c, 0x0d83, 0x0361, 0x0002,
|
||||
0x0179, 0x0171, 0x0066, 0x00bb, 0x02d6, 0x02d2, 0x0166, 0x02c7,
|
||||
0x02c5, 0x0362, 0x06c6, 0x0367, 0x0d82, 0x0366, 0x01b2, 0x0000,
|
||||
0x000c, 0x000a, 0x0007, 0x000b, 0x000a, 0x0011, 0x000b, 0x0009,
|
||||
0x000d, 0x000c, 0x000a, 0x0007, 0x0005, 0x0003, 0x0001, 0x0003,
|
||||
};
|
||||
|
||||
static const uint8_t mpa_huffbits_16[256] = {
|
||||
1, 4, 6, 8, 9, 9, 10, 10,
|
||||
11, 11, 11, 12, 12, 12, 13, 9,
|
||||
3, 4, 6, 7, 8, 9, 9, 9,
|
||||
10, 10, 10, 11, 12, 11, 12, 8,
|
||||
6, 6, 7, 8, 9, 9, 10, 10,
|
||||
11, 10, 11, 11, 11, 12, 12, 9,
|
||||
8, 7, 8, 9, 9, 10, 10, 10,
|
||||
11, 11, 12, 12, 12, 13, 13, 10,
|
||||
9, 8, 9, 9, 10, 10, 11, 11,
|
||||
11, 12, 12, 12, 13, 13, 13, 9,
|
||||
9, 8, 9, 9, 10, 11, 11, 12,
|
||||
11, 12, 12, 13, 13, 13, 14, 10,
|
||||
10, 9, 9, 10, 11, 11, 11, 11,
|
||||
12, 12, 12, 12, 13, 13, 14, 10,
|
||||
10, 9, 10, 10, 11, 11, 11, 12,
|
||||
12, 13, 13, 13, 13, 15, 15, 10,
|
||||
10, 10, 10, 11, 11, 11, 12, 12,
|
||||
13, 13, 13, 13, 14, 14, 14, 10,
|
||||
11, 10, 10, 11, 11, 12, 12, 13,
|
||||
13, 13, 13, 14, 13, 14, 13, 11,
|
||||
11, 11, 10, 11, 12, 12, 12, 12,
|
||||
13, 14, 14, 14, 15, 15, 14, 10,
|
||||
12, 11, 11, 11, 12, 12, 13, 14,
|
||||
14, 14, 14, 14, 14, 13, 14, 11,
|
||||
12, 12, 12, 12, 12, 13, 13, 13,
|
||||
13, 15, 14, 14, 14, 14, 16, 11,
|
||||
14, 12, 12, 12, 13, 13, 14, 14,
|
||||
14, 16, 15, 15, 15, 17, 15, 11,
|
||||
13, 13, 11, 12, 14, 14, 13, 14,
|
||||
14, 15, 16, 15, 17, 15, 14, 11,
|
||||
9, 8, 8, 9, 9, 10, 10, 10,
|
||||
11, 11, 11, 11, 11, 11, 11, 8,
|
||||
};
|
||||
|
||||
static const uint16_t mpa_huffcodes_24[256] = {
|
||||
0x000f, 0x000d, 0x002e, 0x0050, 0x0092, 0x0106, 0x00f8, 0x01b2,
|
||||
0x01aa, 0x029d, 0x028d, 0x0289, 0x026d, 0x0205, 0x0408, 0x0058,
|
||||
0x000e, 0x000c, 0x0015, 0x0026, 0x0047, 0x0082, 0x007a, 0x00d8,
|
||||
0x00d1, 0x00c6, 0x0147, 0x0159, 0x013f, 0x0129, 0x0117, 0x002a,
|
||||
0x002f, 0x0016, 0x0029, 0x004a, 0x0044, 0x0080, 0x0078, 0x00dd,
|
||||
0x00cf, 0x00c2, 0x00b6, 0x0154, 0x013b, 0x0127, 0x021d, 0x0012,
|
||||
0x0051, 0x0027, 0x004b, 0x0046, 0x0086, 0x007d, 0x0074, 0x00dc,
|
||||
0x00cc, 0x00be, 0x00b2, 0x0145, 0x0137, 0x0125, 0x010f, 0x0010,
|
||||
0x0093, 0x0048, 0x0045, 0x0087, 0x007f, 0x0076, 0x0070, 0x00d2,
|
||||
0x00c8, 0x00bc, 0x0160, 0x0143, 0x0132, 0x011d, 0x021c, 0x000e,
|
||||
0x0107, 0x0042, 0x0081, 0x007e, 0x0077, 0x0072, 0x00d6, 0x00ca,
|
||||
0x00c0, 0x00b4, 0x0155, 0x013d, 0x012d, 0x0119, 0x0106, 0x000c,
|
||||
0x00f9, 0x007b, 0x0079, 0x0075, 0x0071, 0x00d7, 0x00ce, 0x00c3,
|
||||
0x00b9, 0x015b, 0x014a, 0x0134, 0x0123, 0x0110, 0x0208, 0x000a,
|
||||
0x01b3, 0x0073, 0x006f, 0x006d, 0x00d3, 0x00cb, 0x00c4, 0x00bb,
|
||||
0x0161, 0x014c, 0x0139, 0x012a, 0x011b, 0x0213, 0x017d, 0x0011,
|
||||
0x01ab, 0x00d4, 0x00d0, 0x00cd, 0x00c9, 0x00c1, 0x00ba, 0x00b1,
|
||||
0x00a9, 0x0140, 0x012f, 0x011e, 0x010c, 0x0202, 0x0179, 0x0010,
|
||||
0x014f, 0x00c7, 0x00c5, 0x00bf, 0x00bd, 0x00b5, 0x00ae, 0x014d,
|
||||
0x0141, 0x0131, 0x0121, 0x0113, 0x0209, 0x017b, 0x0173, 0x000b,
|
||||
0x029c, 0x00b8, 0x00b7, 0x00b3, 0x00af, 0x0158, 0x014b, 0x013a,
|
||||
0x0130, 0x0122, 0x0115, 0x0212, 0x017f, 0x0175, 0x016e, 0x000a,
|
||||
0x028c, 0x015a, 0x00ab, 0x00a8, 0x00a4, 0x013e, 0x0135, 0x012b,
|
||||
0x011f, 0x0114, 0x0107, 0x0201, 0x0177, 0x0170, 0x016a, 0x0006,
|
||||
0x0288, 0x0142, 0x013c, 0x0138, 0x0133, 0x012e, 0x0124, 0x011c,
|
||||
0x010d, 0x0105, 0x0200, 0x0178, 0x0172, 0x016c, 0x0167, 0x0004,
|
||||
0x026c, 0x012c, 0x0128, 0x0126, 0x0120, 0x011a, 0x0111, 0x010a,
|
||||
0x0203, 0x017c, 0x0176, 0x0171, 0x016d, 0x0169, 0x0165, 0x0002,
|
||||
0x0409, 0x0118, 0x0116, 0x0112, 0x010b, 0x0108, 0x0103, 0x017e,
|
||||
0x017a, 0x0174, 0x016f, 0x016b, 0x0168, 0x0166, 0x0164, 0x0000,
|
||||
0x002b, 0x0014, 0x0013, 0x0011, 0x000f, 0x000d, 0x000b, 0x0009,
|
||||
0x0007, 0x0006, 0x0004, 0x0007, 0x0005, 0x0003, 0x0001, 0x0003,
|
||||
};
|
||||
|
||||
static const uint8_t mpa_huffbits_24[256] = {
|
||||
4, 4, 6, 7, 8, 9, 9, 10,
|
||||
10, 11, 11, 11, 11, 11, 12, 9,
|
||||
4, 4, 5, 6, 7, 8, 8, 9,
|
||||
9, 9, 10, 10, 10, 10, 10, 8,
|
||||
6, 5, 6, 7, 7, 8, 8, 9,
|
||||
9, 9, 9, 10, 10, 10, 11, 7,
|
||||
7, 6, 7, 7, 8, 8, 8, 9,
|
||||
9, 9, 9, 10, 10, 10, 10, 7,
|
||||
8, 7, 7, 8, 8, 8, 8, 9,
|
||||
9, 9, 10, 10, 10, 10, 11, 7,
|
||||
9, 7, 8, 8, 8, 8, 9, 9,
|
||||
9, 9, 10, 10, 10, 10, 10, 7,
|
||||
9, 8, 8, 8, 8, 9, 9, 9,
|
||||
9, 10, 10, 10, 10, 10, 11, 7,
|
||||
10, 8, 8, 8, 9, 9, 9, 9,
|
||||
10, 10, 10, 10, 10, 11, 11, 8,
|
||||
10, 9, 9, 9, 9, 9, 9, 9,
|
||||
9, 10, 10, 10, 10, 11, 11, 8,
|
||||
10, 9, 9, 9, 9, 9, 9, 10,
|
||||
10, 10, 10, 10, 11, 11, 11, 8,
|
||||
11, 9, 9, 9, 9, 10, 10, 10,
|
||||
10, 10, 10, 11, 11, 11, 11, 8,
|
||||
11, 10, 9, 9, 9, 10, 10, 10,
|
||||
10, 10, 10, 11, 11, 11, 11, 8,
|
||||
11, 10, 10, 10, 10, 10, 10, 10,
|
||||
10, 10, 11, 11, 11, 11, 11, 8,
|
||||
11, 10, 10, 10, 10, 10, 10, 10,
|
||||
11, 11, 11, 11, 11, 11, 11, 8,
|
||||
12, 10, 10, 10, 10, 10, 10, 11,
|
||||
11, 11, 11, 11, 11, 11, 11, 8,
|
||||
8, 7, 7, 7, 7, 7, 7, 7,
|
||||
7, 7, 7, 8, 8, 8, 8, 4,
|
||||
};
|
||||
|
||||
static const HuffTable mpa_huff_tables[16] = {
|
||||
{ 1, NULL, NULL },
|
||||
{ 2, mpa_huffbits_1, mpa_huffcodes_1 },
|
||||
{ 3, mpa_huffbits_2, mpa_huffcodes_2 },
|
||||
{ 3, mpa_huffbits_3, mpa_huffcodes_3 },
|
||||
{ 4, mpa_huffbits_5, mpa_huffcodes_5 },
|
||||
{ 4, mpa_huffbits_6, mpa_huffcodes_6 },
|
||||
{ 6, mpa_huffbits_7, mpa_huffcodes_7 },
|
||||
{ 6, mpa_huffbits_8, mpa_huffcodes_8 },
|
||||
{ 6, mpa_huffbits_9, mpa_huffcodes_9 },
|
||||
{ 8, mpa_huffbits_10, mpa_huffcodes_10 },
|
||||
{ 8, mpa_huffbits_11, mpa_huffcodes_11 },
|
||||
{ 8, mpa_huffbits_12, mpa_huffcodes_12 },
|
||||
{ 16, mpa_huffbits_13, mpa_huffcodes_13 },
|
||||
{ 16, mpa_huffbits_15, mpa_huffcodes_15 },
|
||||
{ 16, mpa_huffbits_16, mpa_huffcodes_16 },
|
||||
{ 16, mpa_huffbits_24, mpa_huffcodes_24 },
|
||||
};
|
||||
|
||||
static const uint8_t mpa_huff_data[32][2] = {
|
||||
{ 0, 0 },
|
||||
{ 1, 0 },
|
||||
{ 2, 0 },
|
||||
{ 3, 0 },
|
||||
{ 0, 0 },
|
||||
{ 4, 0 },
|
||||
{ 5, 0 },
|
||||
{ 6, 0 },
|
||||
{ 7, 0 },
|
||||
{ 8, 0 },
|
||||
{ 9, 0 },
|
||||
{ 10, 0 },
|
||||
{ 11, 0 },
|
||||
{ 12, 0 },
|
||||
{ 0, 0 },
|
||||
{ 13, 0 },
|
||||
{ 14, 1 },
|
||||
{ 14, 2 },
|
||||
{ 14, 3 },
|
||||
{ 14, 4 },
|
||||
{ 14, 6 },
|
||||
{ 14, 8 },
|
||||
{ 14, 10 },
|
||||
{ 14, 13 },
|
||||
{ 15, 4 },
|
||||
{ 15, 5 },
|
||||
{ 15, 6 },
|
||||
{ 15, 7 },
|
||||
{ 15, 8 },
|
||||
{ 15, 9 },
|
||||
{ 15, 11 },
|
||||
{ 15, 13 },
|
||||
};
|
||||
|
||||
|
||||
/* huffman tables for quadrules */
|
||||
static uint8_t mpa_quad_codes[2][16] = {
|
||||
{ 1, 5, 4, 5, 6, 5, 4, 4, 7, 3, 6, 0, 7, 2, 3, 1, },
|
||||
{ 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0, },
|
||||
};
|
||||
|
||||
static uint8_t mpa_quad_bits[2][16] = {
|
||||
{ 1, 4, 4, 5, 4, 6, 5, 6, 4, 5, 5, 6, 5, 6, 6, 6, },
|
||||
{ 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, },
|
||||
};
|
||||
|
||||
/* band size tables */
|
||||
static const uint8_t band_size_long[9][22] = {
|
||||
{ 4, 4, 4, 4, 4, 4, 6, 6, 8, 8, 10,
|
||||
12, 16, 20, 24, 28, 34, 42, 50, 54, 76, 158, }, /* 44100 */
|
||||
{ 4, 4, 4, 4, 4, 4, 6, 6, 6, 8, 10,
|
||||
12, 16, 18, 22, 28, 34, 40, 46, 54, 54, 192, }, /* 48000 */
|
||||
{ 4, 4, 4, 4, 4, 4, 6, 6, 8, 10, 12,
|
||||
16, 20, 24, 30, 38, 46, 56, 68, 84, 102, 26, }, /* 32000 */
|
||||
{ 6, 6, 6, 6, 6, 6, 8, 10, 12, 14, 16,
|
||||
20, 24, 28, 32, 38, 46, 52, 60, 68, 58, 54, }, /* 22050 */
|
||||
{ 6, 6, 6, 6, 6, 6, 8, 10, 12, 14, 16,
|
||||
18, 22, 26, 32, 38, 46, 52, 64, 70, 76, 36, }, /* 24000 */
|
||||
{ 6, 6, 6, 6, 6, 6, 8, 10, 12, 14, 16,
|
||||
20, 24, 28, 32, 38, 46, 52, 60, 68, 58, 54, }, /* 16000 */
|
||||
{ 6, 6, 6, 6, 6, 6, 8, 10, 12, 14, 16,
|
||||
20, 24, 28, 32, 38, 46, 52, 60, 68, 58, 54, }, /* 11025 */
|
||||
{ 6, 6, 6, 6, 6, 6, 8, 10, 12, 14, 16,
|
||||
20, 24, 28, 32, 38, 46, 52, 60, 68, 58, 54, }, /* 12000 */
|
||||
{ 12, 12, 12, 12, 12, 12, 16, 20, 24, 28, 32,
|
||||
40, 48, 56, 64, 76, 90, 2, 2, 2, 2, 2, }, /* 8000 */
|
||||
};
|
||||
|
||||
static const uint8_t band_size_short[9][13] = {
|
||||
{ 4, 4, 4, 4, 6, 8, 10, 12, 14, 18, 22, 30, 56, }, /* 44100 */
|
||||
{ 4, 4, 4, 4, 6, 6, 10, 12, 14, 16, 20, 26, 66, }, /* 48000 */
|
||||
{ 4, 4, 4, 4, 6, 8, 12, 16, 20, 26, 34, 42, 12, }, /* 32000 */
|
||||
{ 4, 4, 4, 6, 6, 8, 10, 14, 18, 26, 32, 42, 18, }, /* 22050 */
|
||||
{ 4, 4, 4, 6, 8, 10, 12, 14, 18, 24, 32, 44, 12, }, /* 24000 */
|
||||
{ 4, 4, 4, 6, 8, 10, 12, 14, 18, 24, 30, 40, 18, }, /* 16000 */
|
||||
{ 4, 4, 4, 6, 8, 10, 12, 14, 18, 24, 30, 40, 18, }, /* 11025 */
|
||||
{ 4, 4, 4, 6, 8, 10, 12, 14, 18, 24, 30, 40, 18, }, /* 12000 */
|
||||
{ 8, 8, 8, 12, 16, 20, 24, 28, 36, 2, 2, 2, 26, }, /* 8000 */
|
||||
};
|
||||
|
||||
static const uint8_t mpa_pretab[2][22] = {
|
||||
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
|
||||
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 3, 3, 3, 2, 0 },
|
||||
};
|
||||
|
||||
/* table for alias reduction (XXX: store it as integer !) */
|
||||
static const float ci_table[8] = {
|
||||
-0.6f, -0.535f, -0.33f, -0.185f, -0.095f, -0.041f, -0.0142f, -0.0037f,
|
||||
};
|
||||
@@ -1,17 +0,0 @@
|
||||
/* Modified slightly by Matt Campbell <mattcampbell@pobox.com> for the
|
||||
stand-alone mpaudec library. Based on mpegaudio.h from libavcodec. */
|
||||
|
||||
/* max frame size, in samples */
|
||||
#define MPA_FRAME_SIZE 1152
|
||||
|
||||
/* max compressed frame size */
|
||||
#define MPA_MAX_CODED_FRAME_SIZE 1792
|
||||
|
||||
#define MPA_MAX_CHANNELS 2
|
||||
|
||||
#define SBLIMIT 32 /* number of subbands */
|
||||
|
||||
#define MPA_STEREO 0
|
||||
#define MPA_JSTEREO 1
|
||||
#define MPA_DUAL 2
|
||||
#define MPA_MONO 3
|
||||
@@ -1,41 +0,0 @@
|
||||
|
||||
#include <irrKlang.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include "CIrrKlangAudioStreamLoaderMP3.h"
|
||||
|
||||
using namespace irrklang;
|
||||
|
||||
// this is the only function needed to be implemented for the plugin, it gets
|
||||
// called by irrKlang when loaded.
|
||||
// In this plugin, we create an audiostream loader class and register
|
||||
// it at the engine, but a plugin can do anything.
|
||||
// Be sure to name the function 'irrKlangPluginInit' and let the dll start with 'ikp'.
|
||||
|
||||
#ifdef WIN32
|
||||
// Windows version
|
||||
__declspec(dllexport) void __stdcall irrKlangPluginInit(ISoundEngine* engine, const char* version)
|
||||
#else
|
||||
// Linux version
|
||||
void irrKlangPluginInit(ISoundEngine* engine, const char* version)
|
||||
#endif
|
||||
{
|
||||
// do some version security check to be sure that this plugin isn't begin used
|
||||
// by some newer irrKlang version with changed interfaces which could possibily
|
||||
// cause crashes.
|
||||
|
||||
if (strcmp(version, IRR_KLANG_VERSION))
|
||||
{
|
||||
printf("This MP3 plugin only supports irrKlang version %s, mp3 playback disabled.\n", IRR_KLANG_VERSION);
|
||||
return;
|
||||
}
|
||||
|
||||
// create and register the loader
|
||||
|
||||
CIrrKlangAudioStreamLoaderMP3* loader = new CIrrKlangAudioStreamLoaderMP3();
|
||||
engine->registerAudioStreamLoader(loader);
|
||||
loader->drop();
|
||||
|
||||
// that's it, that's all.
|
||||
}
|
||||
|
||||
@@ -1,458 +0,0 @@
|
||||
GNU LESSER GENERAL PUBLIC LICENSE
|
||||
Version 2.1, February 1999
|
||||
|
||||
Copyright (C) 1991, 1999 Free Software Foundation, Inc.
|
||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
Everyone is permitted to copy and distribute verbatim copies
|
||||
of this license document, but changing it is not allowed.
|
||||
|
||||
[This is the first released version of the Lesser GPL. It also counts
|
||||
as the successor of the GNU Library Public License, version 2, hence
|
||||
the version number 2.1.]
|
||||
|
||||
Preamble
|
||||
|
||||
The licenses for most software are designed to take away your
|
||||
freedom to share and change it. By contrast, the GNU General Public
|
||||
Licenses are intended to guarantee your freedom to share and change
|
||||
free software--to make sure the software is free for all its users.
|
||||
|
||||
This license, the Lesser General Public License, applies to some
|
||||
specially designated software packages--typically libraries--of the
|
||||
Free Software Foundation and other authors who decide to use it. You
|
||||
can use it too, but we suggest you first think carefully about whether
|
||||
this license or the ordinary General Public License is the better
|
||||
strategy to use in any particular case, based on the explanations below.
|
||||
|
||||
When we speak of free software, we are referring to freedom of use,
|
||||
not price. Our General Public Licenses are designed to make sure that
|
||||
you have the freedom to distribute copies of free software (and charge
|
||||
for this service if you wish); that you receive source code or can get
|
||||
it if you want it; that you can change the software and use pieces of
|
||||
it in new free programs; and that you are informed that you can do
|
||||
these things.
|
||||
|
||||
To protect your rights, we need to make restrictions that forbid
|
||||
distributors to deny you these rights or to ask you to surrender these
|
||||
rights. These restrictions translate to certain responsibilities for
|
||||
you if you distribute copies of the library or if you modify it.
|
||||
|
||||
For example, if you distribute copies of the library, whether gratis
|
||||
or for a fee, you must give the recipients all the rights that we gave
|
||||
you. You must make sure that they, too, receive or can get the source
|
||||
code. If you link other code with the library, you must provide
|
||||
complete object files to the recipients, so that they can relink them
|
||||
with the library after making changes to the library and recompiling
|
||||
it. And you must show them these terms so they know their rights.
|
||||
|
||||
We protect your rights with a two-step method: (1) we copyright the
|
||||
library, and (2) we offer you this license, which gives you legal
|
||||
permission to copy, distribute and/or modify the library.
|
||||
|
||||
To protect each distributor, we want to make it very clear that
|
||||
there is no warranty for the free library. Also, if the library is
|
||||
modified by someone else and passed on, the recipients should know
|
||||
that what they have is not the original version, so that the original
|
||||
author's reputation will not be affected by problems that might be
|
||||
introduced by others.
|
||||
|
||||
Finally, software patents pose a constant threat to the existence of
|
||||
any free program. We wish to make sure that a company cannot
|
||||
effectively restrict the users of a free program by obtaining a
|
||||
restrictive license from a patent holder. Therefore, we insist that
|
||||
any patent license obtained for a version of the library must be
|
||||
consistent with the full freedom of use specified in this license.
|
||||
|
||||
Most GNU software, including some libraries, is covered by the
|
||||
ordinary GNU General Public License. This license, the GNU Lesser
|
||||
General Public License, applies to certain designated libraries, and
|
||||
is quite different from the ordinary General Public License. We use
|
||||
this license for certain libraries in order to permit linking those
|
||||
libraries into non-free programs.
|
||||
|
||||
When a program is linked with a library, whether statically or using
|
||||
a shared library, the combination of the two is legally speaking a
|
||||
combined work, a derivative of the original library. The ordinary
|
||||
General Public License therefore permits such linking only if the
|
||||
entire combination fits its criteria of freedom. The Lesser General
|
||||
Public License permits more lax criteria for linking other code with
|
||||
the library.
|
||||
|
||||
We call this license the "Lesser" General Public License because it
|
||||
does Less to protect the user's freedom than the ordinary General
|
||||
Public License. It also provides other free software developers Less
|
||||
of an advantage over competing non-free programs. These disadvantages
|
||||
are the reason we use the ordinary General Public License for many
|
||||
libraries. However, the Lesser license provides advantages in certain
|
||||
special circumstances.
|
||||
|
||||
For example, on rare occasions, there may be a special need to
|
||||
encourage the widest possible use of a certain library, so that it becomes
|
||||
a de-facto standard. To achieve this, non-free programs must be
|
||||
allowed to use the library. A more frequent case is that a free
|
||||
library does the same job as widely used non-free libraries. In this
|
||||
case, there is little to gain by limiting the free library to free
|
||||
software only, so we use the Lesser General Public License.
|
||||
|
||||
In other cases, permission to use a particular library in non-free
|
||||
programs enables a greater number of people to use a large body of
|
||||
free software. For example, permission to use the GNU C Library in
|
||||
non-free programs enables many more people to use the whole GNU
|
||||
operating system, as well as its variant, the GNU/Linux operating
|
||||
system.
|
||||
|
||||
Although the Lesser General Public License is Less protective of the
|
||||
users' freedom, it does ensure that the user of a program that is
|
||||
linked with the Library has the freedom and the wherewithal to run
|
||||
that program using a modified version of the Library.
|
||||
|
||||
The precise terms and conditions for copying, distribution and
|
||||
modification follow. Pay close attention to the difference between a
|
||||
"work based on the library" and a "work that uses the library". The
|
||||
former contains code derived from the library, whereas the latter must
|
||||
be combined with the library in order to run.
|
||||
|
||||
GNU LESSER GENERAL PUBLIC LICENSE
|
||||
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
|
||||
|
||||
0. This License Agreement applies to any software library or other
|
||||
program which contains a notice placed by the copyright holder or
|
||||
other authorized party saying it may be distributed under the terms of
|
||||
this Lesser General Public License (also called "this License").
|
||||
Each licensee is addressed as "you".
|
||||
|
||||
A "library" means a collection of software functions and/or data
|
||||
prepared so as to be conveniently linked with application programs
|
||||
(which use some of those functions and data) to form executables.
|
||||
|
||||
The "Library", below, refers to any such software library or work
|
||||
which has been distributed under these terms. A "work based on the
|
||||
Library" means either the Library or any derivative work under
|
||||
copyright law: that is to say, a work containing the Library or a
|
||||
portion of it, either verbatim or with modifications and/or translated
|
||||
straightforwardly into another language. (Hereinafter, translation is
|
||||
included without limitation in the term "modification".)
|
||||
|
||||
"Source code" for a work means the preferred form of the work for
|
||||
making modifications to it. For a library, complete source code means
|
||||
all the source code for all modules it contains, plus any associated
|
||||
interface definition files, plus the scripts used to control compilation
|
||||
and installation of the library.
|
||||
|
||||
Activities other than copying, distribution and modification are not
|
||||
covered by this License; they are outside its scope. The act of
|
||||
running a program using the Library is not restricted, and output from
|
||||
such a program is covered only if its contents constitute a work based
|
||||
on the Library (independent of the use of the Library in a tool for
|
||||
writing it). Whether that is true depends on what the Library does
|
||||
and what the program that uses the Library does.
|
||||
|
||||
1. You may copy and distribute verbatim copies of the Library's
|
||||
complete source code as you receive it, in any medium, provided that
|
||||
you conspicuously and appropriately publish on each copy an
|
||||
appropriate copyright notice and disclaimer of warranty; keep intact
|
||||
all the notices that refer to this License and to the absence of any
|
||||
warranty; and distribute a copy of this License along with the
|
||||
Library.
|
||||
|
||||
You may charge a fee for the physical act of transferring a copy,
|
||||
and you may at your option offer warranty protection in exchange for a
|
||||
fee.
|
||||
|
||||
2. You may modify your copy or copies of the Library or any portion
|
||||
of it, thus forming a work based on the Library, and copy and
|
||||
distribute such modifications or work under the terms of Section 1
|
||||
above, provided that you also meet all of these conditions:
|
||||
|
||||
a) The modified work must itself be a software library.
|
||||
|
||||
b) You must cause the files modified to carry prominent notices
|
||||
stating that you changed the files and the date of any change.
|
||||
|
||||
c) You must cause the whole of the work to be licensed at no
|
||||
charge to all third parties under the terms of this License.
|
||||
|
||||
d) If a facility in the modified Library refers to a function or a
|
||||
table of data to be supplied by an application program that uses
|
||||
the facility, other than as an argument passed when the facility
|
||||
is invoked, then you must make a good faith effort to ensure that,
|
||||
in the event an application does not supply such function or
|
||||
table, the facility still operates, and performs whatever part of
|
||||
its purpose remains meaningful.
|
||||
|
||||
(For example, a function in a library to compute square roots has
|
||||
a purpose that is entirely well-defined independent of the
|
||||
application. Therefore, Subsection 2d requires that any
|
||||
application-supplied function or table used by this function must
|
||||
be optional: if the application does not supply it, the square
|
||||
root function must still compute square roots.)
|
||||
|
||||
These requirements apply to the modified work as a whole. If
|
||||
identifiable sections of that work are not derived from the Library,
|
||||
and can be reasonably considered independent and separate works in
|
||||
themselves, then this License, and its terms, do not apply to those
|
||||
sections when you distribute them as separate works. But when you
|
||||
distribute the same sections as part of a whole which is a work based
|
||||
on the Library, the distribution of the whole must be on the terms of
|
||||
this License, whose permissions for other licensees extend to the
|
||||
entire whole, and thus to each and every part regardless of who wrote
|
||||
it.
|
||||
|
||||
Thus, it is not the intent of this section to claim rights or contest
|
||||
your rights to work written entirely by you; rather, the intent is to
|
||||
exercise the right to control the distribution of derivative or
|
||||
collective works based on the Library.
|
||||
|
||||
In addition, mere aggregation of another work not based on the Library
|
||||
with the Library (or with a work based on the Library) on a volume of
|
||||
a storage or distribution medium does not bring the other work under
|
||||
the scope of this License.
|
||||
|
||||
3. You may opt to apply the terms of the ordinary GNU General Public
|
||||
License instead of this License to a given copy of the Library. To do
|
||||
this, you must alter all the notices that refer to this License, so
|
||||
that they refer to the ordinary GNU General Public License, version 2,
|
||||
instead of to this License. (If a newer version than version 2 of the
|
||||
ordinary GNU General Public License has appeared, then you can specify
|
||||
that version instead if you wish.) Do not make any other change in
|
||||
these notices.
|
||||
|
||||
Once this change is made in a given copy, it is irreversible for
|
||||
that copy, so the ordinary GNU General Public License applies to all
|
||||
subsequent copies and derivative works made from that copy.
|
||||
|
||||
This option is useful when you wish to copy part of the code of
|
||||
the Library into a program that is not a library.
|
||||
|
||||
4. You may copy and distribute the Library (or a portion or
|
||||
derivative of it, under Section 2) in object code or executable form
|
||||
under the terms of Sections 1 and 2 above provided that you accompany
|
||||
it with the complete corresponding machine-readable source code, which
|
||||
must be distributed under the terms of Sections 1 and 2 above on a
|
||||
medium customarily used for software interchange.
|
||||
|
||||
If distribution of object code is made by offering access to copy
|
||||
from a designated place, then offering equivalent access to copy the
|
||||
source code from the same place satisfies the requirement to
|
||||
distribute the source code, even though third parties are not
|
||||
compelled to copy the source along with the object code.
|
||||
|
||||
5. A program that contains no derivative of any portion of the
|
||||
Library, but is designed to work with the Library by being compiled or
|
||||
linked with it, is called a "work that uses the Library". Such a
|
||||
work, in isolation, is not a derivative work of the Library, and
|
||||
therefore falls outside the scope of this License.
|
||||
|
||||
However, linking a "work that uses the Library" with the Library
|
||||
creates an executable that is a derivative of the Library (because it
|
||||
contains portions of the Library), rather than a "work that uses the
|
||||
library". The executable is therefore covered by this License.
|
||||
Section 6 states terms for distribution of such executables.
|
||||
|
||||
When a "work that uses the Library" uses material from a header file
|
||||
that is part of the Library, the object code for the work may be a
|
||||
derivative work of the Library even though the source code is not.
|
||||
Whether this is true is especially significant if the work can be
|
||||
linked without the Library, or if the work is itself a library. The
|
||||
threshold for this to be true is not precisely defined by law.
|
||||
|
||||
If such an object file uses only numerical parameters, data
|
||||
structure layouts and accessors, and small macros and small inline
|
||||
functions (ten lines or less in length), then the use of the object
|
||||
file is unrestricted, regardless of whether it is legally a derivative
|
||||
work. (Executables containing this object code plus portions of the
|
||||
Library will still fall under Section 6.)
|
||||
|
||||
Otherwise, if the work is a derivative of the Library, you may
|
||||
distribute the object code for the work under the terms of Section 6.
|
||||
Any executables containing that work also fall under Section 6,
|
||||
whether or not they are linked directly with the Library itself.
|
||||
|
||||
6. As an exception to the Sections above, you may also combine or
|
||||
link a "work that uses the Library" with the Library to produce a
|
||||
work containing portions of the Library, and distribute that work
|
||||
under terms of your choice, provided that the terms permit
|
||||
modification of the work for the customer's own use and reverse
|
||||
engineering for debugging such modifications.
|
||||
|
||||
You must give prominent notice with each copy of the work that the
|
||||
Library is used in it and that the Library and its use are covered by
|
||||
this License. You must supply a copy of this License. If the work
|
||||
during execution displays copyright notices, you must include the
|
||||
copyright notice for the Library among them, as well as a reference
|
||||
directing the user to the copy of this License. Also, you must do one
|
||||
of these things:
|
||||
|
||||
a) Accompany the work with the complete corresponding
|
||||
machine-readable source code for the Library including whatever
|
||||
changes were used in the work (which must be distributed under
|
||||
Sections 1 and 2 above); and, if the work is an executable linked
|
||||
with the Library, with the complete machine-readable "work that
|
||||
uses the Library", as object code and/or source code, so that the
|
||||
user can modify the Library and then relink to produce a modified
|
||||
executable containing the modified Library. (It is understood
|
||||
that the user who changes the contents of definitions files in the
|
||||
Library will not necessarily be able to recompile the application
|
||||
to use the modified definitions.)
|
||||
|
||||
b) Use a suitable shared library mechanism for linking with the
|
||||
Library. A suitable mechanism is one that (1) uses at run time a
|
||||
copy of the library already present on the user's computer system,
|
||||
rather than copying library functions into the executable, and (2)
|
||||
will operate properly with a modified version of the library, if
|
||||
the user installs one, as long as the modified version is
|
||||
interface-compatible with the version that the work was made with.
|
||||
|
||||
c) Accompany the work with a written offer, valid for at
|
||||
least three years, to give the same user the materials
|
||||
specified in Subsection 6a, above, for a charge no more
|
||||
than the cost of performing this distribution.
|
||||
|
||||
d) If distribution of the work is made by offering access to copy
|
||||
from a designated place, offer equivalent access to copy the above
|
||||
specified materials from the same place.
|
||||
|
||||
e) Verify that the user has already received a copy of these
|
||||
materials or that you have already sent this user a copy.
|
||||
|
||||
For an executable, the required form of the "work that uses the
|
||||
Library" must include any data and utility programs needed for
|
||||
reproducing the executable from it. However, as a special exception,
|
||||
the materials to be distributed need not include anything that is
|
||||
normally distributed (in either source or binary form) with the major
|
||||
components (compiler, kernel, and so on) of the operating system on
|
||||
which the executable runs, unless that component itself accompanies
|
||||
the executable.
|
||||
|
||||
It may happen that this requirement contradicts the license
|
||||
restrictions of other proprietary libraries that do not normally
|
||||
accompany the operating system. Such a contradiction means you cannot
|
||||
use both them and the Library together in an executable that you
|
||||
distribute.
|
||||
|
||||
7. You may place library facilities that are a work based on the
|
||||
Library side-by-side in a single library together with other library
|
||||
facilities not covered by this License, and distribute such a combined
|
||||
library, provided that the separate distribution of the work based on
|
||||
the Library and of the other library facilities is otherwise
|
||||
permitted, and provided that you do these two things:
|
||||
|
||||
a) Accompany the combined library with a copy of the same work
|
||||
based on the Library, uncombined with any other library
|
||||
facilities. This must be distributed under the terms of the
|
||||
Sections above.
|
||||
|
||||
b) Give prominent notice with the combined library of the fact
|
||||
that part of it is a work based on the Library, and explaining
|
||||
where to find the accompanying uncombined form of the same work.
|
||||
|
||||
8. You may not copy, modify, sublicense, link with, or distribute
|
||||
the Library except as expressly provided under this License. Any
|
||||
attempt otherwise to copy, modify, sublicense, link with, or
|
||||
distribute the Library is void, and will automatically terminate your
|
||||
rights under this License. However, parties who have received copies,
|
||||
or rights, from you under this License will not have their licenses
|
||||
terminated so long as such parties remain in full compliance.
|
||||
|
||||
9. You are not required to accept this License, since you have not
|
||||
signed it. However, nothing else grants you permission to modify or
|
||||
distribute the Library or its derivative works. These actions are
|
||||
prohibited by law if you do not accept this License. Therefore, by
|
||||
modifying or distributing the Library (or any work based on the
|
||||
Library), you indicate your acceptance of this License to do so, and
|
||||
all its terms and conditions for copying, distributing or modifying
|
||||
the Library or works based on it.
|
||||
|
||||
10. Each time you redistribute the Library (or any work based on the
|
||||
Library), the recipient automatically receives a license from the
|
||||
original licensor to copy, distribute, link with or modify the Library
|
||||
subject to these terms and conditions. You may not impose any further
|
||||
restrictions on the recipients' exercise of the rights granted herein.
|
||||
You are not responsible for enforcing compliance by third parties with
|
||||
this License.
|
||||
|
||||
11. If, as a consequence of a court judgment or allegation of patent
|
||||
infringement or for any other reason (not limited to patent issues),
|
||||
conditions are imposed on you (whether by court order, agreement or
|
||||
otherwise) that contradict the conditions of this License, they do not
|
||||
excuse you from the conditions of this License. If you cannot
|
||||
distribute so as to satisfy simultaneously your obligations under this
|
||||
License and any other pertinent obligations, then as a consequence you
|
||||
may not distribute the Library at all. For example, if a patent
|
||||
license would not permit royalty-free redistribution of the Library by
|
||||
all those who receive copies directly or indirectly through you, then
|
||||
the only way you could satisfy both it and this License would be to
|
||||
refrain entirely from distribution of the Library.
|
||||
|
||||
If any portion of this section is held invalid or unenforceable under any
|
||||
particular circumstance, the balance of the section is intended to apply,
|
||||
and the section as a whole is intended to apply in other circumstances.
|
||||
|
||||
It is not the purpose of this section to induce you to infringe any
|
||||
patents or other property right claims or to contest validity of any
|
||||
such claims; this section has the sole purpose of protecting the
|
||||
integrity of the free software distribution system which is
|
||||
implemented by public license practices. Many people have made
|
||||
generous contributions to the wide range of software distributed
|
||||
through that system in reliance on consistent application of that
|
||||
system; it is up to the author/donor to decide if he or she is willing
|
||||
to distribute software through any other system and a licensee cannot
|
||||
impose that choice.
|
||||
|
||||
This section is intended to make thoroughly clear what is believed to
|
||||
be a consequence of the rest of this License.
|
||||
|
||||
12. If the distribution and/or use of the Library is restricted in
|
||||
certain countries either by patents or by copyrighted interfaces, the
|
||||
original copyright holder who places the Library under this License may add
|
||||
an explicit geographical distribution limitation excluding those countries,
|
||||
so that distribution is permitted only in or among countries not thus
|
||||
excluded. In such case, this License incorporates the limitation as if
|
||||
written in the body of this License.
|
||||
|
||||
13. The Free Software Foundation may publish revised and/or new
|
||||
versions of the Lesser General Public License from time to time.
|
||||
Such new versions will be similar in spirit to the present version,
|
||||
but may differ in detail to address new problems or concerns.
|
||||
|
||||
Each version is given a distinguishing version number. If the Library
|
||||
specifies a version number of this License which applies to it and
|
||||
"any later version", you have the option of following the terms and
|
||||
conditions either of that version or of any later version published by
|
||||
the Free Software Foundation. If the Library does not specify a
|
||||
license version number, you may choose any version ever published by
|
||||
the Free Software Foundation.
|
||||
|
||||
14. If you wish to incorporate parts of the Library into other free
|
||||
programs whose distribution conditions are incompatible with these,
|
||||
write to the author to ask for permission. For software which is
|
||||
copyrighted by the Free Software Foundation, write to the Free
|
||||
Software Foundation; we sometimes make exceptions for this. Our
|
||||
decision will be guided by the two goals of preserving the free status
|
||||
of all derivatives of our free software and of promoting the sharing
|
||||
and reuse of software generally.
|
||||
|
||||
NO WARRANTY
|
||||
|
||||
15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
|
||||
WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
|
||||
EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
|
||||
OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY
|
||||
KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE
|
||||
LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
|
||||
THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
|
||||
|
||||
16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
|
||||
WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY
|
||||
AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU
|
||||
FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR
|
||||
CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE
|
||||
LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING
|
||||
RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
|
||||
FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
|
||||
SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
|
||||
DAMAGES.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
@@ -1,7 +0,0 @@
|
||||
ikpMP3 is a plugin for irrKlang.
|
||||
Copyright (C) 2002-2007 Nikolaus Gebhardt
|
||||
Part of the code for this plugin for irrKlang is based on:
|
||||
MP3 input for Audiere by Matt Campbell <mattcampbell@pobox.com>, based on
|
||||
libavcodec from ffmpeg (http://ffmpeg.sourceforge.net/).
|
||||
See license.txt for license details of this plugin.
|
||||
|
||||
@@ -1,191 +0,0 @@
|
||||
==========================================================================
|
||||
The irrKlang SDK version 1.6
|
||||
==========================================================================
|
||||
|
||||
Welcome the irrKlang SDK.
|
||||
|
||||
Content of this file:
|
||||
|
||||
1. Directory structure overview
|
||||
2. How to start
|
||||
3. Release Notes
|
||||
4. .NET version dependencies
|
||||
5. License
|
||||
6. Contact
|
||||
|
||||
|
||||
|
||||
==========================================================================
|
||||
1. Directory structure overview
|
||||
==========================================================================
|
||||
|
||||
You will find some directories after decompressing the archive in which
|
||||
came the SDK. These are:
|
||||
|
||||
\bin The compiled library irrKlang.DLL and some compiled demo
|
||||
and example applications, just start them to see
|
||||
irrKlang in action.
|
||||
\doc Documentation of the Irrlicht Engine.
|
||||
\examples Examples and tutorials showing how to use the native engine
|
||||
engine using C++.
|
||||
\example.net Examples written for the .NET version of irrKlang, in C# and
|
||||
VisualBasic.NET
|
||||
\include Header files to include when using the engine.
|
||||
\lib Lib to link with your programs when using the engine.
|
||||
\media Sound data for the demo applications and
|
||||
examples.
|
||||
\plugins Source and documentation of the irrKlang plugins.
|
||||
|
||||
|
||||
==========================================================================
|
||||
2. How to start
|
||||
==========================================================================
|
||||
|
||||
To see the engine in action in Windows, just go to the \bin\Win32
|
||||
directories, and start some applications.
|
||||
|
||||
To start developing own applications and games with the engine take
|
||||
a look at the 01.HelloWorld example in the \examples directory.
|
||||
|
||||
Windows Users:
|
||||
There are Visual Studio as well as CodeBlocks projects for the examples.
|
||||
|
||||
Linux users:
|
||||
Just go into the /examples directory and run 'make' for every
|
||||
example you want to try out. You can run the examples directly from the
|
||||
directory they are created in. Some examples may print some special
|
||||
hints after a successful make and might help you starting them up
|
||||
by typing in 'make run'.
|
||||
|
||||
Mac users:
|
||||
There is a XCode project for each example available in
|
||||
the corresponding example directory. To run the precompiled example
|
||||
applications from bin\macos-gcc, doubleclick the run_0x_xxxxx.command
|
||||
files from the finder (this will change the working directory to
|
||||
bin\macos-gcc) or start them directly from a terminal.
|
||||
|
||||
==========================================================================
|
||||
3. Release Notes
|
||||
==========================================================================
|
||||
|
||||
Informations about changes in this new version of the engine can be
|
||||
found in changes.txt.
|
||||
|
||||
Please note that the included sound files are copyright
|
||||
by their authors and not included in the irrKlang engine license.
|
||||
|
||||
|
||||
==========================================================================
|
||||
4. .NET version dependencies
|
||||
==========================================================================
|
||||
|
||||
There are four versions of irrKlang.NET available. They have the same
|
||||
functionality and can be used from the same .NET projects.
|
||||
The difference are only their dependencies and target platforms:
|
||||
|
||||
irrKlang.NET2.0 in bin\dotnet-2.0:
|
||||
Compiled for .NET common language runtime version 2.0, depends on
|
||||
the modudles MSVCR80.DLL and MSVCM80.DLL. (32 bit)
|
||||
One method to redistribute these is using the visual studio 2005
|
||||
redistributeable (vcredist_x86)
|
||||
|
||||
irrKlang.NET4 in bin\dotnet-4:
|
||||
Compiled for .NET common language runtime version 4.5, depends on
|
||||
VCRUNTIME140.dll. (32 bit)
|
||||
One method to redistribute this is using the visual studio 2017
|
||||
redistributeable (vcredist_x86)
|
||||
|
||||
irrKlang.NET4 in bin\dotnet-4-64: (only in the 64 bit irrKlang SDK)
|
||||
64 bit version, Compiled for .NET common language runtime version 4.5,
|
||||
depends on VCRUNTIME140.dll. (64 bit)
|
||||
One method to redistribute this is using the visual studio 2017
|
||||
redistributeable (vcredist 64 bit)
|
||||
|
||||
==========================================================================
|
||||
5. License
|
||||
==========================================================================
|
||||
|
||||
irrKlang's source codes, documentation and binaries contained within the
|
||||
distributed archive are copyright © Nikolaus Gebhardt / Ambiera 2001-2018.
|
||||
|
||||
The contents of the irrKlang distribution archive may not be redistributed,
|
||||
reproduced, modified, transmitted, broadcast, published or adapted in any
|
||||
way, shape or form, without the prior written consent of the owner,
|
||||
Nikolaus Gebhardt.
|
||||
|
||||
The irrKlang.dll, irrKlang.so and libirrklang.dylib files may be
|
||||
redistributed without the authors prior permission in non-commercial
|
||||
products, and must remain unmodified except for compressing the file.
|
||||
|
||||
For the included plugins which can be found in the \plugins
|
||||
directory, different licenses may be applied, as specified in the
|
||||
actual plugin directory.
|
||||
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
''AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR
|
||||
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
irrKlang may include Xiph.org Foundation code (Ogg Vorbis and FLAC).
|
||||
It's license is the following:
|
||||
|
||||
Copyright (c) 2002, Xiph.org Foundation
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
are met:
|
||||
|
||||
- Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
|
||||
- Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
- Neither the name of the Xiph.org Foundation nor the names of its
|
||||
contributors may be used to endorse or promote products derived from
|
||||
this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION
|
||||
OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
irrKlang may include code from the
|
||||
Dynamic Universal Music Bibliotheque, Version 0.9.3
|
||||
|
||||
Copyright (C) 2001-2005 Ben Davis, Robert J Ohannessian and Julien Cugniere
|
||||
|
||||
==========================================================================
|
||||
6. Contact
|
||||
==========================================================================
|
||||
|
||||
If you have problems, questions or suggestions, please visit the
|
||||
official homepage of the irrKlang Engine:
|
||||
|
||||
http://www.ambiera.com/irrklang
|
||||
|
||||
You will find forums, bugtrackers, patches, tutorials, and other stuff
|
||||
which will help you out.
|
||||
|
||||
If want to contact the author of the engine, please send an email to
|
||||
Nikolaus Gebhardt:
|
||||
|
||||
office@ambiera.com
|
||||
@@ -1,16 +0,0 @@
|
||||
//{{NO_DEPENDENCIES}}
|
||||
// Microsoft Visual C++ generated include file.
|
||||
// Used by BAKKA Editor.rc
|
||||
//
|
||||
#define IDI_ICON1 101
|
||||
|
||||
// Next default values for new objects
|
||||
//
|
||||
#ifdef APSTUDIO_INVOKED
|
||||
#ifndef APSTUDIO_READONLY_SYMBOLS
|
||||
#define _APS_NEXT_RESOURCE_VALUE 102
|
||||
#define _APS_NEXT_COMMAND_VALUE 40001
|
||||
#define _APS_NEXT_CONTROL_VALUE 1001
|
||||
#define _APS_NEXT_SYMED_VALUE 101
|
||||
#endif
|
||||
#endif
|
||||
Binary file not shown.
@@ -0,0 +1,25 @@
|
||||
|
||||
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||
# Visual Studio Version 17
|
||||
VisualStudioVersion = 17.3.32825.248
|
||||
MinimumVisualStudioVersion = 10.0.40219.1
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BAKKA-Editor", "BAKKA-Editor\BAKKA-Editor.csproj", "{76336598-B2BE-4F67-B3D6-821F6A0E302F}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Any CPU = Debug|Any CPU
|
||||
Release|Any CPU = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||
{76336598-B2BE-4F67-B3D6-821F6A0E302F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{76336598-B2BE-4F67-B3D6-821F6A0E302F}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{76336598-B2BE-4F67-B3D6-821F6A0E302F}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{76336598-B2BE-4F67-B3D6-821F6A0E302F}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
EndGlobalSection
|
||||
GlobalSection(ExtensibilityGlobals) = postSolution
|
||||
SolutionGuid = {35C7C2C6-E927-465D-B4B5-46787DDAE60F}
|
||||
EndGlobalSection
|
||||
EndGlobal
|
||||
@@ -0,0 +1,57 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<OutputType>WinExe</OutputType>
|
||||
<TargetFramework>net6.0-windows</TargetFramework>
|
||||
<RootNamespace>BAKKA_Editor</RootNamespace>
|
||||
<Nullable>enable</Nullable>
|
||||
<UseWindowsForms>true</UseWindowsForms>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<Version>$(VersionPrefix)2.1.8</Version>
|
||||
<AssemblyVersion>1.0.0.0</AssemblyVersion>
|
||||
<FileVersion>2.1.8</FileVersion>
|
||||
<Company>Goatgarien</Company>
|
||||
<Copyright>2022</Copyright>
|
||||
<StartupObject>BAKKA_Editor.Program</StartupObject>
|
||||
<ApplicationIcon>icon.ico</ApplicationIcon>
|
||||
<AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects>
|
||||
<PackageReadmeFile>README.md</PackageReadmeFile>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Content Include="icon.ico" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<None Include="..\README.md">
|
||||
<Pack>True</Pack>
|
||||
<PackagePath>\</PackagePath>
|
||||
</None>
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Tomlyn" Version="0.15.0" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Reference Include="irrKlang.NET4">
|
||||
<HintPath>..\lib\irrKlang.NET4.dll</HintPath>
|
||||
</Reference>
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Compile Update="Properties\Resources.Designer.cs">
|
||||
<DesignTime>True</DesignTime>
|
||||
<AutoGen>True</AutoGen>
|
||||
<DependentUpon>Resources.resx</DependentUpon>
|
||||
</Compile>
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<EmbeddedResource Update="Properties\Resources.resx">
|
||||
<Generator>ResXFileCodeGenerator</Generator>
|
||||
<LastGenOutput>Resources.Designer.cs</LastGenOutput>
|
||||
</EmbeddedResource>
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
@@ -0,0 +1,302 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Text.RegularExpressions;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace BAKKA_Editor
|
||||
{
|
||||
internal class Chart
|
||||
{
|
||||
private static readonly CultureInfo _defaultParsingCulture = CultureInfo.InvariantCulture;
|
||||
public List<Note> Notes { get; set; }
|
||||
public List<Gimmick> Gimmicks { get; set; }
|
||||
/// <summary>
|
||||
/// Offset in seconds.
|
||||
/// </summary>
|
||||
public double Offset { get; set; }
|
||||
/// <summary>
|
||||
/// Movie offset in seconds
|
||||
/// </summary>
|
||||
public double MovieOffset { get; set; }
|
||||
String SongFileName { get; set; }
|
||||
List<Gimmick> TimeEvents { get; set; }
|
||||
public bool HasInitEvents
|
||||
{
|
||||
get
|
||||
{
|
||||
return TimeEvents != null &&
|
||||
TimeEvents.Count > 0 &&
|
||||
Gimmicks.Count(x => x.Measure == 0 && x.GimmickType == GimmickType.BpmChange) >= 1 &&
|
||||
Gimmicks.Count(x => x.Measure == 0 && x.GimmickType == GimmickType.TimeSignatureChange) >= 1;
|
||||
}
|
||||
}
|
||||
public bool IsSaved { get; set; }
|
||||
|
||||
public Chart()
|
||||
{
|
||||
Notes = new();
|
||||
Gimmicks = new();
|
||||
Offset = 0;
|
||||
MovieOffset = 0;
|
||||
SongFileName = "";
|
||||
IsSaved = true;
|
||||
}
|
||||
|
||||
public bool ParseFile(string filename)
|
||||
{
|
||||
var file = File.ReadAllLines(filename);
|
||||
|
||||
int index = 0;
|
||||
|
||||
do
|
||||
{
|
||||
var line = file[index];
|
||||
|
||||
var path = Utils.GetTag(line, "#MUSIC_FILE_PATH ");
|
||||
if (path != null)
|
||||
SongFileName = path;
|
||||
var offset = Utils.GetTag(line, "#OFFSET");
|
||||
if (offset != null)
|
||||
Offset = Convert.ToDouble(offset, _defaultParsingCulture);
|
||||
|
||||
offset = Utils.GetTag(line, "#MOVIEOFFSET");
|
||||
if (offset != null)
|
||||
MovieOffset = Convert.ToDouble(offset, _defaultParsingCulture);
|
||||
|
||||
|
||||
if (line.Contains("#BODY"))
|
||||
{
|
||||
index++;
|
||||
break;
|
||||
}
|
||||
|
||||
} while (++index < file.Length);
|
||||
|
||||
int lineNum;
|
||||
Gimmick gimmickTemp;
|
||||
Note noteTemp;
|
||||
Dictionary<int, Note> notesByLine = new();
|
||||
Dictionary<int, int> refByLine = new();
|
||||
for (int i = index; i < file.Length; i++)
|
||||
{
|
||||
if (String.IsNullOrWhiteSpace(file[i]))
|
||||
continue;
|
||||
|
||||
var parsed = file[i].Split(new string[] { " " }, StringSplitOptions.RemoveEmptyEntries | StringSplitOptions.TrimEntries);
|
||||
NoteBase temp = new();
|
||||
temp.BeatInfo = new BeatInfo(Convert.ToInt32(parsed[0], _defaultParsingCulture), Convert.ToInt32(parsed[1], _defaultParsingCulture));
|
||||
temp.GimmickType = (GimmickType)Convert.ToInt32(parsed[2], _defaultParsingCulture);
|
||||
|
||||
switch (temp.GimmickType)
|
||||
{
|
||||
case GimmickType.NoGimmick:
|
||||
noteTemp = new Note(temp.BeatInfo);
|
||||
noteTemp.NoteType = (NoteType)Convert.ToInt32(parsed[3], _defaultParsingCulture);
|
||||
lineNum = Convert.ToInt32(parsed[4], _defaultParsingCulture);
|
||||
noteTemp.Position = Convert.ToInt32(parsed[5], _defaultParsingCulture);
|
||||
noteTemp.Size = Convert.ToInt32(parsed[6], _defaultParsingCulture);
|
||||
noteTemp.HoldChange = Convert.ToBoolean(Convert.ToInt32(parsed[7], _defaultParsingCulture));
|
||||
if (noteTemp.NoteType == NoteType.MaskAdd || noteTemp.NoteType == NoteType.MaskRemove)
|
||||
{
|
||||
noteTemp.MaskFill = (MaskType)Convert.ToInt32(parsed[8], _defaultParsingCulture);
|
||||
}
|
||||
else if (noteTemp.NoteType == NoteType.HoldStartNoBonus ||
|
||||
noteTemp.NoteType == NoteType.HoldJoint ||
|
||||
noteTemp.NoteType == NoteType.HoldStartBonusFlair)
|
||||
{
|
||||
refByLine[lineNum] = Convert.ToInt32(parsed[8], _defaultParsingCulture);
|
||||
}
|
||||
Notes.Add(noteTemp);
|
||||
notesByLine[lineNum] = Notes.Last();
|
||||
break;
|
||||
case GimmickType.BpmChange:
|
||||
gimmickTemp = new Gimmick(temp.BeatInfo, temp.GimmickType);
|
||||
gimmickTemp.BPM = Convert.ToDouble(parsed[3], _defaultParsingCulture);
|
||||
Gimmicks.Add(gimmickTemp);
|
||||
break;
|
||||
case GimmickType.TimeSignatureChange:
|
||||
gimmickTemp = new Gimmick(temp.BeatInfo, temp.GimmickType);
|
||||
gimmickTemp.TimeSig = new TimeSignature() { Upper = Convert.ToInt32(parsed[3], _defaultParsingCulture), Lower = parsed.Length == 5 ? Convert.ToInt32(parsed[4], _defaultParsingCulture) : 4 };
|
||||
Gimmicks.Add(gimmickTemp);
|
||||
break;
|
||||
case GimmickType.HiSpeedChange:
|
||||
gimmickTemp = new Gimmick(temp.BeatInfo, temp.GimmickType);
|
||||
gimmickTemp.HiSpeed = Convert.ToDouble(parsed[3], _defaultParsingCulture);
|
||||
Gimmicks.Add(gimmickTemp);
|
||||
break;
|
||||
case GimmickType.ReverseStart:
|
||||
case GimmickType.ReverseMiddle:
|
||||
case GimmickType.ReverseEnd:
|
||||
case GimmickType.StopStart:
|
||||
case GimmickType.StopEnd:
|
||||
default:
|
||||
Gimmicks.Add(new Gimmick(temp.BeatInfo, temp.GimmickType));
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// Generate hold references
|
||||
for (int i = 0; i < Notes.Count; i++)
|
||||
{
|
||||
if (refByLine.ContainsKey(i))
|
||||
{
|
||||
Notes[i].NextNote = notesByLine[refByLine[i]];
|
||||
Notes[i].NextNote.PrevNote = Notes[i];
|
||||
}
|
||||
}
|
||||
|
||||
RecalcTime();
|
||||
|
||||
IsSaved = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
public bool WriteFile(string filename, bool setSave = true)
|
||||
{
|
||||
using (StreamWriter sw = new StreamWriter(new FileStream(filename, FileMode.Create), new UTF8Encoding(false)))
|
||||
{
|
||||
// LF line ending
|
||||
sw.NewLine = "\n";
|
||||
|
||||
sw.WriteLine("#MUSIC_SCORE_ID 0");
|
||||
sw.WriteLine("#MUSIC_SCORE_VERSION 0");
|
||||
sw.WriteLine("#GAME_VERSION ");
|
||||
sw.WriteLine($"#MUSIC_FILE_PATH {SongFileName}");
|
||||
sw.WriteLine($"#OFFSET {Offset:F6}");
|
||||
sw.WriteLine($"#MOVIEOFFSET {MovieOffset:F6}");
|
||||
sw.WriteLine("#BODY");
|
||||
|
||||
foreach (var gimmick in Gimmicks)
|
||||
{
|
||||
sw.Write($"{gimmick.BeatInfo.Measure,4:F0}{gimmick.BeatInfo.Beat,5:F0}{((int)gimmick.GimmickType),5:F0}");
|
||||
switch (gimmick.GimmickType)
|
||||
{
|
||||
case GimmickType.BpmChange:
|
||||
sw.WriteLine($" {gimmick.BPM:F6}");
|
||||
break;
|
||||
case GimmickType.TimeSignatureChange:
|
||||
sw.WriteLine($"{gimmick.TimeSig.Upper,5:F0}{gimmick.TimeSig.Lower,5:F0}");
|
||||
break;
|
||||
case GimmickType.HiSpeedChange:
|
||||
sw.WriteLine($" {gimmick.HiSpeed:F6}");
|
||||
break;
|
||||
default:
|
||||
sw.WriteLine("");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
foreach (var note in Notes)
|
||||
{
|
||||
sw.Write($"{note.BeatInfo.Measure,4:F0}{note.BeatInfo.Beat,5:F0}{((int)note.GimmickType),5:F0}{(int)note.NoteType,5:F0}");
|
||||
sw.Write($"{Notes.IndexOf(note),5:F0}{note.Position,5:F0}{note.Size,5:F0}{Convert.ToInt32(note.HoldChange, _defaultParsingCulture),5:F0}");
|
||||
if (note.IsMask)
|
||||
sw.Write($"{(int)note.MaskFill,5:F0}");
|
||||
if (note.NextNote != null)
|
||||
sw.Write($"{Notes.IndexOf(note.NextNote),5:F0}");
|
||||
sw.WriteLine("");
|
||||
}
|
||||
}
|
||||
|
||||
IsSaved = setSave;
|
||||
return true;
|
||||
}
|
||||
|
||||
public void RecalcTime()
|
||||
{
|
||||
Gimmicks = Gimmicks.OrderBy(x => x.Measure).ToList();
|
||||
var timeSig = Gimmicks.FirstOrDefault(x => x.GimmickType == GimmickType.TimeSignatureChange && x.Measure == 0.0f);
|
||||
var bpm = Gimmicks.FirstOrDefault(x => x.GimmickType == GimmickType.BpmChange && x.Measure == 0.0f);
|
||||
if (timeSig == null || bpm == null)
|
||||
return; // Cannot calculate times without either starting value
|
||||
|
||||
TimeEvents = new();
|
||||
for (int i = 0; i < Gimmicks.Count; i++)
|
||||
{
|
||||
var evt = TimeEvents.FirstOrDefault(x => x.BeatInfo.MeasureDecimal == Gimmicks[i].BeatInfo.MeasureDecimal);
|
||||
|
||||
if (Gimmicks[i].GimmickType == GimmickType.BpmChange)
|
||||
{
|
||||
if (evt == null)
|
||||
{
|
||||
TimeEvents.Add(new Gimmick()
|
||||
{
|
||||
BeatInfo = new BeatInfo(Gimmicks[i].BeatInfo),
|
||||
BPM = Gimmicks[i].BPM,
|
||||
TimeSig = new TimeSignature(timeSig.TimeSig)
|
||||
});
|
||||
}
|
||||
else
|
||||
{
|
||||
evt.BPM = Gimmicks[i].BPM;
|
||||
}
|
||||
bpm = Gimmicks[i];
|
||||
}
|
||||
if (Gimmicks[i].GimmickType == GimmickType.TimeSignatureChange)
|
||||
{
|
||||
if (evt == null)
|
||||
{
|
||||
TimeEvents.Add(new Gimmick()
|
||||
{
|
||||
BeatInfo = new BeatInfo(Gimmicks[i].BeatInfo),
|
||||
BPM = bpm.BPM,
|
||||
TimeSig = new TimeSignature(Gimmicks[i].TimeSig)
|
||||
});
|
||||
}
|
||||
else
|
||||
{
|
||||
evt.TimeSig = new TimeSignature(Gimmicks[i].TimeSig);
|
||||
}
|
||||
timeSig = Gimmicks[i];
|
||||
}
|
||||
}
|
||||
|
||||
// Run through all time events and generate valid start times
|
||||
TimeEvents[0].StartTime = Offset * 1000.0;
|
||||
for (int i = 1; i < TimeEvents.Count; i++)
|
||||
{
|
||||
TimeEvents[i].StartTime = ((TimeEvents[i].Measure - TimeEvents[i - 1].Measure) * (4.0f * TimeEvents[i - 1].TimeSig.Ratio * (60000.0 / TimeEvents[i - 1].BPM))) + TimeEvents[i - 1].StartTime;
|
||||
}
|
||||
}
|
||||
/*
|
||||
((60000.0 / evt.BPM) * 4.0 * evt.TimeSig.Ratio) * measure = time
|
||||
time / ((60000.0 / evt.BPM) * 4.0 * evt.TimeSig.Ratio) = measure
|
||||
*/
|
||||
|
||||
/// <summary>
|
||||
/// Translate clock time to beats
|
||||
/// </summary>
|
||||
/// <param name="time">Current timestamp in ms</param>
|
||||
/// <returns></returns>
|
||||
public BeatInfo GetBeat(float time)
|
||||
{
|
||||
if (TimeEvents == null || TimeEvents.Count == 0)
|
||||
return new BeatInfo(-1, 0);
|
||||
|
||||
var evt = TimeEvents.Where(x => time >= x.StartTime).LastOrDefault();
|
||||
if (evt == null)
|
||||
evt = TimeEvents[0];
|
||||
return new BeatInfo((float)((time - evt.StartTime) / ((60000.0 / evt.BPM) * 4.0f * evt.TimeSig.Ratio) + evt.Measure));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Translate measures into clock time
|
||||
/// </summary>
|
||||
/// <param name="beat"></param>
|
||||
/// <returns></returns>
|
||||
public int GetTime(BeatInfo beat)
|
||||
{
|
||||
if (TimeEvents == null || TimeEvents.Count == 0)
|
||||
return 0;
|
||||
|
||||
var evt = TimeEvents.Where(x => beat.MeasureDecimal >= x.Measure).LastOrDefault();
|
||||
if (evt == null)
|
||||
evt = TimeEvents[0];
|
||||
return (int)(((60000.0 / evt.BPM) * 4.0f * evt.TimeSig.Ratio) * (beat.MeasureDecimal - evt.Measure) + evt.StartTime);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,585 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Drawing.Drawing2D;
|
||||
using System.Threading.Tasks;
|
||||
using static System.Windows.Forms.VisualStyles.VisualStyleElement.TaskbarClock;
|
||||
using System.ComponentModel;
|
||||
|
||||
namespace BAKKA_Editor
|
||||
{
|
||||
internal class CircleView
|
||||
{
|
||||
public SizeF PanelSize { get; private set; }
|
||||
public RectangleF DrawRect { get; private set; }
|
||||
public PointF TopCorner { get; private set; }
|
||||
public PointF CenterPoint { get; private set; }
|
||||
public float Radius { get; private set; }
|
||||
public float CurrentMeasure { get; set; }
|
||||
public float Hispeed { get; set; } = 1.5f;
|
||||
public bool showHispeed { get; set; } = true;
|
||||
|
||||
// Pens and Brushes
|
||||
public Pen BasePen { get; set; }
|
||||
public Pen BeatPen { get; set; }
|
||||
public Pen TickMinorPen { get; set; }
|
||||
public Pen TickMediumPen { get; set; }
|
||||
public Pen TickMajorPen { get; set; }
|
||||
public SolidBrush HoldBrush { get; set; } = new SolidBrush(Color.FromArgb(170, Color.Yellow));
|
||||
public SolidBrush MaskBrush { get; set; } = new SolidBrush(Color.FromArgb(90, Color.Black));
|
||||
public SolidBrush BackgroundBrush { get; set; }
|
||||
public Pen HighlightPen { get; set; }
|
||||
public Pen FlairPen { get; set; }
|
||||
private int CursorTransparency = 110;
|
||||
private int SelectTransparency = 110;
|
||||
private int FlairTransparency = 75;
|
||||
|
||||
// Graphics.
|
||||
BufferedGraphicsContext gfxContext = BufferedGraphicsManager.Current;
|
||||
BufferedGraphics bufGraphics;
|
||||
|
||||
// Mouse information. Public so other GUI elements can be updated with their values.
|
||||
public int mouseDownPos = -1;
|
||||
public Point mouseDownPt;
|
||||
public int lastMousePos = -1;
|
||||
public bool rolloverPos = false;
|
||||
public bool rolloverNeg = false;
|
||||
|
||||
public CircleView(SizeF size)
|
||||
{
|
||||
Update(size);
|
||||
}
|
||||
|
||||
public void Update(SizeF size)
|
||||
{
|
||||
PanelSize = size;
|
||||
float basePenWidth = PanelSize.Width * 4.0f / 600.0f;
|
||||
TopCorner = new PointF(basePenWidth * 4, basePenWidth * 4);
|
||||
DrawRect = new RectangleF(
|
||||
TopCorner.X,
|
||||
TopCorner.Y,
|
||||
PanelSize.Width - basePenWidth * 8,
|
||||
PanelSize.Height - basePenWidth * 8);
|
||||
Radius = DrawRect.Width / 2.0f;
|
||||
CenterPoint = new PointF(TopCorner.X + Radius, TopCorner.Y + Radius);
|
||||
|
||||
// Pens
|
||||
BasePen = new Pen(Color.Black, basePenWidth);
|
||||
BeatPen = new Pen(Color.White, PanelSize.Width * 1.0f / 600.0f);
|
||||
TickMinorPen = new Pen(Color.Black, PanelSize.Width * 2.0f / 600.0f);
|
||||
TickMediumPen = new Pen(Color.Black, PanelSize.Width * 4.0f / 600.0f);
|
||||
TickMajorPen = new Pen(Color.Black, PanelSize.Width * 7.0f / 600.0f);
|
||||
HighlightPen = new Pen(Color.FromArgb(SelectTransparency, Color.LightPink), PanelSize.Width * 8.0f / 600.0f);
|
||||
FlairPen = new Pen(Color.FromArgb(FlairTransparency, Color.Yellow), PanelSize.Width * 8.0f / 600.0f);
|
||||
}
|
||||
|
||||
private float GetTotalMeasureShowNotes(Chart chart)
|
||||
{
|
||||
//Convert hispeed to frames
|
||||
float displayFrames = 73.0f - ((Hispeed - 1.5f) * 10.0f);
|
||||
float tempTotalTime = ((displayFrames / 60.0f) * 1000.0f);
|
||||
float currentTime = chart.GetTime(new BeatInfo(CurrentMeasure));
|
||||
float tempEndTime = currentTime + tempTotalTime;
|
||||
if (showHispeed)
|
||||
{
|
||||
//Account for hispeed gimmick
|
||||
List<Gimmick> HispeedChanges = new List<Gimmick>();
|
||||
Gimmick InitialSpeed = chart.Gimmicks.Where(x => x.GimmickType == GimmickType.HiSpeedChange && CurrentMeasure > x.Measure).LastOrDefault();
|
||||
//Add initial hispeed to list
|
||||
if (InitialSpeed == null)
|
||||
{
|
||||
InitialSpeed = new Gimmick();
|
||||
InitialSpeed.HiSpeed = 1.0;
|
||||
}
|
||||
HispeedChanges.Add(InitialSpeed);
|
||||
//Random todos that im too lazy to put in applicable locations
|
||||
//TODO: add "time" to notes so we can compare against it every time instead of always calculating what time a note is at
|
||||
//TODO: add function to reevaluate the time of every note when bpm or TS is added/removed.
|
||||
|
||||
//add all hispeed changes to list that happen within the current total time to show notes
|
||||
HispeedChanges.AddRange(chart.Gimmicks.Where(
|
||||
x => x.Measure >= CurrentMeasure
|
||||
&& chart.GetTime(new BeatInfo(x.Measure)) < tempEndTime
|
||||
&& x.GimmickType == GimmickType.HiSpeedChange).ToList());
|
||||
if (HispeedChanges.Count > 1)
|
||||
{
|
||||
for (int i = 0; i < HispeedChanges.Count; i++)
|
||||
{
|
||||
float timeDiff;
|
||||
float itemTime = chart.GetTime(HispeedChanges[i].BeatInfo);
|
||||
float modifiedTime;
|
||||
if (itemTime <= (tempTotalTime + currentTime))
|
||||
{
|
||||
if (i == 0)
|
||||
itemTime = currentTime;
|
||||
|
||||
if (i != HispeedChanges.Count - 1)
|
||||
{
|
||||
float tempTestITimeDiff = (currentTime + tempTotalTime) - itemTime;
|
||||
float tempTestIModifiedTime = (tempTestITimeDiff) / (float)(HispeedChanges[i].HiSpeed);
|
||||
if ((currentTime + tempTotalTime - tempTestITimeDiff + tempTestIModifiedTime) < chart.GetTime(HispeedChanges[i + 1].BeatInfo))
|
||||
{
|
||||
timeDiff = (currentTime + tempTotalTime) - itemTime;
|
||||
modifiedTime = timeDiff / (float)HispeedChanges[i].HiSpeed;
|
||||
}
|
||||
else
|
||||
{
|
||||
timeDiff = chart.GetTime(HispeedChanges[i + 1].BeatInfo) - itemTime;
|
||||
modifiedTime = timeDiff / (float)HispeedChanges[i].HiSpeed;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
timeDiff = (currentTime + tempTotalTime) - itemTime;
|
||||
modifiedTime = timeDiff / (float)HispeedChanges[i].HiSpeed;
|
||||
}
|
||||
tempTotalTime = tempTotalTime - timeDiff + modifiedTime;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
tempTotalTime /= (float)HispeedChanges[0].HiSpeed;
|
||||
}
|
||||
tempEndTime = currentTime + tempTotalTime;
|
||||
}
|
||||
//convert total time to total measure
|
||||
BeatInfo EndMeasure = chart.GetBeat(tempEndTime);
|
||||
return EndMeasure.MeasureDecimal - CurrentMeasure;
|
||||
}
|
||||
|
||||
private float GetNoteScaleFromMeasure(Chart chart, float objectTime)
|
||||
{
|
||||
// Scale from 0-1
|
||||
float objectTimeAsTime = chart.GetTime(new BeatInfo(objectTime));
|
||||
float currentTime = chart.GetTime(new BeatInfo(CurrentMeasure));
|
||||
float EndTimeShowNotes = chart.GetTime(new BeatInfo(CurrentMeasure + GetTotalMeasureShowNotes(chart)));
|
||||
float notescaleInit;
|
||||
var LatestHispeedChange = chart.Gimmicks.Where(x => x.GimmickType == GimmickType.HiSpeedChange && CurrentMeasure >= x.Measure).LastOrDefault();
|
||||
if (LatestHispeedChange != null && LatestHispeedChange.HiSpeed < 0.0)
|
||||
{
|
||||
//Reverse
|
||||
notescaleInit = (objectTimeAsTime - currentTime) / (EndTimeShowNotes - currentTime);
|
||||
}
|
||||
else
|
||||
{
|
||||
//Normal
|
||||
notescaleInit = 1 - ((objectTimeAsTime - currentTime) / (EndTimeShowNotes - currentTime));
|
||||
}
|
||||
//Scale math
|
||||
notescaleInit = 0.001f + (float)Math.Pow(notescaleInit, 3.0f) - (0.501f * (float)Math.Pow(notescaleInit, 2.0f)) + (0.5f * notescaleInit);
|
||||
return notescaleInit;
|
||||
}
|
||||
|
||||
private ArcInfo GetScaledRect(Chart chart, float objectTime)
|
||||
{
|
||||
ArcInfo info = new();
|
||||
|
||||
info.NoteScale = GetNoteScaleFromMeasure(chart, objectTime);
|
||||
float scaledRectSize = DrawRect.Width * info.NoteScale;
|
||||
float scaledRadius = scaledRectSize / 2.0f;
|
||||
info.Rect = new RectangleF(
|
||||
new PointF(
|
||||
CenterPoint.X - scaledRadius,
|
||||
CenterPoint.Y - scaledRadius),
|
||||
new SizeF(scaledRectSize, scaledRectSize));
|
||||
return info;
|
||||
}
|
||||
|
||||
private ArcInfo GetArcInfo(Chart chart, Note note)
|
||||
{
|
||||
ArcInfo info = GetScaledRect(chart, note.Measure);
|
||||
info.StartAngle = -note.Position * 6;
|
||||
info.ArcLength = -note.Size * 6;
|
||||
if(info.ArcLength != -360)
|
||||
{
|
||||
info.StartAngle -= 2;
|
||||
info.ArcLength += 4;
|
||||
}
|
||||
return info;
|
||||
}
|
||||
|
||||
// Updates the mouse down position within the circle, and returns the new position.
|
||||
public void UpdateMouseDown(float xCen, float yCen, Point mousePt)
|
||||
{
|
||||
float theta = (float)(Math.Atan2(yCen, xCen) * 180.0f / Math.PI);
|
||||
if (theta < 0)
|
||||
theta += 360.0f;
|
||||
// Left click moves the cursor
|
||||
mouseDownPos = (int)(theta / 6.0f);
|
||||
mouseDownPt = mousePt;
|
||||
lastMousePos = -1;
|
||||
rolloverPos = false;
|
||||
rolloverNeg = false;
|
||||
}
|
||||
|
||||
public void UpdateMouseUp()
|
||||
{
|
||||
if (mouseDownPos <= -1)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// Reset position and point.
|
||||
mouseDownPos = -1;
|
||||
mouseDownPt = new Point();
|
||||
}
|
||||
|
||||
// Updates the mouse position and returns the new position in degrees.
|
||||
public int UpdateMouseMove(float xCen, float yCen)
|
||||
{
|
||||
float thetaCalc = (float)(Math.Atan2(yCen, xCen) * 180.0f / Math.PI);
|
||||
if (thetaCalc < 0)
|
||||
thetaCalc += 360.0f;
|
||||
int theta = (int)(thetaCalc / 6.0f);
|
||||
|
||||
int delta = theta - lastMousePos;
|
||||
// Handle rollover
|
||||
if (delta == -59)
|
||||
{
|
||||
if (rolloverNeg)
|
||||
rolloverNeg = false;
|
||||
else
|
||||
rolloverPos = true;
|
||||
}
|
||||
else if (delta == 59)
|
||||
{
|
||||
if (rolloverPos)
|
||||
rolloverPos = false;
|
||||
else
|
||||
rolloverNeg = true;
|
||||
}
|
||||
lastMousePos = theta;
|
||||
|
||||
return theta;
|
||||
}
|
||||
|
||||
public void DrawBackground(int width, int height, Color color)
|
||||
{
|
||||
Rectangle panelRect = new Rectangle(0, 0, width, height);
|
||||
|
||||
// Set drawing mode
|
||||
bufGraphics.Graphics.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighSpeed;
|
||||
// Remember background color
|
||||
BackgroundBrush = new SolidBrush(color);
|
||||
// Draw background
|
||||
bufGraphics.Graphics.FillRectangle(BackgroundBrush, panelRect);
|
||||
}
|
||||
|
||||
public void DrawMasks(Chart chart)
|
||||
{
|
||||
var masks = chart.Notes.Where(
|
||||
x => x.Measure <= CurrentMeasure
|
||||
&& x.IsMask).ToList();
|
||||
foreach (var mask in masks)
|
||||
{
|
||||
if (mask.NoteType == NoteType.MaskAdd)
|
||||
{
|
||||
// Check if there's a MaskRemove that counters the MaskAdd (unless the MaskAdd is later)
|
||||
var rem = masks.FirstOrDefault(x => x.NoteType == NoteType.MaskRemove &&
|
||||
x.Position == mask.Position && x.Size == mask.Size);
|
||||
if (rem == null || rem.Measure < mask.Measure)
|
||||
bufGraphics.Graphics.FillPie(MaskBrush, DrawRect.ToInt(), -mask.Position * 6.0f, -mask.Size * 6.0f);
|
||||
}
|
||||
else if (mask.NoteType == NoteType.MaskRemove) // Explicitly draw MaskRemove for edge cases
|
||||
{
|
||||
bufGraphics.Graphics.FillPie(BackgroundBrush, DrawRect.ToInt(), -mask.Position * 6.0f, -mask.Size * 6.0f);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void DrawCircle(Chart chart)
|
||||
{
|
||||
// Switch drawing modes
|
||||
bufGraphics.Graphics.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias;
|
||||
|
||||
// Draw measure circle
|
||||
for (float meas = (float)Math.Ceiling(CurrentMeasure); (meas - CurrentMeasure) < GetTotalMeasureShowNotes(chart); meas += 1.0f)
|
||||
{
|
||||
var info = GetScaledRect(chart, meas);
|
||||
if (info.Rect.Width >= 1)
|
||||
{
|
||||
bufGraphics.Graphics.DrawEllipse(BeatPen, info.Rect);
|
||||
}
|
||||
}
|
||||
|
||||
// Draw base circle
|
||||
bufGraphics.Graphics.DrawEllipse(TickMediumPen, DrawRect);
|
||||
}
|
||||
|
||||
public void DrawDegreeLines()
|
||||
{
|
||||
for (int i = 0; i < 360; i += 6)
|
||||
{
|
||||
PointF startPoint = new PointF(
|
||||
(float)(Radius * Math.Cos(Utils.DegToRad(i))) + CenterPoint.X,
|
||||
(float)(Radius * Math.Sin(Utils.DegToRad(i))) + CenterPoint.Y);
|
||||
float tickLength = PanelSize.Width * 10.0f / 285.0f;
|
||||
float innerRad = Radius - tickLength;
|
||||
Pen activePen;
|
||||
if (i % 90 == 0)
|
||||
{
|
||||
innerRad = Radius - (tickLength * 3.5f);
|
||||
activePen = TickMajorPen;
|
||||
}
|
||||
else if (i % 30 == 0)
|
||||
{
|
||||
innerRad = Radius - (tickLength * 2.5f);
|
||||
activePen = TickMediumPen;
|
||||
}
|
||||
else
|
||||
{
|
||||
activePen = TickMinorPen;
|
||||
}
|
||||
PointF endPoint = new PointF(
|
||||
(float)(innerRad * Math.Cos(Utils.DegToRad(i))) + CenterPoint.X,
|
||||
(float)(innerRad * Math.Sin(Utils.DegToRad(i))) + CenterPoint.Y);
|
||||
|
||||
bufGraphics.Graphics.DrawLine(activePen, startPoint, endPoint);
|
||||
}
|
||||
}
|
||||
|
||||
public void DrawGimmicks(Chart chart, bool showGimmicks, int selectedGimmickIndex)
|
||||
{
|
||||
if (showGimmicks)
|
||||
{
|
||||
List<Gimmick> drawGimmicks = chart.Gimmicks.Where(
|
||||
x => x.Measure >= CurrentMeasure
|
||||
&& x.Measure <= (CurrentMeasure + GetTotalMeasureShowNotes(chart))).ToList();
|
||||
|
||||
foreach (var gimmick in drawGimmicks)
|
||||
{
|
||||
var info = GetScaledRect(chart, gimmick.Measure);
|
||||
|
||||
if (info.Rect.Width >= 1)
|
||||
{
|
||||
bufGraphics.Graphics.DrawEllipse(GetPen(gimmick), info.Rect);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void DrawHolds(Chart chart, bool highlightSelectedNote, int selectedNoteIndex)
|
||||
{
|
||||
ArcInfo currentInfo = GetScaledRect(chart, CurrentMeasure);
|
||||
ArcInfo endInfo = GetScaledRect(chart, CurrentMeasure + GetTotalMeasureShowNotes(chart));
|
||||
|
||||
// First, draw holes that start before the viewpoint and have nodes that end after
|
||||
List<Note> holdNotes = chart.Notes.Where(
|
||||
x => x.Measure < CurrentMeasure
|
||||
&& x.NextNote != null
|
||||
&& x.NextNote.Measure > (CurrentMeasure + GetTotalMeasureShowNotes(chart))
|
||||
&& x.IsHold).ToList();
|
||||
foreach (var note in holdNotes)
|
||||
{
|
||||
ArcInfo info = GetArcInfo(chart, note);
|
||||
ArcInfo nextInfo = GetArcInfo(chart, (Note)note.NextNote);
|
||||
//GraphicsPath path = new GraphicsPath();
|
||||
//path.AddArc(endInfo.Rect, info.StartAngle, info.ArcLength);
|
||||
//path.AddArc(currentInfo.Rect, info.StartAngle + info.ArcLength, -info.ArcLength);
|
||||
//bufGraphics.Graphics.FillPath(HoldBrush, path);
|
||||
|
||||
float ratio = (currentInfo.Rect.Width - nextInfo.Rect.Width) / (info.Rect.Width - nextInfo.Rect.Width);
|
||||
float startNoteAngle = nextInfo.StartAngle;
|
||||
float endNoteAngle = info.StartAngle;
|
||||
if (nextInfo.StartAngle > info.StartAngle && (Math.Abs(nextInfo.StartAngle - info.StartAngle) > 180))
|
||||
{
|
||||
startNoteAngle -= 360;
|
||||
}
|
||||
else if (info.StartAngle > nextInfo.StartAngle && (Math.Abs(nextInfo.StartAngle - info.StartAngle) > 180))
|
||||
{
|
||||
endNoteAngle -= 360;
|
||||
}
|
||||
float startAngle = ratio * (endNoteAngle - startNoteAngle) + startNoteAngle;
|
||||
float endAngle = ratio * ((endNoteAngle - info.ArcLength) - (startNoteAngle - nextInfo.ArcLength)) +
|
||||
(startNoteAngle - nextInfo.ArcLength);
|
||||
float arcLength = startAngle - endAngle;
|
||||
|
||||
float ratio2 = (endInfo.Rect.Width - nextInfo.Rect.Width) / (info.Rect.Width - nextInfo.Rect.Width);
|
||||
float startNoteAngle2 = nextInfo.StartAngle;
|
||||
float endNoteAngle2 = info.StartAngle;
|
||||
if (nextInfo.StartAngle > info.StartAngle && (Math.Abs(nextInfo.StartAngle - info.StartAngle) > 180))
|
||||
{
|
||||
startNoteAngle2 -= 360;
|
||||
}
|
||||
else if (info.StartAngle > nextInfo.StartAngle && (Math.Abs(nextInfo.StartAngle - info.StartAngle) > 180))
|
||||
{
|
||||
endNoteAngle2 -= 360;
|
||||
}
|
||||
float startAngle2 = ratio2 * (endNoteAngle2 - startNoteAngle2) + startNoteAngle2;
|
||||
float endAngle2 = ratio2 * ((endNoteAngle2 - info.ArcLength) - (startNoteAngle2 - nextInfo.ArcLength)) +
|
||||
(startNoteAngle2 - nextInfo.ArcLength);
|
||||
float arcLength2 = startAngle2 - endAngle2;
|
||||
|
||||
GraphicsPath path = new GraphicsPath();
|
||||
path.AddArc(currentInfo.Rect, startAngle, arcLength);
|
||||
path.AddArc(endInfo.Rect, startAngle2 + arcLength2, -arcLength2);
|
||||
bufGraphics.Graphics.FillPath(HoldBrush, path);
|
||||
}
|
||||
|
||||
// Second, draw all the notes on-screen
|
||||
holdNotes = chart.Notes.Where(
|
||||
x => x.Measure >= CurrentMeasure
|
||||
&& x.Measure <= (CurrentMeasure + GetTotalMeasureShowNotes(chart))
|
||||
&& x.IsHold).ToList();
|
||||
foreach (var note in holdNotes)
|
||||
{
|
||||
ArcInfo info = GetArcInfo(chart, note);
|
||||
|
||||
// If the previous note is off-screen, this case handles that
|
||||
if (note.PrevNote != null && note.PrevNote.Measure < CurrentMeasure)
|
||||
{
|
||||
ArcInfo prevInfo = GetArcInfo(chart, (Note)note.PrevNote);
|
||||
float ratio = (currentInfo.Rect.Width - info.Rect.Width) / (prevInfo.Rect.Width - info.Rect.Width);
|
||||
float startNoteAngle = info.StartAngle;
|
||||
float endNoteAngle = prevInfo.StartAngle;
|
||||
if (info.StartAngle > prevInfo.StartAngle && (Math.Abs(info.StartAngle - prevInfo.StartAngle) > 180))
|
||||
{
|
||||
startNoteAngle -= 360;
|
||||
}
|
||||
else if (prevInfo.StartAngle > info.StartAngle && (Math.Abs(info.StartAngle - prevInfo.StartAngle) > 180))
|
||||
{
|
||||
endNoteAngle -= 360;
|
||||
}
|
||||
float startAngle = ratio * (endNoteAngle - startNoteAngle) + startNoteAngle;
|
||||
float endAngle = ratio * ((endNoteAngle - prevInfo.ArcLength) - (startNoteAngle - info.ArcLength)) +
|
||||
(startNoteAngle - info.ArcLength);
|
||||
float arcLength = startAngle - endAngle;
|
||||
|
||||
GraphicsPath path = new GraphicsPath();
|
||||
path.AddArc(info.Rect, info.StartAngle, info.ArcLength);
|
||||
path.AddArc(currentInfo.Rect, startAngle + arcLength, -arcLength);
|
||||
bufGraphics.Graphics.FillPath(HoldBrush, path);
|
||||
}
|
||||
|
||||
// If the next note is on-screen, this case handles that
|
||||
if (note.NextNote != null && note.NextNote.Measure <= (CurrentMeasure + GetTotalMeasureShowNotes(chart)))
|
||||
{
|
||||
ArcInfo nextInfo = GetArcInfo(chart, (Note)note.NextNote);
|
||||
GraphicsPath path = new GraphicsPath();
|
||||
path.AddArc(info.Rect, info.StartAngle, info.ArcLength);
|
||||
path.AddArc(nextInfo.Rect, nextInfo.StartAngle + nextInfo.ArcLength, -nextInfo.ArcLength);
|
||||
bufGraphics.Graphics.FillPath(HoldBrush, path);
|
||||
}
|
||||
|
||||
// If the next note is off-screen, this case handles that
|
||||
if (note.NextNote != null && note.NextNote.Measure > (CurrentMeasure + GetTotalMeasureShowNotes(chart)))
|
||||
{
|
||||
ArcInfo nextInfo = GetArcInfo(chart, (Note)note.NextNote);
|
||||
float ratio = (endInfo.Rect.Width - nextInfo.Rect.Width) / (info.Rect.Width - nextInfo.Rect.Width);
|
||||
float startNoteAngle = nextInfo.StartAngle;
|
||||
float endNoteAngle = info.StartAngle;
|
||||
if (nextInfo.StartAngle > info.StartAngle && (Math.Abs(nextInfo.StartAngle - info.StartAngle) > 180))
|
||||
{
|
||||
startNoteAngle -= 360;
|
||||
}
|
||||
else if (info.StartAngle > nextInfo.StartAngle && (Math.Abs(nextInfo.StartAngle - info.StartAngle) > 180))
|
||||
{
|
||||
endNoteAngle -= 360;
|
||||
}
|
||||
float startAngle = ratio * (endNoteAngle - startNoteAngle) + startNoteAngle;
|
||||
float endAngle = ratio * ((endNoteAngle - info.ArcLength) - (startNoteAngle - nextInfo.ArcLength)) +
|
||||
(startNoteAngle - nextInfo.ArcLength);
|
||||
float arcLength = startAngle - endAngle;
|
||||
|
||||
GraphicsPath path = new GraphicsPath();
|
||||
path.AddArc(endInfo.Rect, startAngle, arcLength);
|
||||
path.AddArc(info.Rect, info.StartAngle + info.ArcLength, -info.ArcLength);
|
||||
bufGraphics.Graphics.FillPath(HoldBrush, path);
|
||||
}
|
||||
|
||||
// Draw note
|
||||
if (info.Rect.Width >= 1)
|
||||
{
|
||||
bufGraphics.Graphics.DrawArc(GetPen(note), info.Rect, info.StartAngle, info.ArcLength);
|
||||
|
||||
// Draw bonus
|
||||
if (note.IsFlair)
|
||||
bufGraphics.Graphics.DrawArc(HighlightPen, info.Rect, info.StartAngle + 2, info.ArcLength - 4);
|
||||
|
||||
// Plot highlighted
|
||||
if (highlightSelectedNote)
|
||||
{
|
||||
if (selectedNoteIndex != -1 && note == chart.Notes[selectedNoteIndex])
|
||||
{
|
||||
bufGraphics.Graphics.DrawArc(HighlightPen, info.Rect, info.StartAngle + 2, info.ArcLength - 4);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void DrawNotes(Chart chart, bool highlightSelectedNote, int selectedNoteIndex)
|
||||
{
|
||||
List<Note> drawNotes = chart.Notes.Where(
|
||||
x => x.Measure >= CurrentMeasure
|
||||
&& x.Measure <= (CurrentMeasure + GetTotalMeasureShowNotes(chart))
|
||||
&& !x.IsHold && !x.IsMask).ToList();
|
||||
foreach (var note in drawNotes)
|
||||
{
|
||||
ArcInfo info = GetArcInfo(chart, note);
|
||||
|
||||
if (info.Rect.Width >= 1)
|
||||
{
|
||||
bufGraphics.Graphics.DrawArc(GetPen(note, info.NoteScale), info.Rect, info.StartAngle, info.ArcLength);
|
||||
if (note.IsFlair)
|
||||
{
|
||||
bufGraphics.Graphics.DrawArc(FlairPen, info.Rect, info.StartAngle + 2, info.ArcLength - 4);
|
||||
}
|
||||
// Plot highlighted
|
||||
if (highlightSelectedNote)
|
||||
{
|
||||
if (selectedNoteIndex != -1 && note == chart.Notes[selectedNoteIndex])
|
||||
{
|
||||
bufGraphics.Graphics.DrawArc(HighlightPen, info.Rect, info.StartAngle + 2, info.ArcLength - 4);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void DrawCursor(NoteType noteType, float startAngle, float sweepAngle)
|
||||
{
|
||||
bufGraphics.Graphics.DrawArc(
|
||||
GetPen(noteType),
|
||||
DrawRect,
|
||||
-(float)startAngle * 6.0f,
|
||||
-(float)sweepAngle * 6.0f);
|
||||
}
|
||||
|
||||
public void Render(Graphics graphics)
|
||||
{
|
||||
bufGraphics.Render(graphics);
|
||||
}
|
||||
|
||||
public void SetBufferedGraphicsContext(int width, int height, Graphics graphics)
|
||||
{
|
||||
gfxContext.MaximumBuffer = new Size(width + 1, height + 1);
|
||||
bufGraphics = gfxContext.Allocate(graphics, new Rectangle(0, 0, width, height));
|
||||
}
|
||||
|
||||
public Pen GetPen(Note note, float noteScale = 1.0f)
|
||||
{
|
||||
return new Pen(note.Color, PanelSize.Width * 8.0f * noteScale / 600.0f);
|
||||
}
|
||||
|
||||
public Pen GetPen(NoteType noteType)
|
||||
{
|
||||
return new Pen(Color.FromArgb(CursorTransparency, Utils.NoteTypeToColor(noteType)), PanelSize.Width * 24.0f / 600.0f);
|
||||
}
|
||||
|
||||
public Pen GetPen(Gimmick gimmick)
|
||||
{
|
||||
return new Pen(Utils.GimmickTypeToColor(gimmick.GimmickType), PanelSize.Width * 1.0f / 600.0f);
|
||||
}
|
||||
}
|
||||
|
||||
internal struct ArcInfo
|
||||
{
|
||||
public float StartAngle;
|
||||
public float ArcLength;
|
||||
public RectangleF Rect;
|
||||
public float NoteScale;
|
||||
}
|
||||
}
|
||||
Binary file not shown.
@@ -0,0 +1,72 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace BAKKA_Editor
|
||||
{
|
||||
internal enum NoteType
|
||||
{
|
||||
TouchNoBonus = 1,
|
||||
TouchBonus = 2,
|
||||
SnapRedNoBonus = 3,
|
||||
SnapBlueNoBonus = 4,
|
||||
SlideOrangeNoBonus = 5,
|
||||
SlideOrangeBonus = 6,
|
||||
SlideGreenNoBonus = 7,
|
||||
SlideGreenBonus = 8,
|
||||
HoldStartNoBonus = 9,
|
||||
HoldJoint = 10,
|
||||
HoldEnd = 11,
|
||||
MaskAdd = 12,
|
||||
MaskRemove = 13,
|
||||
EndOfChart = 14,
|
||||
// MaskSameTime = 15,
|
||||
Chain = 16,
|
||||
// MaskLane = 17,
|
||||
// TutorialTag = 18,
|
||||
// BarLine = 19,
|
||||
TouchBonusFlair = 20,
|
||||
SnapRedBonusFlair = 21,
|
||||
SnapBlueBonusFlair = 22,
|
||||
SlideOrangeBonusFlair = 23,
|
||||
SlideGreenBonusFlair = 24,
|
||||
HoldStartBonusFlair = 25,
|
||||
ChainBonusFlair = 26,
|
||||
}
|
||||
|
||||
internal enum GimmickType
|
||||
{
|
||||
NoGimmick = 1,
|
||||
BpmChange = 2,
|
||||
TimeSignatureChange = 3,
|
||||
// Stop = 4,
|
||||
HiSpeedChange = 5,
|
||||
ReverseStart = 6,
|
||||
ReverseMiddle = 7,
|
||||
ReverseEnd = 8,
|
||||
StopStart = 9,
|
||||
StopEnd = 10,
|
||||
};
|
||||
|
||||
internal enum MaskType
|
||||
{
|
||||
CounterClockwise = 0,
|
||||
Clockwise = 1,
|
||||
Center = 2
|
||||
}
|
||||
|
||||
internal enum BonusType
|
||||
{
|
||||
NoBonus = 0,
|
||||
Bonus = 1,
|
||||
Flair = 2
|
||||
}
|
||||
|
||||
internal enum OperationDirection
|
||||
{
|
||||
Undo,
|
||||
Redo
|
||||
}
|
||||
}
|
||||
Generated
+585
@@ -0,0 +1,585 @@
|
||||
namespace BAKKA_Editor
|
||||
{
|
||||
partial class GimmickForm
|
||||
{
|
||||
/// <summary>
|
||||
/// Required designer variable.
|
||||
/// </summary>
|
||||
private System.ComponentModel.IContainer components = null;
|
||||
|
||||
/// <summary>
|
||||
/// Clean up any resources being used.
|
||||
/// </summary>
|
||||
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
|
||||
protected override void Dispose(bool disposing)
|
||||
{
|
||||
if (disposing && (components != null))
|
||||
{
|
||||
components.Dispose();
|
||||
}
|
||||
base.Dispose(disposing);
|
||||
}
|
||||
|
||||
#region Windows Form Designer generated code
|
||||
|
||||
/// <summary>
|
||||
/// Required method for Designer support - do not modify
|
||||
/// the contents of this method with the code editor.
|
||||
/// </summary>
|
||||
private void InitializeComponent()
|
||||
{
|
||||
this.revEnd2Beat2Numeric = new System.Windows.Forms.NumericUpDown();
|
||||
this.label18 = new System.Windows.Forms.Label();
|
||||
this.revEnd2Beat1Numeric = new System.Windows.Forms.NumericUpDown();
|
||||
this.revEnd2MeasureNumeric = new System.Windows.Forms.NumericUpDown();
|
||||
this.label19 = new System.Windows.Forms.Label();
|
||||
this.revEnd1Beat2Numeric = new System.Windows.Forms.NumericUpDown();
|
||||
this.label16 = new System.Windows.Forms.Label();
|
||||
this.revEnd1Beat1Numeric = new System.Windows.Forms.NumericUpDown();
|
||||
this.revEnd1MeasureNumeric = new System.Windows.Forms.NumericUpDown();
|
||||
this.label17 = new System.Windows.Forms.Label();
|
||||
this.stopEndBeat2Numeric = new System.Windows.Forms.NumericUpDown();
|
||||
this.label10 = new System.Windows.Forms.Label();
|
||||
this.stopEndBeat1Numeric = new System.Windows.Forms.NumericUpDown();
|
||||
this.stopEndMeasureNumeric = new System.Windows.Forms.NumericUpDown();
|
||||
this.label11 = new System.Windows.Forms.Label();
|
||||
this.hiSpeedNumeric = new System.Windows.Forms.NumericUpDown();
|
||||
this.label12 = new System.Windows.Forms.Label();
|
||||
this.label13 = new System.Windows.Forms.Label();
|
||||
this.label14 = new System.Windows.Forms.Label();
|
||||
this.timeSig2Numeric = new System.Windows.Forms.NumericUpDown();
|
||||
this.timeSig1Numeric = new System.Windows.Forms.NumericUpDown();
|
||||
this.gimmickBpmNumeric = new System.Windows.Forms.NumericUpDown();
|
||||
this.label15 = new System.Windows.Forms.Label();
|
||||
this.insertGimmickButton = new System.Windows.Forms.Button();
|
||||
this.startBeat2Numeric = new System.Windows.Forms.NumericUpDown();
|
||||
this.label1 = new System.Windows.Forms.Label();
|
||||
this.startBeat1Numeric = new System.Windows.Forms.NumericUpDown();
|
||||
this.startMeasureNumeric = new System.Windows.Forms.NumericUpDown();
|
||||
this.label2 = new System.Windows.Forms.Label();
|
||||
((System.ComponentModel.ISupportInitialize)(this.revEnd2Beat2Numeric)).BeginInit();
|
||||
((System.ComponentModel.ISupportInitialize)(this.revEnd2Beat1Numeric)).BeginInit();
|
||||
((System.ComponentModel.ISupportInitialize)(this.revEnd2MeasureNumeric)).BeginInit();
|
||||
((System.ComponentModel.ISupportInitialize)(this.revEnd1Beat2Numeric)).BeginInit();
|
||||
((System.ComponentModel.ISupportInitialize)(this.revEnd1Beat1Numeric)).BeginInit();
|
||||
((System.ComponentModel.ISupportInitialize)(this.revEnd1MeasureNumeric)).BeginInit();
|
||||
((System.ComponentModel.ISupportInitialize)(this.stopEndBeat2Numeric)).BeginInit();
|
||||
((System.ComponentModel.ISupportInitialize)(this.stopEndBeat1Numeric)).BeginInit();
|
||||
((System.ComponentModel.ISupportInitialize)(this.stopEndMeasureNumeric)).BeginInit();
|
||||
((System.ComponentModel.ISupportInitialize)(this.hiSpeedNumeric)).BeginInit();
|
||||
((System.ComponentModel.ISupportInitialize)(this.timeSig2Numeric)).BeginInit();
|
||||
((System.ComponentModel.ISupportInitialize)(this.timeSig1Numeric)).BeginInit();
|
||||
((System.ComponentModel.ISupportInitialize)(this.gimmickBpmNumeric)).BeginInit();
|
||||
((System.ComponentModel.ISupportInitialize)(this.startBeat2Numeric)).BeginInit();
|
||||
((System.ComponentModel.ISupportInitialize)(this.startBeat1Numeric)).BeginInit();
|
||||
((System.ComponentModel.ISupportInitialize)(this.startMeasureNumeric)).BeginInit();
|
||||
this.SuspendLayout();
|
||||
//
|
||||
// revEnd2Beat2Numeric
|
||||
//
|
||||
this.revEnd2Beat2Numeric.Location = new System.Drawing.Point(219, 206);
|
||||
this.revEnd2Beat2Numeric.Maximum = new decimal(new int[] {
|
||||
1920,
|
||||
0,
|
||||
0,
|
||||
0});
|
||||
this.revEnd2Beat2Numeric.Minimum = new decimal(new int[] {
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
0});
|
||||
this.revEnd2Beat2Numeric.Name = "revEnd2Beat2Numeric";
|
||||
this.revEnd2Beat2Numeric.Size = new System.Drawing.Size(42, 23);
|
||||
this.revEnd2Beat2Numeric.TabIndex = 38;
|
||||
this.revEnd2Beat2Numeric.Value = new decimal(new int[] {
|
||||
16,
|
||||
0,
|
||||
0,
|
||||
0});
|
||||
//
|
||||
// label18
|
||||
//
|
||||
this.label18.AutoSize = true;
|
||||
this.label18.Location = new System.Drawing.Point(8, 208);
|
||||
this.label18.Name = "label18";
|
||||
this.label18.Size = new System.Drawing.Size(61, 15);
|
||||
this.label18.TabIndex = 40;
|
||||
this.label18.Text = "Rev End 2:";
|
||||
//
|
||||
// revEnd2Beat1Numeric
|
||||
//
|
||||
this.revEnd2Beat1Numeric.Location = new System.Drawing.Point(168, 206);
|
||||
this.revEnd2Beat1Numeric.Maximum = new decimal(new int[] {
|
||||
1920,
|
||||
0,
|
||||
0,
|
||||
0});
|
||||
this.revEnd2Beat1Numeric.Minimum = new decimal(new int[] {
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
-2147483648});
|
||||
this.revEnd2Beat1Numeric.Name = "revEnd2Beat1Numeric";
|
||||
this.revEnd2Beat1Numeric.Size = new System.Drawing.Size(38, 23);
|
||||
this.revEnd2Beat1Numeric.TabIndex = 37;
|
||||
this.revEnd2Beat1Numeric.ValueChanged += new System.EventHandler(this.revEnd2Beat1Numeric_ValueChanged);
|
||||
//
|
||||
// revEnd2MeasureNumeric
|
||||
//
|
||||
this.revEnd2MeasureNumeric.Location = new System.Drawing.Point(75, 206);
|
||||
this.revEnd2MeasureNumeric.Maximum = new decimal(new int[] {
|
||||
9999,
|
||||
0,
|
||||
0,
|
||||
0});
|
||||
this.revEnd2MeasureNumeric.Name = "revEnd2MeasureNumeric";
|
||||
this.revEnd2MeasureNumeric.Size = new System.Drawing.Size(87, 23);
|
||||
this.revEnd2MeasureNumeric.TabIndex = 36;
|
||||
this.revEnd2MeasureNumeric.ValueChanged += new System.EventHandler(this.revEnd2MeasureNumeric_ValueChanged);
|
||||
//
|
||||
// label19
|
||||
//
|
||||
this.label19.AutoSize = true;
|
||||
this.label19.Location = new System.Drawing.Point(207, 208);
|
||||
this.label19.Name = "label19";
|
||||
this.label19.Size = new System.Drawing.Size(12, 15);
|
||||
this.label19.TabIndex = 39;
|
||||
this.label19.Text = "/";
|
||||
//
|
||||
// revEnd1Beat2Numeric
|
||||
//
|
||||
this.revEnd1Beat2Numeric.Location = new System.Drawing.Point(219, 177);
|
||||
this.revEnd1Beat2Numeric.Maximum = new decimal(new int[] {
|
||||
1920,
|
||||
0,
|
||||
0,
|
||||
0});
|
||||
this.revEnd1Beat2Numeric.Minimum = new decimal(new int[] {
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
0});
|
||||
this.revEnd1Beat2Numeric.Name = "revEnd1Beat2Numeric";
|
||||
this.revEnd1Beat2Numeric.Size = new System.Drawing.Size(42, 23);
|
||||
this.revEnd1Beat2Numeric.TabIndex = 33;
|
||||
this.revEnd1Beat2Numeric.Value = new decimal(new int[] {
|
||||
16,
|
||||
0,
|
||||
0,
|
||||
0});
|
||||
//
|
||||
// label16
|
||||
//
|
||||
this.label16.AutoSize = true;
|
||||
this.label16.Location = new System.Drawing.Point(8, 179);
|
||||
this.label16.Name = "label16";
|
||||
this.label16.Size = new System.Drawing.Size(61, 15);
|
||||
this.label16.TabIndex = 35;
|
||||
this.label16.Text = "Rev End 1:";
|
||||
//
|
||||
// revEnd1Beat1Numeric
|
||||
//
|
||||
this.revEnd1Beat1Numeric.Location = new System.Drawing.Point(168, 177);
|
||||
this.revEnd1Beat1Numeric.Maximum = new decimal(new int[] {
|
||||
1920,
|
||||
0,
|
||||
0,
|
||||
0});
|
||||
this.revEnd1Beat1Numeric.Minimum = new decimal(new int[] {
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
-2147483648});
|
||||
this.revEnd1Beat1Numeric.Name = "revEnd1Beat1Numeric";
|
||||
this.revEnd1Beat1Numeric.Size = new System.Drawing.Size(38, 23);
|
||||
this.revEnd1Beat1Numeric.TabIndex = 32;
|
||||
this.revEnd1Beat1Numeric.ValueChanged += new System.EventHandler(this.revEnd1Beat1Numeric_ValueChanged);
|
||||
//
|
||||
// revEnd1MeasureNumeric
|
||||
//
|
||||
this.revEnd1MeasureNumeric.Location = new System.Drawing.Point(75, 177);
|
||||
this.revEnd1MeasureNumeric.Maximum = new decimal(new int[] {
|
||||
9999,
|
||||
0,
|
||||
0,
|
||||
0});
|
||||
this.revEnd1MeasureNumeric.Name = "revEnd1MeasureNumeric";
|
||||
this.revEnd1MeasureNumeric.Size = new System.Drawing.Size(87, 23);
|
||||
this.revEnd1MeasureNumeric.TabIndex = 31;
|
||||
this.revEnd1MeasureNumeric.ValueChanged += new System.EventHandler(this.revEnd1MeasureNumeric_ValueChanged);
|
||||
//
|
||||
// label17
|
||||
//
|
||||
this.label17.AutoSize = true;
|
||||
this.label17.Location = new System.Drawing.Point(207, 179);
|
||||
this.label17.Name = "label17";
|
||||
this.label17.Size = new System.Drawing.Size(12, 15);
|
||||
this.label17.TabIndex = 34;
|
||||
this.label17.Text = "/";
|
||||
//
|
||||
// stopEndBeat2Numeric
|
||||
//
|
||||
this.stopEndBeat2Numeric.Location = new System.Drawing.Point(219, 148);
|
||||
this.stopEndBeat2Numeric.Maximum = new decimal(new int[] {
|
||||
1920,
|
||||
0,
|
||||
0,
|
||||
0});
|
||||
this.stopEndBeat2Numeric.Minimum = new decimal(new int[] {
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
0});
|
||||
this.stopEndBeat2Numeric.Name = "stopEndBeat2Numeric";
|
||||
this.stopEndBeat2Numeric.Size = new System.Drawing.Size(42, 23);
|
||||
this.stopEndBeat2Numeric.TabIndex = 13;
|
||||
this.stopEndBeat2Numeric.Value = new decimal(new int[] {
|
||||
16,
|
||||
0,
|
||||
0,
|
||||
0});
|
||||
//
|
||||
// label10
|
||||
//
|
||||
this.label10.AutoSize = true;
|
||||
this.label10.Location = new System.Drawing.Point(12, 150);
|
||||
this.label10.Name = "label10";
|
||||
this.label10.Size = new System.Drawing.Size(57, 15);
|
||||
this.label10.TabIndex = 29;
|
||||
this.label10.Text = "Stop End:";
|
||||
//
|
||||
// stopEndBeat1Numeric
|
||||
//
|
||||
this.stopEndBeat1Numeric.Location = new System.Drawing.Point(168, 148);
|
||||
this.stopEndBeat1Numeric.Maximum = new decimal(new int[] {
|
||||
1920,
|
||||
0,
|
||||
0,
|
||||
0});
|
||||
this.stopEndBeat1Numeric.Minimum = new decimal(new int[] {
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
-2147483648});
|
||||
this.stopEndBeat1Numeric.Name = "stopEndBeat1Numeric";
|
||||
this.stopEndBeat1Numeric.Size = new System.Drawing.Size(38, 23);
|
||||
this.stopEndBeat1Numeric.TabIndex = 12;
|
||||
this.stopEndBeat1Numeric.ValueChanged += new System.EventHandler(this.stopEndBeat1Numeric_ValueChanged);
|
||||
//
|
||||
// stopEndMeasureNumeric
|
||||
//
|
||||
this.stopEndMeasureNumeric.Location = new System.Drawing.Point(75, 148);
|
||||
this.stopEndMeasureNumeric.Maximum = new decimal(new int[] {
|
||||
9999,
|
||||
0,
|
||||
0,
|
||||
0});
|
||||
this.stopEndMeasureNumeric.Name = "stopEndMeasureNumeric";
|
||||
this.stopEndMeasureNumeric.Size = new System.Drawing.Size(87, 23);
|
||||
this.stopEndMeasureNumeric.TabIndex = 11;
|
||||
this.stopEndMeasureNumeric.ValueChanged += new System.EventHandler(this.stopEndMeasureNumeric_ValueChanged);
|
||||
//
|
||||
// label11
|
||||
//
|
||||
this.label11.AutoSize = true;
|
||||
this.label11.Location = new System.Drawing.Point(10, 121);
|
||||
this.label11.Name = "label11";
|
||||
this.label11.Size = new System.Drawing.Size(59, 15);
|
||||
this.label11.TabIndex = 27;
|
||||
this.label11.Text = "Hi-Speed:";
|
||||
//
|
||||
// hiSpeedNumeric
|
||||
//
|
||||
this.hiSpeedNumeric.DecimalPlaces = 6;
|
||||
this.hiSpeedNumeric.Location = new System.Drawing.Point(75, 119);
|
||||
this.hiSpeedNumeric.Minimum = new decimal(new int[] {
|
||||
100,
|
||||
0,
|
||||
0,
|
||||
-2147483648});
|
||||
this.hiSpeedNumeric.Name = "hiSpeedNumeric";
|
||||
this.hiSpeedNumeric.Size = new System.Drawing.Size(186, 23);
|
||||
this.hiSpeedNumeric.TabIndex = 26;
|
||||
this.hiSpeedNumeric.Value = new decimal(new int[] {
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
0});
|
||||
//
|
||||
// label12
|
||||
//
|
||||
this.label12.AutoSize = true;
|
||||
this.label12.Location = new System.Drawing.Point(14, 92);
|
||||
this.label12.Name = "label12";
|
||||
this.label12.Size = new System.Drawing.Size(55, 15);
|
||||
this.label12.TabIndex = 25;
|
||||
this.label12.Text = "Time Sig:";
|
||||
//
|
||||
// label13
|
||||
//
|
||||
this.label13.AutoSize = true;
|
||||
this.label13.Location = new System.Drawing.Point(140, 92);
|
||||
this.label13.Name = "label13";
|
||||
this.label13.Size = new System.Drawing.Size(12, 15);
|
||||
this.label13.TabIndex = 13;
|
||||
this.label13.Text = "/";
|
||||
//
|
||||
// label14
|
||||
//
|
||||
this.label14.AutoSize = true;
|
||||
this.label14.Location = new System.Drawing.Point(34, 63);
|
||||
this.label14.Name = "label14";
|
||||
this.label14.Size = new System.Drawing.Size(35, 15);
|
||||
this.label14.TabIndex = 24;
|
||||
this.label14.Text = "BPM:";
|
||||
//
|
||||
// timeSig2Numeric
|
||||
//
|
||||
this.timeSig2Numeric.Location = new System.Drawing.Point(158, 90);
|
||||
this.timeSig2Numeric.Maximum = new decimal(new int[] {
|
||||
1920,
|
||||
0,
|
||||
0,
|
||||
0});
|
||||
this.timeSig2Numeric.Minimum = new decimal(new int[] {
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
0});
|
||||
this.timeSig2Numeric.Name = "timeSig2Numeric";
|
||||
this.timeSig2Numeric.Size = new System.Drawing.Size(103, 23);
|
||||
this.timeSig2Numeric.TabIndex = 12;
|
||||
this.timeSig2Numeric.Value = new decimal(new int[] {
|
||||
4,
|
||||
0,
|
||||
0,
|
||||
0});
|
||||
//
|
||||
// timeSig1Numeric
|
||||
//
|
||||
this.timeSig1Numeric.Location = new System.Drawing.Point(75, 90);
|
||||
this.timeSig1Numeric.Maximum = new decimal(new int[] {
|
||||
191,
|
||||
0,
|
||||
0,
|
||||
0});
|
||||
this.timeSig1Numeric.Minimum = new decimal(new int[] {
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
0});
|
||||
this.timeSig1Numeric.Name = "timeSig1Numeric";
|
||||
this.timeSig1Numeric.Size = new System.Drawing.Size(59, 23);
|
||||
this.timeSig1Numeric.TabIndex = 11;
|
||||
this.timeSig1Numeric.Value = new decimal(new int[] {
|
||||
4,
|
||||
0,
|
||||
0,
|
||||
0});
|
||||
//
|
||||
// gimmickBpmNumeric
|
||||
//
|
||||
this.gimmickBpmNumeric.DecimalPlaces = 6;
|
||||
this.gimmickBpmNumeric.Location = new System.Drawing.Point(75, 61);
|
||||
this.gimmickBpmNumeric.Maximum = new decimal(new int[] {
|
||||
9999,
|
||||
0,
|
||||
0,
|
||||
0});
|
||||
this.gimmickBpmNumeric.Minimum = new decimal(new int[] {
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
0});
|
||||
this.gimmickBpmNumeric.Name = "gimmickBpmNumeric";
|
||||
this.gimmickBpmNumeric.Size = new System.Drawing.Size(186, 23);
|
||||
this.gimmickBpmNumeric.TabIndex = 23;
|
||||
this.gimmickBpmNumeric.Value = new decimal(new int[] {
|
||||
120,
|
||||
0,
|
||||
0,
|
||||
0});
|
||||
//
|
||||
// label15
|
||||
//
|
||||
this.label15.AutoSize = true;
|
||||
this.label15.Location = new System.Drawing.Point(207, 150);
|
||||
this.label15.Name = "label15";
|
||||
this.label15.Size = new System.Drawing.Size(12, 15);
|
||||
this.label15.TabIndex = 14;
|
||||
this.label15.Text = "/";
|
||||
//
|
||||
// insertGimmickButton
|
||||
//
|
||||
this.insertGimmickButton.Font = new System.Drawing.Font("Segoe UI", 11F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point);
|
||||
this.insertGimmickButton.Location = new System.Drawing.Point(12, 248);
|
||||
this.insertGimmickButton.Name = "insertGimmickButton";
|
||||
this.insertGimmickButton.Size = new System.Drawing.Size(253, 40);
|
||||
this.insertGimmickButton.TabIndex = 33;
|
||||
this.insertGimmickButton.Text = "Insert Gimmick";
|
||||
this.insertGimmickButton.UseVisualStyleBackColor = true;
|
||||
this.insertGimmickButton.Click += new System.EventHandler(this.insertGimmickButton_Click);
|
||||
//
|
||||
// startBeat2Numeric
|
||||
//
|
||||
this.startBeat2Numeric.Location = new System.Drawing.Point(219, 12);
|
||||
this.startBeat2Numeric.Maximum = new decimal(new int[] {
|
||||
1920,
|
||||
0,
|
||||
0,
|
||||
0});
|
||||
this.startBeat2Numeric.Minimum = new decimal(new int[] {
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
0});
|
||||
this.startBeat2Numeric.Name = "startBeat2Numeric";
|
||||
this.startBeat2Numeric.Size = new System.Drawing.Size(42, 23);
|
||||
this.startBeat2Numeric.TabIndex = 43;
|
||||
this.startBeat2Numeric.Value = new decimal(new int[] {
|
||||
16,
|
||||
0,
|
||||
0,
|
||||
0});
|
||||
//
|
||||
// label1
|
||||
//
|
||||
this.label1.AutoSize = true;
|
||||
this.label1.Location = new System.Drawing.Point(34, 14);
|
||||
this.label1.Name = "label1";
|
||||
this.label1.Size = new System.Drawing.Size(34, 15);
|
||||
this.label1.TabIndex = 45;
|
||||
this.label1.Text = "Start:";
|
||||
//
|
||||
// startBeat1Numeric
|
||||
//
|
||||
this.startBeat1Numeric.Location = new System.Drawing.Point(168, 12);
|
||||
this.startBeat1Numeric.Maximum = new decimal(new int[] {
|
||||
1920,
|
||||
0,
|
||||
0,
|
||||
0});
|
||||
this.startBeat1Numeric.Minimum = new decimal(new int[] {
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
-2147483648});
|
||||
this.startBeat1Numeric.Name = "startBeat1Numeric";
|
||||
this.startBeat1Numeric.Size = new System.Drawing.Size(38, 23);
|
||||
this.startBeat1Numeric.TabIndex = 42;
|
||||
this.startBeat1Numeric.ValueChanged += new System.EventHandler(this.startBeat1Numeric_ValueChanged);
|
||||
//
|
||||
// startMeasureNumeric
|
||||
//
|
||||
this.startMeasureNumeric.Location = new System.Drawing.Point(75, 12);
|
||||
this.startMeasureNumeric.Maximum = new decimal(new int[] {
|
||||
9999,
|
||||
0,
|
||||
0,
|
||||
0});
|
||||
this.startMeasureNumeric.Name = "startMeasureNumeric";
|
||||
this.startMeasureNumeric.Size = new System.Drawing.Size(87, 23);
|
||||
this.startMeasureNumeric.TabIndex = 41;
|
||||
this.startMeasureNumeric.ValueChanged += new System.EventHandler(this.startMeasureNumeric_ValueChanged);
|
||||
//
|
||||
// label2
|
||||
//
|
||||
this.label2.AutoSize = true;
|
||||
this.label2.Location = new System.Drawing.Point(207, 14);
|
||||
this.label2.Name = "label2";
|
||||
this.label2.Size = new System.Drawing.Size(12, 15);
|
||||
this.label2.TabIndex = 44;
|
||||
this.label2.Text = "/";
|
||||
//
|
||||
// GimmickForm
|
||||
//
|
||||
this.AutoScaleDimensions = new System.Drawing.SizeF(7F, 15F);
|
||||
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
|
||||
this.ClientSize = new System.Drawing.Size(281, 303);
|
||||
this.Controls.Add(this.startBeat2Numeric);
|
||||
this.Controls.Add(this.label1);
|
||||
this.Controls.Add(this.startBeat1Numeric);
|
||||
this.Controls.Add(this.startMeasureNumeric);
|
||||
this.Controls.Add(this.label2);
|
||||
this.Controls.Add(this.revEnd2Beat2Numeric);
|
||||
this.Controls.Add(this.insertGimmickButton);
|
||||
this.Controls.Add(this.label18);
|
||||
this.Controls.Add(this.revEnd2Beat1Numeric);
|
||||
this.Controls.Add(this.gimmickBpmNumeric);
|
||||
this.Controls.Add(this.revEnd2MeasureNumeric);
|
||||
this.Controls.Add(this.label15);
|
||||
this.Controls.Add(this.label19);
|
||||
this.Controls.Add(this.timeSig1Numeric);
|
||||
this.Controls.Add(this.revEnd1Beat2Numeric);
|
||||
this.Controls.Add(this.timeSig2Numeric);
|
||||
this.Controls.Add(this.label16);
|
||||
this.Controls.Add(this.label14);
|
||||
this.Controls.Add(this.revEnd1Beat1Numeric);
|
||||
this.Controls.Add(this.label13);
|
||||
this.Controls.Add(this.revEnd1MeasureNumeric);
|
||||
this.Controls.Add(this.label12);
|
||||
this.Controls.Add(this.label17);
|
||||
this.Controls.Add(this.hiSpeedNumeric);
|
||||
this.Controls.Add(this.stopEndBeat2Numeric);
|
||||
this.Controls.Add(this.label11);
|
||||
this.Controls.Add(this.label10);
|
||||
this.Controls.Add(this.stopEndMeasureNumeric);
|
||||
this.Controls.Add(this.stopEndBeat1Numeric);
|
||||
this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedToolWindow;
|
||||
this.Name = "GimmickForm";
|
||||
this.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent;
|
||||
this.Text = "Gimmick Settings";
|
||||
this.FormClosing += new System.Windows.Forms.FormClosingEventHandler(this.GimmickForm_FormClosing);
|
||||
((System.ComponentModel.ISupportInitialize)(this.revEnd2Beat2Numeric)).EndInit();
|
||||
((System.ComponentModel.ISupportInitialize)(this.revEnd2Beat1Numeric)).EndInit();
|
||||
((System.ComponentModel.ISupportInitialize)(this.revEnd2MeasureNumeric)).EndInit();
|
||||
((System.ComponentModel.ISupportInitialize)(this.revEnd1Beat2Numeric)).EndInit();
|
||||
((System.ComponentModel.ISupportInitialize)(this.revEnd1Beat1Numeric)).EndInit();
|
||||
((System.ComponentModel.ISupportInitialize)(this.revEnd1MeasureNumeric)).EndInit();
|
||||
((System.ComponentModel.ISupportInitialize)(this.stopEndBeat2Numeric)).EndInit();
|
||||
((System.ComponentModel.ISupportInitialize)(this.stopEndBeat1Numeric)).EndInit();
|
||||
((System.ComponentModel.ISupportInitialize)(this.stopEndMeasureNumeric)).EndInit();
|
||||
((System.ComponentModel.ISupportInitialize)(this.hiSpeedNumeric)).EndInit();
|
||||
((System.ComponentModel.ISupportInitialize)(this.timeSig2Numeric)).EndInit();
|
||||
((System.ComponentModel.ISupportInitialize)(this.timeSig1Numeric)).EndInit();
|
||||
((System.ComponentModel.ISupportInitialize)(this.gimmickBpmNumeric)).EndInit();
|
||||
((System.ComponentModel.ISupportInitialize)(this.startBeat2Numeric)).EndInit();
|
||||
((System.ComponentModel.ISupportInitialize)(this.startBeat1Numeric)).EndInit();
|
||||
((System.ComponentModel.ISupportInitialize)(this.startMeasureNumeric)).EndInit();
|
||||
this.ResumeLayout(false);
|
||||
this.PerformLayout();
|
||||
|
||||
}
|
||||
|
||||
#endregion
|
||||
private NumericUpDown revEnd2Beat2Numeric;
|
||||
private Label label18;
|
||||
private NumericUpDown revEnd2Beat1Numeric;
|
||||
private NumericUpDown revEnd2MeasureNumeric;
|
||||
private Label label19;
|
||||
private NumericUpDown revEnd1Beat2Numeric;
|
||||
private Label label16;
|
||||
private NumericUpDown revEnd1Beat1Numeric;
|
||||
private NumericUpDown revEnd1MeasureNumeric;
|
||||
private Label label17;
|
||||
private NumericUpDown stopEndBeat2Numeric;
|
||||
private Label label10;
|
||||
private NumericUpDown stopEndBeat1Numeric;
|
||||
private NumericUpDown stopEndMeasureNumeric;
|
||||
private Label label11;
|
||||
private NumericUpDown hiSpeedNumeric;
|
||||
private Label label12;
|
||||
private Label label13;
|
||||
private Label label14;
|
||||
private NumericUpDown timeSig2Numeric;
|
||||
private NumericUpDown timeSig1Numeric;
|
||||
private NumericUpDown gimmickBpmNumeric;
|
||||
private Label label15;
|
||||
private Button insertGimmickButton;
|
||||
private NumericUpDown startBeat2Numeric;
|
||||
private Label label1;
|
||||
private NumericUpDown startBeat1Numeric;
|
||||
private NumericUpDown startMeasureNumeric;
|
||||
private Label label2;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,394 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
using System.Data;
|
||||
using System.Drawing;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows.Forms;
|
||||
|
||||
namespace BAKKA_Editor
|
||||
{
|
||||
public partial class GimmickForm : Form
|
||||
{
|
||||
private Gimmick gimmick;
|
||||
public bool InsertGimmick { get; private set; }
|
||||
internal List<Gimmick> Gimmicks { get; private set; }
|
||||
|
||||
float StartMeasure { get { return (float)startMeasureNumeric.Value + (float)startBeat1Numeric.Value / (float)startBeat2Numeric.Value; } }
|
||||
float StopEndMeasure { get { return (float)stopEndMeasureNumeric.Value + (float)stopEndBeat1Numeric.Value / (float)stopEndBeat2Numeric.Value; } }
|
||||
float RevEnd1Measure { get { return (float)revEnd1MeasureNumeric.Value + (float)revEnd1Beat1Numeric.Value / (float)revEnd1Beat2Numeric.Value; } }
|
||||
float RevEnd2Measure { get { return (float)revEnd2MeasureNumeric.Value + (float)revEnd2Beat1Numeric.Value / (float)revEnd2Beat2Numeric.Value; } }
|
||||
|
||||
|
||||
public enum FormReason
|
||||
{
|
||||
New,
|
||||
Edit
|
||||
};
|
||||
|
||||
public GimmickForm()
|
||||
{
|
||||
InitializeComponent();
|
||||
}
|
||||
|
||||
internal DialogResult Show(
|
||||
Gimmick baseGimmick, FormReason reason, Gimmick? gim1 = null, Gimmick? gim2 = null)
|
||||
{
|
||||
var quant = Utils.GetQuantization(baseGimmick.BeatInfo.Beat, 12);
|
||||
|
||||
gimmick = new Gimmick();
|
||||
gimmick.BeatInfo = new BeatInfo(baseGimmick.BeatInfo);
|
||||
gimmick.GimmickType = baseGimmick.GimmickType;
|
||||
|
||||
switch (gimmick.GimmickType)
|
||||
{
|
||||
case GimmickType.BpmChange:
|
||||
startMeasureNumeric.Value = gimmick.BeatInfo.Measure;
|
||||
startBeat2Numeric.Value = quant.Item2;
|
||||
startBeat1Numeric.Value = quant.Item1;
|
||||
if (reason == FormReason.Edit)
|
||||
gimmickBpmNumeric.Value = (decimal)baseGimmick.BPM;
|
||||
break;
|
||||
case GimmickType.TimeSignatureChange:
|
||||
startMeasureNumeric.Value = gimmick.BeatInfo.Measure;
|
||||
startBeat2Numeric.Value = quant.Item2;
|
||||
startBeat1Numeric.Value = quant.Item1;
|
||||
if (reason == FormReason.Edit)
|
||||
{
|
||||
timeSig1Numeric.Value = baseGimmick.TimeSig.Upper;
|
||||
timeSig2Numeric.Value = baseGimmick.TimeSig.Lower;
|
||||
}
|
||||
break;
|
||||
case GimmickType.HiSpeedChange:
|
||||
startMeasureNumeric.Value = gimmick.BeatInfo.Measure;
|
||||
startBeat2Numeric.Value = quant.Item2;
|
||||
startBeat1Numeric.Value = quant.Item1;
|
||||
if (reason == FormReason.Edit)
|
||||
hiSpeedNumeric.Value = (decimal)baseGimmick.HiSpeed;
|
||||
break;
|
||||
case GimmickType.ReverseStart:
|
||||
startMeasureNumeric.Value = gimmick.BeatInfo.Measure;
|
||||
startBeat2Numeric.Value = quant.Item2;
|
||||
startBeat1Numeric.Value = quant.Item1;
|
||||
if (reason == FormReason.Edit && gim1 != null && gim2 != null)
|
||||
{
|
||||
var quantMid1 = Utils.GetQuantization(gim1.BeatInfo.Beat, 12);
|
||||
var quantEnd1 = Utils.GetQuantization(gim2.BeatInfo.Beat, 12);
|
||||
revEnd1MeasureNumeric.Value = gim1.BeatInfo.Measure;
|
||||
revEnd1Beat2Numeric.Value = quantMid1.Item2;
|
||||
revEnd1Beat1Numeric.Value = quantMid1.Item1;
|
||||
revEnd2MeasureNumeric.Value = gim2.BeatInfo.Measure;
|
||||
revEnd2Beat2Numeric.Value = quantEnd1.Item2;
|
||||
revEnd2Beat1Numeric.Value = quantEnd1.Item1;
|
||||
}
|
||||
break;
|
||||
case GimmickType.ReverseMiddle:
|
||||
var quantStart2 = Utils.GetQuantization(gim1.BeatInfo.Beat, 12);
|
||||
var quantEnd2 = Utils.GetQuantization(gim2.BeatInfo.Beat, 12);
|
||||
startMeasureNumeric.Value = gim1.BeatInfo.Measure;
|
||||
startBeat2Numeric.Value = quantStart2.Item2;
|
||||
startBeat1Numeric.Value = quantStart2.Item1;
|
||||
revEnd1MeasureNumeric.Value = gimmick.BeatInfo.Measure;
|
||||
revEnd1Beat2Numeric.Value = quant.Item2;
|
||||
revEnd1Beat1Numeric.Value = quant.Item1;
|
||||
revEnd2MeasureNumeric.Value = gim2.BeatInfo.Measure;
|
||||
revEnd2Beat2Numeric.Value = quantEnd2.Item2;
|
||||
revEnd2Beat1Numeric.Value = quantEnd2.Item1;
|
||||
break;
|
||||
case GimmickType.ReverseEnd:
|
||||
var quantStart3 = Utils.GetQuantization(gim1.BeatInfo.Beat, 12);
|
||||
var quantMid3 = Utils.GetQuantization(gim2.BeatInfo.Beat, 12);
|
||||
startMeasureNumeric.Value = gim1.BeatInfo.Measure;
|
||||
startBeat2Numeric.Value = quantStart3.Item2;
|
||||
startBeat1Numeric.Value = quantStart3.Item1;
|
||||
revEnd1MeasureNumeric.Value = gim2.BeatInfo.Measure;
|
||||
revEnd1Beat2Numeric.Value = quantMid3.Item2;
|
||||
revEnd1Beat1Numeric.Value = quantMid3.Item1;
|
||||
revEnd2MeasureNumeric.Value = gimmick.BeatInfo.Measure;
|
||||
revEnd2Beat2Numeric.Value = quant.Item2;
|
||||
revEnd2Beat1Numeric.Value = quant.Item1;
|
||||
break;
|
||||
case GimmickType.StopStart:
|
||||
startMeasureNumeric.Value = gimmick.BeatInfo.Measure;
|
||||
startBeat2Numeric.Value = quant.Item2;
|
||||
startBeat1Numeric.Value = quant.Item1;
|
||||
if (reason == FormReason.Edit)
|
||||
{
|
||||
var stopEnd = Utils.GetQuantization(gim1.BeatInfo.Beat, 12);
|
||||
stopEndMeasureNumeric.Value = gim1.BeatInfo.Measure;
|
||||
stopEndBeat2Numeric.Value = stopEnd.Item2;
|
||||
stopEndBeat1Numeric.Value = stopEnd.Item1;
|
||||
}
|
||||
break;
|
||||
case GimmickType.StopEnd:
|
||||
var stopStart = Utils.GetQuantization(gim1.BeatInfo.Beat, 12);
|
||||
startMeasureNumeric.Value = gim1.BeatInfo.Measure;
|
||||
startBeat2Numeric.Value = stopStart.Item2;
|
||||
startBeat1Numeric.Value = stopStart.Item1;
|
||||
stopEndMeasureNumeric.Value = gimmick.BeatInfo.Measure;
|
||||
stopEndBeat2Numeric.Value = quant.Item2;
|
||||
stopEndBeat1Numeric.Value = quant.Item1;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
gimmickBpmNumeric.Enabled = gimmick.GimmickType == GimmickType.BpmChange;
|
||||
|
||||
timeSig1Numeric.Enabled = gimmick.GimmickType == GimmickType.TimeSignatureChange;
|
||||
timeSig2Numeric.Enabled = gimmick.GimmickType == GimmickType.TimeSignatureChange;
|
||||
|
||||
hiSpeedNumeric.Enabled = gimmick.GimmickType == GimmickType.HiSpeedChange;
|
||||
|
||||
stopEndMeasureNumeric.Enabled = gimmick.IsStop;
|
||||
stopEndBeat1Numeric.Enabled = gimmick.IsStop;
|
||||
stopEndBeat2Numeric.Enabled = gimmick.IsStop;
|
||||
|
||||
revEnd1MeasureNumeric.Enabled = gimmick.IsReverse;
|
||||
revEnd1Beat1Numeric.Enabled = gimmick.IsReverse;
|
||||
revEnd1Beat2Numeric.Enabled = gimmick.IsReverse;
|
||||
revEnd2MeasureNumeric.Enabled = gimmick.IsReverse;
|
||||
revEnd2Beat1Numeric.Enabled = gimmick.IsReverse;
|
||||
revEnd2Beat2Numeric.Enabled = gimmick.IsReverse;
|
||||
|
||||
Gimmicks = new List<Gimmick>();
|
||||
|
||||
InsertGimmick = false;
|
||||
|
||||
switch (reason)
|
||||
{
|
||||
case FormReason.New:
|
||||
insertGimmickButton.Text = "Insert Gimmick";
|
||||
break;
|
||||
case FormReason.Edit:
|
||||
insertGimmickButton.Text = "Edit Gimmick";
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return ShowDialog();
|
||||
}
|
||||
|
||||
private void GimmickForm_FormClosing(object sender, FormClosingEventArgs e)
|
||||
{
|
||||
}
|
||||
|
||||
private void insertGimmickButton_Click(object sender, EventArgs e)
|
||||
{
|
||||
switch (gimmick.GimmickType)
|
||||
{
|
||||
case GimmickType.BpmChange:
|
||||
gimmick.BeatInfo = new BeatInfo((int)startMeasureNumeric.Value, (int)startBeat1Numeric.Value * 1920 / (int)startBeat2Numeric.Value);
|
||||
gimmick.BPM = (double)gimmickBpmNumeric.Value;
|
||||
Gimmicks.Add(gimmick);
|
||||
break;
|
||||
case GimmickType.TimeSignatureChange:
|
||||
gimmick.BeatInfo = new BeatInfo((int)startMeasureNumeric.Value, (int)startBeat1Numeric.Value * 1920 / (int)startBeat2Numeric.Value);
|
||||
gimmick.TimeSig.Upper = (int)timeSig1Numeric.Value;
|
||||
gimmick.TimeSig.Lower = (int)timeSig2Numeric.Value;
|
||||
Gimmicks.Add(gimmick);
|
||||
break;
|
||||
case GimmickType.HiSpeedChange:
|
||||
gimmick.BeatInfo = new BeatInfo((int)startMeasureNumeric.Value, (int)startBeat1Numeric.Value * 1920 / (int)startBeat2Numeric.Value);
|
||||
gimmick.HiSpeed = (double)hiSpeedNumeric.Value;
|
||||
Gimmicks.Add(gimmick);
|
||||
break;
|
||||
case GimmickType.ReverseStart:
|
||||
case GimmickType.ReverseMiddle:
|
||||
case GimmickType.ReverseEnd:
|
||||
Gimmicks.Add(new Gimmick()
|
||||
{
|
||||
BeatInfo = new BeatInfo((int)startMeasureNumeric.Value, (int)startBeat1Numeric.Value * 1920 / (int)startBeat2Numeric.Value),
|
||||
GimmickType = GimmickType.ReverseStart
|
||||
});
|
||||
Gimmicks.Add(new Gimmick()
|
||||
{
|
||||
BeatInfo = new BeatInfo((int)revEnd1MeasureNumeric.Value, (int)revEnd1Beat1Numeric.Value * 1920 / (int)revEnd1Beat2Numeric.Value),
|
||||
GimmickType = GimmickType.ReverseMiddle
|
||||
});
|
||||
Gimmicks.Add(new Gimmick()
|
||||
{
|
||||
BeatInfo = new BeatInfo((int)revEnd2MeasureNumeric.Value, (int)revEnd2Beat1Numeric.Value * 1920 / (int)revEnd2Beat2Numeric.Value),
|
||||
GimmickType = GimmickType.ReverseEnd
|
||||
});
|
||||
break;
|
||||
case GimmickType.StopStart:
|
||||
case GimmickType.StopEnd:
|
||||
Gimmicks.Add(new Gimmick()
|
||||
{
|
||||
BeatInfo = new BeatInfo((int)startMeasureNumeric.Value, (int)startBeat1Numeric.Value * 1920 / (int)startBeat2Numeric.Value),
|
||||
GimmickType = GimmickType.StopStart
|
||||
});
|
||||
Gimmicks.Add(new Gimmick()
|
||||
{
|
||||
BeatInfo = new BeatInfo((int)stopEndMeasureNumeric.Value, (int)stopEndBeat1Numeric.Value * 1920 / (int)stopEndBeat2Numeric.Value),
|
||||
GimmickType = GimmickType.StopEnd
|
||||
});
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
DialogResult = DialogResult.OK;
|
||||
}
|
||||
|
||||
private void startMeasureNumeric_ValueChanged(object sender, EventArgs e)
|
||||
{
|
||||
if (stopEndMeasureNumeric.Enabled && StopEndMeasure < StartMeasure)
|
||||
{
|
||||
stopEndMeasureNumeric.Value = startMeasureNumeric.Value + 1;
|
||||
}
|
||||
if (revEnd1MeasureNumeric.Enabled && RevEnd1Measure < StartMeasure)
|
||||
{
|
||||
revEnd1MeasureNumeric.Value = startMeasureNumeric.Value + 1;
|
||||
}
|
||||
}
|
||||
|
||||
private void startBeat1Numeric_ValueChanged(object sender, EventArgs e)
|
||||
{
|
||||
if (startBeat1Numeric.Value >= startBeat2Numeric.Value)
|
||||
{
|
||||
startMeasureNumeric.Value++;
|
||||
startBeat1Numeric.Value = 0;
|
||||
}
|
||||
else if (startBeat1Numeric.Value < 0)
|
||||
{
|
||||
if (startMeasureNumeric.Value > 0)
|
||||
{
|
||||
startMeasureNumeric.Value--;
|
||||
startBeat1Numeric.Value = startBeat2Numeric.Value - 1;
|
||||
}
|
||||
else if (startMeasureNumeric.Value == 0)
|
||||
{
|
||||
startBeat1Numeric.Value = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void stopEndMeasureNumeric_ValueChanged(object sender, EventArgs e)
|
||||
{
|
||||
if (StopEndMeasure < StartMeasure)
|
||||
{
|
||||
stopEndMeasureNumeric.Value = startMeasureNumeric.Value;
|
||||
stopEndBeat1Numeric.Value = startBeat1Numeric.Value;
|
||||
stopEndBeat2Numeric.Value = startBeat2Numeric.Value;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
private void stopEndBeat1Numeric_ValueChanged(object sender, EventArgs e)
|
||||
{
|
||||
if (StopEndMeasure < StartMeasure)
|
||||
{
|
||||
stopEndMeasureNumeric.Value = startMeasureNumeric.Value;
|
||||
stopEndBeat1Numeric.Value = startBeat1Numeric.Value;
|
||||
stopEndBeat2Numeric.Value = startBeat2Numeric.Value;
|
||||
return;
|
||||
}
|
||||
|
||||
if (stopEndBeat1Numeric.Value >= stopEndBeat2Numeric.Value)
|
||||
{
|
||||
stopEndMeasureNumeric.Value++;
|
||||
stopEndBeat1Numeric.Value = 0;
|
||||
}
|
||||
else if (stopEndBeat1Numeric.Value < 0)
|
||||
{
|
||||
if (stopEndMeasureNumeric.Value > 0)
|
||||
{
|
||||
stopEndMeasureNumeric.Value--;
|
||||
stopEndBeat1Numeric.Value = stopEndBeat2Numeric.Value - 1;
|
||||
}
|
||||
else if (stopEndMeasureNumeric.Value == 0)
|
||||
{
|
||||
stopEndBeat1Numeric.Value = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void revEnd1MeasureNumeric_ValueChanged(object sender, EventArgs e)
|
||||
{
|
||||
if (RevEnd1Measure < StartMeasure)
|
||||
{
|
||||
revEnd1MeasureNumeric.Value = startMeasureNumeric.Value;
|
||||
revEnd1Beat1Numeric.Value = startBeat1Numeric.Value;
|
||||
revEnd1Beat2Numeric.Value = startBeat2Numeric.Value;
|
||||
}
|
||||
if (RevEnd2Measure < RevEnd1Measure)
|
||||
{
|
||||
revEnd2MeasureNumeric.Value = revEnd1MeasureNumeric.Value;
|
||||
revEnd2Beat1Numeric.Value = revEnd1Beat1Numeric.Value;
|
||||
revEnd2Beat2Numeric.Value = revEnd1Beat2Numeric.Value;
|
||||
}
|
||||
}
|
||||
|
||||
private void revEnd1Beat1Numeric_ValueChanged(object sender, EventArgs e)
|
||||
{
|
||||
if (RevEnd1Measure < StartMeasure)
|
||||
{
|
||||
revEnd1MeasureNumeric.Value = startMeasureNumeric.Value;
|
||||
revEnd1Beat1Numeric.Value = startBeat1Numeric.Value;
|
||||
revEnd1Beat2Numeric.Value = startBeat2Numeric.Value;
|
||||
return;
|
||||
}
|
||||
|
||||
if (revEnd1Beat1Numeric.Value >= revEnd1Beat2Numeric.Value)
|
||||
{
|
||||
revEnd1MeasureNumeric.Value++;
|
||||
revEnd1Beat1Numeric.Value = 0;
|
||||
}
|
||||
else if (revEnd1Beat1Numeric.Value < 0)
|
||||
{
|
||||
if (revEnd1MeasureNumeric.Value > 0)
|
||||
{
|
||||
revEnd1MeasureNumeric.Value--;
|
||||
revEnd1Beat1Numeric.Value = revEnd1Beat2Numeric.Value - 1;
|
||||
}
|
||||
else if (revEnd1MeasureNumeric.Value == 0)
|
||||
{
|
||||
revEnd1Beat1Numeric.Value = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void revEnd2MeasureNumeric_ValueChanged(object sender, EventArgs e)
|
||||
{
|
||||
if (RevEnd2Measure < RevEnd1Measure)
|
||||
{
|
||||
revEnd2MeasureNumeric.Value = revEnd1MeasureNumeric.Value;
|
||||
revEnd2Beat1Numeric.Value = revEnd1Beat1Numeric.Value;
|
||||
revEnd2Beat2Numeric.Value = revEnd1Beat2Numeric.Value;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
private void revEnd2Beat1Numeric_ValueChanged(object sender, EventArgs e)
|
||||
{
|
||||
if (RevEnd2Measure < RevEnd1Measure)
|
||||
{
|
||||
revEnd2MeasureNumeric.Value = revEnd1MeasureNumeric.Value;
|
||||
revEnd2Beat1Numeric.Value = revEnd1Beat1Numeric.Value;
|
||||
revEnd2Beat2Numeric.Value = revEnd1Beat2Numeric.Value;
|
||||
return;
|
||||
}
|
||||
|
||||
if (revEnd2Beat1Numeric.Value >= revEnd2Beat2Numeric.Value)
|
||||
{
|
||||
revEnd2MeasureNumeric.Value++;
|
||||
revEnd2Beat1Numeric.Value = 0;
|
||||
}
|
||||
else if (revEnd2Beat1Numeric.Value < 0)
|
||||
{
|
||||
if (revEnd2MeasureNumeric.Value > 0)
|
||||
{
|
||||
revEnd2MeasureNumeric.Value--;
|
||||
revEnd2Beat1Numeric.Value = revEnd2Beat2Numeric.Value - 1;
|
||||
}
|
||||
else if (revEnd2MeasureNumeric.Value == 0)
|
||||
{
|
||||
revEnd2Beat1Numeric.Value = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,60 @@
|
||||
<root>
|
||||
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
|
||||
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
|
||||
<xsd:element name="root" msdata:IsDataSet="true">
|
||||
<xsd:complexType>
|
||||
<xsd:choice maxOccurs="unbounded">
|
||||
<xsd:element name="metadata">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" use="required" type="xsd:string" />
|
||||
<xsd:attribute name="type" type="xsd:string" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="assembly">
|
||||
<xsd:complexType>
|
||||
<xsd:attribute name="alias" type="xsd:string" />
|
||||
<xsd:attribute name="name" type="xsd:string" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="data">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
|
||||
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="resheader">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:choice>
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:schema>
|
||||
<resheader name="resmimetype">
|
||||
<value>text/microsoft-resx</value>
|
||||
</resheader>
|
||||
<resheader name="version">
|
||||
<value>2.0</value>
|
||||
</resheader>
|
||||
<resheader name="reader">
|
||||
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<resheader name="writer">
|
||||
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
</root>
|
||||
+246
@@ -0,0 +1,246 @@
|
||||
namespace BAKKA_Editor
|
||||
{
|
||||
partial class InitChartSettingsForm
|
||||
{
|
||||
/// <summary>
|
||||
/// Required designer variable.
|
||||
/// </summary>
|
||||
private System.ComponentModel.IContainer components = null;
|
||||
|
||||
/// <summary>
|
||||
/// Clean up any resources being used.
|
||||
/// </summary>
|
||||
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
|
||||
protected override void Dispose(bool disposing)
|
||||
{
|
||||
if (disposing && (components != null))
|
||||
{
|
||||
components.Dispose();
|
||||
}
|
||||
base.Dispose(disposing);
|
||||
}
|
||||
|
||||
#region Windows Form Designer generated code
|
||||
|
||||
/// <summary>
|
||||
/// Required method for Designer support - do not modify
|
||||
/// the contents of this method with the code editor.
|
||||
/// </summary>
|
||||
private void InitializeComponent()
|
||||
{
|
||||
this.initSaveSettingsButton = new System.Windows.Forms.Button();
|
||||
this.label9 = new System.Windows.Forms.Label();
|
||||
this.initMovieOffsetNumeric = new System.Windows.Forms.NumericUpDown();
|
||||
this.label8 = new System.Windows.Forms.Label();
|
||||
this.initOffsetNumeric = new System.Windows.Forms.NumericUpDown();
|
||||
this.label7 = new System.Windows.Forms.Label();
|
||||
this.label6 = new System.Windows.Forms.Label();
|
||||
this.label5 = new System.Windows.Forms.Label();
|
||||
this.initTimeSig2Numeric = new System.Windows.Forms.NumericUpDown();
|
||||
this.initTimeSig1Numeric = new System.Windows.Forms.NumericUpDown();
|
||||
this.initBpmNumeric = new System.Windows.Forms.NumericUpDown();
|
||||
((System.ComponentModel.ISupportInitialize)(this.initMovieOffsetNumeric)).BeginInit();
|
||||
((System.ComponentModel.ISupportInitialize)(this.initOffsetNumeric)).BeginInit();
|
||||
((System.ComponentModel.ISupportInitialize)(this.initTimeSig2Numeric)).BeginInit();
|
||||
((System.ComponentModel.ISupportInitialize)(this.initTimeSig1Numeric)).BeginInit();
|
||||
((System.ComponentModel.ISupportInitialize)(this.initBpmNumeric)).BeginInit();
|
||||
this.SuspendLayout();
|
||||
//
|
||||
// initSaveSettingsButton
|
||||
//
|
||||
this.initSaveSettingsButton.Location = new System.Drawing.Point(12, 128);
|
||||
this.initSaveSettingsButton.Name = "initSaveSettingsButton";
|
||||
this.initSaveSettingsButton.Size = new System.Drawing.Size(218, 23);
|
||||
this.initSaveSettingsButton.TabIndex = 30;
|
||||
this.initSaveSettingsButton.Text = "Save Settings";
|
||||
this.initSaveSettingsButton.UseVisualStyleBackColor = true;
|
||||
this.initSaveSettingsButton.Click += new System.EventHandler(this.initSaveSettingsButton_Click);
|
||||
//
|
||||
// label9
|
||||
//
|
||||
this.label9.AutoSize = true;
|
||||
this.label9.Location = new System.Drawing.Point(46, 101);
|
||||
this.label9.Name = "label9";
|
||||
this.label9.Size = new System.Drawing.Size(78, 15);
|
||||
this.label9.TabIndex = 29;
|
||||
this.label9.Text = "Movie Offset:";
|
||||
//
|
||||
// initMovieOffsetNumeric
|
||||
//
|
||||
this.initMovieOffsetNumeric.DecimalPlaces = 6;
|
||||
this.initMovieOffsetNumeric.Location = new System.Drawing.Point(130, 99);
|
||||
this.initMovieOffsetNumeric.Maximum = new decimal(new int[] {
|
||||
9999,
|
||||
0,
|
||||
0,
|
||||
0});
|
||||
this.initMovieOffsetNumeric.Name = "initMovieOffsetNumeric";
|
||||
this.initMovieOffsetNumeric.Size = new System.Drawing.Size(100, 23);
|
||||
this.initMovieOffsetNumeric.TabIndex = 28;
|
||||
//
|
||||
// label8
|
||||
//
|
||||
this.label8.AutoSize = true;
|
||||
this.label8.Location = new System.Drawing.Point(82, 74);
|
||||
this.label8.Name = "label8";
|
||||
this.label8.Size = new System.Drawing.Size(42, 15);
|
||||
this.label8.TabIndex = 27;
|
||||
this.label8.Text = "Offset:";
|
||||
//
|
||||
// initOffsetNumeric
|
||||
//
|
||||
this.initOffsetNumeric.DecimalPlaces = 6;
|
||||
this.initOffsetNumeric.Location = new System.Drawing.Point(130, 70);
|
||||
this.initOffsetNumeric.Maximum = new decimal(new int[] {
|
||||
9999,
|
||||
0,
|
||||
0,
|
||||
0});
|
||||
this.initOffsetNumeric.Minimum = new decimal(new int[] {
|
||||
9999,
|
||||
0,
|
||||
0,
|
||||
-2147483648});
|
||||
this.initOffsetNumeric.Name = "initOffsetNumeric";
|
||||
this.initOffsetNumeric.Size = new System.Drawing.Size(100, 23);
|
||||
this.initOffsetNumeric.TabIndex = 26;
|
||||
//
|
||||
// label7
|
||||
//
|
||||
this.label7.AutoSize = true;
|
||||
this.label7.Location = new System.Drawing.Point(35, 43);
|
||||
this.label7.Name = "label7";
|
||||
this.label7.Size = new System.Drawing.Size(89, 15);
|
||||
this.label7.TabIndex = 25;
|
||||
this.label7.Text = "Time Signature:";
|
||||
//
|
||||
// label6
|
||||
//
|
||||
this.label6.AutoSize = true;
|
||||
this.label6.Location = new System.Drawing.Point(174, 43);
|
||||
this.label6.Name = "label6";
|
||||
this.label6.Size = new System.Drawing.Size(12, 15);
|
||||
this.label6.TabIndex = 13;
|
||||
this.label6.Text = "/";
|
||||
//
|
||||
// label5
|
||||
//
|
||||
this.label5.AutoSize = true;
|
||||
this.label5.Location = new System.Drawing.Point(89, 14);
|
||||
this.label5.Name = "label5";
|
||||
this.label5.Size = new System.Drawing.Size(35, 15);
|
||||
this.label5.TabIndex = 24;
|
||||
this.label5.Text = "BPM:";
|
||||
//
|
||||
// initTimeSig2Numeric
|
||||
//
|
||||
this.initTimeSig2Numeric.Location = new System.Drawing.Point(192, 41);
|
||||
this.initTimeSig2Numeric.Maximum = new decimal(new int[] {
|
||||
1920,
|
||||
0,
|
||||
0,
|
||||
0});
|
||||
this.initTimeSig2Numeric.Minimum = new decimal(new int[] {
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
0});
|
||||
this.initTimeSig2Numeric.Name = "initTimeSig2Numeric";
|
||||
this.initTimeSig2Numeric.Size = new System.Drawing.Size(38, 23);
|
||||
this.initTimeSig2Numeric.TabIndex = 12;
|
||||
this.initTimeSig2Numeric.Value = new decimal(new int[] {
|
||||
4,
|
||||
0,
|
||||
0,
|
||||
0});
|
||||
//
|
||||
// initTimeSig1Numeric
|
||||
//
|
||||
this.initTimeSig1Numeric.Location = new System.Drawing.Point(130, 41);
|
||||
this.initTimeSig1Numeric.Maximum = new decimal(new int[] {
|
||||
191,
|
||||
0,
|
||||
0,
|
||||
0});
|
||||
this.initTimeSig1Numeric.Minimum = new decimal(new int[] {
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
0});
|
||||
this.initTimeSig1Numeric.Name = "initTimeSig1Numeric";
|
||||
this.initTimeSig1Numeric.Size = new System.Drawing.Size(38, 23);
|
||||
this.initTimeSig1Numeric.TabIndex = 11;
|
||||
this.initTimeSig1Numeric.Value = new decimal(new int[] {
|
||||
4,
|
||||
0,
|
||||
0,
|
||||
0});
|
||||
//
|
||||
// initBpmNumeric
|
||||
//
|
||||
this.initBpmNumeric.DecimalPlaces = 6;
|
||||
this.initBpmNumeric.Location = new System.Drawing.Point(130, 12);
|
||||
this.initBpmNumeric.Maximum = new decimal(new int[] {
|
||||
9999,
|
||||
0,
|
||||
0,
|
||||
0});
|
||||
this.initBpmNumeric.Minimum = new decimal(new int[] {
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
0});
|
||||
this.initBpmNumeric.Name = "initBpmNumeric";
|
||||
this.initBpmNumeric.Size = new System.Drawing.Size(100, 23);
|
||||
this.initBpmNumeric.TabIndex = 23;
|
||||
this.initBpmNumeric.Value = new decimal(new int[] {
|
||||
120,
|
||||
0,
|
||||
0,
|
||||
0});
|
||||
//
|
||||
// InitChartSettingsForm
|
||||
//
|
||||
this.AutoScaleDimensions = new System.Drawing.SizeF(7F, 15F);
|
||||
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
|
||||
this.ClientSize = new System.Drawing.Size(242, 164);
|
||||
this.Controls.Add(this.initSaveSettingsButton);
|
||||
this.Controls.Add(this.label9);
|
||||
this.Controls.Add(this.initBpmNumeric);
|
||||
this.Controls.Add(this.initMovieOffsetNumeric);
|
||||
this.Controls.Add(this.initTimeSig1Numeric);
|
||||
this.Controls.Add(this.label8);
|
||||
this.Controls.Add(this.initTimeSig2Numeric);
|
||||
this.Controls.Add(this.initOffsetNumeric);
|
||||
this.Controls.Add(this.label5);
|
||||
this.Controls.Add(this.label7);
|
||||
this.Controls.Add(this.label6);
|
||||
this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedToolWindow;
|
||||
this.Name = "InitChartSettingsForm";
|
||||
this.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent;
|
||||
this.Text = "Initial Chart Settings";
|
||||
((System.ComponentModel.ISupportInitialize)(this.initMovieOffsetNumeric)).EndInit();
|
||||
((System.ComponentModel.ISupportInitialize)(this.initOffsetNumeric)).EndInit();
|
||||
((System.ComponentModel.ISupportInitialize)(this.initTimeSig2Numeric)).EndInit();
|
||||
((System.ComponentModel.ISupportInitialize)(this.initTimeSig1Numeric)).EndInit();
|
||||
((System.ComponentModel.ISupportInitialize)(this.initBpmNumeric)).EndInit();
|
||||
this.ResumeLayout(false);
|
||||
this.PerformLayout();
|
||||
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
private Button initSaveSettingsButton;
|
||||
private Label label9;
|
||||
private NumericUpDown initMovieOffsetNumeric;
|
||||
private Label label8;
|
||||
private NumericUpDown initOffsetNumeric;
|
||||
private Label label7;
|
||||
private Label label6;
|
||||
private Label label5;
|
||||
private NumericUpDown initTimeSig2Numeric;
|
||||
private NumericUpDown initTimeSig1Numeric;
|
||||
private NumericUpDown initBpmNumeric;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,40 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
using System.Data;
|
||||
using System.Drawing;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows.Forms;
|
||||
|
||||
namespace BAKKA_Editor
|
||||
{
|
||||
public partial class InitChartSettingsForm : Form
|
||||
{
|
||||
public double Bpm { get { return (double)initBpmNumeric.Value; } }
|
||||
public int TimeSigUpper { get { return (int)initTimeSig1Numeric.Value; } }
|
||||
public int TimeSigLower { get { return (int)initTimeSig2Numeric.Value; } }
|
||||
public double Offset { get { return (double)initOffsetNumeric.Value; } }
|
||||
public double MovieOffset { get { return (double)initMovieOffsetNumeric.Value; } }
|
||||
|
||||
public InitChartSettingsForm()
|
||||
{
|
||||
InitializeComponent();
|
||||
}
|
||||
|
||||
public void SetValues(double bpm, int timeSigUpper, int timeSigLower, double offset, double movieOffset)
|
||||
{
|
||||
initBpmNumeric.Value = (decimal)bpm;
|
||||
initTimeSig1Numeric.Value = timeSigUpper;
|
||||
initTimeSig2Numeric.Value = timeSigLower;
|
||||
initOffsetNumeric.Value = (decimal)offset;
|
||||
initMovieOffsetNumeric.Value = (decimal)movieOffset;
|
||||
}
|
||||
|
||||
private void initSaveSettingsButton_Click(object sender, EventArgs e)
|
||||
{
|
||||
DialogResult = DialogResult.OK;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,60 @@
|
||||
<root>
|
||||
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
|
||||
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
|
||||
<xsd:element name="root" msdata:IsDataSet="true">
|
||||
<xsd:complexType>
|
||||
<xsd:choice maxOccurs="unbounded">
|
||||
<xsd:element name="metadata">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" use="required" type="xsd:string" />
|
||||
<xsd:attribute name="type" type="xsd:string" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="assembly">
|
||||
<xsd:complexType>
|
||||
<xsd:attribute name="alias" type="xsd:string" />
|
||||
<xsd:attribute name="name" type="xsd:string" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="data">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
|
||||
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="resheader">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:choice>
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:schema>
|
||||
<resheader name="resmimetype">
|
||||
<value>text/microsoft-resx</value>
|
||||
</resheader>
|
||||
<resheader name="version">
|
||||
<value>2.0</value>
|
||||
</resheader>
|
||||
<resheader name="reader">
|
||||
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<resheader name="writer">
|
||||
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
</root>
|
||||
Generated
+1592
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,229 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace BAKKA_Editor
|
||||
{
|
||||
internal class BeatInfo
|
||||
{
|
||||
public int Measure;
|
||||
public int Beat;
|
||||
|
||||
public BeatInfo(int measure, int beat)
|
||||
{
|
||||
Measure = measure;
|
||||
Beat = beat;
|
||||
}
|
||||
|
||||
public BeatInfo(float measure)
|
||||
{
|
||||
Measure = (int)Math.Floor(measure);
|
||||
Beat = (int)((measure - (float)Measure) * 1920.0f);
|
||||
}
|
||||
|
||||
public BeatInfo(BeatInfo info)
|
||||
{
|
||||
Measure = info.Measure;
|
||||
Beat = info.Beat;
|
||||
}
|
||||
|
||||
public float MeasureDecimal { get { return (float)Measure + (float)Beat / 1920.0f; } }
|
||||
}
|
||||
|
||||
internal class TimeSignature
|
||||
{
|
||||
public int Upper;
|
||||
public int Lower;
|
||||
|
||||
public double Ratio { get { return (double)Upper / (double)Lower; } }
|
||||
|
||||
public TimeSignature()
|
||||
{
|
||||
Upper = 4;
|
||||
Lower = 4;
|
||||
}
|
||||
|
||||
public TimeSignature(TimeSignature sig)
|
||||
{
|
||||
Upper = sig.Upper;
|
||||
Lower = sig.Lower;
|
||||
}
|
||||
}
|
||||
|
||||
internal class NoteBase
|
||||
{
|
||||
public BeatInfo BeatInfo { get; set; } = new BeatInfo(-1, 0);
|
||||
public GimmickType GimmickType { get; set; } = GimmickType.NoGimmick;
|
||||
|
||||
public float Measure { get { return BeatInfo.MeasureDecimal; } }
|
||||
}
|
||||
|
||||
internal class Note : NoteBase
|
||||
{
|
||||
public NoteType NoteType { get; set; } = NoteType.TouchNoBonus;
|
||||
public int Position { get; set; }
|
||||
public int Size { get; set; }
|
||||
[System.ComponentModel.Browsable(false)]
|
||||
public bool HoldChange { get; set; }
|
||||
[System.ComponentModel.Browsable(false)]
|
||||
public MaskType MaskFill { get; set; }
|
||||
[System.ComponentModel.Browsable(false)]
|
||||
public Note NextNote { get; set; }
|
||||
[System.ComponentModel.Browsable(false)]
|
||||
public Note PrevNote { get; set; }
|
||||
|
||||
[System.ComponentModel.Browsable(false)]
|
||||
public bool IsHold
|
||||
{
|
||||
get
|
||||
{
|
||||
switch (NoteType)
|
||||
{
|
||||
case NoteType.HoldStartNoBonus:
|
||||
case NoteType.HoldJoint:
|
||||
case NoteType.HoldEnd:
|
||||
case NoteType.HoldStartBonusFlair:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
[System.ComponentModel.Browsable(false)]
|
||||
public bool IsMask
|
||||
{
|
||||
get
|
||||
{
|
||||
switch (NoteType)
|
||||
{
|
||||
case NoteType.MaskAdd:
|
||||
case NoteType.MaskRemove:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
[System.ComponentModel.Browsable(false)]
|
||||
public bool IsBonus
|
||||
{
|
||||
get
|
||||
{
|
||||
switch (NoteType)
|
||||
{
|
||||
case NoteType.TouchBonus:
|
||||
case NoteType.SlideOrangeBonus:
|
||||
case NoteType.SlideGreenBonus:
|
||||
return true;
|
||||
default:
|
||||
return false; ;
|
||||
}
|
||||
}
|
||||
}
|
||||
[System.ComponentModel.Browsable(false)]
|
||||
public bool IsFlair
|
||||
{
|
||||
get
|
||||
{
|
||||
switch (NoteType)
|
||||
{
|
||||
case NoteType.TouchBonusFlair:
|
||||
case NoteType.SnapRedBonusFlair:
|
||||
case NoteType.SnapBlueBonusFlair:
|
||||
case NoteType.SlideOrangeBonusFlair:
|
||||
case NoteType.SlideGreenBonusFlair:
|
||||
case NoteType.HoldStartBonusFlair:
|
||||
case NoteType.ChainBonusFlair:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
[System.ComponentModel.Browsable(false)]
|
||||
public Color Color
|
||||
{
|
||||
get
|
||||
{
|
||||
return Utils.NoteTypeToColor(NoteType);
|
||||
}
|
||||
}
|
||||
|
||||
public Note() { }
|
||||
public Note(BeatInfo info)
|
||||
{
|
||||
BeatInfo = info;
|
||||
GimmickType = GimmickType.NoGimmick;
|
||||
}
|
||||
|
||||
public Note(Note baseNote) : this(baseNote.BeatInfo)
|
||||
{
|
||||
Position = baseNote.Position;
|
||||
Size = baseNote.Size;
|
||||
NoteType = baseNote.NoteType;
|
||||
}
|
||||
}
|
||||
|
||||
internal class Gimmick : NoteBase
|
||||
{
|
||||
public double BPM { get; set; }
|
||||
public TimeSignature TimeSig { get; set; } = new();
|
||||
public double HiSpeed { get; set; }
|
||||
public double StartTime { get; set; }
|
||||
|
||||
public bool IsReverse
|
||||
{
|
||||
get
|
||||
{
|
||||
switch (GimmickType)
|
||||
{
|
||||
case GimmickType.ReverseStart:
|
||||
case GimmickType.ReverseMiddle:
|
||||
case GimmickType.ReverseEnd:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public bool IsStop
|
||||
{
|
||||
get
|
||||
{
|
||||
switch (GimmickType)
|
||||
{
|
||||
case GimmickType.StopStart:
|
||||
case GimmickType.StopEnd:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public Gimmick() { }
|
||||
public Gimmick(BeatInfo info, GimmickType type)
|
||||
{
|
||||
BeatInfo = info;
|
||||
GimmickType = type;
|
||||
}
|
||||
public Gimmick(Gimmick baseGimmick) : this(baseGimmick.BeatInfo, baseGimmick.GimmickType)
|
||||
{
|
||||
switch (GimmickType)
|
||||
{
|
||||
case GimmickType.BpmChange:
|
||||
HiSpeed = baseGimmick.HiSpeed;
|
||||
break;
|
||||
case GimmickType.TimeSignatureChange:
|
||||
TimeSig = new TimeSignature(baseGimmick.TimeSig);
|
||||
break;
|
||||
case GimmickType.HiSpeedChange:
|
||||
HiSpeed = baseGimmick.HiSpeed;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace BAKKA_Editor.Operations
|
||||
{
|
||||
internal class CompositeOperation : IOperation
|
||||
{
|
||||
public string Description { get; }
|
||||
|
||||
protected IEnumerable<IOperation> Operations { get; }
|
||||
|
||||
public CompositeOperation(string description, IEnumerable<IOperation> operations)
|
||||
{
|
||||
Description = description;
|
||||
Operations = operations;
|
||||
}
|
||||
|
||||
public void Redo()
|
||||
{
|
||||
foreach (var op in Operations)
|
||||
{
|
||||
op.Redo();
|
||||
}
|
||||
}
|
||||
|
||||
public void Undo()
|
||||
{
|
||||
foreach (var op in Operations)
|
||||
{
|
||||
op.Undo();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,111 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace BAKKA_Editor.Operations
|
||||
{
|
||||
internal abstract class GimmickOperation : IOperation
|
||||
{
|
||||
protected Gimmick Gimmick { get; }
|
||||
protected Chart Chart { get; }
|
||||
public abstract string Description { get; }
|
||||
|
||||
public GimmickOperation(Chart chart, Gimmick item)
|
||||
{
|
||||
Chart = chart;
|
||||
Gimmick = item;
|
||||
}
|
||||
|
||||
public abstract void Redo();
|
||||
|
||||
public abstract void Undo();
|
||||
}
|
||||
|
||||
internal class InsertGimmick : GimmickOperation
|
||||
{
|
||||
public override string Description => "Insert gimmick";
|
||||
|
||||
public InsertGimmick(Chart chart, Gimmick item) : base(chart, item)
|
||||
{ }
|
||||
|
||||
public override void Redo()
|
||||
{
|
||||
Chart.Gimmicks.Add(Gimmick);
|
||||
}
|
||||
|
||||
public override void Undo()
|
||||
{
|
||||
Chart.Gimmicks.Remove(Gimmick);
|
||||
}
|
||||
}
|
||||
|
||||
internal class RemoveGimmick : GimmickOperation
|
||||
{
|
||||
public override string Description => "Remove gimmick";
|
||||
|
||||
public RemoveGimmick(Chart chart, Gimmick item) : base(chart, item)
|
||||
{ }
|
||||
|
||||
public override void Redo()
|
||||
{
|
||||
Chart.Gimmicks.Remove(Gimmick);
|
||||
}
|
||||
|
||||
public override void Undo()
|
||||
{
|
||||
Chart.Gimmicks.Add(Gimmick);
|
||||
}
|
||||
}
|
||||
|
||||
internal class EditGimmick : IOperation
|
||||
{
|
||||
public string Description => "Edit gimmick";
|
||||
|
||||
protected Gimmick Base { get; }
|
||||
protected Gimmick OldGimmick { get; }
|
||||
protected Gimmick NewGimmick { get; }
|
||||
|
||||
public EditGimmick(Gimmick baseGimmick, Gimmick newGimmick)
|
||||
{
|
||||
Base = baseGimmick;
|
||||
OldGimmick = new Gimmick(baseGimmick);
|
||||
NewGimmick = new Gimmick(newGimmick);
|
||||
}
|
||||
|
||||
public void Redo()
|
||||
{
|
||||
Base.BeatInfo = new BeatInfo(NewGimmick.BeatInfo);
|
||||
switch (Base.GimmickType)
|
||||
{
|
||||
case GimmickType.BpmChange:
|
||||
Base.BPM = NewGimmick.BPM;
|
||||
break;
|
||||
case GimmickType.TimeSignatureChange:
|
||||
Base.TimeSig = new TimeSignature(NewGimmick.TimeSig);
|
||||
break;
|
||||
case GimmickType.HiSpeedChange:
|
||||
Base.HiSpeed = NewGimmick.HiSpeed;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
public void Undo()
|
||||
{
|
||||
Base.BeatInfo = new BeatInfo(OldGimmick.BeatInfo);
|
||||
switch (Base.GimmickType)
|
||||
{
|
||||
case GimmickType.BpmChange:
|
||||
Base.BPM = OldGimmick.BPM;
|
||||
break;
|
||||
case GimmickType.TimeSignatureChange:
|
||||
Base.TimeSig = new TimeSignature(OldGimmick.TimeSig);
|
||||
break;
|
||||
case GimmickType.HiSpeedChange:
|
||||
Base.HiSpeed = OldGimmick.HiSpeed;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace BAKKA_Editor.Operations
|
||||
{
|
||||
internal interface IOperation
|
||||
{
|
||||
string Description { get; }
|
||||
|
||||
void Undo();
|
||||
|
||||
void Redo();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,203 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace BAKKA_Editor.Operations
|
||||
{
|
||||
internal abstract class NoteOperation : IOperation
|
||||
{
|
||||
public Note Note { get; }
|
||||
protected Chart Chart { get; }
|
||||
public abstract string Description { get; }
|
||||
|
||||
public NoteOperation(Chart chart, Note item)
|
||||
{
|
||||
Chart = chart;
|
||||
Note = item;
|
||||
|
||||
// Force End of Chart note to be the correct position and size
|
||||
if (Note.NoteType == NoteType.EndOfChart)
|
||||
{
|
||||
Note.Position = 0;
|
||||
Note.Size = 60;
|
||||
}
|
||||
}
|
||||
|
||||
public abstract void Redo();
|
||||
|
||||
public abstract void Undo();
|
||||
}
|
||||
|
||||
internal class InsertNote : NoteOperation
|
||||
{
|
||||
public override string Description => "Insert note";
|
||||
|
||||
public InsertNote(Chart chart, Note item) : base(chart, item)
|
||||
{ }
|
||||
|
||||
public override void Redo()
|
||||
{
|
||||
Chart.Notes.Add(Note);
|
||||
}
|
||||
|
||||
public override void Undo()
|
||||
{
|
||||
Chart.Notes.Remove(Note);
|
||||
}
|
||||
}
|
||||
|
||||
internal class RemoveNote : NoteOperation
|
||||
{
|
||||
public override string Description => "Remove note";
|
||||
|
||||
public RemoveNote(Chart chart, Note item) : base(chart, item)
|
||||
{ }
|
||||
|
||||
public override void Redo()
|
||||
{
|
||||
Chart.Notes.Remove(Note);
|
||||
}
|
||||
|
||||
public override void Undo()
|
||||
{
|
||||
Chart.Notes.Add(Note);
|
||||
}
|
||||
}
|
||||
|
||||
internal class EditNote : IOperation
|
||||
{
|
||||
public string Description => "Edit note";
|
||||
|
||||
protected Note Base { get; }
|
||||
protected Note OldNote { get; }
|
||||
protected Note NewNote { get; }
|
||||
|
||||
public EditNote(Note baseNote, Note newNote)
|
||||
{
|
||||
Base = baseNote;
|
||||
OldNote = new Note(baseNote);
|
||||
NewNote = new Note(newNote);
|
||||
}
|
||||
|
||||
public void Redo()
|
||||
{
|
||||
Base.BeatInfo = new BeatInfo(NewNote.BeatInfo);
|
||||
Base.Position = NewNote.Position;
|
||||
Base.Size = NewNote.Size;
|
||||
}
|
||||
|
||||
public void Undo()
|
||||
{
|
||||
Base.BeatInfo = new BeatInfo(OldNote.BeatInfo);
|
||||
Base.Position = OldNote.Position;
|
||||
Base.Size = OldNote.Size;
|
||||
}
|
||||
}
|
||||
|
||||
internal class InsertHoldNote : NoteOperation
|
||||
{
|
||||
public override string Description => "Insert hold note";
|
||||
private Note prevNote;
|
||||
|
||||
public InsertHoldNote(Chart chart, Note item) : base(chart, item)
|
||||
{
|
||||
prevNote = item.PrevNote;
|
||||
}
|
||||
|
||||
public override void Redo()
|
||||
{
|
||||
if (Note.PrevNote != null)
|
||||
Note.PrevNote.NextNote = Note;
|
||||
Chart.Notes.Add(Note);
|
||||
}
|
||||
|
||||
public override void Undo()
|
||||
{
|
||||
if (Note.PrevNote != null)
|
||||
Note.PrevNote.NextNote = null;
|
||||
Chart.Notes.Remove(Note);
|
||||
}
|
||||
}
|
||||
|
||||
internal class RemoveHoldNote : NoteOperation
|
||||
{
|
||||
public override string Description => "Remove hold note";
|
||||
private Note prevNote;
|
||||
private NoteType prevNoteType;
|
||||
private Note nextNote;
|
||||
private NoteType nextNoteType;
|
||||
|
||||
public RemoveHoldNote(Chart chart, Note item) : base(chart, item)
|
||||
{
|
||||
prevNote = item.PrevNote;
|
||||
if (prevNote != null)
|
||||
prevNoteType = prevNote.NoteType;
|
||||
nextNote = item.NextNote;
|
||||
if (nextNote != null)
|
||||
nextNoteType = nextNote.NoteType;
|
||||
}
|
||||
|
||||
public override void Redo()
|
||||
{
|
||||
switch (Note.NoteType)
|
||||
{
|
||||
case NoteType.HoldStartNoBonus:
|
||||
case NoteType.HoldStartBonusFlair:
|
||||
if (nextNote != null)
|
||||
{
|
||||
nextNote.PrevNote = null;
|
||||
if (nextNote.NoteType == NoteType.HoldJoint)
|
||||
nextNote.NoteType = Note.NoteType;
|
||||
}
|
||||
break;
|
||||
case NoteType.HoldJoint:
|
||||
prevNote.NextNote = nextNote;
|
||||
if (nextNote != null)
|
||||
nextNote.PrevNote = prevNote;
|
||||
break;
|
||||
case NoteType.HoldEnd:
|
||||
if (prevNote != null)
|
||||
{
|
||||
prevNote.NextNote = null;
|
||||
prevNote.NoteType = NoteType.HoldEnd;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
Chart.Notes.Remove(Note);
|
||||
}
|
||||
|
||||
public override void Undo()
|
||||
{
|
||||
switch (Note.NoteType)
|
||||
{
|
||||
case NoteType.HoldStartNoBonus:
|
||||
case NoteType.HoldStartBonusFlair:
|
||||
if (nextNote != null)
|
||||
{
|
||||
nextNote.PrevNote = Note;
|
||||
nextNote.NoteType = nextNoteType;
|
||||
}
|
||||
break;
|
||||
case NoteType.HoldJoint:
|
||||
prevNote.NextNote = Note;
|
||||
if (nextNote != null)
|
||||
nextNote.PrevNote = Note;
|
||||
break;
|
||||
case NoteType.HoldEnd:
|
||||
if (prevNote != null)
|
||||
{
|
||||
prevNote.NextNote = Note;
|
||||
prevNote.NoteType = prevNoteType;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
Chart.Notes.Add(Note);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,73 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace BAKKA_Editor.Operations
|
||||
{
|
||||
internal class OperationManager
|
||||
{
|
||||
public event EventHandler? OperationHistoryChanged;
|
||||
public event EventHandler? ChangesCommitted;
|
||||
|
||||
protected Stack<IOperation> UndoStack { get; } = new Stack<IOperation>();
|
||||
protected Stack<IOperation> RedoStack { get; } = new Stack<IOperation>();
|
||||
|
||||
private IOperation? LastCommittedOperation { get; set; } = null;
|
||||
|
||||
public IEnumerable<string> UndoOperationsDescription
|
||||
{
|
||||
get { return UndoStack.Select(p => p.Description); }
|
||||
}
|
||||
|
||||
public IEnumerable<string> RedoOperationsDescription
|
||||
{
|
||||
get { return RedoStack.Select(p => p.Description); }
|
||||
}
|
||||
|
||||
public bool CanUndo { get { return UndoStack.Count > 0; } }
|
||||
|
||||
public bool CanRedo { get { return RedoStack.Count > 0; } }
|
||||
|
||||
public void Push(IOperation op)
|
||||
{
|
||||
UndoStack.Push(op);
|
||||
RedoStack.Clear();
|
||||
OperationHistoryChanged?.Invoke(this, EventArgs.Empty);
|
||||
}
|
||||
|
||||
public void InvokeAndPush(IOperation op)
|
||||
{
|
||||
op.Redo();
|
||||
Push(op);
|
||||
}
|
||||
|
||||
public IOperation Undo()
|
||||
{
|
||||
IOperation op = UndoStack.Pop();
|
||||
op.Undo();
|
||||
var type = op.GetType();
|
||||
RedoStack.Push(op);
|
||||
OperationHistoryChanged?.Invoke(this, EventArgs.Empty);
|
||||
return op;
|
||||
}
|
||||
|
||||
public IOperation Redo()
|
||||
{
|
||||
IOperation op = RedoStack.Pop();
|
||||
op.Redo();
|
||||
UndoStack.Push(op);
|
||||
OperationHistoryChanged?.Invoke(this, EventArgs.Empty);
|
||||
return op;
|
||||
}
|
||||
|
||||
public void Clear()
|
||||
{
|
||||
UndoStack.Clear();
|
||||
RedoStack.Clear();
|
||||
LastCommittedOperation = null;
|
||||
OperationHistoryChanged?.Invoke(this, EventArgs.Empty);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
namespace BAKKA_Editor
|
||||
{
|
||||
internal static class Program
|
||||
{
|
||||
/// <summary>
|
||||
/// The main entry point for the application.
|
||||
/// </summary>
|
||||
[STAThread]
|
||||
static void Main()
|
||||
{
|
||||
// To customize application configuration such as set high DPI settings or default font,
|
||||
// see https://aka.ms/applicationconfiguration.
|
||||
ApplicationConfiguration.Initialize();
|
||||
Application.Run(new MainForm());
|
||||
}
|
||||
}
|
||||
}
|
||||
+63
@@ -0,0 +1,63 @@
|
||||
//------------------------------------------------------------------------------
|
||||
// <auto-generated>
|
||||
// This code was generated by a tool.
|
||||
// Runtime Version:4.0.30319.42000
|
||||
//
|
||||
// Changes to this file may cause incorrect behavior and will be lost if
|
||||
// the code is regenerated.
|
||||
// </auto-generated>
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
namespace BAKKA_Editor.Properties {
|
||||
using System;
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// A strongly-typed resource class, for looking up localized strings, etc.
|
||||
/// </summary>
|
||||
// This class was auto-generated by the StronglyTypedResourceBuilder
|
||||
// class via a tool like ResGen or Visual Studio.
|
||||
// To add or remove a member, edit your .ResX file then rerun ResGen
|
||||
// with the /str option, or rebuild your VS project.
|
||||
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "17.0.0.0")]
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
|
||||
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
|
||||
internal class Resources {
|
||||
|
||||
private static global::System.Resources.ResourceManager resourceMan;
|
||||
|
||||
private static global::System.Globalization.CultureInfo resourceCulture;
|
||||
|
||||
[global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
|
||||
internal Resources() {
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns the cached ResourceManager instance used by this class.
|
||||
/// </summary>
|
||||
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
|
||||
internal static global::System.Resources.ResourceManager ResourceManager {
|
||||
get {
|
||||
if (object.ReferenceEquals(resourceMan, null)) {
|
||||
global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("BAKKA_Editor.Properties.Resources", typeof(Resources).Assembly);
|
||||
resourceMan = temp;
|
||||
}
|
||||
return resourceMan;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Overrides the current thread's CurrentUICulture property for all
|
||||
/// resource lookups using this strongly typed resource class.
|
||||
/// </summary>
|
||||
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
|
||||
internal static global::System.Globalization.CultureInfo Culture {
|
||||
get {
|
||||
return resourceCulture;
|
||||
}
|
||||
set {
|
||||
resourceCulture = value;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -117,26 +117,4 @@
|
||||
<resheader name="writer">
|
||||
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<assembly alias="System.Drawing" name="System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
|
||||
<data name="newToolStripMenuItem.Size" type="System.Drawing.Size, System.Drawing">
|
||||
<value>114, 22</value>
|
||||
</data>
|
||||
<data name="openToolStripMenuItem.Size" type="System.Drawing.Size, System.Drawing">
|
||||
<value>114, 22</value>
|
||||
</data>
|
||||
<data name="saveToolStripMenuItem.Size" type="System.Drawing.Size, System.Drawing">
|
||||
<value>114, 22</value>
|
||||
</data>
|
||||
<data name="saveAsToolStripMenuItem.Size" type="System.Drawing.Size, System.Drawing">
|
||||
<value>114, 22</value>
|
||||
</data>
|
||||
<data name="exitToolStripMenuItem.Size" type="System.Drawing.Size, System.Drawing">
|
||||
<value>114, 22</value>
|
||||
</data>
|
||||
<data name="BonusBox.Location" type="System.Drawing.Point, System.Drawing">
|
||||
<value>12, 48</value>
|
||||
</data>
|
||||
<data name="NoteTypesButtons.Size" type="System.Drawing.Size, System.Drawing">
|
||||
<value>666, 74</value>
|
||||
</data>
|
||||
</root>
|
||||
@@ -0,0 +1,7 @@
|
||||
{
|
||||
"profiles": {
|
||||
"BAKKA-Editor": {
|
||||
"commandName": "Project"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,50 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace BAKKA_Editor
|
||||
{
|
||||
|
||||
internal class UserSettings
|
||||
{
|
||||
public ViewSettings ViewSettings { get; set; } = new();
|
||||
public SaveSettings SaveSettings { get; set; } = new();
|
||||
public HotkeySettings HotkeySettings { get; set; } = new();
|
||||
}
|
||||
|
||||
internal class ViewSettings
|
||||
{
|
||||
public bool ShowCursor { get; set; } = true;
|
||||
public bool ShowCursorDuringPlayback { get; set; } = false;
|
||||
public bool HighlightViewedNote { get; set; } = true;
|
||||
public bool SelectLastInsertedNote { get; set; } = true;
|
||||
public bool ShowGimmicks { get; set; } = true;
|
||||
public bool ShowGimmicksDuringPlayback { get; set; } = true;
|
||||
public float HispeedSetting { get; set; } = 1.5f;
|
||||
public int Volume { get; set; } = 100;
|
||||
}
|
||||
|
||||
internal class SaveSettings
|
||||
{
|
||||
/// <summary>
|
||||
/// How frequently autosave occurs (in minutes)
|
||||
/// </summary>
|
||||
public int AutoSaveInterval { get; set; } = 1;
|
||||
}
|
||||
|
||||
internal class HotkeySettings
|
||||
{
|
||||
private static readonly CultureInfo _defaultParsingCulture = CultureInfo.InvariantCulture;
|
||||
public int TouchHotkey { get; set; } = Convert.ToInt32(Keys.D1, _defaultParsingCulture);
|
||||
public int SlideLeftHotkey { get; set; } = Convert.ToInt32(Keys.D2, _defaultParsingCulture);
|
||||
public int SlideRightHotkey { get; set; } = Convert.ToInt32(Keys.D3, _defaultParsingCulture);
|
||||
public int SnapUpHotkey { get; set; } = Convert.ToInt32(Keys.D4, _defaultParsingCulture);
|
||||
public int SnapDownHotkey { get; set; } = Convert.ToInt32(Keys.D5, _defaultParsingCulture);
|
||||
public int ChainHotkey { get; set; } = Convert.ToInt32(Keys.D6, _defaultParsingCulture);
|
||||
public int HoldHotkey { get; set; } = Convert.ToInt32(Keys.D7, _defaultParsingCulture);
|
||||
public int PlayHotkey { get; set; } = Convert.ToInt32(Keys.Space, _defaultParsingCulture);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,242 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace BAKKA_Editor
|
||||
{
|
||||
internal static class Utils
|
||||
{
|
||||
internal static string? GetTag(string input, string tag)
|
||||
{
|
||||
if (input.Contains(tag))
|
||||
{
|
||||
return input.Substring(input.IndexOf(tag) + tag.Length);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
internal static double DegToRad(double deg)
|
||||
{
|
||||
return deg * Math.PI / 180.0f;
|
||||
}
|
||||
|
||||
internal static Color NoteTypeToColor(NoteType type)
|
||||
{
|
||||
switch (type)
|
||||
{
|
||||
case NoteType.TouchNoBonus:
|
||||
case NoteType.TouchBonus:
|
||||
case NoteType.TouchBonusFlair:
|
||||
return Color.Fuchsia;
|
||||
case NoteType.SnapRedNoBonus:
|
||||
case NoteType.SnapRedBonusFlair:
|
||||
return Color.Red;
|
||||
case NoteType.SnapBlueNoBonus:
|
||||
case NoteType.SnapBlueBonusFlair:
|
||||
return Color.Aqua;
|
||||
case NoteType.SlideOrangeNoBonus:
|
||||
case NoteType.SlideOrangeBonus:
|
||||
case NoteType.SlideOrangeBonusFlair:
|
||||
return Color.FromArgb(255, 128, 0);
|
||||
case NoteType.SlideGreenNoBonus:
|
||||
case NoteType.SlideGreenBonus:
|
||||
case NoteType.SlideGreenBonusFlair:
|
||||
return Color.LimeGreen;
|
||||
case NoteType.HoldStartNoBonus:
|
||||
case NoteType.HoldJoint:
|
||||
case NoteType.HoldEnd:
|
||||
case NoteType.HoldStartBonusFlair:
|
||||
return Color.Yellow;
|
||||
case NoteType.Chain:
|
||||
case NoteType.ChainBonusFlair:
|
||||
return Color.FromArgb(204, 190, 45);
|
||||
case NoteType.EndOfChart:
|
||||
return Color.Black;
|
||||
default:
|
||||
return Color.Transparent;
|
||||
}
|
||||
}
|
||||
|
||||
internal static Color GimmickTypeToColor(GimmickType type)
|
||||
{
|
||||
switch (type)
|
||||
{
|
||||
case GimmickType.NoGimmick:
|
||||
return Color.Transparent;
|
||||
case GimmickType.BpmChange:
|
||||
return Color.FromArgb(200, 0, 255, 255);
|
||||
case GimmickType.TimeSignatureChange:
|
||||
return Color.FromArgb(200, 160, 255, 160);
|
||||
case GimmickType.HiSpeedChange:
|
||||
return Color.FromArgb(200, 0, 255, 0);
|
||||
case GimmickType.ReverseStart:
|
||||
case GimmickType.ReverseMiddle:
|
||||
case GimmickType.ReverseEnd:
|
||||
return Color.FromArgb(200, 255, 255, 0);
|
||||
case GimmickType.StopStart:
|
||||
case GimmickType.StopEnd:
|
||||
return Color.FromArgb(200, 255, 0, 0);
|
||||
default:
|
||||
return Color.Transparent;
|
||||
}
|
||||
}
|
||||
|
||||
internal static void InvokeIfRequired(this Control control, MethodInvoker action)
|
||||
{
|
||||
if (control.InvokeRequired)
|
||||
{
|
||||
control.Invoke(action);
|
||||
}
|
||||
else
|
||||
{
|
||||
action();
|
||||
}
|
||||
}
|
||||
|
||||
internal static Rectangle ToInt(this RectangleF rect)
|
||||
{
|
||||
return new Rectangle((int)rect.X, (int)rect.Y, (int)rect.Width, (int)rect.Height);
|
||||
}
|
||||
|
||||
internal static int FindGCD(int a, int b)
|
||||
{
|
||||
if (b == 0)
|
||||
return a;
|
||||
return FindGCD(b, a & b);
|
||||
}
|
||||
|
||||
internal static string ToLabel(this NoteType type)
|
||||
{
|
||||
switch (type)
|
||||
{
|
||||
case NoteType.TouchNoBonus:
|
||||
return "Touch";
|
||||
case NoteType.TouchBonus:
|
||||
return "Touch [Bonus]";
|
||||
case NoteType.SnapRedNoBonus:
|
||||
return "Snap (R)";
|
||||
case NoteType.SnapBlueNoBonus:
|
||||
return "Snap (B)";
|
||||
case NoteType.SlideOrangeNoBonus:
|
||||
return "Slide (O)";
|
||||
case NoteType.SlideOrangeBonus:
|
||||
return "Slide (O) [Bonus]";
|
||||
case NoteType.SlideGreenNoBonus:
|
||||
return "Slide (G)";
|
||||
case NoteType.SlideGreenBonus:
|
||||
return "Slide (G) [Bonus]";
|
||||
case NoteType.HoldStartNoBonus:
|
||||
return "Hold Start";
|
||||
case NoteType.HoldJoint:
|
||||
return "Hold Joint";
|
||||
case NoteType.HoldEnd:
|
||||
return "Hold End";
|
||||
case NoteType.MaskAdd:
|
||||
return "Mask Add";
|
||||
case NoteType.MaskRemove:
|
||||
return "Mask Remove";
|
||||
case NoteType.EndOfChart:
|
||||
return "End of Chart";
|
||||
case NoteType.Chain:
|
||||
return "Chain";
|
||||
case NoteType.TouchBonusFlair:
|
||||
return "Touch [R Note]";
|
||||
case NoteType.SnapRedBonusFlair:
|
||||
return "Snap (R) [R Note]";
|
||||
case NoteType.SnapBlueBonusFlair:
|
||||
return "Snap (B) [R Note]";
|
||||
case NoteType.SlideOrangeBonusFlair:
|
||||
return "Slide (O) [R Note]";
|
||||
case NoteType.SlideGreenBonusFlair:
|
||||
return "Slide (G) [R Note]";
|
||||
case NoteType.HoldStartBonusFlair:
|
||||
return "Hold Start [R Note]";
|
||||
case NoteType.ChainBonusFlair:
|
||||
return "Chain [R Note]";
|
||||
default:
|
||||
return "Undefined Note Type";
|
||||
}
|
||||
}
|
||||
|
||||
internal static string ToLabel(this GimmickType type)
|
||||
{
|
||||
switch (type)
|
||||
{
|
||||
case GimmickType.BpmChange:
|
||||
return "BPM Change";
|
||||
case GimmickType.TimeSignatureChange:
|
||||
return "Time Signature Change";
|
||||
case GimmickType.HiSpeedChange:
|
||||
return "Hi-Speed Change";
|
||||
case GimmickType.ReverseStart:
|
||||
return "Reverse Start";
|
||||
case GimmickType.ReverseMiddle:
|
||||
return "Reverse Middle";
|
||||
case GimmickType.ReverseEnd:
|
||||
return "Reverse Stop";
|
||||
case GimmickType.StopStart:
|
||||
return "Stop Start";
|
||||
case GimmickType.StopEnd:
|
||||
return "Stop End";
|
||||
default:
|
||||
return "Undefined Gimmick";
|
||||
}
|
||||
}
|
||||
|
||||
internal static bool HasDecimal(double num)
|
||||
{
|
||||
return Math.Ceiling(num) == Math.Floor(num);
|
||||
}
|
||||
|
||||
internal static Tuple<int, int> GetQuantization(int val, int min)
|
||||
{
|
||||
int numerator = val;
|
||||
int denominator = 1920;
|
||||
|
||||
int gcd = GetGcd(numerator, denominator);
|
||||
|
||||
numerator /= gcd;
|
||||
denominator /= gcd;
|
||||
|
||||
while (denominator < min)
|
||||
{
|
||||
numerator *= 2;
|
||||
denominator *= 2;
|
||||
}
|
||||
|
||||
return Tuple.Create(numerator, denominator);
|
||||
}
|
||||
|
||||
private static int GetGcd(int a, int b)
|
||||
{
|
||||
if (b == 0)
|
||||
return a;
|
||||
return GetGcd(b, (int)a % (int)b);
|
||||
}
|
||||
|
||||
internal static float GetDist(Point a, Point b)
|
||||
{
|
||||
return (float)Math.Sqrt(Math.Pow(a.X - b.X, 2) + Math.Pow(a.Y - b.Y, 2));
|
||||
}
|
||||
|
||||
internal static string KeyIntToString(int key)
|
||||
{
|
||||
// Gets the key name from the keycode
|
||||
string val = ((Keys)key).ToString();
|
||||
// Converts digit keycode into number instead of key name
|
||||
if (key >= 48 && key <= 57)
|
||||
{
|
||||
val = $"{key - 48}";
|
||||
}
|
||||
return val;
|
||||
}
|
||||
|
||||
internal static void AppendHotkey(this Button button, int key)
|
||||
{
|
||||
button.Text += $" ({KeyIntToString(key)})";
|
||||
}
|
||||
}
|
||||
}
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 83 KiB |
@@ -1,4 +1,5 @@
|
||||
# BAKKA-Editor
|
||||
# BAKKA Editor
|
||||
A Marvelously simple and scuffed editor.
|
||||
|
||||
Find me on discord for any issues @Goatgarien or submit them on the issues tab
|
||||
Find me on discord for any issues @Goatgarien in https://discord.gg/hDZtQ2tVcW
|
||||
or submit them on the issues tab.
|
||||
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Reference in New Issue
Block a user