Giter Site home page Giter Site logo

h1romas4 / libymfm.wasm Goto Github PK

View Code? Open in Web Editor NEW
53.0 5.0 8.0 19.95 MB

This repository is an experimental WebAssembly build of the [ymfm](https://github.com/aaronsgiles/ymfm) Yamaha FM sound cores library.

Home Page: https://chipstream.netlify.app/

License: BSD 3-Clause "New" or "Revised" License

CMake 1.73% C++ 4.68% Rust 93.16% HTML 0.43%
ym2612 ym2151 ym2203 ym2149 vgm vgmplay webassembly wasi wasm wasm32-wasi

libymfm.wasm's People

Contributors

h1romas4 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar

libymfm.wasm's Issues

Question on the FFI wrapper

Hi Hiromasa,

I'm trying to use your FFI wrapper to simply replay a YM registers dump file (captured every 50Hz) but the result is not good at all. I guess I don't use your wrapper correctly, can you tell me what is wrong ? I guess this is due to the frequency I call ymfm_generate but I don't undertstand why.

Here is the principle (in Zig but not really different from Rust):

(if not clear in the comments)

  1. I call ymfm_add_chip to set up a YM2149 at 2000000 Hz and get the sampling rate: 31250
  2. I loop over the blocks of 14 YM2149 registers contained in my YM dump file
    • I write the 14 registers using ymfm_write
    • I generate 31250/50 ticks with ymfm_generate
      • I write the first i32 of the buffer (mono channel) in a file for each tick
  3. Done!
pub fn main() !void {

    // YM2149 clock: 2MHz
    const YM2149_clock: u32 = 2e6;
    const fYM2149_clock: f32 = @intToFloat(f32, YM2149_clock);

    // Get YM2149 enum value, basically 0
    const ym2149: u16 = @enumToInt(ChipType.CHIP_YM2149);

    // create wav file
    const file = try std.fs.cwd().createFile(
        "sound.wav",
        .{ .read = true },
    );
    defer file.close();

    // Get a buffered writer to write in this file
    var buf_writer = std.io.bufferedWriter(file.writer());
    const writer = buf_writer.writer();    

    // add a YM2149, YM2149_clock == 
    var sampling_rate: u32 = ymfm.ymfm_add_chip(ym2149, YM2149_clock);

    std.debug.print("Sampling Rate: {} for master clock: {}\n", .{ sampling_rate, YM2149_clock });
    std.debug.print("Dump length: {} frames = {} seconds\n", .{ dump_b.len / 14, dump_b.len / 14 / 50 });
    std.debug.print("Tick per frame: {}\n", .{ sampling_rate / 50 });

    // counters for the YM dump file
    var counter: u64 = 0;
    var dump_loop: u32 = 0;

    // the YM dump file is composed of 50Hz frames capturing the first 14 YM2149 registers
    // loop on those frames
    while(dump_loop < dump_b.len / 14) : (dump_loop += 1) {

        // write the 14 registers
        var i: u32 = 0;
        while( i < 14) : ( i += 1) {
            ymfm.ymfm_write(ym2149, 0, i, dump_b[counter]);  
            counter += 1;
        }     

        // generate some sound for 50 Hz, so tick the YM (sampling_rate / 50) times
        // write every sample output to the file
        var tick: u32 = 0;
        var buffer: [2]i32 = undefined;
        while (tick < sampling_rate / 50) : ( tick += 1) {
            ymfm.ymfm_generate(ym2149, 0, &buffer);

            // store only left channel
            const slice = buffer[0];            
            try writer.writeAll(std.mem.asBytes(&slice));       
        }
                
        // std.debug.print("Frame {} done\n", .{ dump_loop } );
        
    }
    try buf_writer.flush();
}
Sampling Rate: 31250 for master clock: 2000000
Dump length: 8833 frames = 176 seconds
Tick per frame: 625

Any idea what I did wrong ?

More consistent location for the c++ library (native build) + another readme suggestion

I've found that I have to set build.rs to this if I want to use your library as a library in my project, because the CWD is actually set to the workspace root of my package for some reason:

let dir = env::var("CARGO_MANIFEST_DIR").unwrap();
println!("cargo:rustc-link-search=native={}/dist", dir);

Also the cmake build instructions could have been simpler:

cmake -DCMAKE_TOOLCHAIN_FILE=./cmake/x86-64.cmake -S . -B build
cmake --build build --parallel $(nproc)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.