import
BIN
Data/vsti/IMG/vsti_troll.jpg
Normal file
|
After Width: | Height: | Size: 128 KiB |
BIN
Data/vsti/IMG/vsti_troll.psd
Normal file
BIN
Data/vsti/IMG/vsti_troll_about_01.png
Normal file
|
After Width: | Height: | Size: 3.9 KiB |
BIN
Data/vsti/IMG/vsti_troll_about_02.png
Normal file
|
After Width: | Height: | Size: 4.9 KiB |
BIN
Data/vsti/IMG/vsti_troll_about_03.png
Normal file
|
After Width: | Height: | Size: 4.4 KiB |
BIN
Data/vsti/IMG/vsti_troll_ecran_grand.png
Normal file
|
After Width: | Height: | Size: 4.8 KiB |
BIN
Data/vsti/IMG/vsti_troll_ecran_petit.png
Normal file
|
After Width: | Height: | Size: 3.3 KiB |
BIN
Data/vsti/IMG/vsti_troll_export_01.png
Normal file
|
After Width: | Height: | Size: 4.0 KiB |
BIN
Data/vsti/IMG/vsti_troll_export_02.png
Normal file
|
After Width: | Height: | Size: 5.1 KiB |
BIN
Data/vsti/IMG/vsti_troll_export_03.png
Normal file
|
After Width: | Height: | Size: 4.4 KiB |
BIN
Data/vsti/IMG/vsti_troll_fond.tga
Normal file
|
After Width: | Height: | Size: 359 KiB |
BIN
Data/vsti/IMG/vsti_troll_import_01.png
Normal file
|
After Width: | Height: | Size: 3.9 KiB |
BIN
Data/vsti/IMG/vsti_troll_import_02.png
Normal file
|
After Width: | Height: | Size: 5.1 KiB |
BIN
Data/vsti/IMG/vsti_troll_import_03.png
Normal file
|
After Width: | Height: | Size: 4.4 KiB |
BIN
Data/vsti/IMG/vsti_troll_instru_milieu.png
Normal file
|
After Width: | Height: | Size: 3.3 KiB |
BIN
Data/vsti/IMG/vsti_troll_instru_moins.png
Normal file
|
After Width: | Height: | Size: 3.4 KiB |
BIN
Data/vsti/IMG/vsti_troll_instru_plus.png
Normal file
|
After Width: | Height: | Size: 3.4 KiB |
BIN
Data/vsti/IMG/vsti_troll_potar_big_01.png
Normal file
|
After Width: | Height: | Size: 6.2 KiB |
BIN
Data/vsti/IMG/vsti_troll_potar_big_02.png
Normal file
|
After Width: | Height: | Size: 6.2 KiB |
BIN
Data/vsti/IMG/vsti_troll_potar_medium_01.png
Normal file
|
After Width: | Height: | Size: 5.7 KiB |
BIN
Data/vsti/IMG/vsti_troll_potar_medium_02.png
Normal file
|
After Width: | Height: | Size: 5.8 KiB |
BIN
Data/vsti/IMG/vsti_troll_potar_small_01.png
Normal file
|
After Width: | Height: | Size: 5.0 KiB |
BIN
Data/vsti/IMG/vsti_troll_potar_small_02.png
Normal file
|
After Width: | Height: | Size: 5.0 KiB |
BIN
Data/vsti/IMG/vsti_troll_record_01.png
Normal file
|
After Width: | Height: | Size: 4.1 KiB |
BIN
Data/vsti/IMG/vsti_troll_record_02.png
Normal file
|
After Width: | Height: | Size: 5.2 KiB |
BIN
Data/vsti/IMG/vsti_troll_record_03.png
Normal file
|
After Width: | Height: | Size: 4.5 KiB |
BIN
Data/vsti/IMG/vsti_troll_slide_-1.png
Normal file
|
After Width: | Height: | Size: 3.8 KiB |
BIN
Data/vsti/IMG/vsti_troll_slide_-2.png
Normal file
|
After Width: | Height: | Size: 3.7 KiB |
BIN
Data/vsti/IMG/vsti_troll_slide_-3.png
Normal file
|
After Width: | Height: | Size: 3.6 KiB |
BIN
Data/vsti/IMG/vsti_troll_slide_0.png
Normal file
|
After Width: | Height: | Size: 3.7 KiB |
BIN
Data/vsti/IMG/vsti_troll_slide_1.png
Normal file
|
After Width: | Height: | Size: 3.7 KiB |
BIN
Data/vsti/IMG/vsti_troll_slide_2.png
Normal file
|
After Width: | Height: | Size: 3.7 KiB |
BIN
Data/vsti/IMG/vsti_troll_slide_3.png
Normal file
|
After Width: | Height: | Size: 3.6 KiB |
BIN
Data/vsti_troll_duty.jpg
Normal file
|
After Width: | Height: | Size: 66 KiB |
50
Data/yann.tracker.vst.infos.txt
Normal file
@@ -0,0 +1,50 @@
|
|||||||
|
== Sweep
|
||||||
|
Part d'une fr<66>quence donn<6E>e et qui s'arr<72>te sur la note
|
||||||
|
avec comme commande :
|
||||||
|
- le premier nombre fr<66>quence de d<>part (de 20 <20> 20000 Hz par exemple)
|
||||||
|
- et le deuxi<78>me temps du sweep (de 0 <20> 500 ms par exemple)
|
||||||
|
|
||||||
|
== Vibrato
|
||||||
|
- premier nombre = amplitude de la modulation <20> +/- 2 octaves (-24..+24)
|
||||||
|
- deuxi<78>me nombre = fr<66>quence de la modulation de 0.1Hz <20> 100Hz
|
||||||
|
(un multiple de la fr<66>quence de la note originale,
|
||||||
|
et en plus si possible la moiti<74> de cette fr<66>quence)
|
||||||
|
|
||||||
|
== Chord
|
||||||
|
une commande chord
|
||||||
|
chacun des nombres = nb de demi-tons <20> ajouter, comme dans lsdj
|
||||||
|
ou alors : premier nombre = deuxi<78>me note, et deuxi<78>me nombre = vitesse de l'arp<72>ge
|
||||||
|
-> par le tracker/s<>quenceur
|
||||||
|
|
||||||
|
== Pitch Bend
|
||||||
|
modification de la fr<66>quence entre -1 et +1 ton (-2 et +2 midi notes)
|
||||||
|
de la note actuellement jou<6F>e !
|
||||||
|
|
||||||
|
== Min/Max
|
||||||
|
attack(1, 255)
|
||||||
|
decay(1, 255)
|
||||||
|
sustain(0, 127)
|
||||||
|
release(1, 255)
|
||||||
|
sweeptime(1, 255)
|
||||||
|
sweepfreq(-127, 127) (en midinotes)
|
||||||
|
|
||||||
|
== Interface
|
||||||
|
Settings
|
||||||
|
Volume(0,127)
|
||||||
|
Panning(0,128)
|
||||||
|
Sweep
|
||||||
|
Time(0,255)
|
||||||
|
Start(-127,127)
|
||||||
|
Envelope
|
||||||
|
Attack(1,255)
|
||||||
|
Decay(1,255)
|
||||||
|
Sustain(0,127)
|
||||||
|
Release(1,255)
|
||||||
|
System
|
||||||
|
File
|
||||||
|
Record
|
||||||
|
Import (instruments)
|
||||||
|
Export (instruments)
|
||||||
|
Author
|
||||||
|
Name
|
||||||
|
Style
|
||||||
185
ExportCheck/ExportCheck/ExportCheck.vcproj
Normal file
@@ -0,0 +1,185 @@
|
|||||||
|
<?xml version="1.0" encoding="Windows-1252"?>
|
||||||
|
<VisualStudioProject
|
||||||
|
ProjectType="Visual C++"
|
||||||
|
Version="9,00"
|
||||||
|
Name="ExportCheck"
|
||||||
|
ProjectGUID="{12105306-A616-447D-9408-E32E91449AB2}"
|
||||||
|
RootNamespace="ExportCheck"
|
||||||
|
TargetFrameworkVersion="196613"
|
||||||
|
>
|
||||||
|
<Platforms>
|
||||||
|
<Platform
|
||||||
|
Name="Win32"
|
||||||
|
/>
|
||||||
|
</Platforms>
|
||||||
|
<ToolFiles>
|
||||||
|
</ToolFiles>
|
||||||
|
<Configurations>
|
||||||
|
<Configuration
|
||||||
|
Name="Debug|Win32"
|
||||||
|
OutputDirectory="$(SolutionDir)$(ConfigurationName)"
|
||||||
|
IntermediateDirectory="$(ConfigurationName)"
|
||||||
|
ConfigurationType="1"
|
||||||
|
CharacterSet="2"
|
||||||
|
>
|
||||||
|
<Tool
|
||||||
|
Name="VCPreBuildEventTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCCustomBuildTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCXMLDataGeneratorTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCWebServiceProxyGeneratorTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCMIDLTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCCLCompilerTool"
|
||||||
|
Optimization="0"
|
||||||
|
PreprocessorDefinitions="_CRT_SECURE_NO_WARNINGS"
|
||||||
|
MinimalRebuild="true"
|
||||||
|
BasicRuntimeChecks="3"
|
||||||
|
RuntimeLibrary="3"
|
||||||
|
WarningLevel="3"
|
||||||
|
DebugInformationFormat="4"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCManagedResourceCompilerTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCResourceCompilerTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCPreLinkEventTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCLinkerTool"
|
||||||
|
GenerateDebugInformation="true"
|
||||||
|
TargetMachine="1"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCALinkTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCManifestTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCXDCMakeTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCBscMakeTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCFxCopTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCAppVerifierTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCPostBuildEventTool"
|
||||||
|
/>
|
||||||
|
</Configuration>
|
||||||
|
<Configuration
|
||||||
|
Name="Release|Win32"
|
||||||
|
OutputDirectory="$(SolutionDir)$(ConfigurationName)"
|
||||||
|
IntermediateDirectory="$(ConfigurationName)"
|
||||||
|
ConfigurationType="1"
|
||||||
|
CharacterSet="2"
|
||||||
|
WholeProgramOptimization="1"
|
||||||
|
>
|
||||||
|
<Tool
|
||||||
|
Name="VCPreBuildEventTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCCustomBuildTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCXMLDataGeneratorTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCWebServiceProxyGeneratorTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCMIDLTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCCLCompilerTool"
|
||||||
|
Optimization="2"
|
||||||
|
EnableIntrinsicFunctions="true"
|
||||||
|
RuntimeLibrary="2"
|
||||||
|
EnableFunctionLevelLinking="true"
|
||||||
|
WarningLevel="3"
|
||||||
|
DebugInformationFormat="3"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCManagedResourceCompilerTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCResourceCompilerTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCPreLinkEventTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCLinkerTool"
|
||||||
|
GenerateDebugInformation="true"
|
||||||
|
OptimizeReferences="2"
|
||||||
|
EnableCOMDATFolding="2"
|
||||||
|
TargetMachine="1"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCALinkTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCManifestTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCXDCMakeTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCBscMakeTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCFxCopTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCAppVerifierTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCPostBuildEventTool"
|
||||||
|
/>
|
||||||
|
</Configuration>
|
||||||
|
</Configurations>
|
||||||
|
<References>
|
||||||
|
</References>
|
||||||
|
<Files>
|
||||||
|
<Filter
|
||||||
|
Name="Source Files"
|
||||||
|
Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx"
|
||||||
|
UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"
|
||||||
|
>
|
||||||
|
<File
|
||||||
|
RelativePath=".\main.cpp"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
</Filter>
|
||||||
|
<Filter
|
||||||
|
Name="Header Files"
|
||||||
|
Filter="h;hpp;hxx;hm;inl;inc;xsd"
|
||||||
|
UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"
|
||||||
|
>
|
||||||
|
</Filter>
|
||||||
|
<Filter
|
||||||
|
Name="Resource Files"
|
||||||
|
Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav"
|
||||||
|
UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}"
|
||||||
|
>
|
||||||
|
</Filter>
|
||||||
|
</Files>
|
||||||
|
<Globals>
|
||||||
|
</Globals>
|
||||||
|
</VisualStudioProject>
|
||||||
120
ExportCheck/ExportCheck/ExportCheck.vcxproj
Normal file
@@ -0,0 +1,120 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||||
|
<ItemGroup Label="ProjectConfigurations">
|
||||||
|
<ProjectConfiguration Include="Debug|Win32">
|
||||||
|
<Configuration>Debug</Configuration>
|
||||||
|
<Platform>Win32</Platform>
|
||||||
|
</ProjectConfiguration>
|
||||||
|
<ProjectConfiguration Include="NoGUI|Win32">
|
||||||
|
<Configuration>NoGUI</Configuration>
|
||||||
|
<Platform>Win32</Platform>
|
||||||
|
</ProjectConfiguration>
|
||||||
|
<ProjectConfiguration Include="Release|Win32">
|
||||||
|
<Configuration>Release</Configuration>
|
||||||
|
<Platform>Win32</Platform>
|
||||||
|
</ProjectConfiguration>
|
||||||
|
</ItemGroup>
|
||||||
|
<PropertyGroup Label="Globals">
|
||||||
|
<ProjectGuid>{12105306-A616-447D-9408-E32E91449AB2}</ProjectGuid>
|
||||||
|
<RootNamespace>ExportCheck</RootNamespace>
|
||||||
|
</PropertyGroup>
|
||||||
|
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
|
||||||
|
<ConfigurationType>Application</ConfigurationType>
|
||||||
|
<CharacterSet>MultiByte</CharacterSet>
|
||||||
|
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='NoGUI|Win32'" Label="Configuration">
|
||||||
|
<ConfigurationType>Application</ConfigurationType>
|
||||||
|
<CharacterSet>MultiByte</CharacterSet>
|
||||||
|
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
|
||||||
|
<ConfigurationType>Application</ConfigurationType>
|
||||||
|
<CharacterSet>MultiByte</CharacterSet>
|
||||||
|
</PropertyGroup>
|
||||||
|
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
||||||
|
<ImportGroup Label="ExtensionSettings">
|
||||||
|
</ImportGroup>
|
||||||
|
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets">
|
||||||
|
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||||
|
</ImportGroup>
|
||||||
|
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='NoGUI|Win32'" Label="PropertySheets">
|
||||||
|
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||||
|
</ImportGroup>
|
||||||
|
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets">
|
||||||
|
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||||
|
</ImportGroup>
|
||||||
|
<PropertyGroup Label="UserMacros" />
|
||||||
|
<PropertyGroup>
|
||||||
|
<_ProjectFileVersion>10.0.40219.1</_ProjectFileVersion>
|
||||||
|
<OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(SolutionDir)$(Configuration)\</OutDir>
|
||||||
|
<IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(Configuration)\</IntDir>
|
||||||
|
<OutDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(SolutionDir)$(Configuration)\</OutDir>
|
||||||
|
<OutDir Condition="'$(Configuration)|$(Platform)'=='NoGUI|Win32'">$(SolutionDir)$(Configuration)\</OutDir>
|
||||||
|
<IntDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(Configuration)\</IntDir>
|
||||||
|
<IntDir Condition="'$(Configuration)|$(Platform)'=='NoGUI|Win32'">$(Configuration)\</IntDir>
|
||||||
|
<CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">AllRules.ruleset</CodeAnalysisRuleSet>
|
||||||
|
<CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" />
|
||||||
|
<CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" />
|
||||||
|
<CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">AllRules.ruleset</CodeAnalysisRuleSet>
|
||||||
|
<CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='NoGUI|Win32'">AllRules.ruleset</CodeAnalysisRuleSet>
|
||||||
|
<CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" />
|
||||||
|
<CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='NoGUI|Win32'" />
|
||||||
|
<CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" />
|
||||||
|
<CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='NoGUI|Win32'" />
|
||||||
|
</PropertyGroup>
|
||||||
|
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||||
|
<ClCompile>
|
||||||
|
<Optimization>Disabled</Optimization>
|
||||||
|
<PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||||
|
<MinimalRebuild>true</MinimalRebuild>
|
||||||
|
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
|
||||||
|
<RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
|
||||||
|
<WarningLevel>Level3</WarningLevel>
|
||||||
|
<DebugInformationFormat>EditAndContinue</DebugInformationFormat>
|
||||||
|
</ClCompile>
|
||||||
|
<Link>
|
||||||
|
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||||
|
<TargetMachine>MachineX86</TargetMachine>
|
||||||
|
</Link>
|
||||||
|
</ItemDefinitionGroup>
|
||||||
|
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||||
|
<ClCompile>
|
||||||
|
<Optimization>MaxSpeed</Optimization>
|
||||||
|
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||||
|
<RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
|
||||||
|
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||||
|
<WarningLevel>Level3</WarningLevel>
|
||||||
|
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
|
||||||
|
</ClCompile>
|
||||||
|
<Link>
|
||||||
|
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||||
|
<OptimizeReferences>true</OptimizeReferences>
|
||||||
|
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||||
|
<TargetMachine>MachineX86</TargetMachine>
|
||||||
|
</Link>
|
||||||
|
</ItemDefinitionGroup>
|
||||||
|
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='NoGUI|Win32'">
|
||||||
|
<ClCompile>
|
||||||
|
<Optimization>MaxSpeed</Optimization>
|
||||||
|
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||||
|
<RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
|
||||||
|
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||||
|
<WarningLevel>Level3</WarningLevel>
|
||||||
|
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
|
||||||
|
</ClCompile>
|
||||||
|
<Link>
|
||||||
|
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||||
|
<OptimizeReferences>true</OptimizeReferences>
|
||||||
|
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||||
|
<TargetMachine>MachineX86</TargetMachine>
|
||||||
|
</Link>
|
||||||
|
</ItemDefinitionGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<ClCompile Include="main.cpp" />
|
||||||
|
</ItemGroup>
|
||||||
|
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||||
|
<ImportGroup Label="ExtensionTargets">
|
||||||
|
</ImportGroup>
|
||||||
|
</Project>
|
||||||
3
ExportCheck/ExportCheck/ExportCheck.vcxproj.user
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||||
|
</Project>
|
||||||
177
ExportCheck/ExportCheck/main.cpp
Normal file
@@ -0,0 +1,177 @@
|
|||||||
|
#pragma pack(push, 1)
|
||||||
|
struct InstrumentParameters
|
||||||
|
{
|
||||||
|
typedef enum {
|
||||||
|
VOLUME,
|
||||||
|
PANNING,
|
||||||
|
DETUNE,
|
||||||
|
ENVELOPE_ATTACK,
|
||||||
|
ENVELOPE_DECAY,
|
||||||
|
ENVELOPE_SUSTAIN,
|
||||||
|
ENVELOPE_RELEASE,
|
||||||
|
DUTY,
|
||||||
|
PORTAMENTO_LENGTH,
|
||||||
|
ARPEGGIO,
|
||||||
|
SWEEP_LENGTH,
|
||||||
|
SWEEP_OFFSET,
|
||||||
|
MODULATION_AMPLITUDE,
|
||||||
|
MODULATION_FREQUENCY,
|
||||||
|
TREMOLO_AMPLITUDE,
|
||||||
|
TREMOLO_FREQUENCY,
|
||||||
|
LAST,
|
||||||
|
NOTEON = 29, // for export
|
||||||
|
NOTEOFF = 30, // for export
|
||||||
|
END = 31 // for export
|
||||||
|
};
|
||||||
|
|
||||||
|
unsigned char iVolume;
|
||||||
|
unsigned char iPanning;
|
||||||
|
signed char iDetune;
|
||||||
|
unsigned char iDuty;
|
||||||
|
|
||||||
|
struct {
|
||||||
|
unsigned char iAttack; // 1..255
|
||||||
|
unsigned char iDecay; // 1..255
|
||||||
|
unsigned char iSustain; // 0..127
|
||||||
|
unsigned char iRelease; // 1..255
|
||||||
|
} Envelope;
|
||||||
|
|
||||||
|
struct {
|
||||||
|
unsigned char iAmplitude;
|
||||||
|
unsigned char iFrequency;
|
||||||
|
} Tremolo;
|
||||||
|
|
||||||
|
unsigned char iPortamentoLength;
|
||||||
|
|
||||||
|
struct {
|
||||||
|
unsigned char iLength;
|
||||||
|
signed short iOffset;
|
||||||
|
} Sweep;
|
||||||
|
|
||||||
|
struct {
|
||||||
|
unsigned char iAmplitude;
|
||||||
|
unsigned char iFrequency;
|
||||||
|
} Modulation;
|
||||||
|
|
||||||
|
unsigned char iArpeggio;
|
||||||
|
unsigned char pad;
|
||||||
|
|
||||||
|
InstrumentParameters();
|
||||||
|
};
|
||||||
|
#pragma pack(pop)
|
||||||
|
|
||||||
|
InstrumentParameters::InstrumentParameters()
|
||||||
|
: iVolume(64),
|
||||||
|
iPanning(64),
|
||||||
|
iDetune(0),
|
||||||
|
iDuty(0),
|
||||||
|
iPortamentoLength(0),
|
||||||
|
iArpeggio(0)
|
||||||
|
{
|
||||||
|
Envelope.iAttack = 2;
|
||||||
|
Envelope.iDecay = 16;
|
||||||
|
Envelope.iSustain = 64;
|
||||||
|
Envelope.iRelease = 5;
|
||||||
|
Tremolo.iAmplitude = 0;
|
||||||
|
Tremolo.iFrequency = 0;
|
||||||
|
Sweep.iOffset = 0;
|
||||||
|
Sweep.iLength = 0;
|
||||||
|
Modulation.iAmplitude = 0;
|
||||||
|
Modulation.iFrequency = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
#pragma pack(push, 1)
|
||||||
|
struct Command
|
||||||
|
{
|
||||||
|
unsigned int iFrame : 24;
|
||||||
|
unsigned int iChannel : 3;
|
||||||
|
unsigned int iCommand : 5; // 0-14 = parameters, 29 = note on, 30 = note off, 31 = song end
|
||||||
|
int iValue;
|
||||||
|
};
|
||||||
|
#pragma pack(pop)
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <windows.h>
|
||||||
|
|
||||||
|
const char * GetCommandName(int c)
|
||||||
|
{
|
||||||
|
static const char * pParameterName[InstrumentParameters::LAST] = { "vol", "pan", "dtune", "attck", "decay", "sustn", "rlz", "duty", "porta", "arp", "swlen", "swofs", "mdamp", "mdfrq", "tmamp", "tmfrq" };
|
||||||
|
if ( c < InstrumentParameters::LAST )
|
||||||
|
return pParameterName[c];
|
||||||
|
if ( c == InstrumentParameters::NOTEOFF )
|
||||||
|
return "note off";
|
||||||
|
if ( c == InstrumentParameters::NOTEON )
|
||||||
|
return "note on";
|
||||||
|
if ( c == InstrumentParameters::END )
|
||||||
|
return "end";
|
||||||
|
return "WTF?";
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(int argc, char ** argv)
|
||||||
|
{
|
||||||
|
if ( argc == 2 )
|
||||||
|
{
|
||||||
|
FILE * f = fopen(argv[1], "rb");
|
||||||
|
if ( f )
|
||||||
|
{
|
||||||
|
fseek(f, 0, SEEK_END);
|
||||||
|
int size = ftell(f);
|
||||||
|
fseek(f, 0, SEEK_SET);
|
||||||
|
|
||||||
|
unsigned char * buf = new unsigned char[size];
|
||||||
|
|
||||||
|
fread(buf, 1, size, f);
|
||||||
|
|
||||||
|
char txtpath[MAX_PATH];
|
||||||
|
strcpy(txtpath, argv[1]);
|
||||||
|
strcat(txtpath, ".txt");
|
||||||
|
FILE * txt = fopen(txtpath, "w");
|
||||||
|
|
||||||
|
InstrumentParameters * pParameters = (InstrumentParameters *) buf;
|
||||||
|
Command * pCommands = (Command *) (buf+sizeof(InstrumentParameters)*8);
|
||||||
|
|
||||||
|
for ( int i = 0 ; i < 8 ; i++ )
|
||||||
|
{
|
||||||
|
fprintf(txt, "Instrument %d\n", i);
|
||||||
|
fprintf(txt, " Volume %d\n", pParameters[i].iVolume);
|
||||||
|
fprintf(txt, " Panning %d\n", pParameters[i].iPanning-64);
|
||||||
|
fprintf(txt, " Detune %d\n", pParameters[i].iDetune);
|
||||||
|
fprintf(txt, " Duty %d\n", pParameters[i].iDuty);
|
||||||
|
fprintf(txt, " Attack %d\n", pParameters[i].Envelope.iAttack);
|
||||||
|
fprintf(txt, " Decay %d\n", pParameters[i].Envelope.iDecay);
|
||||||
|
fprintf(txt, " Sustain %d\n", pParameters[i].Envelope.iSustain);
|
||||||
|
fprintf(txt, " Release %d\n", pParameters[i].Envelope.iRelease);
|
||||||
|
fprintf(txt, " Tremolo amp %d\n", pParameters[i].Tremolo.iAmplitude);
|
||||||
|
fprintf(txt, " Tremolo frq %d\n", pParameters[i].Tremolo.iFrequency);
|
||||||
|
fprintf(txt, " Sweep len %d\n", pParameters[i].Sweep.iLength);
|
||||||
|
fprintf(txt, " Sweep ofs %3.2f\n", pParameters[i].Sweep.iOffset / 16.0f);
|
||||||
|
fprintf(txt, " Modulation amp %d\n", pParameters[i].Modulation.iAmplitude);
|
||||||
|
fprintf(txt, " Modulation frq %d\n", pParameters[i].Modulation.iFrequency);
|
||||||
|
fprintf(txt, " Portamento %d\n", pParameters[i].iPortamentoLength);
|
||||||
|
fprintf(txt, " Arpeggio %d\n", pParameters[i].iArpeggio);
|
||||||
|
}
|
||||||
|
|
||||||
|
fputs("\n", txt);
|
||||||
|
fputs("Commands\n", txt);
|
||||||
|
fputs(" [delta t] cha command value\n\n", txt);
|
||||||
|
|
||||||
|
while ( pCommands->iCommand != InstrumentParameters::END )
|
||||||
|
{
|
||||||
|
fprintf(txt, " [%7d] %3d %10s ", pCommands->iFrame, pCommands->iChannel, GetCommandName(pCommands->iCommand));
|
||||||
|
if ( pCommands->iCommand < InstrumentParameters::LAST )
|
||||||
|
fprintf(txt, "%10d\n", pCommands->iValue);
|
||||||
|
else if ( pCommands->iCommand == InstrumentParameters::NOTEON ) //(iNote * 16 /*+ pEvent->detune*/) | (iVelocity << 16);
|
||||||
|
fprintf(txt, "%3.2f %d\n", (pCommands->iValue & 0xFFFF) / 16.0f, (pCommands->iValue >> 16) & 0x7F);
|
||||||
|
else
|
||||||
|
fprintf(txt, "\n");
|
||||||
|
pCommands++;
|
||||||
|
}
|
||||||
|
|
||||||
|
delete[] buf;
|
||||||
|
fclose(f);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
31
NitroSynth.sln
Normal file
@@ -0,0 +1,31 @@
|
|||||||
|
|
||||||
|
Microsoft Visual Studio Solution File, Format Version 11.00
|
||||||
|
# Visual Studio 2010
|
||||||
|
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "NitroSynth", "NitroSynth\NitroSynth.vcxproj", "{2501786E-30DD-44A8-90D6-3E91417566A1}"
|
||||||
|
EndProject
|
||||||
|
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ExportCheck", "ExportCheck\ExportCheck\ExportCheck.vcxproj", "{12105306-A616-447D-9408-E32E91449AB2}"
|
||||||
|
EndProject
|
||||||
|
Global
|
||||||
|
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||||
|
Debug|Win32 = Debug|Win32
|
||||||
|
NoGUI|Win32 = NoGUI|Win32
|
||||||
|
Release|Win32 = Release|Win32
|
||||||
|
EndGlobalSection
|
||||||
|
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||||
|
{2501786E-30DD-44A8-90D6-3E91417566A1}.Debug|Win32.ActiveCfg = Debug|Win32
|
||||||
|
{2501786E-30DD-44A8-90D6-3E91417566A1}.Debug|Win32.Build.0 = Debug|Win32
|
||||||
|
{2501786E-30DD-44A8-90D6-3E91417566A1}.NoGUI|Win32.ActiveCfg = NoGUI|Win32
|
||||||
|
{2501786E-30DD-44A8-90D6-3E91417566A1}.NoGUI|Win32.Build.0 = NoGUI|Win32
|
||||||
|
{2501786E-30DD-44A8-90D6-3E91417566A1}.Release|Win32.ActiveCfg = Release|Win32
|
||||||
|
{2501786E-30DD-44A8-90D6-3E91417566A1}.Release|Win32.Build.0 = Release|Win32
|
||||||
|
{12105306-A616-447D-9408-E32E91449AB2}.Debug|Win32.ActiveCfg = Debug|Win32
|
||||||
|
{12105306-A616-447D-9408-E32E91449AB2}.Debug|Win32.Build.0 = Debug|Win32
|
||||||
|
{12105306-A616-447D-9408-E32E91449AB2}.NoGUI|Win32.ActiveCfg = NoGUI|Win32
|
||||||
|
{12105306-A616-447D-9408-E32E91449AB2}.NoGUI|Win32.Build.0 = NoGUI|Win32
|
||||||
|
{12105306-A616-447D-9408-E32E91449AB2}.Release|Win32.ActiveCfg = Release|Win32
|
||||||
|
{12105306-A616-447D-9408-E32E91449AB2}.Release|Win32.Build.0 = Release|Win32
|
||||||
|
EndGlobalSection
|
||||||
|
GlobalSection(SolutionProperties) = preSolution
|
||||||
|
HideSolutionNode = FALSE
|
||||||
|
EndGlobalSection
|
||||||
|
EndGlobal
|
||||||
81
NitroSynth/Envelope.cpp
Normal file
@@ -0,0 +1,81 @@
|
|||||||
|
#include "Envelope.h"
|
||||||
|
#include "Instrument.h"
|
||||||
|
|
||||||
|
#define MAX_VOLUME 512
|
||||||
|
|
||||||
|
Envelope::Envelope()
|
||||||
|
: iTime(0),
|
||||||
|
iLastEnvelope(0),
|
||||||
|
iVelocity(0),
|
||||||
|
iState(RELEASE)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned int Envelope::Compute(InstrumentParameters * pParameters)
|
||||||
|
{
|
||||||
|
unsigned int iEnvelope = 0;
|
||||||
|
|
||||||
|
int iAttack = pParameters->Envelope.iAttack;
|
||||||
|
int iDecay = pParameters->Envelope.iDecay;
|
||||||
|
int iSustain = pParameters->Envelope.iSustain * MAX_VOLUME / 127;
|
||||||
|
int iRelease = pParameters->Envelope.iRelease;
|
||||||
|
|
||||||
|
iTime++;
|
||||||
|
|
||||||
|
switch ( iState )
|
||||||
|
{
|
||||||
|
case ATTACK:
|
||||||
|
{
|
||||||
|
iEnvelope = (iTime * MAX_VOLUME) / iAttack;
|
||||||
|
if ( iTime >= iAttack ) {
|
||||||
|
iTime = 0;
|
||||||
|
iState = DECAY;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case DECAY:
|
||||||
|
{
|
||||||
|
int s = MAX_VOLUME - iSustain;
|
||||||
|
iEnvelope = iSustain + s - ((iTime * s) / iDecay);
|
||||||
|
if ( iTime >= iDecay ) {
|
||||||
|
iTime = 0;
|
||||||
|
iState = SUSTAIN;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case SUSTAIN:
|
||||||
|
{
|
||||||
|
iEnvelope = iSustain;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case RELEASE:
|
||||||
|
{
|
||||||
|
if ( iTime <= iRelease )
|
||||||
|
iEnvelope = iLastEnvelope - ((iTime * iLastEnvelope) / iRelease);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( iState != RELEASE )
|
||||||
|
iLastEnvelope = iEnvelope;
|
||||||
|
|
||||||
|
iEnvelope = iEnvelope * iVelocity / 127;
|
||||||
|
|
||||||
|
return iEnvelope / (MAX_VOLUME / 128);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Envelope::NoteOff()
|
||||||
|
{
|
||||||
|
iTime = 0;
|
||||||
|
iState = RELEASE;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Envelope::NoteOn(int v)
|
||||||
|
{
|
||||||
|
iVelocity = v;
|
||||||
|
iTime = 0;
|
||||||
|
iState = ATTACK;
|
||||||
|
}
|
||||||
29
NitroSynth/Envelope.h
Normal file
@@ -0,0 +1,29 @@
|
|||||||
|
#ifndef _ENVELOPE_H_
|
||||||
|
#define _ENVELOPE_H_
|
||||||
|
|
||||||
|
struct InstrumentParameters;
|
||||||
|
|
||||||
|
class Envelope
|
||||||
|
{
|
||||||
|
typedef enum State
|
||||||
|
{
|
||||||
|
ATTACK, DECAY, SUSTAIN, RELEASE
|
||||||
|
};
|
||||||
|
|
||||||
|
int iTime;
|
||||||
|
int iLastEnvelope;
|
||||||
|
|
||||||
|
int iVelocity;
|
||||||
|
|
||||||
|
State iState;
|
||||||
|
|
||||||
|
public:
|
||||||
|
Envelope();
|
||||||
|
|
||||||
|
unsigned int Compute(InstrumentParameters * pParameters);
|
||||||
|
|
||||||
|
void NoteOn(int velocity);
|
||||||
|
void NoteOff();
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // _ENVELOPE_H_
|
||||||
4
NitroSynth/Export.def
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
LIBRARY "NitroSynth"
|
||||||
|
EXPORTS
|
||||||
|
VSTPluginMain
|
||||||
|
main=VSTPluginMain
|
||||||
137
NitroSynth/Instrument.cpp
Normal file
@@ -0,0 +1,137 @@
|
|||||||
|
#include "Instrument.h"
|
||||||
|
#include "Utils.h"
|
||||||
|
|
||||||
|
Instrument::Instrument(PSG* pSoundGenerator, InstrumentParameters* pParameters)
|
||||||
|
: pParameters(pParameters),
|
||||||
|
pSoundGenerator(pSoundGenerator),
|
||||||
|
fTime(0.0f),
|
||||||
|
iLastEnvelope(0),
|
||||||
|
iLastFrequency(0),
|
||||||
|
iLastNote(-1),
|
||||||
|
iNbFrequencies(0),
|
||||||
|
iFrequency(0),
|
||||||
|
iArpeggioTimer(0),
|
||||||
|
iEffectTimer(0),
|
||||||
|
iSweepFrequency(0),
|
||||||
|
iModulationAmplitude(0),
|
||||||
|
iPortamentoFrequency(0),
|
||||||
|
iNoteCounter(0)
|
||||||
|
{
|
||||||
|
pFrequencies[0] = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
Instrument::~Instrument()
|
||||||
|
{
|
||||||
|
delete pSoundGenerator;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Instrument::Compute(float dt, int & iLeft, int & iRight)
|
||||||
|
{
|
||||||
|
fTime += dt;
|
||||||
|
|
||||||
|
if ( fTime > 1.0f / 60.0f )
|
||||||
|
{
|
||||||
|
fTime -= 1.0f/60.0f;
|
||||||
|
|
||||||
|
int iVolume = pParameters->iVolume;
|
||||||
|
if ( pParameters->Tremolo.iAmplitude != 0 )
|
||||||
|
{
|
||||||
|
int iSin = Sinus(iEffectTimer * 12868 * pParameters->Tremolo.iFrequency / 256) / 2 + 2048;
|
||||||
|
int iAmplitude = pParameters->Tremolo.iAmplitude * pParameters->iVolume / 255;
|
||||||
|
iVolume -= iSin * iAmplitude / 4096;
|
||||||
|
}
|
||||||
|
|
||||||
|
iLastEnvelope = oEnvelope.Compute(pParameters) * iVolume / 127;
|
||||||
|
|
||||||
|
if ( pParameters->iArpeggio > 0 )
|
||||||
|
{
|
||||||
|
iArpeggioTimer++;
|
||||||
|
if ( iArpeggioTimer >= pParameters->iArpeggio )
|
||||||
|
{
|
||||||
|
iArpeggioTimer = 0;
|
||||||
|
iFrequency++;
|
||||||
|
if ( iFrequency >= iNbFrequencies )
|
||||||
|
iFrequency = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
iEffectTimer++;
|
||||||
|
|
||||||
|
int iSweep = 0;
|
||||||
|
if ( pParameters->Sweep.iLength != 0 && iEffectTimer < pParameters->Sweep.iLength )
|
||||||
|
iSweep = iSweepFrequency - (iEffectTimer * iSweepFrequency) / pParameters->Sweep.iLength;
|
||||||
|
|
||||||
|
int iModulation = Sinus(iEffectTimer * 12868 * pParameters->Modulation.iFrequency / 256) * iModulationAmplitude / 4096;
|
||||||
|
|
||||||
|
int iPortamento = 0;
|
||||||
|
if ( pParameters->iPortamentoLength != 0 && iEffectTimer < pParameters->iPortamentoLength )
|
||||||
|
iPortamento = iPortamentoFrequency - (iEffectTimer * iPortamentoFrequency) / pParameters->iPortamentoLength;
|
||||||
|
|
||||||
|
iLastFrequency = pFrequencies[iFrequency] + iSweep + iModulation + iPortamento;
|
||||||
|
}
|
||||||
|
|
||||||
|
pSoundGenerator->SetDuty(pParameters->iDuty);
|
||||||
|
pSoundGenerator->SetFrequency(iLastFrequency);
|
||||||
|
|
||||||
|
signed short iSample = pSoundGenerator->Compute(dt);
|
||||||
|
iSample = iSample * iLastEnvelope / 128;
|
||||||
|
|
||||||
|
iRight += iSample * pParameters->iPanning / 128;
|
||||||
|
iLeft += iSample * (128 - pParameters->iPanning) / 128;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Instrument::NoteOn(int iNote, int iVelocity)
|
||||||
|
{
|
||||||
|
iLastNote = iNote;
|
||||||
|
int n = iNote + pParameters->iDetune;
|
||||||
|
|
||||||
|
oEnvelope.NoteOn(iVelocity);
|
||||||
|
|
||||||
|
if ( iEffectTimer < 3
|
||||||
|
&& iNbFrequencies <= sizeof(pFrequencies)/sizeof(pFrequencies[0]) )
|
||||||
|
{
|
||||||
|
// Arpeggio !
|
||||||
|
pFrequencies[iNbFrequencies++] = MidiNoteToFrequency(n);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
pFrequencies[0] = MidiNoteToFrequency(n);
|
||||||
|
iNbFrequencies = 1;
|
||||||
|
iArpeggioTimer = 0;
|
||||||
|
iEffectTimer = 0;
|
||||||
|
iFrequency = 0;
|
||||||
|
if ( iLastFrequency == 0 )
|
||||||
|
iLastFrequency = pFrequencies[0];
|
||||||
|
iPortamentoFrequency = iLastFrequency - pFrequencies[0];
|
||||||
|
iSweepFrequency = MidiNoteToFrequency(n + pParameters->Sweep.iOffset) - pFrequencies[0];
|
||||||
|
iModulationAmplitude = MidiNoteToFrequency(n + pParameters->Modulation.iAmplitude) - pFrequencies[0];
|
||||||
|
}
|
||||||
|
iNoteCounter++;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Instrument::NoteOff(int iNote)
|
||||||
|
{
|
||||||
|
iNoteCounter--;
|
||||||
|
if ( iNoteCounter == 0 )
|
||||||
|
oEnvelope.NoteOff();
|
||||||
|
}
|
||||||
|
|
||||||
|
InstrumentParameters::InstrumentParameters()
|
||||||
|
: iVolume(64),
|
||||||
|
iPanning(64),
|
||||||
|
iDetune(0),
|
||||||
|
iDuty(0),
|
||||||
|
iPortamentoLength(0),
|
||||||
|
iArpeggio(0)
|
||||||
|
{
|
||||||
|
Envelope.iAttack = 2;
|
||||||
|
Envelope.iDecay = 16;
|
||||||
|
Envelope.iSustain = 64;
|
||||||
|
Envelope.iRelease = 5;
|
||||||
|
Tremolo.iAmplitude = 0;
|
||||||
|
Tremolo.iFrequency = 0;
|
||||||
|
Sweep.iOffset = 0;
|
||||||
|
Sweep.iLength = 0;
|
||||||
|
Modulation.iAmplitude = 0;
|
||||||
|
Modulation.iFrequency = 0;
|
||||||
|
}
|
||||||
103
NitroSynth/Instrument.h
Normal file
@@ -0,0 +1,103 @@
|
|||||||
|
#ifndef _INSTRUMENT_H_
|
||||||
|
#define _INSTRUMENT_H_
|
||||||
|
|
||||||
|
#include "PSG.h"
|
||||||
|
#include "Envelope.h"
|
||||||
|
|
||||||
|
#pragma pack(push, 1)
|
||||||
|
struct InstrumentParameters
|
||||||
|
{
|
||||||
|
typedef enum {
|
||||||
|
VOLUME,
|
||||||
|
PANNING,
|
||||||
|
DETUNE,
|
||||||
|
ENVELOPE_ATTACK,
|
||||||
|
ENVELOPE_DECAY,
|
||||||
|
ENVELOPE_SUSTAIN,
|
||||||
|
ENVELOPE_RELEASE,
|
||||||
|
DUTY,
|
||||||
|
PORTAMENTO_LENGTH,
|
||||||
|
ARPEGGIO,
|
||||||
|
SWEEP_LENGTH,
|
||||||
|
SWEEP_OFFSET,
|
||||||
|
MODULATION_AMPLITUDE,
|
||||||
|
MODULATION_FREQUENCY,
|
||||||
|
TREMOLO_AMPLITUDE,
|
||||||
|
TREMOLO_FREQUENCY,
|
||||||
|
LAST,
|
||||||
|
NOTEON = 29, // for export
|
||||||
|
NOTEOFF = 30, // for export
|
||||||
|
END = 31 // for export
|
||||||
|
};
|
||||||
|
|
||||||
|
unsigned char iVolume;
|
||||||
|
unsigned char iPanning;
|
||||||
|
signed char iDetune;
|
||||||
|
unsigned char iDuty;
|
||||||
|
|
||||||
|
struct {
|
||||||
|
unsigned char iAttack; // 1..255
|
||||||
|
unsigned char iDecay; // 1..255
|
||||||
|
unsigned char iSustain; // 0..127
|
||||||
|
unsigned char iRelease; // 1..255
|
||||||
|
} Envelope;
|
||||||
|
|
||||||
|
struct {
|
||||||
|
unsigned char iAmplitude;
|
||||||
|
unsigned char iFrequency;
|
||||||
|
} Tremolo;
|
||||||
|
|
||||||
|
unsigned char iPortamentoLength;
|
||||||
|
|
||||||
|
struct {
|
||||||
|
unsigned char iLength;
|
||||||
|
signed short iOffset;
|
||||||
|
} Sweep;
|
||||||
|
|
||||||
|
struct {
|
||||||
|
unsigned char iAmplitude;
|
||||||
|
unsigned char iFrequency;
|
||||||
|
} Modulation;
|
||||||
|
|
||||||
|
unsigned char iArpeggio;
|
||||||
|
unsigned char pad;
|
||||||
|
|
||||||
|
InstrumentParameters();
|
||||||
|
};
|
||||||
|
#pragma pack(pop)
|
||||||
|
|
||||||
|
class Instrument {
|
||||||
|
InstrumentParameters* pParameters;
|
||||||
|
|
||||||
|
PSG* pSoundGenerator;
|
||||||
|
Envelope oEnvelope;
|
||||||
|
|
||||||
|
float fTime;
|
||||||
|
unsigned int iLastEnvelope;
|
||||||
|
int iLastFrequency;
|
||||||
|
int iLastNote;
|
||||||
|
|
||||||
|
unsigned int pFrequencies[8];
|
||||||
|
unsigned int iNbFrequencies;
|
||||||
|
unsigned int iFrequency;
|
||||||
|
unsigned int iArpeggioTimer;
|
||||||
|
int iEffectTimer;
|
||||||
|
int iSweepFrequency;
|
||||||
|
int iModulationAmplitude;
|
||||||
|
int iPortamentoFrequency;
|
||||||
|
|
||||||
|
int iNoteCounter;
|
||||||
|
|
||||||
|
public:
|
||||||
|
Instrument(PSG* pSoundGenerator, InstrumentParameters* pParameters);
|
||||||
|
~Instrument();
|
||||||
|
|
||||||
|
void Compute(float dt, int & iLeft, int & iRight);
|
||||||
|
|
||||||
|
void NoteOn(int iNote, int iVelocity);
|
||||||
|
void NoteOff(int iNote);
|
||||||
|
|
||||||
|
void SetParameters(InstrumentParameters* p) { pParameters = p; }
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // _INSTRUMENT_H_
|
||||||
6
NitroSynth/Main.cpp
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
#include "NitroSynth.h"
|
||||||
|
|
||||||
|
AudioEffect* createEffectInstance(audioMasterCallback pCallback)
|
||||||
|
{
|
||||||
|
return new NitroSynth(pCallback);
|
||||||
|
}
|
||||||
BIN
NitroSynth/NitroSynth.aps
Normal file
502
NitroSynth/NitroSynth.cpp
Normal file
@@ -0,0 +1,502 @@
|
|||||||
|
#include "NitroSynth.h"
|
||||||
|
#ifndef NO_VST_GUI
|
||||||
|
#include "NitroSynthInterface.h"
|
||||||
|
#endif // NO_VST_GUI
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <math.h>
|
||||||
|
|
||||||
|
NitroSynth::NitroSynth(audioMasterCallback pCallback)
|
||||||
|
: AudioEffectX(pCallback, 0, 128),
|
||||||
|
fSamplePeriod(1.0f/44100.0f),
|
||||||
|
bRecording(false),
|
||||||
|
iRecorderState(IDLE)
|
||||||
|
{
|
||||||
|
if ( pCallback )
|
||||||
|
{
|
||||||
|
setNumInputs(0);
|
||||||
|
setNumOutputs(2);
|
||||||
|
canProcessReplacing();
|
||||||
|
isSynth();
|
||||||
|
setUniqueID('SRTN');
|
||||||
|
}
|
||||||
|
|
||||||
|
for ( int i = 0 ; i < 8 ; i++ )
|
||||||
|
if ( i < 6 )
|
||||||
|
pInstruments[i] = new Instrument(new WaveDuty(), & pParameters[i]);
|
||||||
|
else
|
||||||
|
pInstruments[i] = new Instrument(new Noise(), & pParameters[i]);
|
||||||
|
|
||||||
|
#ifndef NO_VST_GUI
|
||||||
|
setEditor(new NitroSynthInterface(this));
|
||||||
|
#endif // NO_VST_GUI
|
||||||
|
}
|
||||||
|
|
||||||
|
NitroSynth::~NitroSynth()
|
||||||
|
{
|
||||||
|
for ( int i = 0 ; i < 8 ; i++ )
|
||||||
|
delete pInstruments[i];
|
||||||
|
|
||||||
|
#ifndef NO_VST_GUI
|
||||||
|
if ( editor )
|
||||||
|
{
|
||||||
|
delete editor;
|
||||||
|
editor = 0;
|
||||||
|
}
|
||||||
|
#endif // NO_VST_GUI
|
||||||
|
}
|
||||||
|
|
||||||
|
void NitroSynth::processReplacing(float** pInput, float** pOutput, VstInt32 iSamples)
|
||||||
|
{
|
||||||
|
float* pLeft = pOutput[0];
|
||||||
|
float* pRight = pOutput[1];
|
||||||
|
|
||||||
|
VstTimeInfo* pTimeInfo = getTimeInfo(0);
|
||||||
|
|
||||||
|
for ( int i = 0 ; i < iSamples ; i++ )
|
||||||
|
{
|
||||||
|
while ( oEvents.size() != 0 && oEvents.front().iDeltaFrames == i )
|
||||||
|
{
|
||||||
|
MidiNote oEvent = oEvents.front();
|
||||||
|
int iNote = oEvent.iNote * 16;
|
||||||
|
|
||||||
|
if ( oEvent.bNoteOn )
|
||||||
|
pInstruments[oEvent.iChannel]->NoteOn(iNote, oEvent.iVelocity);
|
||||||
|
else
|
||||||
|
pInstruments[oEvent.iChannel]->NoteOff(iNote);
|
||||||
|
|
||||||
|
if ( bRecording )
|
||||||
|
{
|
||||||
|
double fTime = (pTimeInfo->samplePos + i) / pTimeInfo->sampleRate;
|
||||||
|
int iFrame = (int)(fTime * 1000.0 / 16.0);
|
||||||
|
|
||||||
|
Command oCommand;
|
||||||
|
oCommand.iChannel = oEvent.iChannel;
|
||||||
|
oCommand.iFrame = iFrame;
|
||||||
|
oCommand.iCommand = oEvent.bNoteOn ? InstrumentParameters::NOTEON : InstrumentParameters::NOTEOFF;
|
||||||
|
oCommand.iValue = (iNote) | (oEvent.iVelocity << 16);
|
||||||
|
|
||||||
|
oCommands.push_back(oCommand);
|
||||||
|
}
|
||||||
|
|
||||||
|
oEvents.pop_front();
|
||||||
|
}
|
||||||
|
|
||||||
|
int iLeft = 0;
|
||||||
|
int iRight = 0;
|
||||||
|
for ( int i = 0 ; i < 8 ; i++ )
|
||||||
|
pInstruments[i]->Compute(fSamplePeriod, iLeft, iRight);
|
||||||
|
|
||||||
|
*pLeft++ = iLeft / (float)0x7FFF;
|
||||||
|
*pRight++ = iRight / (float)0x7FFF;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void NitroSynth::StartRecording()
|
||||||
|
{
|
||||||
|
bRecording = true;
|
||||||
|
oCommands.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
void NitroSynth::StopRecording()
|
||||||
|
{
|
||||||
|
bRecording = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
VstInt32 NitroSynth::processEvents(VstEvents * pEvents)
|
||||||
|
{
|
||||||
|
for ( int i = 0 ; i < pEvents->numEvents ; i++ )
|
||||||
|
{
|
||||||
|
if ( pEvents->events[i]->type == kVstMidiType )
|
||||||
|
{
|
||||||
|
VstMidiEvent* pEvent = (VstMidiEvent *) pEvents->events[i];
|
||||||
|
char* pMidiData = pEvent->midiData;
|
||||||
|
|
||||||
|
int iChannel = pMidiData[0] & 0x0F;
|
||||||
|
|
||||||
|
if ( iChannel < 8 )
|
||||||
|
{
|
||||||
|
int iCommand = pMidiData[0] & 0xF0;
|
||||||
|
|
||||||
|
if ( iCommand == 0x90 || iCommand == 0x80 )
|
||||||
|
{
|
||||||
|
MidiNote oEvent;
|
||||||
|
oEvent.iChannel = iChannel;
|
||||||
|
oEvent.iNote = (int)(pMidiData[1] & 0x7F);
|
||||||
|
oEvent.iVelocity = (int)(pMidiData[2] & 0x7F);
|
||||||
|
oEvent.bNoteOn = (iCommand == 0x90);
|
||||||
|
oEvent.iDeltaFrames = pEvent->deltaFrames;
|
||||||
|
|
||||||
|
oEvents.push_back(oEvent);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
void NitroSynth::setSampleRate(float fSampleRate)
|
||||||
|
{
|
||||||
|
fSamplePeriod = 1.0f / fSampleRate;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool NitroSynth::getEffectName(char * pText)
|
||||||
|
{
|
||||||
|
strncpy(pText, "NitroSynth", kVstMaxEffectNameLen);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool NitroSynth::getProductString(char * pText)
|
||||||
|
{
|
||||||
|
strncpy(pText, "NitroSynth", kVstMaxProductStrLen);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool NitroSynth::getVendorString(char * pText)
|
||||||
|
{
|
||||||
|
strncpy(pText, "MsK`", kVstMaxVendorStrLen);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
VstInt32 NitroSynth::getVendorVersion()
|
||||||
|
{
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
void NitroSynth::setParameter(VstInt32 index, float value)
|
||||||
|
{
|
||||||
|
int iChannel = index / 16;
|
||||||
|
int iParameter = index % 16;
|
||||||
|
InstrumentParameters * pParameter = & pParameters[iChannel];
|
||||||
|
|
||||||
|
int iValue = -1;
|
||||||
|
|
||||||
|
if ( iParameter < InstrumentParameters::LAST )
|
||||||
|
{
|
||||||
|
switch ( iParameter )
|
||||||
|
{
|
||||||
|
case InstrumentParameters::VOLUME:
|
||||||
|
iValue = pParameter->iVolume = (int) (value * 127.0f);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case InstrumentParameters::PANNING:
|
||||||
|
iValue = pParameter->iPanning = (int) (value * 128.0f);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case InstrumentParameters::DETUNE:
|
||||||
|
iValue = pParameter->iDetune = (int) ((value-0.5f) * 2.0f * 32.0f);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case InstrumentParameters::ENVELOPE_ATTACK:
|
||||||
|
if ( value <= 1.2f/127.0f )
|
||||||
|
iValue = pParameter->Envelope.iAttack = 1;
|
||||||
|
else
|
||||||
|
iValue = pParameter->Envelope.iAttack = (int)(value * 127.0f);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case InstrumentParameters::ENVELOPE_DECAY:
|
||||||
|
if ( value <= 1.2f/127.0f )
|
||||||
|
iValue = pParameter->Envelope.iDecay = 1;
|
||||||
|
else
|
||||||
|
iValue = pParameter->Envelope.iDecay = (int)(value * 127.0f);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case InstrumentParameters::ENVELOPE_SUSTAIN:
|
||||||
|
iValue = pParameter->Envelope.iSustain = (int)(value * 127.0f);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case InstrumentParameters::ENVELOPE_RELEASE:
|
||||||
|
if ( value <= 1.2f/127.0f )
|
||||||
|
iValue = pParameter->Envelope.iRelease = 1;
|
||||||
|
else
|
||||||
|
iValue = pParameter->Envelope.iRelease = (int)(value * 127.0f);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case InstrumentParameters::DUTY:
|
||||||
|
iValue = pParameter->iDuty = (int)(value * 7.0f);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case InstrumentParameters::PORTAMENTO_LENGTH:
|
||||||
|
iValue = pParameter->iPortamentoLength = (int)(value * 128.0f);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case InstrumentParameters::SWEEP_LENGTH:
|
||||||
|
iValue = pParameter->Sweep.iLength = (int)(value * 127.0f);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case InstrumentParameters::SWEEP_OFFSET:
|
||||||
|
iValue = pParameter->Sweep.iOffset = (int)((value-0.5f) * 2.0f * 32.0f * 16.0f);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case InstrumentParameters::MODULATION_AMPLITUDE:
|
||||||
|
iValue = pParameter->Modulation.iAmplitude = (int)(value * 127.0f);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case InstrumentParameters::MODULATION_FREQUENCY:
|
||||||
|
iValue = pParameter->Modulation.iFrequency = (int)(value * 128.0f);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case InstrumentParameters::TREMOLO_AMPLITUDE:
|
||||||
|
iValue = pParameter->Tremolo.iAmplitude = (int)(value * 255.0f);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case InstrumentParameters::TREMOLO_FREQUENCY:
|
||||||
|
iValue = pParameter->Tremolo.iFrequency = (int)(value * 128.0f);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case InstrumentParameters::ARPEGGIO:
|
||||||
|
iValue = pParameter->iArpeggio = (int)(value * 32.0f);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( bRecording && iValue != -1 )
|
||||||
|
{
|
||||||
|
VstTimeInfo* pTimeInfo = getTimeInfo(0);
|
||||||
|
if ( pTimeInfo )
|
||||||
|
{
|
||||||
|
double iTime = pTimeInfo->samplePos / pTimeInfo->sampleRate;
|
||||||
|
int iFrame = (int)(iTime * 1000.0 / 16.0);
|
||||||
|
|
||||||
|
Command oCommand;
|
||||||
|
oCommand.iChannel = iChannel;
|
||||||
|
oCommand.iFrame = iFrame;
|
||||||
|
oCommand.iCommand = iParameter;
|
||||||
|
oCommand.iValue = iValue;
|
||||||
|
|
||||||
|
oCommands.push_back(oCommand);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
float NitroSynth::getParameter(VstInt32 index)
|
||||||
|
{
|
||||||
|
int iChannel = index / 16;
|
||||||
|
int iParameter = index % 16;
|
||||||
|
InstrumentParameters* pParameter = & pParameters[iChannel];
|
||||||
|
|
||||||
|
if ( iParameter < InstrumentParameters::LAST )
|
||||||
|
{
|
||||||
|
switch ( iParameter )
|
||||||
|
{
|
||||||
|
case InstrumentParameters::VOLUME:
|
||||||
|
return pParameter->iVolume / 127.0f;
|
||||||
|
|
||||||
|
case InstrumentParameters::PANNING:
|
||||||
|
return pParameter->iPanning / 128.0f;
|
||||||
|
|
||||||
|
case InstrumentParameters::DETUNE:
|
||||||
|
return pParameter->iDetune / 32.0f / 2.0f + 0.5f;
|
||||||
|
|
||||||
|
case InstrumentParameters::ENVELOPE_ATTACK:
|
||||||
|
return pParameter->Envelope.iAttack / 127.0f;
|
||||||
|
|
||||||
|
case InstrumentParameters::ENVELOPE_DECAY:
|
||||||
|
return pParameter->Envelope.iDecay / 127.0f;
|
||||||
|
|
||||||
|
case InstrumentParameters::ENVELOPE_SUSTAIN:
|
||||||
|
return pParameter->Envelope.iSustain / 127.0f;
|
||||||
|
|
||||||
|
case InstrumentParameters::ENVELOPE_RELEASE:
|
||||||
|
return pParameter->Envelope.iRelease / 127.0f;
|
||||||
|
|
||||||
|
case InstrumentParameters::DUTY:
|
||||||
|
return pParameter->iDuty / 7.0f;
|
||||||
|
|
||||||
|
case InstrumentParameters::PORTAMENTO_LENGTH:
|
||||||
|
return pParameter->iPortamentoLength / 128.0f;
|
||||||
|
|
||||||
|
case InstrumentParameters::SWEEP_LENGTH:
|
||||||
|
return pParameter->Sweep.iLength / 127.0f;
|
||||||
|
|
||||||
|
case InstrumentParameters::SWEEP_OFFSET:
|
||||||
|
return pParameter->Sweep.iOffset / 16.0f / 32.0f / 2.0f + 0.5f;
|
||||||
|
|
||||||
|
case InstrumentParameters::MODULATION_AMPLITUDE:
|
||||||
|
return pParameter->Modulation.iAmplitude / 127.0f;
|
||||||
|
|
||||||
|
case InstrumentParameters::MODULATION_FREQUENCY:
|
||||||
|
return pParameter->Modulation.iFrequency / 128.0f;
|
||||||
|
|
||||||
|
case InstrumentParameters::TREMOLO_AMPLITUDE:
|
||||||
|
return pParameter->Tremolo.iAmplitude / 255.0f;
|
||||||
|
|
||||||
|
case InstrumentParameters::TREMOLO_FREQUENCY:
|
||||||
|
return pParameter->Tremolo.iFrequency / 128.0f;
|
||||||
|
|
||||||
|
case InstrumentParameters::ARPEGGIO:
|
||||||
|
return pParameter->iArpeggio / 32.0f;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if ( index == 127 )
|
||||||
|
{
|
||||||
|
return iRecorderState / 2.0f;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0.0f;
|
||||||
|
}
|
||||||
|
|
||||||
|
void NitroSynth::getParameterDisplay(VstInt32 index, char* text)
|
||||||
|
{
|
||||||
|
int iChannel = index / 16;
|
||||||
|
int iParameter = index % 16;
|
||||||
|
InstrumentParameters * pParameter = & pParameters[iChannel];
|
||||||
|
|
||||||
|
if ( iParameter < InstrumentParameters::LAST )
|
||||||
|
{
|
||||||
|
switch ( iParameter )
|
||||||
|
{
|
||||||
|
case InstrumentParameters::VOLUME:
|
||||||
|
//sprintf(text, "%d", pParameter->iVolume);
|
||||||
|
sprintf(text, "%d%%", (int)(pParameter->iVolume * (100.0/127.0)));
|
||||||
|
break;
|
||||||
|
|
||||||
|
case InstrumentParameters::PANNING:
|
||||||
|
sprintf(text, "%d", pParameter->iPanning - 64);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case InstrumentParameters::DETUNE:
|
||||||
|
//sprintf(text, "%d", pParameter->iDetune);
|
||||||
|
sprintf(text, "%3.2f", pParameter->iDetune / 16.0f);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case InstrumentParameters::ENVELOPE_ATTACK:
|
||||||
|
sprintf(text, "%d", pParameter->Envelope.iAttack);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case InstrumentParameters::ENVELOPE_DECAY:
|
||||||
|
sprintf(text, "%d", pParameter->Envelope.iDecay);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case InstrumentParameters::ENVELOPE_SUSTAIN:
|
||||||
|
sprintf(text, "%d", pParameter->Envelope.iSustain);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case InstrumentParameters::ENVELOPE_RELEASE:
|
||||||
|
sprintf(text, "%d", pParameter->Envelope.iRelease);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case InstrumentParameters::DUTY:
|
||||||
|
//sprintf(text, "%d", pParameter->iDuty);
|
||||||
|
sprintf(text, "%d%%", (int)(pParameter->iDuty * (100.0/7.0)));
|
||||||
|
break;
|
||||||
|
|
||||||
|
case InstrumentParameters::PORTAMENTO_LENGTH:
|
||||||
|
sprintf(text, "%d", pParameter->iPortamentoLength);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case InstrumentParameters::SWEEP_LENGTH:
|
||||||
|
sprintf(text, "%d", pParameter->Sweep.iLength);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case InstrumentParameters::SWEEP_OFFSET:
|
||||||
|
sprintf(text, "%3.2f", pParameter->Sweep.iOffset / 16.0f);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case InstrumentParameters::MODULATION_AMPLITUDE:
|
||||||
|
sprintf(text, "%d", pParameter->Modulation.iAmplitude);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case InstrumentParameters::MODULATION_FREQUENCY:
|
||||||
|
sprintf(text, "%d", pParameter->Modulation.iFrequency);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case InstrumentParameters::TREMOLO_AMPLITUDE:
|
||||||
|
sprintf(text, "%d", pParameter->Tremolo.iAmplitude);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case InstrumentParameters::TREMOLO_FREQUENCY:
|
||||||
|
sprintf(text, "%d", pParameter->Tremolo.iFrequency);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case InstrumentParameters::ARPEGGIO:
|
||||||
|
sprintf(text, "%d", pParameter->iArpeggio);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
strncpy(text, " ", kVstMaxParamStrLen);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void NitroSynth::getParameterName(VstInt32 index, char* label)
|
||||||
|
{
|
||||||
|
int iChannel = index / 16;
|
||||||
|
int iParameter = index % 16;
|
||||||
|
|
||||||
|
if ( iParameter < InstrumentParameters::LAST )
|
||||||
|
{
|
||||||
|
static const char * pParameterName[InstrumentParameters::LAST] =
|
||||||
|
{
|
||||||
|
"vol", "pan", "dtune", "attck", "decay", "sustn", "rlz", "duty", "porta", "arp", "swlen", "swofs", "mdamp", "mdfrq", "tmamp", "tmfrq"
|
||||||
|
};
|
||||||
|
sprintf_s(label, kVstMaxParamStrLen, "%d-%s", iChannel, pParameterName[iParameter]);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
strncpy(label, " ", kVstMaxParamStrLen);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool NitroSynth::SaveTo(const char* pFilename) const
|
||||||
|
{
|
||||||
|
FILE* f = fopen(pFilename, "wb");
|
||||||
|
|
||||||
|
if ( f )
|
||||||
|
{
|
||||||
|
for ( int i = 0 ; i < 8 ; i++ )
|
||||||
|
fwrite(&pParameters[i], sizeof(InstrumentParameters), 1, f);
|
||||||
|
|
||||||
|
std::vector<Command>::const_iterator it = oCommands.begin();
|
||||||
|
int iLastFrame = 0;
|
||||||
|
|
||||||
|
while ( it != oCommands.end() )
|
||||||
|
{
|
||||||
|
Command oCommand = *it;
|
||||||
|
oCommand.iFrame -= iLastFrame;
|
||||||
|
fwrite(& oCommand, sizeof(Command), 1, f);
|
||||||
|
|
||||||
|
iLastFrame = it->iFrame;
|
||||||
|
|
||||||
|
++it;
|
||||||
|
}
|
||||||
|
|
||||||
|
Command oCommand;
|
||||||
|
oCommand.iChannel = 0;
|
||||||
|
oCommand.iCommand = InstrumentParameters::END;
|
||||||
|
oCommand.iFrame = 0;
|
||||||
|
oCommand.iValue = 0;
|
||||||
|
fwrite(& oCommand, sizeof(Command), 1, f);
|
||||||
|
|
||||||
|
fclose(f);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool NitroSynth::ImportInstruments(const char* pFilename)
|
||||||
|
{
|
||||||
|
FILE* f = fopen(pFilename, "rb");
|
||||||
|
|
||||||
|
if ( f )
|
||||||
|
{
|
||||||
|
for ( int i = 0 ; i < 8 ; i++ )
|
||||||
|
{
|
||||||
|
if ( ! fread(&pParameters[i], sizeof(InstrumentParameters), 1, f) )
|
||||||
|
{
|
||||||
|
fclose(f);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fclose(f);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
70
NitroSynth/NitroSynth.h
Normal file
@@ -0,0 +1,70 @@
|
|||||||
|
#ifndef _NITROSYNTH_H_
|
||||||
|
#define _NITROSYNTH_H_
|
||||||
|
|
||||||
|
#include "audioeffectx.h"
|
||||||
|
|
||||||
|
#include "PSG.h"
|
||||||
|
#include "Instrument.h"
|
||||||
|
|
||||||
|
#include <vector>
|
||||||
|
#include <queue>
|
||||||
|
|
||||||
|
#pragma pack(push, 1)
|
||||||
|
struct Command
|
||||||
|
{
|
||||||
|
unsigned int iFrame : 24;
|
||||||
|
unsigned int iChannel : 3;
|
||||||
|
unsigned int iCommand : 5; // 0-14 = parameters, 29 = note on, 30 = note off, 31 = song end
|
||||||
|
int iValue;
|
||||||
|
};
|
||||||
|
#pragma pack(pop)
|
||||||
|
|
||||||
|
struct MidiNote
|
||||||
|
{
|
||||||
|
int iChannel;
|
||||||
|
int iNote;
|
||||||
|
int iVelocity;
|
||||||
|
bool bNoteOn;
|
||||||
|
int iDeltaFrames;
|
||||||
|
};
|
||||||
|
|
||||||
|
class NitroSynth : public AudioEffectX
|
||||||
|
{
|
||||||
|
float fSamplePeriod;
|
||||||
|
enum ParamRecorderState { IDLE, RECORD, SAVE } iRecorderState;
|
||||||
|
bool bRecording;
|
||||||
|
std::vector<Command> oCommands;
|
||||||
|
std::deque<MidiNote> oEvents;
|
||||||
|
|
||||||
|
Instrument* pInstruments[8];
|
||||||
|
InstrumentParameters pParameters[8];
|
||||||
|
|
||||||
|
void processReplacing(float ** pInput, float ** pOutput, VstInt32 iSamples);
|
||||||
|
VstInt32 processEvents(VstEvents * pEvents);
|
||||||
|
void setSampleRate(float fSampleRate);
|
||||||
|
|
||||||
|
bool getProductString(char * pText);
|
||||||
|
bool getEffectName(char * pText);
|
||||||
|
bool getVendorString(char * pText);
|
||||||
|
VstInt32 getVendorVersion();
|
||||||
|
|
||||||
|
void getParameterName(VstInt32 index, char* label);
|
||||||
|
|
||||||
|
public:
|
||||||
|
NitroSynth(audioMasterCallback pCallback);
|
||||||
|
~NitroSynth();
|
||||||
|
|
||||||
|
void StartRecording();
|
||||||
|
void StopRecording();
|
||||||
|
bool IsRecording() const { return bRecording; }
|
||||||
|
bool HasRecord() const { return oCommands.size() > 0; }
|
||||||
|
|
||||||
|
bool SaveTo(const char* pFilename) const;
|
||||||
|
bool ImportInstruments(const char* pFilename);
|
||||||
|
|
||||||
|
void setParameter(VstInt32 index, float value);
|
||||||
|
float getParameter(VstInt32 index);
|
||||||
|
void getParameterDisplay(VstInt32 index, char* text);
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // _NITROSYNTH_H_
|
||||||
61
NitroSynth/NitroSynth.rc
Normal file
@@ -0,0 +1,61 @@
|
|||||||
|
// Microsoft Visual C++ generated resource script.
|
||||||
|
//
|
||||||
|
#include "resource.h"
|
||||||
|
|
||||||
|
#define APSTUDIO_READONLY_SYMBOLS
|
||||||
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
// Generated from the TEXTINCLUDE 2 resource.
|
||||||
|
//
|
||||||
|
#include "afxres.h"
|
||||||
|
|
||||||
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
|
#undef APSTUDIO_READONLY_SYMBOLS
|
||||||
|
|
||||||
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
|
// English (U.S.) resources
|
||||||
|
|
||||||
|
#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
|
||||||
|
LANGUAGE 12, 1
|
||||||
|
#pragma code_page(1252)
|
||||||
|
|
||||||
|
#ifdef APSTUDIO_INVOKED
|
||||||
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
// TEXTINCLUDE
|
||||||
|
//
|
||||||
|
|
||||||
|
1 TEXTINCLUDE
|
||||||
|
BEGIN
|
||||||
|
"resource.h\0"
|
||||||
|
END
|
||||||
|
|
||||||
|
2 TEXTINCLUDE
|
||||||
|
BEGIN
|
||||||
|
"#include ""afxres.h""\r\n"
|
||||||
|
"\0"
|
||||||
|
END
|
||||||
|
|
||||||
|
3 TEXTINCLUDE
|
||||||
|
BEGIN
|
||||||
|
"\r\n"
|
||||||
|
"\0"
|
||||||
|
END
|
||||||
|
|
||||||
|
#endif // APSTUDIO_INVOKED
|
||||||
|
|
||||||
|
#endif // English (U.S.) resources
|
||||||
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef APSTUDIO_INVOKED
|
||||||
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
// Generated from the TEXTINCLUDE 3 resource.
|
||||||
|
//
|
||||||
|
|
||||||
|
|
||||||
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
|
#endif // not APSTUDIO_INVOKED
|
||||||
|
|
||||||
195
NitroSynth/NitroSynth.vcxproj
Normal file
@@ -0,0 +1,195 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||||
|
<ItemGroup Label="ProjectConfigurations">
|
||||||
|
<ProjectConfiguration Include="Debug|Win32">
|
||||||
|
<Configuration>Debug</Configuration>
|
||||||
|
<Platform>Win32</Platform>
|
||||||
|
</ProjectConfiguration>
|
||||||
|
<ProjectConfiguration Include="NoGUI|Win32">
|
||||||
|
<Configuration>NoGUI</Configuration>
|
||||||
|
<Platform>Win32</Platform>
|
||||||
|
</ProjectConfiguration>
|
||||||
|
<ProjectConfiguration Include="Release|Win32">
|
||||||
|
<Configuration>Release</Configuration>
|
||||||
|
<Platform>Win32</Platform>
|
||||||
|
</ProjectConfiguration>
|
||||||
|
</ItemGroup>
|
||||||
|
<PropertyGroup Label="Globals">
|
||||||
|
<ProjectGuid>{2501786E-30DD-44A8-90D6-3E91417566A1}</ProjectGuid>
|
||||||
|
<RootNamespace>NitroSynth</RootNamespace>
|
||||||
|
</PropertyGroup>
|
||||||
|
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
|
||||||
|
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
||||||
|
<CharacterSet>NotSet</CharacterSet>
|
||||||
|
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='NoGUI|Win32'" Label="Configuration">
|
||||||
|
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
||||||
|
<CharacterSet>NotSet</CharacterSet>
|
||||||
|
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
|
||||||
|
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
||||||
|
<CharacterSet>NotSet</CharacterSet>
|
||||||
|
</PropertyGroup>
|
||||||
|
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
||||||
|
<ImportGroup Label="ExtensionSettings">
|
||||||
|
</ImportGroup>
|
||||||
|
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets">
|
||||||
|
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||||
|
</ImportGroup>
|
||||||
|
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='NoGUI|Win32'" Label="PropertySheets">
|
||||||
|
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||||
|
</ImportGroup>
|
||||||
|
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets">
|
||||||
|
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||||
|
</ImportGroup>
|
||||||
|
<PropertyGroup Label="UserMacros" />
|
||||||
|
<PropertyGroup>
|
||||||
|
<_ProjectFileVersion>10.0.40219.1</_ProjectFileVersion>
|
||||||
|
<OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(SolutionDir)$(Configuration)\</OutDir>
|
||||||
|
<IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(Configuration)\</IntDir>
|
||||||
|
<LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</LinkIncremental>
|
||||||
|
<OutDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(SolutionDir)$(Configuration)\</OutDir>
|
||||||
|
<OutDir Condition="'$(Configuration)|$(Platform)'=='NoGUI|Win32'">$(SolutionDir)$(Configuration)\</OutDir>
|
||||||
|
<IntDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(Configuration)\</IntDir>
|
||||||
|
<IntDir Condition="'$(Configuration)|$(Platform)'=='NoGUI|Win32'">$(Configuration)\</IntDir>
|
||||||
|
<LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</LinkIncremental>
|
||||||
|
<LinkIncremental Condition="'$(Configuration)|$(Platform)'=='NoGUI|Win32'">true</LinkIncremental>
|
||||||
|
<CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">AllRules.ruleset</CodeAnalysisRuleSet>
|
||||||
|
<CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" />
|
||||||
|
<CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" />
|
||||||
|
<CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">AllRules.ruleset</CodeAnalysisRuleSet>
|
||||||
|
<CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='NoGUI|Win32'">AllRules.ruleset</CodeAnalysisRuleSet>
|
||||||
|
<CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" />
|
||||||
|
<CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='NoGUI|Win32'" />
|
||||||
|
<CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" />
|
||||||
|
<CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='NoGUI|Win32'" />
|
||||||
|
</PropertyGroup>
|
||||||
|
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||||
|
<ClCompile>
|
||||||
|
<AdditionalOptions>/MP %(AdditionalOptions)</AdditionalOptions>
|
||||||
|
<Optimization>Disabled</Optimization>
|
||||||
|
<AdditionalIncludeDirectories>VST;VST/GUI;libpng;zlib;$(QT_HOME)\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||||
|
<PreprocessorDefinitions>_DEBUG;WIN32;_WIN32;_CRT_SECURE_NO_WARNINGS;_USRDLL;VSTXSYNTH_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||||
|
<MinimalRebuild>false</MinimalRebuild>
|
||||||
|
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
|
||||||
|
<RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
|
||||||
|
<WarningLevel>Level3</WarningLevel>
|
||||||
|
<DebugInformationFormat>EditAndContinue</DebugInformationFormat>
|
||||||
|
</ClCompile>
|
||||||
|
<Link>
|
||||||
|
<AdditionalDependencies>QtCored4.lib;QtGuid4.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||||
|
<OutputFile>$(OutDir)$(ProjectName).dll</OutputFile>
|
||||||
|
<AdditionalLibraryDirectories>$(QT_HOME)\lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
|
||||||
|
<ModuleDefinitionFile>Export.def</ModuleDefinitionFile>
|
||||||
|
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||||
|
<SubSystem>Windows</SubSystem>
|
||||||
|
<RandomizedBaseAddress>false</RandomizedBaseAddress>
|
||||||
|
<DataExecutionPrevention>
|
||||||
|
</DataExecutionPrevention>
|
||||||
|
<TargetMachine>MachineX86</TargetMachine>
|
||||||
|
</Link>
|
||||||
|
</ItemDefinitionGroup>
|
||||||
|
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||||
|
<ClCompile>
|
||||||
|
<Optimization>Full</Optimization>
|
||||||
|
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||||
|
<FavorSizeOrSpeed>Speed</FavorSizeOrSpeed>
|
||||||
|
<AdditionalIncludeDirectories>VST;VST/GUI;libpng;zlib;$(QT_HOME)\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||||
|
<PreprocessorDefinitions>WIN32;_WIN32;_CRT_SECURE_NO_WARNINGS;_USRDLL;VSTXSYNTH_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||||
|
<RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
|
||||||
|
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||||
|
<WarningLevel>Level3</WarningLevel>
|
||||||
|
<DebugInformationFormat>
|
||||||
|
</DebugInformationFormat>
|
||||||
|
</ClCompile>
|
||||||
|
<Link>
|
||||||
|
<AdditionalDependencies>QtCore4.lib;QtGui4.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||||
|
<OutputFile>$(OutDir)$(ProjectName).dll</OutputFile>
|
||||||
|
<AdditionalLibraryDirectories>$(QT_HOME)\lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
|
||||||
|
<ModuleDefinitionFile>Export.def</ModuleDefinitionFile>
|
||||||
|
<GenerateDebugInformation>false</GenerateDebugInformation>
|
||||||
|
<SubSystem>Windows</SubSystem>
|
||||||
|
<OptimizeReferences>true</OptimizeReferences>
|
||||||
|
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||||
|
<RandomizedBaseAddress>false</RandomizedBaseAddress>
|
||||||
|
<DataExecutionPrevention>
|
||||||
|
</DataExecutionPrevention>
|
||||||
|
<TargetMachine>MachineX86</TargetMachine>
|
||||||
|
</Link>
|
||||||
|
</ItemDefinitionGroup>
|
||||||
|
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='NoGUI|Win32'">
|
||||||
|
<ClCompile>
|
||||||
|
<Optimization>Full</Optimization>
|
||||||
|
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||||
|
<FavorSizeOrSpeed>Speed</FavorSizeOrSpeed>
|
||||||
|
<AdditionalIncludeDirectories>VST;VST/GUI;libpng;zlib;$(QT_HOME)\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||||
|
<PreprocessorDefinitions>NO_VST_GUI;WIN32;_WIN32;_CRT_SECURE_NO_WARNINGS;_USRDLL;VSTXSYNTH_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||||
|
<RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
|
||||||
|
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||||
|
<WarningLevel>Level3</WarningLevel>
|
||||||
|
<DebugInformationFormat>
|
||||||
|
</DebugInformationFormat>
|
||||||
|
</ClCompile>
|
||||||
|
<Link>
|
||||||
|
<AdditionalDependencies>%(AdditionalDependencies)</AdditionalDependencies>
|
||||||
|
<OutputFile>$(OutDir)$(ProjectName).dll</OutputFile>
|
||||||
|
<AdditionalLibraryDirectories>$(QT_HOME)\lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
|
||||||
|
<ModuleDefinitionFile>Export.def</ModuleDefinitionFile>
|
||||||
|
<GenerateDebugInformation>false</GenerateDebugInformation>
|
||||||
|
<SubSystem>Windows</SubSystem>
|
||||||
|
<OptimizeReferences>true</OptimizeReferences>
|
||||||
|
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||||
|
<RandomizedBaseAddress>false</RandomizedBaseAddress>
|
||||||
|
<DataExecutionPrevention>
|
||||||
|
</DataExecutionPrevention>
|
||||||
|
<TargetMachine>MachineX86</TargetMachine>
|
||||||
|
</Link>
|
||||||
|
</ItemDefinitionGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<ClCompile Include="Envelope.cpp" />
|
||||||
|
<ClCompile Include="Instrument.cpp" />
|
||||||
|
<ClCompile Include="Main.cpp" />
|
||||||
|
<ClCompile Include="NitroSynth.cpp" />
|
||||||
|
<ClCompile Include="PSG.cpp" />
|
||||||
|
<ClCompile Include="Utils.cpp" />
|
||||||
|
<ClCompile Include="moc_NitroSynthWindow.cpp">
|
||||||
|
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='NoGUI|Win32'">true</ExcludedFromBuild>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="NitroSynthInterface.cpp">
|
||||||
|
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='NoGUI|Win32'">true</ExcludedFromBuild>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="NitroSynthWindow.cpp">
|
||||||
|
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='NoGUI|Win32'">true</ExcludedFromBuild>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="VST\audioeffect.cpp" />
|
||||||
|
<ClCompile Include="VST\audioeffectx.cpp" />
|
||||||
|
<ClCompile Include="VST\vstplugmain.cpp" />
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<ClInclude Include="Envelope.h" />
|
||||||
|
<ClInclude Include="Instrument.h" />
|
||||||
|
<ClInclude Include="NitroSynth.h" />
|
||||||
|
<ClInclude Include="PSG.h" />
|
||||||
|
<ClInclude Include="Utils.h" />
|
||||||
|
<CustomBuildStep Include="NitroSynthInterface.h" />
|
||||||
|
<ClInclude Include="VST\aeffect.h" />
|
||||||
|
<ClInclude Include="VST\aeffectx.h" />
|
||||||
|
<ClInclude Include="VST\aeffeditor.h" />
|
||||||
|
<ClInclude Include="VST\audioeffect.h" />
|
||||||
|
<ClInclude Include="VST\audioeffectx.h" />
|
||||||
|
<ClInclude Include="VST\vstfxstore.h" />
|
||||||
|
<ClInclude Include="resource.h" />
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<None Include="Export.def" />
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<ResourceCompile Include="NitroSynth.rc" />
|
||||||
|
</ItemGroup>
|
||||||
|
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||||
|
<ImportGroup Label="ExtensionTargets">
|
||||||
|
</ImportGroup>
|
||||||
|
</Project>
|
||||||
119
NitroSynth/NitroSynthInterface.cpp
Normal file
@@ -0,0 +1,119 @@
|
|||||||
|
#include "NitroSynthInterface.h"
|
||||||
|
|
||||||
|
#include <Qt/QApplication.h>
|
||||||
|
#include <Qt/QFile.h>
|
||||||
|
#include "NitroSynthWindow.h"
|
||||||
|
|
||||||
|
static const char* stylesheet =
|
||||||
|
"QWidget {\
|
||||||
|
background-color: #d9ecff;\
|
||||||
|
}\
|
||||||
|
\
|
||||||
|
QLabel, QSlider {\
|
||||||
|
background: none;\
|
||||||
|
}\
|
||||||
|
\
|
||||||
|
QPushButton {\
|
||||||
|
border: 1px solid #626a73;\
|
||||||
|
border-radius: 7px;\
|
||||||
|
background-color: qlineargradient(x1: 0, y1: 1, x2: 0, y2: 0, stop: 0 #98a5b2, stop: 1 #b8c8d9);\
|
||||||
|
}\
|
||||||
|
\
|
||||||
|
QPushButton:pressed {\
|
||||||
|
background-color: qlineargradient(x1: 0, y1: 1, x2: 0, y2: 0, stop: 0 #b8c8d9, stop: 1 #98a5b2);\
|
||||||
|
}\
|
||||||
|
\
|
||||||
|
QPushButton:hover {\
|
||||||
|
border-color: #98a5b2;\
|
||||||
|
}\
|
||||||
|
\
|
||||||
|
QSlider::groove:horizontal {\
|
||||||
|
border: 1px solid #626a73;\
|
||||||
|
height: 8px;\
|
||||||
|
background-color: qlineargradient(x1:0, y1:0, x2:0, y2:1, stop:0 #cee0f2, stop:1 #d9ecff);\
|
||||||
|
margin: 2px 0;\
|
||||||
|
border-radius: 5px;\
|
||||||
|
}\
|
||||||
|
\
|
||||||
|
QSlider::handle:horizontal {\
|
||||||
|
border: 1px solid #626a73;\
|
||||||
|
background: qlineargradient(x1:0, y1:1, x2:0, y2:0, stop:0 #d9ecff, stop:1 #98a5b2);\
|
||||||
|
width: 15px;\
|
||||||
|
margin: -0.72px 0;\
|
||||||
|
border-radius: 6px;\
|
||||||
|
}\
|
||||||
|
\
|
||||||
|
QGroupBox {\
|
||||||
|
background-color: qlineargradient(x1: 0, y1: 1, x2: 0, y2: 0, stop: 0 #cee0f2, stop: 1 #d9ecff);\
|
||||||
|
border: 1px solid #626a73;\
|
||||||
|
border-radius: 7px;\
|
||||||
|
margin-top: 2ex;\
|
||||||
|
}\
|
||||||
|
\
|
||||||
|
QGroupBox::title {\
|
||||||
|
subcontrol-origin: margin;\
|
||||||
|
subcontrol-position: top center;\
|
||||||
|
padding: 0 5px;\
|
||||||
|
}\
|
||||||
|
\
|
||||||
|
QTabWidget::pane {\
|
||||||
|
border-top: 1px solid #626a73;\
|
||||||
|
position: absolute;\
|
||||||
|
top: -0.78em;\
|
||||||
|
padding-top: 0.78em;\
|
||||||
|
}\
|
||||||
|
\
|
||||||
|
QTabWidget::tab-bar {\
|
||||||
|
alignment: center;\
|
||||||
|
}\
|
||||||
|
\
|
||||||
|
QTabBar::tab {\
|
||||||
|
background: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1, stop: 0 #b8c8d9, stop: 1.0 #98a5b2);\
|
||||||
|
border: 1px solid #626a73;\
|
||||||
|
border-radius: 5px;\
|
||||||
|
min-width: 8ex;\
|
||||||
|
padding: 4px;\
|
||||||
|
}\
|
||||||
|
\
|
||||||
|
QTabBar::tab:selected, QTabBar::tab:hover {\
|
||||||
|
background: #d9ecff;\
|
||||||
|
}\
|
||||||
|
\
|
||||||
|
QTabBar::tab:selected {\
|
||||||
|
border-color: #98a5b2;\
|
||||||
|
}";
|
||||||
|
|
||||||
|
NitroSynthInterface::NitroSynthInterface(AudioEffectX* pEffect)
|
||||||
|
: AEffEditor(pEffect),
|
||||||
|
pApplication(0),
|
||||||
|
pWindow(0)
|
||||||
|
{
|
||||||
|
int argc = 0;
|
||||||
|
pApplication = new QApplication(argc, 0, true);
|
||||||
|
pApplication->setStyleSheet(stylesheet);
|
||||||
|
}
|
||||||
|
|
||||||
|
NitroSynthInterface::~NitroSynthInterface()
|
||||||
|
{
|
||||||
|
delete pApplication;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool NitroSynthInterface::open(void* window)
|
||||||
|
{
|
||||||
|
pWindow = new NitroSynthWindow((NitroSynth*) effect, window);
|
||||||
|
pWindow->show();
|
||||||
|
systemWindow = window;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void NitroSynthInterface::close()
|
||||||
|
{
|
||||||
|
pWindow->hide();
|
||||||
|
delete pWindow;
|
||||||
|
systemWindow = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void NitroSynthInterface::idle()
|
||||||
|
{
|
||||||
|
pApplication->processEvents();
|
||||||
|
}
|
||||||
23
NitroSynth/NitroSynthInterface.h
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
#ifndef _NITROSYNTHINTERFACE_H_
|
||||||
|
#define _NITROSYNTHINTERFACE_H_
|
||||||
|
|
||||||
|
#include "aeffeditor.h"
|
||||||
|
|
||||||
|
class QApplication;
|
||||||
|
class NitroSynthWindow;
|
||||||
|
|
||||||
|
class NitroSynthInterface : public AEffEditor
|
||||||
|
{
|
||||||
|
QApplication* pApplication;
|
||||||
|
NitroSynthWindow* pWindow;
|
||||||
|
|
||||||
|
bool open(void* ptr);
|
||||||
|
void close();
|
||||||
|
void idle();
|
||||||
|
|
||||||
|
public:
|
||||||
|
NitroSynthInterface(AudioEffectX* pEffect);
|
||||||
|
~NitroSynthInterface();
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // _NITROSYNTHINTERFACE_H_
|
||||||
238
NitroSynth/NitroSynthWindow.cpp
Normal file
@@ -0,0 +1,238 @@
|
|||||||
|
#include "NitroSynthWindow.h"
|
||||||
|
|
||||||
|
#include <Qt/QLabel.h>
|
||||||
|
#include <Qt/QSlider.h>
|
||||||
|
#include <Qt/QGroupBox.h>
|
||||||
|
#include <Qt/QTabWidget.h>
|
||||||
|
#include <Qt/QPushButton.h>
|
||||||
|
#include <Qt/QFileDialog.h>
|
||||||
|
#include <Qt/QMessageBox.h>
|
||||||
|
|
||||||
|
#include "NitroSynth.h"
|
||||||
|
|
||||||
|
NitroSynthWindow::NitroSynthWindow(NitroSynth* ns, void* window)
|
||||||
|
: ns(ns),
|
||||||
|
importing(false)
|
||||||
|
{
|
||||||
|
create(WId(window));
|
||||||
|
|
||||||
|
setGeometry(50, 50, 480, 320);
|
||||||
|
setWindowTitle("NitroSynth");
|
||||||
|
|
||||||
|
pTabWidget = new QTabWidget(this);
|
||||||
|
pTabWidget->setGeometry(QRect(0, 10, 481, 274));
|
||||||
|
|
||||||
|
for ( int i = 0 ; i < 8 ; i++ )
|
||||||
|
{
|
||||||
|
Tab* pTab = &pTabs[i];
|
||||||
|
pTab->pWidget = new QWidget(pTabWidget);
|
||||||
|
|
||||||
|
for ( int j = 0 ; j < 4 ; j++ )
|
||||||
|
{
|
||||||
|
static const int x[] = { 13, 245, 245, 245 };
|
||||||
|
static const int y[] = { 70, 10, 90, 170 };
|
||||||
|
static const char* pGroupName[] =
|
||||||
|
{
|
||||||
|
"Envelope", "Sweep", "Vibrato", "Tremolo"
|
||||||
|
};
|
||||||
|
|
||||||
|
pTab->pGroupBoxes[j] = new QGroupBox(QString::fromAscii(pGroupName[j]), pTab->pWidget);
|
||||||
|
pTab->pGroupBoxes[j]->setGeometry(QRect(x[j], y[j], 221, j == 0 ? 111 : 71));
|
||||||
|
pTab->pGroupBoxes[j]->raise();
|
||||||
|
}
|
||||||
|
|
||||||
|
for ( int j = 0 ; j < InstrumentParameters::LAST ; j++ )
|
||||||
|
{
|
||||||
|
if ( i > 5 && j == InstrumentParameters::DUTY )
|
||||||
|
{
|
||||||
|
pTab->pLabels[j] = 0;
|
||||||
|
pTab->pSliders[j] = 0;
|
||||||
|
pTab->pSliderValues[j] = 0;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
static const int x[] =
|
||||||
|
{
|
||||||
|
20, 20, 20, 20, 20, 20, 20, 20, 20, 20,
|
||||||
|
252, 252, 252, 252, 252, 252
|
||||||
|
};
|
||||||
|
static const int y[] = {
|
||||||
|
10, 30, 50, 90, 110, 130, 150, 185, 205, 225,
|
||||||
|
30, 50, 110, 130, 190, 210
|
||||||
|
};
|
||||||
|
static const char* pLabelName[] =
|
||||||
|
{
|
||||||
|
"Volume", "Panning", "Detune", "Attack", "Decay", "Sustain", "Release", "Pulse Width", "Portamento", "Arpeggio",
|
||||||
|
"Length", "Offset", "Amplitude", "Frequency", "Amplitude", "Frequency"
|
||||||
|
};
|
||||||
|
|
||||||
|
int index = i * 16 + j;
|
||||||
|
float value = ns->getParameter(index);
|
||||||
|
|
||||||
|
pTab->pLabels[j] = new QLabel(QString::fromAscii(pLabelName[j]), pTab->pWidget);
|
||||||
|
pTab->pLabels[j]->setGeometry(QRect(x[j], y[j], 56, 20));
|
||||||
|
pTab->pLabels[j]->raise();
|
||||||
|
|
||||||
|
pTab->pSliders[j] = new QSlider(pTab->pWidget);
|
||||||
|
pTab->pSliders[j]->setGeometry(QRect(x[j] + 60, y[j], 111, 19));
|
||||||
|
pTab->pSliders[j]->setOrientation(Qt::Horizontal);
|
||||||
|
pTab->pSliders[j]->setRange(0, 127);
|
||||||
|
pTab->pSliders[j]->setValue(value * 127);
|
||||||
|
pTab->pSliders[j]->raise();
|
||||||
|
connect(pTab->pSliders[j], SIGNAL(valueChanged(int)), this, SLOT(slider(int)));
|
||||||
|
|
||||||
|
char txt[32];
|
||||||
|
ns->getParameterDisplay(index, txt);
|
||||||
|
pTab->pSliderValues[j] = new QLabel(txt, pTab->pWidget);
|
||||||
|
pTab->pSliderValues[j]->setGeometry(QRect(x[j] + 177, y[j], 35, 20));
|
||||||
|
pTab->pSliderValues[j]->raise();
|
||||||
|
}
|
||||||
|
|
||||||
|
static const char* pTabName[] =
|
||||||
|
{
|
||||||
|
"1 Pulse", "2 Pulse", "3 Pulse", "4 Pulse", "5 Pulse", "6 Pulse", "7 Noise", "8 Noise"
|
||||||
|
};
|
||||||
|
pTabWidget->addTab(pTab->pWidget, QString::fromAscii(pTabName[i]));
|
||||||
|
}
|
||||||
|
|
||||||
|
pImportButton = new QPushButton(QString::fromUtf8("Import"), this);
|
||||||
|
pImportButton->setGeometry(QRect(210, 290, 75, 23));
|
||||||
|
pRecordButton = new QPushButton(QString::fromUtf8("Record"), this);
|
||||||
|
pRecordButton->setGeometry(QRect(300, 290, 75, 23));
|
||||||
|
pSaveButton = new QPushButton(QString::fromUtf8("Save"), this);
|
||||||
|
pSaveButton->setGeometry(QRect(390, 290, 75, 23));
|
||||||
|
pSaveButton->setEnabled(false);
|
||||||
|
|
||||||
|
connect(pRecordButton, SIGNAL(clicked()), this, SLOT(recordButton()));
|
||||||
|
connect(pSaveButton, SIGNAL(clicked()), this, SLOT(saveButton()));
|
||||||
|
connect(pImportButton, SIGNAL(clicked()), this, SLOT(importButton()));
|
||||||
|
}
|
||||||
|
|
||||||
|
NitroSynthWindow::~NitroSynthWindow()
|
||||||
|
{
|
||||||
|
for ( int j = 0 ; j < 8 ; j++ )
|
||||||
|
{
|
||||||
|
Tab* pTab = &pTabs[j];
|
||||||
|
|
||||||
|
for ( int i = 0 ; i < 14 ; i++ )
|
||||||
|
{
|
||||||
|
if ( pTab->pLabels[i] ) delete pTab->pLabels[i];
|
||||||
|
if ( pTab->pSliders[i] ) delete pTab->pSliders[i];
|
||||||
|
if ( pTab->pSliderValues[i] ) delete pTab->pSliderValues[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
for ( int i = 0 ; i < 4 ; i++ )
|
||||||
|
{
|
||||||
|
delete pTab->pGroupBoxes[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
delete pTab->pWidget;
|
||||||
|
}
|
||||||
|
|
||||||
|
delete pTabWidget;
|
||||||
|
|
||||||
|
delete pRecordButton;
|
||||||
|
delete pSaveButton;
|
||||||
|
}
|
||||||
|
|
||||||
|
void NitroSynthWindow::recordButton()
|
||||||
|
{
|
||||||
|
if ( ns->IsRecording() )
|
||||||
|
{
|
||||||
|
if ( ns->HasRecord() )
|
||||||
|
pSaveButton->setEnabled(true);
|
||||||
|
ns->StopRecording();
|
||||||
|
pRecordButton->setText("Record");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ns->StartRecording();
|
||||||
|
pRecordButton->setText("Stop");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void NitroSynthWindow::importButton()
|
||||||
|
{
|
||||||
|
QString str = QFileDialog::getOpenFileName(this, "Import instruments from");
|
||||||
|
|
||||||
|
if ( ns->ImportInstruments(str.toAscii()) )
|
||||||
|
{
|
||||||
|
importing = true;
|
||||||
|
// Update sliders in all instruments
|
||||||
|
for ( int i = 0 ; i < 8 ; i++ )
|
||||||
|
{
|
||||||
|
Tab* pTab = &pTabs[i];
|
||||||
|
|
||||||
|
for ( int j = 0 ; j < InstrumentParameters::LAST ; j++ )
|
||||||
|
{
|
||||||
|
if ( !(i > 5 && j == InstrumentParameters::DUTY) )
|
||||||
|
{
|
||||||
|
int index = i * 16 + j;
|
||||||
|
float value = ns->getParameter(index);
|
||||||
|
pTab->pSliders[j]->setValue(value * 127);
|
||||||
|
|
||||||
|
char txt[32];
|
||||||
|
ns->getParameterDisplay(index, txt);
|
||||||
|
pTab->pSliderValues[j]->setText(txt);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
importing = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void NitroSynthWindow::saveButton()
|
||||||
|
{
|
||||||
|
QString str = QFileDialog::getSaveFileName(this, "Save to");
|
||||||
|
|
||||||
|
if ( ! ns->SaveTo(str.toAscii()) )
|
||||||
|
QMessageBox::warning(this, "Warning", QString("Could not save to \"") + str + QString("\"."));
|
||||||
|
}
|
||||||
|
|
||||||
|
void NitroSynthWindow::slider(int value)
|
||||||
|
{
|
||||||
|
if ( importing )
|
||||||
|
return;
|
||||||
|
|
||||||
|
QSlider* slider = (QSlider*) sender();
|
||||||
|
QWidget* widget = (QWidget*) slider->parent();
|
||||||
|
|
||||||
|
int channel = -1;
|
||||||
|
for ( int i = 0 ; i < 8 ; i++ )
|
||||||
|
{
|
||||||
|
if ( pTabs[i].pWidget == widget )
|
||||||
|
{
|
||||||
|
channel = i;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( channel == -1 )
|
||||||
|
{
|
||||||
|
QMessageBox::warning(this, "WTF?!", "Unknown channel");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
int param = -1;
|
||||||
|
for ( int i = 0 ; i < InstrumentParameters::LAST ; i++ )
|
||||||
|
{
|
||||||
|
if ( pTabs[channel].pSliders[i] == slider )
|
||||||
|
{
|
||||||
|
param = i;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( param == -1 )
|
||||||
|
{
|
||||||
|
QMessageBox::warning(this, "WTF?!", "Unknown parameter");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
int index = param + channel * 16;
|
||||||
|
ns->setParameter(index, value / 127.0f);
|
||||||
|
|
||||||
|
char txt[32];
|
||||||
|
ns->getParameterDisplay(index, txt);
|
||||||
|
pTabs[channel].pSliderValues[param]->setText(txt);
|
||||||
|
}
|
||||||
49
NitroSynth/NitroSynthWindow.h
Normal file
@@ -0,0 +1,49 @@
|
|||||||
|
#ifndef _NITROSYNTHWINDOW_H_
|
||||||
|
#define _NITROSYNTHWINDOW_H_
|
||||||
|
|
||||||
|
#include <Qt/QWidget.h>
|
||||||
|
|
||||||
|
#include "Instrument.h"
|
||||||
|
|
||||||
|
class QLabel;
|
||||||
|
class QSlider;
|
||||||
|
class QGroupBox;
|
||||||
|
class QTabWidget;
|
||||||
|
class QPushButton;
|
||||||
|
class NitroSynth;
|
||||||
|
|
||||||
|
class NitroSynthWindow : public QWidget
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
struct Tab
|
||||||
|
{
|
||||||
|
QWidget* pWidget;
|
||||||
|
QLabel* pLabels[InstrumentParameters::LAST];
|
||||||
|
QLabel* pSliderValues[InstrumentParameters::LAST];
|
||||||
|
QSlider* pSliders[InstrumentParameters::LAST];
|
||||||
|
QGroupBox* pGroupBoxes[4];
|
||||||
|
};
|
||||||
|
|
||||||
|
QTabWidget* pTabWidget;
|
||||||
|
Tab pTabs[8];
|
||||||
|
|
||||||
|
QPushButton* pImportButton;
|
||||||
|
QPushButton* pRecordButton;
|
||||||
|
QPushButton* pSaveButton;
|
||||||
|
|
||||||
|
NitroSynth* ns;
|
||||||
|
bool importing;
|
||||||
|
|
||||||
|
private slots:
|
||||||
|
void importButton();
|
||||||
|
void recordButton();
|
||||||
|
void saveButton();
|
||||||
|
void slider(int);
|
||||||
|
|
||||||
|
public:
|
||||||
|
NitroSynthWindow(NitroSynth* ns, void* window);
|
||||||
|
~NitroSynthWindow();
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // _NITROSYNTHWINDOW_H_
|
||||||
79
NitroSynth/PSG.cpp
Normal file
@@ -0,0 +1,79 @@
|
|||||||
|
#include "PSG.h"
|
||||||
|
|
||||||
|
PSG::PSG()
|
||||||
|
: iLastSample(0),
|
||||||
|
fTime(0.0f),
|
||||||
|
iFrequency(1),
|
||||||
|
iDuty(0)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
signed short PSG::Compute(float dt)
|
||||||
|
{
|
||||||
|
fTime += dt;
|
||||||
|
|
||||||
|
if ( fTime >= 1.0f/(float)iFrequency ) {
|
||||||
|
iLastSample = Generate();
|
||||||
|
fTime -= 1.0f/(float)iFrequency;
|
||||||
|
}
|
||||||
|
|
||||||
|
return iLastSample;
|
||||||
|
}
|
||||||
|
|
||||||
|
void PSG::Reset()
|
||||||
|
{
|
||||||
|
fTime = 0.0f;
|
||||||
|
iLastSample = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// NDS PSG Noise
|
||||||
|
// X=X SHR 1, IF carry THEN Out=LOW, X=X XOR 6000h ELSE Out=HIGH
|
||||||
|
signed short Noise::Generate()
|
||||||
|
{
|
||||||
|
int carry;
|
||||||
|
|
||||||
|
carry = x & 1;
|
||||||
|
x >>= 1;
|
||||||
|
|
||||||
|
if ( carry ) {
|
||||||
|
x = x ^ 0x6000;
|
||||||
|
return -0x7FFF;
|
||||||
|
} else {
|
||||||
|
return 0x7FFF;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Noise::Reset()
|
||||||
|
{
|
||||||
|
x = 0x7FFF;
|
||||||
|
PSG::Reset();
|
||||||
|
}
|
||||||
|
|
||||||
|
// NDS Wave Duty
|
||||||
|
// Each duty cycle consists of eight HIGH or LOW samples, so the sound
|
||||||
|
// frequency is 1/8th of the selected sample rate. The duty cycle always
|
||||||
|
// starts at the begin of the LOW period when the sound gets (re-)started.
|
||||||
|
//
|
||||||
|
// 0 12.5% "_______-_______-_______-"
|
||||||
|
// 1 25.0% "______--______--______--"
|
||||||
|
// 2 37.5% "_____---_____---_____---"
|
||||||
|
// 3 50.0% "____----____----____----"
|
||||||
|
// 4 62.5% "___-----___-----___-----"
|
||||||
|
// 5 75.0% "__------__------__------"
|
||||||
|
// 6 87.5% "_-------_-------_-------"
|
||||||
|
// 7 0.0% "________________________"
|
||||||
|
signed short WaveDuty::Generate()
|
||||||
|
{
|
||||||
|
x = (x + 1) % 8;
|
||||||
|
|
||||||
|
if ( x <= iDuty )
|
||||||
|
return -0x7FFF;
|
||||||
|
else
|
||||||
|
return 0x7FFF;
|
||||||
|
}
|
||||||
|
|
||||||
|
void WaveDuty::Reset()
|
||||||
|
{
|
||||||
|
x = 0;
|
||||||
|
PSG::Reset();
|
||||||
|
}
|
||||||
40
NitroSynth/PSG.h
Normal file
@@ -0,0 +1,40 @@
|
|||||||
|
#ifndef _PSG_H_
|
||||||
|
#define _PSG_H_
|
||||||
|
|
||||||
|
class PSG {
|
||||||
|
float fTime;
|
||||||
|
int iFrequency;
|
||||||
|
signed short iLastSample;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
int x;
|
||||||
|
int iDuty;
|
||||||
|
|
||||||
|
virtual signed short Generate() = 0;
|
||||||
|
|
||||||
|
public:
|
||||||
|
PSG();
|
||||||
|
|
||||||
|
void SetDuty(int d) { iDuty = d; }
|
||||||
|
void SetFrequency(int f) { iFrequency = f * 8; }
|
||||||
|
|
||||||
|
virtual void Reset();
|
||||||
|
|
||||||
|
signed short Compute(float dt);
|
||||||
|
};
|
||||||
|
|
||||||
|
class Noise : public PSG {
|
||||||
|
signed short Generate();
|
||||||
|
void Reset();
|
||||||
|
public:
|
||||||
|
Noise() : PSG() { Reset(); }
|
||||||
|
};
|
||||||
|
|
||||||
|
class WaveDuty : public PSG {
|
||||||
|
signed short Generate();
|
||||||
|
void Reset();
|
||||||
|
public:
|
||||||
|
WaveDuty() : PSG() { Reset(); }
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // _PSG_H_
|
||||||
173
NitroSynth/Utils.cpp
Normal file
@@ -0,0 +1,173 @@
|
|||||||
|
#include "Utils.h"
|
||||||
|
|
||||||
|
#ifdef PRECISE
|
||||||
|
#include <math.h>
|
||||||
|
|
||||||
|
unsigned short MidiNoteToFrequency(int note)
|
||||||
|
{
|
||||||
|
return (int) (440.0f * pow(2.0f, (float(note)/16.0f - 69.0f)/12.0f));
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
unsigned short MidiNoteToFrequency(int note)
|
||||||
|
{
|
||||||
|
static const unsigned short pFrequencies[] =
|
||||||
|
{
|
||||||
|
8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
|
||||||
|
8,8,8,8,8,8,8,8,8,8,8,9,9,9,9,9,
|
||||||
|
9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,
|
||||||
|
9,9,9,9,9,9,9,9,10,10,10,10,10,10,10,10,
|
||||||
|
10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,
|
||||||
|
10,10,10,11,11,11,11,11,11,11,11,11,11,11,11,11,
|
||||||
|
11,11,11,11,11,11,11,11,11,11,11,12,12,12,12,12,
|
||||||
|
12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,
|
||||||
|
12,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,
|
||||||
|
13,13,13,13,13,14,14,14,14,14,14,14,14,14,14,14,
|
||||||
|
14,14,14,14,14,14,14,14,14,15,15,15,15,15,15,15,
|
||||||
|
15,15,15,15,15,15,15,15,15,15,16,16,16,16,16,16,
|
||||||
|
16,16,16,16,16,16,16,16,16,16,16,17,17,17,17,17,
|
||||||
|
17,17,17,17,17,17,17,17,17,17,17,18,18,18,18,18,
|
||||||
|
18,18,18,18,18,18,18,18,18,18,19,19,19,19,19,19,
|
||||||
|
19,19,19,19,19,19,19,19,20,20,20,20,20,20,20,20,
|
||||||
|
20,20,20,20,20,20,21,21,21,21,21,21,21,21,21,21,
|
||||||
|
21,21,21,22,22,22,22,22,22,22,22,22,22,22,22,23,
|
||||||
|
23,23,23,23,23,23,23,23,23,23,23,24,24,24,24,24,
|
||||||
|
24,24,24,24,24,24,25,25,25,25,25,25,25,25,25,25,
|
||||||
|
25,26,26,26,26,26,26,26,26,26,26,27,27,27,27,27,
|
||||||
|
27,27,27,27,27,28,28,28,28,28,28,28,28,28,28,29,
|
||||||
|
29,29,29,29,29,29,29,29,29,30,30,30,30,30,30,30,
|
||||||
|
30,30,31,31,31,31,31,31,31,31,32,32,32,32,32,32,
|
||||||
|
32,32,32,33,33,33,33,33,33,33,33,34,34,34,34,34,
|
||||||
|
34,34,34,35,35,35,35,35,35,35,35,36,36,36,36,36,
|
||||||
|
36,36,36,37,37,37,37,37,37,37,38,38,38,38,38,38,
|
||||||
|
38,39,39,39,39,39,39,39,40,40,40,40,40,40,40,41,
|
||||||
|
41,41,41,41,41,41,42,42,42,42,42,42,43,43,43,43,
|
||||||
|
43,43,43,44,44,44,44,44,44,45,45,45,45,45,45,46,
|
||||||
|
46,46,46,46,46,47,47,47,47,47,47,48,48,48,48,48,
|
||||||
|
48,49,49,49,49,49,50,50,50,50,50,50,51,51,51,51,
|
||||||
|
51,52,52,52,52,52,53,53,53,53,53,54,54,54,54,54,
|
||||||
|
55,55,55,55,55,56,56,56,56,56,57,57,57,57,57,58,
|
||||||
|
58,58,58,58,59,59,59,59,59,60,60,60,60,61,61,61,
|
||||||
|
61,61,62,62,62,62,63,63,63,63,64,64,64,64,64,65,
|
||||||
|
65,65,65,66,66,66,66,67,67,67,67,68,68,68,68,69,
|
||||||
|
69,69,69,70,70,70,70,71,71,71,71,72,72,72,72,73,
|
||||||
|
73,73,73,74,74,74,75,75,75,75,76,76,76,76,77,77,
|
||||||
|
77,78,78,78,78,79,79,79,80,80,80,80,81,81,81,82,
|
||||||
|
82,82,83,83,83,83,84,84,84,85,85,85,86,86,86,86,
|
||||||
|
87,87,87,88,88,88,89,89,89,90,90,90,91,91,91,92,
|
||||||
|
92,92,93,93,93,94,94,94,95,95,95,96,96,96,97,97,
|
||||||
|
97,98,98,99,99,99,100,100,100,101,101,101,102,102,103,103,
|
||||||
|
103,104,104,104,105,105,106,106,106,107,107,108,108,108,109,109,
|
||||||
|
110,110,110,111,111,112,112,112,113,113,114,114,114,115,115,116,
|
||||||
|
116,116,117,117,118,118,119,119,119,120,120,121,121,122,122,123,
|
||||||
|
123,123,124,124,125,125,126,126,127,127,128,128,128,129,129,130,
|
||||||
|
130,131,131,132,132,133,133,134,134,135,135,136,136,137,137,138,
|
||||||
|
138,139,139,140,140,141,141,142,142,143,143,144,144,145,145,146,
|
||||||
|
146,147,147,148,148,149,150,150,151,151,152,152,153,153,154,155,
|
||||||
|
155,156,156,157,157,158,158,159,160,160,161,161,162,163,163,164,
|
||||||
|
164,165,166,166,167,167,168,169,169,170,170,171,172,172,173,173,
|
||||||
|
174,175,175,176,177,177,178,179,179,180,181,181,182,183,183,184,
|
||||||
|
184,185,186,187,187,188,189,189,190,191,191,192,193,193,194,195,
|
||||||
|
195,196,197,198,198,199,200,201,201,202,203,203,204,205,206,206,
|
||||||
|
207,208,209,209,210,211,212,212,213,214,215,216,216,217,218,219,
|
||||||
|
220,220,221,222,223,224,224,225,226,227,228,228,229,230,231,232,
|
||||||
|
233,233,234,235,236,237,238,239,239,240,241,242,243,244,245,246,
|
||||||
|
246,247,248,249,250,251,252,253,254,255,256,256,257,258,259,260,
|
||||||
|
261,262,263,264,265,266,267,268,269,270,271,272,273,274,275,276,
|
||||||
|
277,278,279,280,281,282,283,284,285,286,287,288,289,290,291,292,
|
||||||
|
293,294,295,296,297,299,300,301,302,303,304,305,306,307,308,310,
|
||||||
|
311,312,313,314,315,316,317,319,320,321,322,323,324,326,327,328,
|
||||||
|
329,330,332,333,334,335,336,338,339,340,341,342,344,345,346,347,
|
||||||
|
349,350,351,353,354,355,356,358,359,360,362,363,364,366,367,368,
|
||||||
|
369,371,372,374,375,376,378,379,380,382,383,384,386,387,389,390,
|
||||||
|
391,393,394,396,397,399,400,402,403,404,406,407,409,410,412,413,
|
||||||
|
415,416,418,419,421,422,424,425,427,429,430,432,433,435,436,438,
|
||||||
|
440,441,443,444,446,448,449,451,452,454,456,457,459,461,462,464,
|
||||||
|
466,467,469,471,472,474,476,478,479,481,483,485,486,488,490,492,
|
||||||
|
493,495,497,499,501,502,504,506,508,510,512,513,515,517,519,521,
|
||||||
|
523,525,527,528,530,532,534,536,538,540,542,544,546,548,550,552,
|
||||||
|
554,556,558,560,562,564,566,568,570,572,574,576,578,581,583,585,
|
||||||
|
587,589,591,593,595,598,600,602,604,606,608,611,613,615,617,620,
|
||||||
|
622,624,626,629,631,633,635,638,640,642,645,647,649,652,654,656,
|
||||||
|
659,661,664,666,668,671,673,676,678,681,683,685,688,690,693,695,
|
||||||
|
698,700,703,706,708,711,713,716,718,721,724,726,729,732,734,737,
|
||||||
|
739,742,745,748,750,753,756,758,761,764,767,769,772,775,778,781,
|
||||||
|
783,786,789,792,795,798,801,804,806,809,812,815,818,821,824,827,
|
||||||
|
830,833,836,839,842,845,848,851,854,858,861,864,867,870,873,876,
|
||||||
|
880,883,886,889,892,896,899,902,905,909,912,915,918,922,925,928,
|
||||||
|
932,935,939,942,945,949,952,956,959,963,966,970,973,977,980,984,
|
||||||
|
987,991,994,998,1002,1005,1009,1013,1016,1020,1024,1027,1031,1035,1038,1042,
|
||||||
|
1046,1050,1054,1057,1061,1065,1069,1073,1077,1081,1084,1088,1092,1096,1100,1104,
|
||||||
|
1108,1112,1116,1120,1124,1128,1133,1137,1141,1145,1149,1153,1157,1162,1166,1170,
|
||||||
|
1174,1178,1183,1187,1191,1196,1200,1204,1209,1213,1217,1222,1226,1231,1235,1240,
|
||||||
|
1244,1249,1253,1258,1262,1267,1271,1276,1280,1285,1290,1294,1299,1304,1309,1313,
|
||||||
|
1318,1323,1328,1332,1337,1342,1347,1352,1357,1362,1366,1371,1376,1381,1386,1391,
|
||||||
|
1396,1401,1407,1412,1417,1422,1427,1432,1437,1443,1448,1453,1458,1464,1469,1474,
|
||||||
|
1479,1485,1490,1496,1501,1506,1512,1517,1523,1528,1534,1539,1545,1551,1556,1562,
|
||||||
|
1567,1573,1579,1585,1590,1596,1602,1608,1613,1619,1625,1631,1637,1643,1649,1655,
|
||||||
|
1661,1667,1673,1679,1685,1691,1697,1703,1709,1716,1722,1728,1734,1741,1747,1753,
|
||||||
|
1760,1766,1772,1779,1785,1792,1798,1805,1811,1818,1824,1831,1837,1844,1851,1857,
|
||||||
|
1864,1871,1878,1884,1891,1898,1905,1912,1919,1926,1933,1940,1947,1954,1961,1968,
|
||||||
|
1975,1982,1989,1997,2004,2011,2018,2026,2033,2040,2048,2055,2062,2070,2077,2085,
|
||||||
|
2093,2100,2108,2115,2123,2131,2138,2146,2154,2162,2169,2177,2185,2193,2201,2209,
|
||||||
|
2217,2225,2233,2241,2249,2257,2266,2274,2282,2290,2298,2307,2315,2324,2332,2340,
|
||||||
|
2349,2357,2366,2374,2383,2392,2400,2409,2418,2426,2435,2444,2453,2462,2471,2480,
|
||||||
|
2489,2498,2507,2516,2525,2534,2543,2552,2561,2571,2580,2589,2599,2608,2618,2627,
|
||||||
|
2637,2646,2656,2665,2675,2685,2694,2704,2714,2724,2733,2743,2753,2763,2773,2783,
|
||||||
|
2793,2803,2814,2824,2834,2844,2855,2865,2875,2886,2896,2907,2917,2928,2938,2949,
|
||||||
|
2959,2970,2981,2992,3003,3013,3024,3035,3046,3057,3068,3079,3091,3102,3113,3124,
|
||||||
|
3135,3147,3158,3170,3181,3193,3204,3216,3227,3239,3251,3263,3274,3286,3298,3310,
|
||||||
|
3322,3334,3346,3358,3370,3382,3395,3407,3419,3432,3444,3457,3469,3482,3494,3507,
|
||||||
|
3520,3532,3545,3558,3571,3584,3597,3610,3623,3636,3649,3662,3675,3689,3702,3715,
|
||||||
|
3729,3742,3756,3769,3783,3797,3810,3824,3838,3852,3866,3880,3894,3908,3922,3936,
|
||||||
|
3951,3965,3979,3994,4008,4023,4037,4052,4066,4081,4096,4111,4125,4140,4155,4170,
|
||||||
|
4186,4201,4216,4231,4246,4262,4277,4293,4308,4324,4339,4355,4371,4387,4403,4418,
|
||||||
|
4434,4450,4467,4483,4499,4515,4532,4548,4564,4581,4597,4614,4631,4648,4664,4681,
|
||||||
|
4698,4715,4732,4749,4766,4784,4801,4818,4836,4853,4871,4888,4906,4924,4942,4960,
|
||||||
|
4978,4996,5014,5032,5050,5068,5087,5105,5123,5142,5161,5179,5198,5217,5236,5255,
|
||||||
|
5274,5293,5312,5331,5350,5370,5389,5409,5428,5448,5467,5487,5507,5527,5547,5567,
|
||||||
|
5587,5607,5628,5648,5668,5689,5710,5730,5751,5772,5793,5814,5835,5856,5877,5898,
|
||||||
|
5919,5941,5962,5984,6006,6027,6049,6071,6093,6115,6137,6159,6182,6204,6226,6249,
|
||||||
|
6271,6294,6317,6340,6363,6386,6409,6432,6455,6479,6502,6526,6549,6573,6597,6620,
|
||||||
|
6644,6668,6693,6717,6741,6765,6790,6814,6839,6864,6889,6914,6939,6964,6989,7014,
|
||||||
|
7040,7065,7091,7116,7142,7168,7194,7220,7246,7272,7298,7325,7351,7378,7404,7431,
|
||||||
|
7458,7485,7512,7539,7567,7594,7621,7649,7677,7704,7732,7760,7788,7817,7845,7873,
|
||||||
|
7902,7930,7959,7988,8017,8046,8075,8104,8133,8163,8192,8222,8251,8281,8311,8341,
|
||||||
|
8372,8402,8432,8463,8493,8524,8555,8586,8617,8648,8679,8711,8742,8774,8806,8837,
|
||||||
|
8869,8901,8934,8966,8998,9031,9064,9096,9129,9162,9195,9229,9262,9296,9329,9363,
|
||||||
|
9397,9431,9465,9499,9533,9568,9603,9637,9672,9707,9742,9777,9813,9848,9884,9920,
|
||||||
|
9956,9992,10028,10064,10100,10137,10174,10210,10247,10284,10322,10359,10396,10434,10472,10510,
|
||||||
|
10548,10586,10624,10662,10701,10740,10779,10818,10857,10896,10935,10975,11015,11054,11094,11135,
|
||||||
|
11175,11215,11256,11296,11337,11378,11420,11461,11502,11544,11586,11628,11670,11712,11754,11797,
|
||||||
|
11839,11882,11925,11968,12012,12055,12099,12142,12186,12230,12275,12319,12364,12408,12453,12498,
|
||||||
|
12543,12589,12634,12680,12726,12772,12818,12864,12911,12958,13004,13052,13099,13146,13194,13241,
|
||||||
|
};
|
||||||
|
|
||||||
|
if ( note < 0 )
|
||||||
|
note = 0;
|
||||||
|
if ( note > 127*16 )
|
||||||
|
note = 127*16;
|
||||||
|
|
||||||
|
return pFrequencies[note];
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
int Abs(int x)
|
||||||
|
{
|
||||||
|
if ( x < 0 )
|
||||||
|
return -x;
|
||||||
|
return x;
|
||||||
|
}
|
||||||
|
|
||||||
|
int Sinus(int x)
|
||||||
|
{
|
||||||
|
// translate x into [-pi, pi].f12
|
||||||
|
while ( x > 12868 )
|
||||||
|
x -= 25736;
|
||||||
|
while ( x < -12868 )
|
||||||
|
x += 25736;
|
||||||
|
// compute sin(x)
|
||||||
|
// see http://www.devmaster.net/forums/showthread.php?t=5784
|
||||||
|
const int B = 5215;
|
||||||
|
const int C = -1660;
|
||||||
|
return (B*x + ((C*x)>>12)*Abs(x))>>12;
|
||||||
|
}
|
||||||
8
NitroSynth/Utils.h
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
#ifndef _MIDI_H_
|
||||||
|
#define _MIDI_H_
|
||||||
|
|
||||||
|
unsigned short MidiNoteToFrequency(int note);
|
||||||
|
int Abs(int x);
|
||||||
|
int Sinus(int x); // fixed point .12
|
||||||
|
|
||||||
|
#endif // _MIDI_H_
|
||||||
1
NitroSynth/VST/README
Normal file
@@ -0,0 +1 @@
|
|||||||
|
Add here VST SDK 2.4
|
||||||
14
NitroSynth/resource.h
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
//{{NO_DEPENDENCIES}}
|
||||||
|
// Microsoft Visual C++ generated include file.
|
||||||
|
// Used by NitroSynth.rc
|
||||||
|
|
||||||
|
// Next default values for new objects
|
||||||
|
//
|
||||||
|
#ifdef APSTUDIO_INVOKED
|
||||||
|
#ifndef APSTUDIO_READONLY_SYMBOLS
|
||||||
|
#define _APS_NEXT_RESOURCE_VALUE 101
|
||||||
|
#define _APS_NEXT_COMMAND_VALUE 40001
|
||||||
|
#define _APS_NEXT_CONTROL_VALUE 1001
|
||||||
|
#define _APS_NEXT_SYMED_VALUE 101
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
41
Player/Makefile
Normal file
@@ -0,0 +1,41 @@
|
|||||||
|
#---------------------------------------------------------------------------------
|
||||||
|
.SUFFIXES:
|
||||||
|
#---------------------------------------------------------------------------------
|
||||||
|
ifeq ($(strip $(DEVKITARM)),)
|
||||||
|
$(error "Please set DEVKITARM in your environment. export DEVKITARM=<path to>devkitARM")
|
||||||
|
endif
|
||||||
|
|
||||||
|
include $(DEVKITARM)/ds_rules
|
||||||
|
|
||||||
|
export TARGET := $(shell basename $(CURDIR))
|
||||||
|
export TOPDIR := $(CURDIR)
|
||||||
|
|
||||||
|
|
||||||
|
.PHONY: $(TARGET).arm7 $(TARGET).arm9
|
||||||
|
|
||||||
|
#---------------------------------------------------------------------------------
|
||||||
|
# main targets
|
||||||
|
#---------------------------------------------------------------------------------
|
||||||
|
all: $(TARGET).nds
|
||||||
|
|
||||||
|
#---------------------------------------------------------------------------------
|
||||||
|
$(TARGET).nds : $(TARGET).arm7 $(TARGET).arm9
|
||||||
|
ndstool -c $(TARGET).nds -7 $(TARGET).arm7 -9 $(TARGET).arm9
|
||||||
|
|
||||||
|
#---------------------------------------------------------------------------------
|
||||||
|
$(TARGET).arm7 : arm7/$(TARGET).elf
|
||||||
|
$(TARGET).arm9 : arm9/$(TARGET).elf
|
||||||
|
|
||||||
|
#---------------------------------------------------------------------------------
|
||||||
|
arm7/$(TARGET).elf:
|
||||||
|
$(MAKE) -C arm7
|
||||||
|
|
||||||
|
#---------------------------------------------------------------------------------
|
||||||
|
arm9/$(TARGET).elf:
|
||||||
|
$(MAKE) -C arm9
|
||||||
|
|
||||||
|
#---------------------------------------------------------------------------------
|
||||||
|
clean:
|
||||||
|
$(MAKE) -C arm9 clean
|
||||||
|
$(MAKE) -C arm7 clean
|
||||||
|
rm -f $(TARGET).nds $(TARGET).arm7 $(TARGET).arm9
|
||||||
132
Player/arm7/Makefile
Normal file
@@ -0,0 +1,132 @@
|
|||||||
|
#---------------------------------------------------------------------------------
|
||||||
|
.SUFFIXES:
|
||||||
|
#---------------------------------------------------------------------------------
|
||||||
|
ifeq ($(strip $(DEVKITARM)),)
|
||||||
|
$(error "Please set DEVKITARM in your environment. export DEVKITARM=<path to>devkitARM")
|
||||||
|
endif
|
||||||
|
|
||||||
|
include $(DEVKITARM)/ds_rules
|
||||||
|
|
||||||
|
#---------------------------------------------------------------------------------
|
||||||
|
# BUILD is the directory where object files & intermediate files will be placed
|
||||||
|
# SOURCES is a list of directories containing source code
|
||||||
|
# INCLUDES is a list of directories containing extra header files
|
||||||
|
# DATA is a list of directories containing binary files
|
||||||
|
# all directories are relative to this makefile
|
||||||
|
#---------------------------------------------------------------------------------
|
||||||
|
BUILD := build
|
||||||
|
SOURCES := source
|
||||||
|
INCLUDES := include build
|
||||||
|
DATA :=
|
||||||
|
|
||||||
|
#---------------------------------------------------------------------------------
|
||||||
|
# options for code generation
|
||||||
|
#---------------------------------------------------------------------------------
|
||||||
|
ARCH := -mthumb-interwork -marm
|
||||||
|
|
||||||
|
CFLAGS := -g -Wall -O2\
|
||||||
|
-mcpu=arm7tdmi -mtune=arm7tdmi -fomit-frame-pointer\
|
||||||
|
-ffast-math \
|
||||||
|
$(ARCH)
|
||||||
|
|
||||||
|
CFLAGS += $(INCLUDE) -DARM7
|
||||||
|
CXXFLAGS := $(CFLAGS) -fno-rtti -fno-exceptions
|
||||||
|
|
||||||
|
|
||||||
|
ASFLAGS := -g $(ARCH) -Isource
|
||||||
|
LDFLAGS = -specs=ds_arm7.specs -g $(ARCH) -Wl,-Map,$(notdir $*).map
|
||||||
|
|
||||||
|
LIBS := -ldswifi7 -lmm7 -lnds7
|
||||||
|
|
||||||
|
#---------------------------------------------------------------------------------
|
||||||
|
# list of directories containing libraries, this must be the top level containing
|
||||||
|
# include and lib
|
||||||
|
#---------------------------------------------------------------------------------
|
||||||
|
LIBDIRS := $(LIBNDS)
|
||||||
|
|
||||||
|
|
||||||
|
#---------------------------------------------------------------------------------
|
||||||
|
# no real need to edit anything past this point unless you need to add additional
|
||||||
|
# rules for different file extensions
|
||||||
|
#---------------------------------------------------------------------------------
|
||||||
|
ifneq ($(BUILD),$(notdir $(CURDIR)))
|
||||||
|
#---------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
export ARM7BIN := $(TOPDIR)/$(TARGET).arm7
|
||||||
|
export ARM7ELF := $(CURDIR)/$(TARGET).arm7.elf
|
||||||
|
export DEPSDIR := $(CURDIR)/$(BUILD)
|
||||||
|
|
||||||
|
export VPATH := $(foreach dir,$(SOURCES),$(CURDIR)/$(dir))
|
||||||
|
|
||||||
|
CFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.c)))
|
||||||
|
CPPFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.cpp)))
|
||||||
|
SFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.s)))
|
||||||
|
BINFILES := $(foreach dir,$(DATA),$(notdir $(wildcard $(dir)/*.*)))
|
||||||
|
|
||||||
|
export OFILES := $(addsuffix .o,$(BINFILES)) \
|
||||||
|
$(CPPFILES:.cpp=.o) $(CFILES:.c=.o) $(SFILES:.s=.o)
|
||||||
|
|
||||||
|
export INCLUDE := $(foreach dir,$(INCLUDES),-I$(CURDIR)/$(dir)) \
|
||||||
|
$(foreach dir,$(LIBDIRS),-I$(dir)/include) \
|
||||||
|
-I$(CURDIR)/$(BUILD)
|
||||||
|
|
||||||
|
export LIBPATHS := $(foreach dir,$(LIBDIRS),-L$(dir)/lib)
|
||||||
|
|
||||||
|
#---------------------------------------------------------------------------------
|
||||||
|
# use CXX for linking C++ projects, CC for standard C
|
||||||
|
#---------------------------------------------------------------------------------
|
||||||
|
ifeq ($(strip $(CPPFILES)),)
|
||||||
|
#---------------------------------------------------------------------------------
|
||||||
|
export LD := $(CC)
|
||||||
|
#---------------------------------------------------------------------------------
|
||||||
|
else
|
||||||
|
#---------------------------------------------------------------------------------
|
||||||
|
export LD := $(CXX)
|
||||||
|
#---------------------------------------------------------------------------------
|
||||||
|
endif
|
||||||
|
#---------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
.PHONY: $(BUILD) clean
|
||||||
|
|
||||||
|
#---------------------------------------------------------------------------------
|
||||||
|
$(BUILD):
|
||||||
|
@[ -d $@ ] || mkdir -p $@
|
||||||
|
@make --no-print-directory -C $(BUILD) -f $(CURDIR)/Makefile
|
||||||
|
|
||||||
|
#---------------------------------------------------------------------------------
|
||||||
|
clean:
|
||||||
|
@echo clean ...
|
||||||
|
@rm -fr $(BUILD) *.elf
|
||||||
|
|
||||||
|
|
||||||
|
#---------------------------------------------------------------------------------
|
||||||
|
else
|
||||||
|
|
||||||
|
DEPENDS := $(OFILES:.o=.d)
|
||||||
|
|
||||||
|
#---------------------------------------------------------------------------------
|
||||||
|
# main targets
|
||||||
|
#---------------------------------------------------------------------------------
|
||||||
|
$(ARM7BIN) : $(ARM7ELF)
|
||||||
|
@$(OBJCOPY) -O binary $< $@
|
||||||
|
@echo built ... $(notdir $@)
|
||||||
|
|
||||||
|
|
||||||
|
$(ARM7ELF) : $(OFILES)
|
||||||
|
@echo linking $(notdir $@)
|
||||||
|
@$(LD) $(LDFLAGS) $(OFILES) $(LIBPATHS) $(LIBS) -o $@
|
||||||
|
|
||||||
|
|
||||||
|
#---------------------------------------------------------------------------------
|
||||||
|
# you need a rule like this for each extension you use as binary data
|
||||||
|
#---------------------------------------------------------------------------------
|
||||||
|
%.bin.o : %.bin
|
||||||
|
#---------------------------------------------------------------------------------
|
||||||
|
@echo $(notdir $<)
|
||||||
|
@$(bin2o)
|
||||||
|
|
||||||
|
-include $(DEPENDS)
|
||||||
|
|
||||||
|
#---------------------------------------------------------------------------------------
|
||||||
|
endif
|
||||||
|
#---------------------------------------------------------------------------------------
|
||||||
85
Player/arm7/source/Envelope.c
Normal file
@@ -0,0 +1,85 @@
|
|||||||
|
#include "Envelope.h"
|
||||||
|
#include "InstrumentParameters.h"
|
||||||
|
|
||||||
|
#define MAX_VOLUME 512
|
||||||
|
|
||||||
|
void Envelope_Init(Envelope * pEnvelope)
|
||||||
|
{
|
||||||
|
pEnvelope->iTime = 0;
|
||||||
|
pEnvelope->iLastEnvelope = 0;
|
||||||
|
pEnvelope->iVelocity = 0;
|
||||||
|
pEnvelope->iState = RELEASE;
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned int Envelope_Compute(Envelope * pEnvelope, InstrumentParameters * pParameters)
|
||||||
|
{
|
||||||
|
unsigned int iEnvelope = 0;
|
||||||
|
|
||||||
|
int iAttack = pParameters->iAttack;
|
||||||
|
int iDecay = pParameters->iDecay;
|
||||||
|
int iSustain = pParameters->iSustain * MAX_VOLUME / 127;
|
||||||
|
int iRelease = pParameters->iRelease;
|
||||||
|
|
||||||
|
pEnvelope->iTime++;
|
||||||
|
|
||||||
|
switch ( pEnvelope->iState )
|
||||||
|
{
|
||||||
|
case ATTACK:
|
||||||
|
{
|
||||||
|
iEnvelope = (pEnvelope->iTime * MAX_VOLUME) / iAttack;
|
||||||
|
if ( pEnvelope->iTime >= iAttack ) {
|
||||||
|
pEnvelope->iTime = 0;
|
||||||
|
pEnvelope->iState = DECAY;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case DECAY:
|
||||||
|
{
|
||||||
|
int s = MAX_VOLUME - iSustain;
|
||||||
|
iEnvelope = iSustain + s - ((pEnvelope->iTime * s) / iDecay);
|
||||||
|
if ( pEnvelope->iTime >= iDecay ) {
|
||||||
|
pEnvelope->iTime = 0;
|
||||||
|
pEnvelope->iState = SUSTAIN;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case SUSTAIN:
|
||||||
|
{
|
||||||
|
iEnvelope = iSustain;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case RELEASE:
|
||||||
|
{
|
||||||
|
if ( pEnvelope->iTime <= iRelease )
|
||||||
|
iEnvelope = pEnvelope->iLastEnvelope -
|
||||||
|
((pEnvelope->iTime * pEnvelope->iLastEnvelope) / iRelease);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( pEnvelope->iState != RELEASE )
|
||||||
|
pEnvelope->iLastEnvelope = iEnvelope;
|
||||||
|
|
||||||
|
iEnvelope = iEnvelope * pEnvelope->iVelocity / 127;
|
||||||
|
|
||||||
|
return iEnvelope / (MAX_VOLUME / 128);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Envelope_NoteOn(Envelope * pEnvelope, int v)
|
||||||
|
{
|
||||||
|
pEnvelope->iVelocity = v;
|
||||||
|
pEnvelope->iTime = 0;
|
||||||
|
pEnvelope->iState = ATTACK;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Envelope_NoteOff(Envelope * pEnvelope)
|
||||||
|
{
|
||||||
|
if ( pEnvelope->iState != RELEASE )
|
||||||
|
{
|
||||||
|
pEnvelope->iTime = 0;
|
||||||
|
pEnvelope->iState = RELEASE;
|
||||||
|
}
|
||||||
|
}
|
||||||
31
Player/arm7/source/Envelope.h
Normal file
@@ -0,0 +1,31 @@
|
|||||||
|
#ifndef _ENVELOPE_H_
|
||||||
|
#define _ENVELOPE_H_
|
||||||
|
|
||||||
|
#include "InstrumentParameters.h"
|
||||||
|
|
||||||
|
typedef enum
|
||||||
|
{
|
||||||
|
ATTACK,
|
||||||
|
DECAY,
|
||||||
|
SUSTAIN,
|
||||||
|
RELEASE
|
||||||
|
}
|
||||||
|
EnvelopeState;
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
int iTime;
|
||||||
|
int iLastEnvelope;
|
||||||
|
|
||||||
|
int iVelocity;
|
||||||
|
|
||||||
|
EnvelopeState iState;
|
||||||
|
}
|
||||||
|
Envelope;
|
||||||
|
|
||||||
|
void Envelope_Init(Envelope * pEnvelope);
|
||||||
|
unsigned int Envelope_Compute(Envelope * pEnvelope, InstrumentParameters * pParameters);
|
||||||
|
void Envelope_NoteOn(Envelope * pEnvelope, int velocity);
|
||||||
|
void Envelope_NoteOff(Envelope * pEnvelope);
|
||||||
|
|
||||||
|
#endif // _ENVELOPE_H_
|
||||||
109
Player/arm7/source/Instrument.c
Normal file
@@ -0,0 +1,109 @@
|
|||||||
|
#include "Instrument.h"
|
||||||
|
#include "Utils.h"
|
||||||
|
#include <nds.h>
|
||||||
|
|
||||||
|
#define SOUND_PSG_DUTY(duty) ((duty)<<24)
|
||||||
|
|
||||||
|
void Instrument_Init(Instrument* pInstrument, int iChannel, InstrumentParameters* pParameters)
|
||||||
|
{
|
||||||
|
pInstrument->pParameters = pParameters;
|
||||||
|
pInstrument->iChannel = iChannel;
|
||||||
|
pInstrument->iLastFrequency = 0;
|
||||||
|
pInstrument->pFrequencies[0] = 1;
|
||||||
|
pInstrument->iFrequency = 0;
|
||||||
|
pInstrument->iNbFrequencies = 0;
|
||||||
|
pInstrument->iEffectTimer = 0;
|
||||||
|
pInstrument->iSweepFrequency = 0;
|
||||||
|
pInstrument->iModulationAmplitude = 0;
|
||||||
|
pInstrument->iPortamentoFrequency = 0;
|
||||||
|
pInstrument->iArpeggioTimer = 0;
|
||||||
|
|
||||||
|
Envelope_Init(&pInstrument->oEnvelope);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Instrument_Compute(Instrument* pInstrument)
|
||||||
|
{
|
||||||
|
InstrumentParameters* pParameters = pInstrument->pParameters;
|
||||||
|
|
||||||
|
int iVolume = pParameters->iVolume;
|
||||||
|
|
||||||
|
if ( pParameters->iTremoloAmplitude != 0 )
|
||||||
|
{
|
||||||
|
int iSin = Sinus(pInstrument->iEffectTimer * 12868 * pParameters->iTremoloFrequency / 256) / 2 + 2048;
|
||||||
|
int iAmplitude = pParameters->iTremoloAmplitude * pParameters->iVolume / 255;
|
||||||
|
iVolume -= iSin * iAmplitude / 4096;
|
||||||
|
}
|
||||||
|
|
||||||
|
iVolume = Envelope_Compute(& pInstrument->oEnvelope, pParameters) * iVolume / 127;
|
||||||
|
|
||||||
|
if ( pParameters->iArpeggio > 0 )
|
||||||
|
{
|
||||||
|
pInstrument->iArpeggioTimer++;
|
||||||
|
if ( pInstrument->iArpeggioTimer >= pParameters->iArpeggio )
|
||||||
|
{
|
||||||
|
pInstrument->iArpeggioTimer = 0;
|
||||||
|
pInstrument->iFrequency++;
|
||||||
|
if ( pInstrument->iFrequency >= pInstrument->iNbFrequencies )
|
||||||
|
pInstrument->iFrequency = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pInstrument->iEffectTimer++;
|
||||||
|
|
||||||
|
int iSweep = 0;
|
||||||
|
if ( pParameters->iSweepLength != 0
|
||||||
|
&& pInstrument->iEffectTimer < pParameters->iSweepLength )
|
||||||
|
iSweep = pInstrument->iSweepFrequency - (pInstrument->iEffectTimer * pInstrument->iSweepFrequency) / pParameters->iSweepLength;
|
||||||
|
|
||||||
|
int iModulation = Sinus(pInstrument->iEffectTimer * 12868 * pParameters->iModulationFrequency / 256) * pInstrument->iModulationAmplitude / 4096;
|
||||||
|
|
||||||
|
int iPortamento = 0;
|
||||||
|
if ( pParameters->iPortamentoLength != 0 && pInstrument->iEffectTimer < pParameters->iPortamentoLength )
|
||||||
|
iPortamento = pInstrument->iPortamentoFrequency - (pInstrument->iEffectTimer * pInstrument->iPortamentoFrequency) / pParameters->iPortamentoLength;
|
||||||
|
|
||||||
|
pInstrument->iLastFrequency = pInstrument->pFrequencies[pInstrument->iFrequency] + iSweep + iModulation + iPortamento;
|
||||||
|
|
||||||
|
if ( pInstrument->iLastFrequency <= 0 )
|
||||||
|
pInstrument->iLastFrequency = 1;
|
||||||
|
|
||||||
|
SCHANNEL_CR(pInstrument->iChannel) = SCHANNEL_ENABLE
|
||||||
|
| SOUND_VOL(iVolume)
|
||||||
|
| SOUND_PAN(pParameters->iPanning)
|
||||||
|
| SOUND_FORMAT_PSG
|
||||||
|
| SOUND_PSG_DUTY(pParameters->iDuty)
|
||||||
|
;
|
||||||
|
SCHANNEL_TIMER(pInstrument->iChannel) = SOUND_FREQ(pInstrument->iLastFrequency * 8);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Instrument_NoteOn(Instrument* pInstrument, int iNote, int iVelocity)
|
||||||
|
{
|
||||||
|
int n = iNote + pInstrument->pParameters->iDetune;
|
||||||
|
|
||||||
|
Envelope_NoteOn(& pInstrument->oEnvelope, iVelocity);
|
||||||
|
|
||||||
|
if ( pInstrument->iEffectTimer < 3
|
||||||
|
&& pInstrument->iNbFrequencies <= sizeof(pInstrument->pFrequencies)/sizeof(pInstrument->pFrequencies[0]) )
|
||||||
|
{
|
||||||
|
// Arpeggio !
|
||||||
|
pInstrument->pFrequencies[pInstrument->iNbFrequencies++] = MidiNoteToFrequency(n);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
pInstrument->pFrequencies[0] = MidiNoteToFrequency(n);
|
||||||
|
pInstrument->iNbFrequencies = 1;
|
||||||
|
pInstrument->iArpeggioTimer = 0;
|
||||||
|
pInstrument->iEffectTimer = 0;
|
||||||
|
pInstrument->iFrequency = 0;
|
||||||
|
if ( pInstrument->iLastFrequency == 0 )
|
||||||
|
pInstrument->iLastFrequency = pInstrument->pFrequencies[0];
|
||||||
|
pInstrument->iPortamentoFrequency = pInstrument->iLastFrequency - pInstrument->pFrequencies[0];
|
||||||
|
pInstrument->iSweepFrequency = MidiNoteToFrequency(n + pInstrument->pParameters->iSweepOffset) - pInstrument->pFrequencies[0];
|
||||||
|
pInstrument->iModulationAmplitude = MidiNoteToFrequency(n + pInstrument->pParameters->iModulationAmplitude) - pInstrument->pFrequencies[0];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Instrument_NoteOff(Instrument* pInstrument)
|
||||||
|
{
|
||||||
|
Envelope_NoteOff(& pInstrument->oEnvelope);
|
||||||
|
}
|
||||||
|
|
||||||
60
Player/arm7/source/Instrument.h
Normal file
@@ -0,0 +1,60 @@
|
|||||||
|
#ifndef _INSTRUMENT_H_
|
||||||
|
#define _INSTRUMENT_H_
|
||||||
|
|
||||||
|
#include "Envelope.h"
|
||||||
|
#include "InstrumentParameters.h"
|
||||||
|
|
||||||
|
enum {
|
||||||
|
VOLUME,
|
||||||
|
PANNING,
|
||||||
|
DETUNE,
|
||||||
|
ENVELOPE_ATTACK,
|
||||||
|
ENVELOPE_DECAY,
|
||||||
|
ENVELOPE_SUSTAIN,
|
||||||
|
ENVELOPE_RELEASE,
|
||||||
|
DUTY,
|
||||||
|
PORTAMENTO_LENGTH,
|
||||||
|
ARPEGGIO,
|
||||||
|
SWEEP_LENGTH,
|
||||||
|
SWEEP_OFFSET,
|
||||||
|
MODULATION_AMPLITUDE,
|
||||||
|
MODULATION_FREQUENCY,
|
||||||
|
TREMOLO_AMPLITUDE,
|
||||||
|
TREMOLO_FREQUENCY,
|
||||||
|
LAST,
|
||||||
|
NOTEON = 29, // for export
|
||||||
|
NOTEOFF = 30, // for export
|
||||||
|
END = 31 // for export
|
||||||
|
};
|
||||||
|
|
||||||
|
struct sInstrument {
|
||||||
|
InstrumentParameters * pParameters;
|
||||||
|
|
||||||
|
int iChannel;
|
||||||
|
Envelope oEnvelope;
|
||||||
|
|
||||||
|
float fTime;
|
||||||
|
int iLastFrequency;
|
||||||
|
|
||||||
|
unsigned int pFrequencies[8];
|
||||||
|
unsigned int iNbFrequencies;
|
||||||
|
unsigned int iFrequency;
|
||||||
|
unsigned int iArpeggioTimer;
|
||||||
|
int iEffectTimer;
|
||||||
|
int iSweepFrequency;
|
||||||
|
int iModulationAmplitude;
|
||||||
|
int iPortamentoFrequency;
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef struct sInstrument Instrument;
|
||||||
|
|
||||||
|
void Instrument_Init(Instrument * pInstrument, int iChannel, InstrumentParameters * pParameters);
|
||||||
|
|
||||||
|
void Instrument_Compute(Instrument * pInstrument);
|
||||||
|
|
||||||
|
void Instrument_NoteOn(Instrument * pInstrument, int iNote, int iVelocity);
|
||||||
|
void Instrument_NoteOff(Instrument * pInstrument);
|
||||||
|
|
||||||
|
void Instrument_SetParameters(Instrument * pInstrument, InstrumentParameters * p);
|
||||||
|
|
||||||
|
#endif // _INSTRUMENT_H_
|
||||||
21
Player/arm7/source/InstrumentParameters.c
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
#include "InstrumentParameters.h"
|
||||||
|
|
||||||
|
void InstrumentParameters_Init(InstrumentParameters * pParameters)
|
||||||
|
{
|
||||||
|
pParameters->iVolume = 64;
|
||||||
|
pParameters->iPanning = 64;
|
||||||
|
pParameters->iDetune = 0;
|
||||||
|
pParameters->iDuty = 0;
|
||||||
|
pParameters->iPortamentoLength = 0;
|
||||||
|
pParameters->iAttack = 2;
|
||||||
|
pParameters->iDecay = 16;
|
||||||
|
pParameters->iSustain = 64;
|
||||||
|
pParameters->iRelease = 5;
|
||||||
|
pParameters->iTremoloAmplitude = 0;
|
||||||
|
pParameters->iTremoloFrequency = 0;
|
||||||
|
pParameters->iSweepOffset = 0;
|
||||||
|
pParameters->iSweepLength = 0;
|
||||||
|
pParameters->iModulationAmplitude = 0;
|
||||||
|
pParameters->iModulationFrequency = 0;
|
||||||
|
pParameters->iArpeggio = 0;
|
||||||
|
}
|
||||||
35
Player/arm7/source/InstrumentParameters.h
Normal file
@@ -0,0 +1,35 @@
|
|||||||
|
#ifndef _INSTRUMENTPARAMETERS_H_
|
||||||
|
#define _INSTRUMENTPARAMETERS_H_
|
||||||
|
|
||||||
|
struct sInstrumentParameters
|
||||||
|
{
|
||||||
|
unsigned char iVolume;
|
||||||
|
unsigned char iPanning;
|
||||||
|
signed char iDetune;
|
||||||
|
unsigned char iDuty;
|
||||||
|
|
||||||
|
unsigned char iAttack; // 1..255
|
||||||
|
unsigned char iDecay; // 1..255
|
||||||
|
unsigned char iSustain; // 0..127
|
||||||
|
unsigned char iRelease; // 1..255
|
||||||
|
|
||||||
|
unsigned char iTremoloAmplitude;
|
||||||
|
unsigned char iTremoloFrequency;
|
||||||
|
|
||||||
|
unsigned char iPortamentoLength;
|
||||||
|
|
||||||
|
unsigned char iSweepLength;
|
||||||
|
signed short iSweepOffset;
|
||||||
|
|
||||||
|
unsigned char iModulationAmplitude;
|
||||||
|
unsigned char iModulationFrequency;
|
||||||
|
|
||||||
|
unsigned char iArpeggio;
|
||||||
|
unsigned char pad;
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef struct sInstrumentParameters InstrumentParameters;
|
||||||
|
|
||||||
|
void InstrumentParameters_Init(InstrumentParameters * pParameters);
|
||||||
|
|
||||||
|
#endif // _INSTRUMENTPARAMETERS_H_
|
||||||
155
Player/arm7/source/Player.c
Normal file
@@ -0,0 +1,155 @@
|
|||||||
|
#include "Player.h"
|
||||||
|
#include "Utils.h"
|
||||||
|
#include <nds.h>
|
||||||
|
|
||||||
|
void Player_Handler(u32 iCommand, void* pUserdata)
|
||||||
|
{
|
||||||
|
Player* pPlayer = (Player *) pUserdata;
|
||||||
|
if ( iCommand == 0 )
|
||||||
|
Player_Stop(pPlayer);
|
||||||
|
else
|
||||||
|
Player_Play(pPlayer, (unsigned char *) iCommand);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Player_Init(Player* pPlayer)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for ( i = 0 ; i < 8 ; i++ )
|
||||||
|
{
|
||||||
|
InstrumentParameters_Init(& pPlayer->pParameters[i]);
|
||||||
|
Instrument_Init(& pPlayer->pInstruments[i], i + 8, & pPlayer->pParameters[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
pPlayer->pCommand = 0;
|
||||||
|
pPlayer->iTimer = 0;
|
||||||
|
|
||||||
|
fifoSetValue32Handler(FIFO_USER_01, Player_Handler, pPlayer);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Player_Play(Player* pPlayer, unsigned char* pData)
|
||||||
|
{
|
||||||
|
MemCopy(pPlayer->pParameters, pData, sizeof(InstrumentParameters)*8);
|
||||||
|
pPlayer->pCommand = (Command *) (pData + sizeof(InstrumentParameters)*8);
|
||||||
|
pPlayer->iTimer = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Player_Stop(Player* pPlayer)
|
||||||
|
{
|
||||||
|
pPlayer->pCommand = 0;
|
||||||
|
|
||||||
|
int i;
|
||||||
|
for ( i = 0 ; i < 8 ; i++ )
|
||||||
|
Instrument_NoteOff(& pPlayer->pInstruments[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Player_Execute(Player* pPlayer)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
if ( pPlayer->pCommand != 0 )
|
||||||
|
{
|
||||||
|
int iCommand = pPlayer->pCommand->iCommand;
|
||||||
|
|
||||||
|
while ( iCommand != END && pPlayer->iTimer == pPlayer->pCommand->iFrame )
|
||||||
|
{
|
||||||
|
Instrument* pInstrument = & pPlayer->pInstruments[pPlayer->pCommand->iChannel];
|
||||||
|
InstrumentParameters* pParameters = & pPlayer->pParameters[pPlayer->pCommand->iChannel];
|
||||||
|
int iValue = pPlayer->pCommand->iValue;
|
||||||
|
|
||||||
|
switch ( iCommand )
|
||||||
|
{
|
||||||
|
case VOLUME:
|
||||||
|
pParameters->iVolume = iValue;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case PANNING:
|
||||||
|
pParameters->iPanning = iValue;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case DETUNE:
|
||||||
|
pParameters->iDetune = iValue;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case ENVELOPE_ATTACK:
|
||||||
|
pParameters->iAttack = iValue;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case ENVELOPE_DECAY:
|
||||||
|
pParameters->iDecay = iValue;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case ENVELOPE_SUSTAIN:
|
||||||
|
pParameters->iSustain = iValue;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case ENVELOPE_RELEASE:
|
||||||
|
pParameters->iRelease = iValue;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case DUTY:
|
||||||
|
pParameters->iDuty = iValue;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case PORTAMENTO_LENGTH:
|
||||||
|
pParameters->iPortamentoLength = iValue;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case SWEEP_LENGTH:
|
||||||
|
pParameters->iSweepLength = iValue;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case SWEEP_OFFSET:
|
||||||
|
pParameters->iSweepOffset = iValue;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case MODULATION_AMPLITUDE:
|
||||||
|
pParameters->iModulationAmplitude = iValue;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case MODULATION_FREQUENCY:
|
||||||
|
pParameters->iModulationFrequency = iValue;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case TREMOLO_AMPLITUDE:
|
||||||
|
pParameters->iTremoloAmplitude = iValue;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case TREMOLO_FREQUENCY:
|
||||||
|
pParameters->iTremoloFrequency = iValue;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case ARPEGGIO:
|
||||||
|
pParameters->iArpeggio = iValue;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case NOTEON:
|
||||||
|
Instrument_NoteOn(pInstrument,
|
||||||
|
iValue & 0xFFFF,
|
||||||
|
iValue >> 16);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case NOTEOFF:
|
||||||
|
Instrument_NoteOff(pInstrument);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
pPlayer->pCommand++;
|
||||||
|
pPlayer->iTimer = 0;
|
||||||
|
|
||||||
|
iCommand = pPlayer->pCommand->iCommand;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( pPlayer->pCommand->iCommand == END )
|
||||||
|
{
|
||||||
|
for ( i = 0 ; i < 8 ; i++ )
|
||||||
|
Instrument_NoteOff(& pPlayer->pInstruments[i]);
|
||||||
|
pPlayer->pCommand = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
pPlayer->iTimer++;
|
||||||
|
}
|
||||||
|
|
||||||
|
for ( i = 0 ; i < 8 ; i++ )
|
||||||
|
Instrument_Compute(& pPlayer->pInstruments[i]);
|
||||||
|
}
|
||||||
25
Player/arm7/source/Player.h
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
#ifndef _PLAYER_H_
|
||||||
|
#define _PLAYER_H_
|
||||||
|
|
||||||
|
#include "Instrument.h"
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
unsigned int iFrame : 24;
|
||||||
|
unsigned int iChannel : 3;
|
||||||
|
unsigned int iCommand : 5; // see Instrument.h
|
||||||
|
int iValue;
|
||||||
|
} Command;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
Instrument pInstruments[8];
|
||||||
|
InstrumentParameters pParameters[8];
|
||||||
|
Command * pCommand;
|
||||||
|
int iTimer;
|
||||||
|
} Player;
|
||||||
|
|
||||||
|
void Player_Init(Player * pPlayer);
|
||||||
|
void Player_Play(Player * pPlayer, unsigned char * pData);
|
||||||
|
void Player_Stop(Player * pPlayer);
|
||||||
|
void Player_Execute(Player * pPlayer);
|
||||||
|
|
||||||
|
#endif // _PLAYER_H_
|
||||||
174
Player/arm7/source/Utils.c
Normal file
@@ -0,0 +1,174 @@
|
|||||||
|
#include "Utils.h"
|
||||||
|
|
||||||
|
unsigned short MidiNoteToFrequency(int note)
|
||||||
|
{
|
||||||
|
static const unsigned short pFrequencies[] =
|
||||||
|
{
|
||||||
|
8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
|
||||||
|
8,8,8,8,8,8,8,8,8,8,8,9,9,9,9,9,
|
||||||
|
9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,
|
||||||
|
9,9,9,9,9,9,9,9,10,10,10,10,10,10,10,10,
|
||||||
|
10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,
|
||||||
|
10,10,10,11,11,11,11,11,11,11,11,11,11,11,11,11,
|
||||||
|
11,11,11,11,11,11,11,11,11,11,11,12,12,12,12,12,
|
||||||
|
12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,
|
||||||
|
12,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,
|
||||||
|
13,13,13,13,13,14,14,14,14,14,14,14,14,14,14,14,
|
||||||
|
14,14,14,14,14,14,14,14,14,15,15,15,15,15,15,15,
|
||||||
|
15,15,15,15,15,15,15,15,15,15,16,16,16,16,16,16,
|
||||||
|
16,16,16,16,16,16,16,16,16,16,16,17,17,17,17,17,
|
||||||
|
17,17,17,17,17,17,17,17,17,17,17,18,18,18,18,18,
|
||||||
|
18,18,18,18,18,18,18,18,18,18,19,19,19,19,19,19,
|
||||||
|
19,19,19,19,19,19,19,19,20,20,20,20,20,20,20,20,
|
||||||
|
20,20,20,20,20,20,21,21,21,21,21,21,21,21,21,21,
|
||||||
|
21,21,21,22,22,22,22,22,22,22,22,22,22,22,22,23,
|
||||||
|
23,23,23,23,23,23,23,23,23,23,23,24,24,24,24,24,
|
||||||
|
24,24,24,24,24,24,25,25,25,25,25,25,25,25,25,25,
|
||||||
|
25,26,26,26,26,26,26,26,26,26,26,27,27,27,27,27,
|
||||||
|
27,27,27,27,27,28,28,28,28,28,28,28,28,28,28,29,
|
||||||
|
29,29,29,29,29,29,29,29,29,30,30,30,30,30,30,30,
|
||||||
|
30,30,31,31,31,31,31,31,31,31,32,32,32,32,32,32,
|
||||||
|
32,32,32,33,33,33,33,33,33,33,33,34,34,34,34,34,
|
||||||
|
34,34,34,35,35,35,35,35,35,35,35,36,36,36,36,36,
|
||||||
|
36,36,36,37,37,37,37,37,37,37,38,38,38,38,38,38,
|
||||||
|
38,39,39,39,39,39,39,39,40,40,40,40,40,40,40,41,
|
||||||
|
41,41,41,41,41,41,42,42,42,42,42,42,43,43,43,43,
|
||||||
|
43,43,43,44,44,44,44,44,44,45,45,45,45,45,45,46,
|
||||||
|
46,46,46,46,46,47,47,47,47,47,47,48,48,48,48,48,
|
||||||
|
48,49,49,49,49,49,50,50,50,50,50,50,51,51,51,51,
|
||||||
|
51,52,52,52,52,52,53,53,53,53,53,54,54,54,54,54,
|
||||||
|
55,55,55,55,55,56,56,56,56,56,57,57,57,57,57,58,
|
||||||
|
58,58,58,58,59,59,59,59,59,60,60,60,60,61,61,61,
|
||||||
|
61,61,62,62,62,62,63,63,63,63,64,64,64,64,64,65,
|
||||||
|
65,65,65,66,66,66,66,67,67,67,67,68,68,68,68,69,
|
||||||
|
69,69,69,70,70,70,70,71,71,71,71,72,72,72,72,73,
|
||||||
|
73,73,73,74,74,74,75,75,75,75,76,76,76,76,77,77,
|
||||||
|
77,78,78,78,78,79,79,79,80,80,80,80,81,81,81,82,
|
||||||
|
82,82,83,83,83,83,84,84,84,85,85,85,86,86,86,86,
|
||||||
|
87,87,87,88,88,88,89,89,89,90,90,90,91,91,91,92,
|
||||||
|
92,92,93,93,93,94,94,94,95,95,95,96,96,96,97,97,
|
||||||
|
97,98,98,99,99,99,100,100,100,101,101,101,102,102,103,103,
|
||||||
|
103,104,104,104,105,105,106,106,106,107,107,108,108,108,109,109,
|
||||||
|
110,110,110,111,111,112,112,112,113,113,114,114,114,115,115,116,
|
||||||
|
116,116,117,117,118,118,119,119,119,120,120,121,121,122,122,123,
|
||||||
|
123,123,124,124,125,125,126,126,127,127,128,128,128,129,129,130,
|
||||||
|
130,131,131,132,132,133,133,134,134,135,135,136,136,137,137,138,
|
||||||
|
138,139,139,140,140,141,141,142,142,143,143,144,144,145,145,146,
|
||||||
|
146,147,147,148,148,149,150,150,151,151,152,152,153,153,154,155,
|
||||||
|
155,156,156,157,157,158,158,159,160,160,161,161,162,163,163,164,
|
||||||
|
164,165,166,166,167,167,168,169,169,170,170,171,172,172,173,173,
|
||||||
|
174,175,175,176,177,177,178,179,179,180,181,181,182,183,183,184,
|
||||||
|
184,185,186,187,187,188,189,189,190,191,191,192,193,193,194,195,
|
||||||
|
195,196,197,198,198,199,200,201,201,202,203,203,204,205,206,206,
|
||||||
|
207,208,209,209,210,211,212,212,213,214,215,216,216,217,218,219,
|
||||||
|
220,220,221,222,223,224,224,225,226,227,228,228,229,230,231,232,
|
||||||
|
233,233,234,235,236,237,238,239,239,240,241,242,243,244,245,246,
|
||||||
|
246,247,248,249,250,251,252,253,254,255,256,256,257,258,259,260,
|
||||||
|
261,262,263,264,265,266,267,268,269,270,271,272,273,274,275,276,
|
||||||
|
277,278,279,280,281,282,283,284,285,286,287,288,289,290,291,292,
|
||||||
|
293,294,295,296,297,299,300,301,302,303,304,305,306,307,308,310,
|
||||||
|
311,312,313,314,315,316,317,319,320,321,322,323,324,326,327,328,
|
||||||
|
329,330,332,333,334,335,336,338,339,340,341,342,344,345,346,347,
|
||||||
|
349,350,351,353,354,355,356,358,359,360,362,363,364,366,367,368,
|
||||||
|
369,371,372,374,375,376,378,379,380,382,383,384,386,387,389,390,
|
||||||
|
391,393,394,396,397,399,400,402,403,404,406,407,409,410,412,413,
|
||||||
|
415,416,418,419,421,422,424,425,427,429,430,432,433,435,436,438,
|
||||||
|
440,441,443,444,446,448,449,451,452,454,456,457,459,461,462,464,
|
||||||
|
466,467,469,471,472,474,476,478,479,481,483,485,486,488,490,492,
|
||||||
|
493,495,497,499,501,502,504,506,508,510,512,513,515,517,519,521,
|
||||||
|
523,525,527,528,530,532,534,536,538,540,542,544,546,548,550,552,
|
||||||
|
554,556,558,560,562,564,566,568,570,572,574,576,578,581,583,585,
|
||||||
|
587,589,591,593,595,598,600,602,604,606,608,611,613,615,617,620,
|
||||||
|
622,624,626,629,631,633,635,638,640,642,645,647,649,652,654,656,
|
||||||
|
659,661,664,666,668,671,673,676,678,681,683,685,688,690,693,695,
|
||||||
|
698,700,703,706,708,711,713,716,718,721,724,726,729,732,734,737,
|
||||||
|
739,742,745,748,750,753,756,758,761,764,767,769,772,775,778,781,
|
||||||
|
783,786,789,792,795,798,801,804,806,809,812,815,818,821,824,827,
|
||||||
|
830,833,836,839,842,845,848,851,854,858,861,864,867,870,873,876,
|
||||||
|
880,883,886,889,892,896,899,902,905,909,912,915,918,922,925,928,
|
||||||
|
932,935,939,942,945,949,952,956,959,963,966,970,973,977,980,984,
|
||||||
|
987,991,994,998,1002,1005,1009,1013,1016,1020,1024,1027,1031,1035,1038,1042,
|
||||||
|
1046,1050,1054,1057,1061,1065,1069,1073,1077,1081,1084,1088,1092,1096,1100,1104,
|
||||||
|
1108,1112,1116,1120,1124,1128,1133,1137,1141,1145,1149,1153,1157,1162,1166,1170,
|
||||||
|
1174,1178,1183,1187,1191,1196,1200,1204,1209,1213,1217,1222,1226,1231,1235,1240,
|
||||||
|
1244,1249,1253,1258,1262,1267,1271,1276,1280,1285,1290,1294,1299,1304,1309,1313,
|
||||||
|
1318,1323,1328,1332,1337,1342,1347,1352,1357,1362,1366,1371,1376,1381,1386,1391,
|
||||||
|
1396,1401,1407,1412,1417,1422,1427,1432,1437,1443,1448,1453,1458,1464,1469,1474,
|
||||||
|
1479,1485,1490,1496,1501,1506,1512,1517,1523,1528,1534,1539,1545,1551,1556,1562,
|
||||||
|
1567,1573,1579,1585,1590,1596,1602,1608,1613,1619,1625,1631,1637,1643,1649,1655,
|
||||||
|
1661,1667,1673,1679,1685,1691,1697,1703,1709,1716,1722,1728,1734,1741,1747,1753,
|
||||||
|
1760,1766,1772,1779,1785,1792,1798,1805,1811,1818,1824,1831,1837,1844,1851,1857,
|
||||||
|
1864,1871,1878,1884,1891,1898,1905,1912,1919,1926,1933,1940,1947,1954,1961,1968,
|
||||||
|
1975,1982,1989,1997,2004,2011,2018,2026,2033,2040,2048,2055,2062,2070,2077,2085,
|
||||||
|
2093,2100,2108,2115,2123,2131,2138,2146,2154,2162,2169,2177,2185,2193,2201,2209,
|
||||||
|
2217,2225,2233,2241,2249,2257,2266,2274,2282,2290,2298,2307,2315,2324,2332,2340,
|
||||||
|
2349,2357,2366,2374,2383,2392,2400,2409,2418,2426,2435,2444,2453,2462,2471,2480,
|
||||||
|
2489,2498,2507,2516,2525,2534,2543,2552,2561,2571,2580,2589,2599,2608,2618,2627,
|
||||||
|
2637,2646,2656,2665,2675,2685,2694,2704,2714,2724,2733,2743,2753,2763,2773,2783,
|
||||||
|
2793,2803,2814,2824,2834,2844,2855,2865,2875,2886,2896,2907,2917,2928,2938,2949,
|
||||||
|
2959,2970,2981,2992,3003,3013,3024,3035,3046,3057,3068,3079,3091,3102,3113,3124,
|
||||||
|
3135,3147,3158,3170,3181,3193,3204,3216,3227,3239,3251,3263,3274,3286,3298,3310,
|
||||||
|
3322,3334,3346,3358,3370,3382,3395,3407,3419,3432,3444,3457,3469,3482,3494,3507,
|
||||||
|
3520,3532,3545,3558,3571,3584,3597,3610,3623,3636,3649,3662,3675,3689,3702,3715,
|
||||||
|
3729,3742,3756,3769,3783,3797,3810,3824,3838,3852,3866,3880,3894,3908,3922,3936,
|
||||||
|
3951,3965,3979,3994,4008,4023,4037,4052,4066,4081,4096,4111,4125,4140,4155,4170,
|
||||||
|
4186,4201,4216,4231,4246,4262,4277,4293,4308,4324,4339,4355,4371,4387,4403,4418,
|
||||||
|
4434,4450,4467,4483,4499,4515,4532,4548,4564,4581,4597,4614,4631,4648,4664,4681,
|
||||||
|
4698,4715,4732,4749,4766,4784,4801,4818,4836,4853,4871,4888,4906,4924,4942,4960,
|
||||||
|
4978,4996,5014,5032,5050,5068,5087,5105,5123,5142,5161,5179,5198,5217,5236,5255,
|
||||||
|
5274,5293,5312,5331,5350,5370,5389,5409,5428,5448,5467,5487,5507,5527,5547,5567,
|
||||||
|
5587,5607,5628,5648,5668,5689,5710,5730,5751,5772,5793,5814,5835,5856,5877,5898,
|
||||||
|
5919,5941,5962,5984,6006,6027,6049,6071,6093,6115,6137,6159,6182,6204,6226,6249,
|
||||||
|
6271,6294,6317,6340,6363,6386,6409,6432,6455,6479,6502,6526,6549,6573,6597,6620,
|
||||||
|
6644,6668,6693,6717,6741,6765,6790,6814,6839,6864,6889,6914,6939,6964,6989,7014,
|
||||||
|
7040,7065,7091,7116,7142,7168,7194,7220,7246,7272,7298,7325,7351,7378,7404,7431,
|
||||||
|
7458,7485,7512,7539,7567,7594,7621,7649,7677,7704,7732,7760,7788,7817,7845,7873,
|
||||||
|
7902,7930,7959,7988,8017,8046,8075,8104,8133,8163,8192,8222,8251,8281,8311,8341,
|
||||||
|
8372,8402,8432,8463,8493,8524,8555,8586,8617,8648,8679,8711,8742,8774,8806,8837,
|
||||||
|
8869,8901,8934,8966,8998,9031,9064,9096,9129,9162,9195,9229,9262,9296,9329,9363,
|
||||||
|
9397,9431,9465,9499,9533,9568,9603,9637,9672,9707,9742,9777,9813,9848,9884,9920,
|
||||||
|
9956,9992,10028,10064,10100,10137,10174,10210,10247,10284,10322,10359,10396,10434,10472,10510,
|
||||||
|
10548,10586,10624,10662,10701,10740,10779,10818,10857,10896,10935,10975,11015,11054,11094,11135,
|
||||||
|
11175,11215,11256,11296,11337,11378,11420,11461,11502,11544,11586,11628,11670,11712,11754,11797,
|
||||||
|
11839,11882,11925,11968,12012,12055,12099,12142,12186,12230,12275,12319,12364,12408,12453,12498,
|
||||||
|
12543,12589,12634,12680,12726,12772,12818,12864,12911,12958,13004,13052,13099,13146,13194,13241,
|
||||||
|
};
|
||||||
|
|
||||||
|
if ( note < 0 )
|
||||||
|
note = 0;
|
||||||
|
if ( note > 127*16 )
|
||||||
|
note = 127*16;
|
||||||
|
|
||||||
|
return pFrequencies[note];
|
||||||
|
}
|
||||||
|
|
||||||
|
int Abs(int x)
|
||||||
|
{
|
||||||
|
if ( x < 0 )
|
||||||
|
return -x;
|
||||||
|
return x;
|
||||||
|
}
|
||||||
|
|
||||||
|
int Sinus(int x)
|
||||||
|
{
|
||||||
|
// translate x into [-pi, pi].f12
|
||||||
|
while ( x > 12868 )
|
||||||
|
x -= 25736;
|
||||||
|
while ( x < -12868 )
|
||||||
|
x += 25736;
|
||||||
|
// compute sin(x)
|
||||||
|
// see http://www.devmaster.net/forums/showthread.php?t=5784
|
||||||
|
const int B = 5215;
|
||||||
|
const int C = -1660;
|
||||||
|
return (B*x + ((C*x)>>12)*Abs(x))>>12;
|
||||||
|
}
|
||||||
|
|
||||||
|
void MemCopy(void * dst, void * src, int len)
|
||||||
|
{
|
||||||
|
unsigned char * d = (unsigned char *) dst;
|
||||||
|
unsigned char * s = (unsigned char *) src;
|
||||||
|
|
||||||
|
while ( len-- )
|
||||||
|
*d++ = *s++;
|
||||||
|
}
|
||||||
|
|
||||||
9
Player/arm7/source/Utils.h
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
#ifndef _MIDI_H_
|
||||||
|
#define _MIDI_H_
|
||||||
|
|
||||||
|
unsigned short MidiNoteToFrequency(int note);
|
||||||
|
int Abs(int x);
|
||||||
|
int Sinus(int x); // fixed point .12
|
||||||
|
void MemCopy(void * pDestination, void * pSource, int iSize);
|
||||||
|
|
||||||
|
#endif // _MIDI_H_
|
||||||
8
Player/arm7/source/bios.s
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
.text
|
||||||
|
.align 4
|
||||||
|
.thumb
|
||||||
|
.global swiWaitVBL
|
||||||
|
.thumb_func
|
||||||
|
swiWaitVBL:
|
||||||
|
swi 0x05
|
||||||
|
bx lr
|
||||||
41
Player/arm7/source/main.c
Normal file
@@ -0,0 +1,41 @@
|
|||||||
|
#include <nds.h>
|
||||||
|
#include <dswifi7.h>
|
||||||
|
#include <maxmod7.h>
|
||||||
|
#include "Player.h"
|
||||||
|
|
||||||
|
void VCountHandler()
|
||||||
|
{
|
||||||
|
inputGetAndSend();
|
||||||
|
}
|
||||||
|
|
||||||
|
int main()
|
||||||
|
{
|
||||||
|
irqInit();
|
||||||
|
fifoInit();
|
||||||
|
|
||||||
|
readUserSettings();
|
||||||
|
initClockIRQ();
|
||||||
|
|
||||||
|
SetYtrigger(80);
|
||||||
|
|
||||||
|
installSystemFIFO();
|
||||||
|
|
||||||
|
irqSet(IRQ_VCOUNT, VCountHandler);
|
||||||
|
irqSet(IRQ_VBLANK, 0);
|
||||||
|
irqEnable(IRQ_VBLANK|IRQ_VCOUNT|IRQ_NETWORK);
|
||||||
|
|
||||||
|
powerOn(POWER_SOUND);
|
||||||
|
REG_SOUNDCNT = SOUND_ENABLE | SOUND_VOL(127);
|
||||||
|
|
||||||
|
static Player oPlayer;
|
||||||
|
Player_Init(& oPlayer);
|
||||||
|
|
||||||
|
while ( 1 )
|
||||||
|
{
|
||||||
|
swiWaitForVBlank();
|
||||||
|
|
||||||
|
Player_Execute(& oPlayer);
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
132
Player/arm9/Makefile
Normal file
@@ -0,0 +1,132 @@
|
|||||||
|
#---------------------------------------------------------------------------------
|
||||||
|
.SUFFIXES:
|
||||||
|
#---------------------------------------------------------------------------------
|
||||||
|
ifeq ($(strip $(DEVKITARM)),)
|
||||||
|
$(error "Please set DEVKITARM in your environment. export DEVKITARM=<path to>devkitARM")
|
||||||
|
endif
|
||||||
|
|
||||||
|
include $(DEVKITARM)/ds_rules
|
||||||
|
|
||||||
|
#---------------------------------------------------------------------------------
|
||||||
|
# BUILD is the directory where object files & intermediate files will be placed
|
||||||
|
# SOURCES is a list of directories containing source code
|
||||||
|
# INCLUDES is a list of directories containing extra header files
|
||||||
|
# DATA is a list of directories containing binary files
|
||||||
|
# all directories are relative to this makefile
|
||||||
|
#---------------------------------------------------------------------------------
|
||||||
|
BUILD := build
|
||||||
|
SOURCES := source
|
||||||
|
INCLUDES := include
|
||||||
|
DATA :=
|
||||||
|
|
||||||
|
|
||||||
|
#---------------------------------------------------------------------------------
|
||||||
|
# options for code generation
|
||||||
|
#---------------------------------------------------------------------------------
|
||||||
|
ARCH := -mthumb -mthumb-interwork
|
||||||
|
|
||||||
|
CFLAGS := -g -Wall -O2\
|
||||||
|
-march=armv5te -mtune=arm946e-s -fomit-frame-pointer\
|
||||||
|
-ffast-math \
|
||||||
|
$(ARCH)
|
||||||
|
|
||||||
|
CFLAGS += $(INCLUDE) -DARM9
|
||||||
|
CXXFLAGS := $(CFLAGS) -fno-rtti -fno-exceptions
|
||||||
|
|
||||||
|
ASFLAGS := -g $(ARCH) -march=armv5te -mtune=arm946e-s -I$(CURDIR)/../source
|
||||||
|
|
||||||
|
LDFLAGS = -specs=ds_arm9.specs -g $(ARCH) -Wl,-Map,$(notdir $*.map)
|
||||||
|
|
||||||
|
#---------------------------------------------------------------------------------
|
||||||
|
# any extra libraries we wish to link with the project
|
||||||
|
#---------------------------------------------------------------------------------
|
||||||
|
LIBS := -lnds9
|
||||||
|
|
||||||
|
#---------------------------------------------------------------------------------
|
||||||
|
# list of directories containing libraries, this must be the top level containing
|
||||||
|
# include and lib
|
||||||
|
#---------------------------------------------------------------------------------
|
||||||
|
LIBDIRS := $(LIBNDS)
|
||||||
|
|
||||||
|
#---------------------------------------------------------------------------------
|
||||||
|
# no real need to edit anything past this point unless you need to add additional
|
||||||
|
# rules for different file extensions
|
||||||
|
#---------------------------------------------------------------------------------
|
||||||
|
ifneq ($(BUILD),$(notdir $(CURDIR)))
|
||||||
|
#---------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
export ARM9BIN := $(TOPDIR)/$(TARGET).arm9
|
||||||
|
export ARM9ELF := $(CURDIR)/$(TARGET).arm9.elf
|
||||||
|
export DEPSDIR := $(CURDIR)/$(BUILD)
|
||||||
|
|
||||||
|
export VPATH := $(foreach dir,$(SOURCES),$(CURDIR)/$(dir)) \
|
||||||
|
$(foreach dir,$(DATA),$(CURDIR)/$(dir))
|
||||||
|
|
||||||
|
CFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.c)))
|
||||||
|
CPPFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.cpp)))
|
||||||
|
SFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.s)))
|
||||||
|
BINFILES := $(foreach dir,$(DATA),$(notdir $(wildcard $(dir)/*.*)))
|
||||||
|
|
||||||
|
#---------------------------------------------------------------------------------
|
||||||
|
# use CXX for linking C++ projects, CC for standard C
|
||||||
|
#---------------------------------------------------------------------------------
|
||||||
|
ifeq ($(strip $(CPPFILES)),)
|
||||||
|
#---------------------------------------------------------------------------------
|
||||||
|
export LD := $(CC)
|
||||||
|
#---------------------------------------------------------------------------------
|
||||||
|
else
|
||||||
|
#---------------------------------------------------------------------------------
|
||||||
|
export LD := $(CXX)
|
||||||
|
#---------------------------------------------------------------------------------
|
||||||
|
endif
|
||||||
|
#---------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
export OFILES := $(addsuffix .o,$(BINFILES)) \
|
||||||
|
$(CPPFILES:.cpp=.o) $(CFILES:.c=.o) $(SFILES:.s=.o)
|
||||||
|
|
||||||
|
export INCLUDE := $(foreach dir,$(INCLUDES),-I$(CURDIR)/$(dir)) \
|
||||||
|
$(foreach dir,$(LIBDIRS),-I$(dir)/include) \
|
||||||
|
-I$(CURDIR)/$(BUILD)
|
||||||
|
|
||||||
|
export LIBPATHS := $(foreach dir,$(LIBDIRS),-L$(dir)/lib)
|
||||||
|
|
||||||
|
.PHONY: $(BUILD) clean
|
||||||
|
|
||||||
|
#---------------------------------------------------------------------------------
|
||||||
|
$(BUILD):
|
||||||
|
@[ -d $@ ] || mkdir -p $@
|
||||||
|
@$(MAKE) --no-print-directory -C $(BUILD) -f $(CURDIR)/Makefile
|
||||||
|
|
||||||
|
#---------------------------------------------------------------------------------
|
||||||
|
clean:
|
||||||
|
@echo clean ...
|
||||||
|
@rm -fr $(BUILD) *.elf *.nds* *.bin
|
||||||
|
|
||||||
|
|
||||||
|
#---------------------------------------------------------------------------------
|
||||||
|
else
|
||||||
|
|
||||||
|
#---------------------------------------------------------------------------------
|
||||||
|
# main targets
|
||||||
|
#---------------------------------------------------------------------------------
|
||||||
|
$(ARM9BIN) : $(ARM9ELF)
|
||||||
|
@$(OBJCOPY) -O binary $< $@
|
||||||
|
@echo built ... $(notdir $@)
|
||||||
|
|
||||||
|
$(ARM9ELF) : $(OFILES)
|
||||||
|
@echo linking $(notdir $@)
|
||||||
|
@$(LD) $(LDFLAGS) $(OFILES) $(LIBPATHS) $(LIBS) -o $@
|
||||||
|
|
||||||
|
#---------------------------------------------------------------------------------
|
||||||
|
# you need a rule like this for each extension you use as binary data
|
||||||
|
#---------------------------------------------------------------------------------
|
||||||
|
%.bin.o : %.bin
|
||||||
|
#---------------------------------------------------------------------------------
|
||||||
|
@echo $(notdir $<)
|
||||||
|
@$(bin2o)
|
||||||
|
|
||||||
|
-include $(DEPSDIR)/*.d
|
||||||
|
|
||||||
|
#---------------------------------------------------------------------------------------
|
||||||
|
endif
|
||||||
|
#---------------------------------------------------------------------------------------
|
||||||
BIN
Player/arm9/source/basicloop.ns
Normal file
34
Player/arm9/source/main.cpp
Normal file
@@ -0,0 +1,34 @@
|
|||||||
|
#include <nds.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
extern unsigned char basicloop[];
|
||||||
|
|
||||||
|
int main()
|
||||||
|
{
|
||||||
|
powerOn(POWER_ALL);
|
||||||
|
|
||||||
|
videoSetMode(MODE_0_2D);
|
||||||
|
|
||||||
|
consoleDemoInit();
|
||||||
|
|
||||||
|
BG_PALETTE[0] = RGB15(0, 0, 0);
|
||||||
|
|
||||||
|
while ( 1 )
|
||||||
|
{
|
||||||
|
swiWaitForVBlank();
|
||||||
|
scanKeys();
|
||||||
|
|
||||||
|
if ( keysDown() & KEY_X )
|
||||||
|
{
|
||||||
|
fifoSendValue32(FIFO_USER_01, (u32)(& basicloop[0]));
|
||||||
|
BG_PALETTE[0] = RGB15(15, 0, 0);
|
||||||
|
}
|
||||||
|
else if ( keysHeld() & KEY_B )
|
||||||
|
{
|
||||||
|
fifoSendValue32(FIFO_USER_01, 0);
|
||||||
|
BG_PALETTE[0] = RGB15(0, 0, 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
5
Player/arm9/source/tunes.s
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
.section .rodata
|
||||||
|
.balign 4
|
||||||
|
.global basicloop
|
||||||
|
basicloop:
|
||||||
|
.incbin "test"
|
||||||