Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

General idea and roadmap #20

Open
ValleyBell opened this issue Apr 6, 2019 · 7 comments
Open

General idea and roadmap #20

ValleyBell opened this issue Apr 6, 2019 · 7 comments

Comments

@ValleyBell
Copy link
Owner

ValleyBell commented Apr 6, 2019

General plan and current state

The idea behind libvgm is to make a collection of libraries and classes that make it easy to write a VGM player or programs that emulate sound chips in general. It includes sub-libraries for audio output, sound chip emulation and VGM playback. (and maybe VGM parsing as well)

The project is CMake based and will allow you to enable/disable almost all features. So if you include it within your project, you may e.g. just compile the sound chips you really need.
C++ might be used during development when I think that stuff is faster/easier to do with it. Eventually I'd like to have everything as pure C code. (mostly C90 with C++ comments)

audio library

The audio sub-library should be a simple abstraction layer in order to allow platform-independent audio output. There is support for multiple (often platform-dependent) "audio drivers".
You can either set a callback that will be called with a buffer to be filled or you can poll the driver and explicitly send data to it.

Features:

  • support for Windows audio APIs (done, supports WinMM, DirectSound, XAudio2, WASAPI)
  • support for Linux audio APIs (done, supports OSS, ALSA, PulseAudio)
  • support for Mac OS X audio APIs (done, supports Core Audio)
  • support for writing audio to files (WAV writer supported)
  • The library should be able to chain multiple audio drivers together. (for simple playback + WAV logging)

emulation library

The emulation sub-library allows you to emulate sound chips in software, resulting in samples being rendered into a buffer. In order to access sound chips, you need to read and write registers and memory. It focuses on being fast and flexible rather than being very easy to use.

  • support for all sound chips that are required for VGM v1.71 (done, except ES5505/06, those need some reworking on the VGM format side)
  • adding new cores or sound chips should be simple (means "adding a new file and an include / a reference somewhere else" is good, "adding tons of if statements" is not)
  • support for an optional (!) resampler that brings the sound chips's native sample rate to whatever sample rate you use for audio output

player library

The player sub-library should make it easy to play back VGMs (and possibly other logged formats). It uses the emulation library for sound chip emulation and outputs samples into a buffer.

  • The player class has a method to check whether or not it is his file type. (for easy checking)
  • The player does parsing of additional metadata like tags and has functions to get them encoded as UTF-8.
  • The host application sets a sample rate in the player that output samples are rendered at.
  • The player class supports seeking to arbitrary time stamps (and possibly file offsets).
  • The player class supports playback rate scaling. (allowing for slower or faster playback of the song)
  • The current timestamp is returned as:
    • samples (scale: output sample rate, unaffected by playback rate)
    • ticks (scale: internal VGM tick rate, affected by playback rate)
  • A callback function can be set. There are callbacks for
    • playback start (call of "Start" function)
    • playback end (call of "Stop" function)
    • reaching the end of a loop
    • reaching the end of the song
    • arbitrary playback position changes (call of "Seek" and "Reset" functions)
    • maybe additional functions for errors?
  • There is a way to obtain format-specific information. (e.g. VGM or S98 header structs)
  • There is a function to get a list of sound chips used by the current song.
  • There is a way to configure the sound chip parameters. (e.g. sound core, Nuked OPN2 type, ...)
  • Files are loaded by a helper class that transparently decompressed gzip'ed data. Loading (and decompressing) should work from actual files or from memory.

Future plans

audio library

I don't have any additional future plans for this right now. Maybe a dummy device that just redirects all data to custom callback? (for potential FLAC/MP3 export in host applications)

emulation library

  • additional resamplers
    • BlipBuffer from kode54's VGMPlay fork (I definitely want that)
    • maybe support for libsamplerate or something similar
  • maybe more sound chips/cores

player library

  • XGM support
  • support for "start playing while still loading"
  • support for loading from HTTP (maybe even HTTPS?)

other

  • I'd like to have a VGM parser with a syntax similar to standard streams (fget/fput) sometime. This could be of use for writing VGM tools.
@parski
Copy link

parski commented Dec 9, 2020

The Mac version of vgmplay relies on the libao dynamic library and it says above that:

support for Mac OS X audio APIs (done, supports Core Audio)

Does this mean libao is not required for libvgm and you're using Core Audio directly instead?

@ValleyBell
Copy link
Owner Author

Yes, that's correct. We have a Core Audio driver: https://github.com/ValleyBell/libvgm/blob/c068dffd272bc7ad3a8e96b17426b3f48e7ccf2d/audio/AudDrv_CoreAudio.c

In the vgmplay config, setting AudioDriver = "Core Audio" should do the trick, if you have compiled libvgm with Core Audio support. (AUDIODRV_APPLE ON in the CMake configuration)

@parski
Copy link

parski commented Dec 9, 2020

Works like a charm. Can't wait to see what people make with this!

@cyberic99
Copy link

Is it the correct place to add a feature request?

I have a project were I'd like to feed vgmplay from a pipe.

I know .vgm files have a header etc, but once the header has been read or the clocks correctly set, it could be useful to process incoming events in realtime. This could be useful to test sound engines or libraries against emulated chips.
Also, the 'sleeping' commands would have to be bypassed and/or ignored.

What do you think about it?

@kode54
Copy link
Contributor

kode54 commented Dec 12, 2020

Real time via pipe is not really feasible, anyway, since pipes buffer data at rates you don't really control, similar to how USB devices buffer commands in blocks. You'll likely want to handle timing and delay commands yourself as you stream them to it. Even if it's only stepping in small steps between commands and checks for input, assuming you're piping data from a MIDI or HID input.

@ValleyBell
Copy link
Owner Author

Is it the correct place to add a feature request?

No, in general feature requests should be new issues.

I have a project were I'd like to feed vgmplay from a pipe.

I know .vgm files have a header etc, but once the header has been read or the clocks correctly set, it could be useful to process incoming events in realtime. This could be useful to test sound engines or libraries against emulated chips.

This sounds interesting, but I won't add parsing custom commands for now.
For the things that you want, you should just use the emu library directly. Or you make a copy of the VGMPlayer class that you modify to your own needs.

@cyberic99
Copy link

For the things that you want, you should just use the emu library directly.

Okay, I didn't know about this library, but this is exactly what I needed. thanks a lot.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants