Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -7,3 +7,5 @@ obj/
.DS_Store
.directory
thumbs.db

Bass.Net.dll # provide it yourself
27 changes: 27 additions & 0 deletions ChuTools.Tests/BeReadWrite.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
using Be.IO;

using BmsDerg.Utility;

namespace ChuTools.Tests;

[TestFixture]
public class BeReadWrite
{
[Test]
[TestCase(10)]
[TestCase(200)]
[TestCase(20000)]
[TestCase(20000000)]
public static void TestVarInt(int value)
{
var ms = new MemoryStream();
var writer = new BeBinaryWriter(ms);
writer.WriteVarInt(value);

ms.Position = 0;
var reader = new BeBinaryReader(ms);
var readBack = reader.ReadVarInt32();

Assert.That(readBack, Is.EqualTo(value));
}
}
8 changes: 7 additions & 1 deletion Directory.Packages.props
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,15 @@
<ManagePackageVersionsCentrally>true</ManagePackageVersionsCentrally>
</PropertyGroup>
<ItemGroup>
<PackageVersion Include="MessageBox.Avalonia" Version="12.0.0" />
<PackageVersion Include="Newtonsoft.Json" Version="13.0.4" />
<PackageVersion Include="System.CommandLine" Version="2.0.10" />

<PackageVersion Include="Avalonia" Version="12.0.2" />
<PackageVersion Include="Avalonia.Desktop" Version="12.0.2" />
<PackageVersion Include="Avalonia.Themes.Fluent" Version="12.0.2" />
<PackageVersion Include="Avalonia.Fonts.Inter" Version="12.0.2" />
<PackageVersion Include="AvaloniaUI.DiagnosticsSupport" Version="2.2.1" />
<PackageVersion Include="MidiSharp" Version="0.9.6516.2348" />
<!-- Tests -->
<PackageVersion Include="coverlet.collector" Version="10.0.1" />
<PackageVersion Include="Microsoft.NET.Test.Sdk" Version="18.8.1" />
Expand Down
1 change: 1 addition & 0 deletions JAIMaker/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Bass.Net.dll # Provide it yourself
10 changes: 10 additions & 0 deletions JAIMaker/App.axaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
<Application xmlns="https://github.com/avaloniaui"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
x:Class="JaiMaker.App"
RequestedThemeVariant="Default">
<!-- "Default" ThemeVariant follows system theme variant. "Dark" or "Light" are other available options. -->

<Application.Styles>
<FluentTheme DensityStyle="Compact" />
</Application.Styles>
</Application>
28 changes: 28 additions & 0 deletions JAIMaker/App.axaml.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
using Avalonia;
using Avalonia.Controls.ApplicationLifetimes;
using Avalonia.Markup.Xaml;

using JaiSeqX.Player.BassBuff;

namespace JaiMaker;

public partial class App : Application
{
public override void Initialize()
{
AvaloniaXamlLoader.Load(this);

Engine.Init(); // Start audio engine.
Keyboard.init();
}

public override void OnFrameworkInitializationCompleted()
{
if (ApplicationLifetime is IClassicDesktopStyleApplicationLifetime desktop)
{
desktop.MainWindow = new MainWindow();
}

base.OnFrameworkInitializationCompleted();
}
}
Binary file added JAIMaker/Assets/coollogo_com-29453469.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added JAIMaker/Assets/coollogo_com-3970742.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
240 changes: 240 additions & 0 deletions JAIMaker/BMSChannelManager.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,240 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using JaiSeqX.Player.BassBuff;

