DEV Community

Cover image for Creating chip-tuned square & triangle wave sounds on web browsers with Blazor WebAssembly
jsakamoto
jsakamoto

Posted on

Creating chip-tuned square & triangle wave sounds on web browsers with Blazor WebAssembly

"SoundMaker" Library

I found an interesting post in my Twitter timeline last month.

The tweet introduced a library that allows us to create chip-tuned square & triangle wave sounds and save them to a .wav file by only C#, "SoundMaker". (The GitHub repository URL is below.)

GitHub logo AutumnSky1010 / SoundMaker

You can do The following content with this library. 1. make the sound of chiptune(old game sound) 2. export sound to a file of wave format.

SoundMakerCover

🗺️言語(Language)

  1. 日本語
  2. English

🎵概要

本ライブラリを用いると、以下の事が可能です。

  • チップチューンサウンド?を作成する
  • waveファイルにサウンドを書き込む

📑ドキュメント

Wiki

⛰️要件

.NET 6

インストール方法

NuGet

SoundMaker

🎶簡単な使い方

using SoundMaker.Sounds
using SoundMaker.Sounds.Score;
using SoundMaker.Sounds.SoundChannels;
using SoundMaker.WaveFile;

namespace YourNamespace;
public static class YourClass
{
    private static void Main()
    {
        // サウンドの形式を作成する。
        var soundFormat = new SoundFormat(SoundMaker.Sounds.SamplingFrequencyType.FourtyEightKHz, SoundMaker.Sounds.BitRateType.SixteenBit, SoundMaker.Sounds.ChannelType.Stereo);
        StereoWave wave = MakeStereoWave(soundFormat);

        // ファイルに書き込む。
        var sound = new SoundWaveChunk(wave.GetBytes(soundFormat.BitRate));
        var waveFileFormat = new FormatChunk(SoundMaker.WaveFile.SamplingFrequencyType.FourtyEightKHz, SoundMaker.WaveFile.BitRateType.SixteenBit, SoundMaker.WaveFile.ChannelType.Stereo);
        var writer = new WaveWriter
Enter fullscreen mode Exit fullscreen mode

The "SoundMaker" is distributed under the MIT license.

When I saw that tweet, one idea came to my mind. He said the "SoundMaker" is built on 100% pure C#. If it is true, we should also be able to run the "SoundMaker" on web browsers powered by Blazor WebAssembly. So I tried it.

Implement it

There is a simple example code on how to use the "SoundMaker" to create and save square & triangle wave sounds on the README document in the GitHub repository of the "SoundMaker". I created a new Blazor WebAssembly project and copied that example code, almost as is, into a @code { ... } code block of a Razor component file (.razor) in that Blazor WebAssembly project.

The outline of the code is like this:

...
@code {
  private static string GenerateWavFile()
  {
    // Specify sound format, and generate sound waves.
    var soundFormat = new SoundFormat(SoundMaker.Sounds.SamplingFrequencyType.FourtyEightKHz, SoundMaker.Sounds.BitRateType.SixteenBit, SoundMaker.Sounds.ChannelType.Stereo);
    var wave = MakeStereoWave(soundFormat);

    // Save it into a file.
    var sound = new SoundWaveChunk(wave.GetBytes(soundFormat.BitRate));
    var waveFileFormat = new FormatChunk(SoundMaker.WaveFile.SamplingFrequencyType.FourtyEightKHz, SoundMaker.WaveFile.BitRateType.SixteenBit, SoundMaker.WaveFile.ChannelType.Stereo);
    var writer = new WaveWriter(waveFileFormat, sound);
    var filePath = "sample.wav";
    writer.Write(filePath);

    return filePath;
  }

  private static StereoWave MakeStereoWave(SoundFormat format)
  {
    // Number of quarter notes per minute.
    var tempo = 100;
    ...
    // can mix with StereoMixer class. 
    return new StereoMixer(channels).Mix();
  }
}
Enter fullscreen mode Exit fullscreen mode

But, wait, wait.

If you look closely at the above code, you will find that the program is doing a write to a file. Here is an excerpt.

private static string GenerateWavFile()
{
    // Save it into a file.
    ...
    var filePath = "sample.wav";
    writer.Write(filePath);
    ...
Enter fullscreen mode Exit fullscreen mode

This program is a Blazor WebAssembly program that is loaded into a web browser and executed in its sandbox. So what happens when you do this write to a local file? Of course, it would not be written to the local storage of the device on which the web browser is actually running. So, would this process fail with an exception? That said, the WaveWriter class in the SoundMaker library apparently does not have the ability to write to an arbitrary Stream, and there is no way to write a .wav file other than specifying the file path. Is this that the "SoundMaker" library is not available on Blazor WebAssembly, unfortunately?

Writing to local files in Blazor WebAssembly apps will be a success

In fact, writing to local files in Blazor WebAssembly apps will be a success!

Blazor WebAssembly uses Emscripten as its foundation to generate WebAssembly code generation, and because of this, the on-memory filesystem simulation (virtual file system) provided by Emscripten is also available in Blazor WebAssembly! (For more information, please refer to the following links.)

Therefore, writing a .wav file into the local file system by the WaveWriter class in the "SoundMaker" library will be successful. The written file exists on the virtual file system in the web browser's WebAssembly process memory space. And, we can read the .wav file written to the virtual file system into an array of byte, and can do anything, such as playing back, downloading, etc., from the web browser.

Real example

I've publicly pushed the Blazor WebAssembly project source code I explained above on the following GitHub repository.

GitHub logo sample-by-jsakamoto / Blazor-SoundMaker-on-BlazorWasm

Demonstration of the "SoundMaker" on Blazor WebAssembly

And, this example has been deployed on GitHub Pages by a GitHub Actions script. You can try it immediately by following the next link.

The screenshot below shows how the above link looks when opened.

image.png

When you click the "Generate Sound and Play" button, the sound generated on the fly by the C# program I explained above will be played back. When you click the "Generate Sound and Download" button, the .wav file will be downloaded instead of playing back it. Please remember the generating sound process runs on your web browser! I confirmed that the example site can also be run on Apple mobile devices. I could generate the chip-tuned sound with that example site and play it on my iPhone SE2. That's amazing!

Moreover, as I already mentioned above, due to the source code of the example site being hosted on the GitHub repository, when you create a new "GitHub Codespace" for this repository, like the following screenshot,

image.png

As shown in the screenshot below, you can edit and run the code ("dotnet run" command execution) of this example site in a web browser immediately, without the need to set up a local development environment on your PC!

image.png

Conclusion

Now you can easily enjoy chip-tuned sound generation programming with "SoundMaker" anytime, anywhere, as long as you are connected to the Internet and use any device that supports GitHub Codespaces! That's really amazing!

Thanks to the author of the "SoundMaker", AutumnSky1010, for publishing such a great library as an Open Source!

Happy Coding :)

Top comments (0)