namespace JaiSeqX.Player
{
public class BMSChannel
{
SoundEffectInstance[] voices;
public SoundEffectInstance LastVoice;
public int ActiveVoices;
public BMSChannel()
{
voices = new SoundEffectInstance[256]; // Should only ever have 8 voices, but still.
}

public void silence()
{
for (int i = 0; i < voices.Length; i++)
{
if (voices[i]!=null)
{
voices[i].Stop();
}
}
}


public bool addVoice(int index, SoundEffectInstance voice) // to add a voice to a channel
{
if (index < voices.Length) // Make sure the index isn't stupid.
{
if (voices[index] != null) // Check if we already have a sound playing there.
{
stopVoice(index); // Stop it if we do.
}
voices[index] = voice; // Throw the voice into its index
LastVoice = voice;
ActiveVoices++;
return true; // success
}
return false;
}

public bool stopVoice(int index)
{
if (index < voices.Length)
{ // Make sure the index isnt stupid
if (voices[index] != null) // dont do any work if we dont have anything to do
{
var voi = voices[index]; // grab the voice
voi.Stop(); // Stop the voice
voi.Dispose(); // feed it to GC
voices[index] = null; // clear its index in the voice table
ActiveVoices--;
return true; // good

}
}
return false; // we didnt do anything
}

}

public class BMSChannelManager
{
SoundEffect[] Cache; // Sound cache
string[] CacheStrings; // Maps the sound path to the cache index
public BMSChannel[] channels; // current channels
int cacheHigh; // Highest number in the cache we have

bool[] bending;

double[] bendtarget;
int[] bendtargetricks;
int[] bendticks;


float[] bendPitchBase;

public BMSChannelManager()
{

Cache = new SoundEffect[1024]; // I HOPE that the engine doesn't need more than 1024 sounds at once.
CacheStrings = new string[1024]; // ^

channels = new BMSChannel[32]; // Usually no more than 16 channels. Again, just to be safe

bendtarget = new double[32];
bending = new bool[32];
bendPitchBase = new float[32];
bendticks = new int[32];
bendtargetricks = new int[32];

for (int i = 0; i < channels.Length; i++)
{
channels[i] = new BMSChannel(); // Preallocating the channels
}

}

public bool doPitchBend(byte channel, int bend, int duration, byte type)
{
var chn = channels[channel];

if (chn.LastVoice != null)
{
var voi = chn.LastVoice;
//Console.WriteLine("Add PitchBend: {0} {1} {2} ", channel, duration, bend);
bendPitchBase[channel] = voi.Pitch; // fuck
bending[channel] = true; // fuck
bendticks[channel] = 0; // fuck
bendtargetricks[channel] = duration; // fuck

float target = 0;
if (type == 1)
{
target = (float)bend / 0xFF;
}
if (type == 2)
{
target = (float)bend / 0x7F;
}
if (type == 3)
{
target = (float)bend / 0x7FFF;
}

//Console.WriteLine("Add Target {0} ", target);

bendtarget[channel] = target; // fuck

return true;
}

return false;
}

public bool onTick()
{
for (int chn = 0; chn < channels.Length; chn++)
{
// bend

if (bending[chn])
{
var bendChannel = channels[chn];
bendticks[chn]++;
var ticks = bendticks[chn];
var targetTicks = bendtargetricks[chn];
if (ticks > targetTicks)
{
bending[chn] = false;
}
float bendPercent = ((float)ticks / targetTicks) < 1 ? ((float)ticks / targetTicks) : 1;
double semitones = bendtarget[chn] * bendPercent;

if (bendChannel.LastVoice != null)
{
// Console.WriteLine("doing it ");
// var real_pitch = (float)Math.Pow(2, / 12f);
var voice = bendChannel.LastVoice;
var basepitch = bendPitchBase[chn];
// var newpitch = (float)Math.Pow(2, / 12) ;
//double newpitch = Math.Pow(2,-semitones / 12 );

//Console.WriteLine("BEND DEGREE {0} {1}", newpitch,semitones);
//voice.Pitch = basepitch * (float)(newpitch);
}

}

}

return true;
}
public SoundEffect loadSound(string file, bool lo, int ls, int le)
{
for (int i = 0; i < CacheStrings.Length; i++)
{
if (CacheStrings[i] == null || i > cacheHigh) // if we've hit null, we've hit the end of our array.
{
break; // So just stop the loop
}
else
{
if (CacheStrings[i] == file) // If we find it.
{
return Cache[i]; // Return the same index of the cache (will be our file)
}
}
}
#if DEBUG
var b = Console.ForegroundColor;
Console.ForegroundColor = ConsoleColor.Magenta;
Console.WriteLine("loadSound {0}", file);
Console.ForegroundColor = b;


#endif
CacheStrings[cacheHigh] = file; // otherwise, it's not loaded. so we need to store it in our cache
Cache[cacheHigh] = new SoundEffect(file, lo, ls, le); // Load the WAV for it.
var ret = Cache[cacheHigh]; // Then set our return value (we store it, because we increment cacheHigh below)
cacheHigh++; // Increment our next cache index.

return ret; // Return our object.
}

public void startVoice(SoundEffectInstance snd, byte channel, byte voice)
{
if (channels[channel] != null) // check if the channel exists
{
var chn = channels[channel]; // if it does, reference it
chn.addVoice(voice, snd); // store the voice
}
}

public void silenceChannel(byte channel)
{
if (channels[channel] != null) // check if the channel exists
{
var chn = channels[channel]; // if it does, reference it
chn.silence();
}
}

public void stopVoice(byte channel, byte voice)
{
// see above, inverse.
if (channels[channel] != null)
{
var chn = channels[channel];
chn.stopVoice(voice);
}
}
}
}
Binary file added JAIMaker/Bass.Net.dll
Binary file not shown.
Loading
Loading