Skip to content

c# wrapper for an incomplete re-implementation of DirectMusic, Microsoft's adaptive soundtrack API for games delivered as part of Direct3D and DirectX

License

Notifications You must be signed in to change notification settings

GothicKit/dmusic-cs

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

13 Commits
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

DirectMusic for C#

Very experimental wrapper for the also very experimental dmusic C-library.

Example

Here's how to use it, very simply. Refer to the C-library's docs for more details dmusic.

using DirectMusic;

const string root = "/path/to/your/music/folder/";

Logger.SetDefault(LogLevel.Info);

// 1. Create a new loader. The loader is responsible for loading and caching DirectMusic files using a
//    user-defined callback function called a "resolver". You really only ever need one for your application.
var loader = Loader.Create(LoaderOptions.Download);

// 2. Register a resolver with the loader. A resolver is simply a function which gets a filename and returns a
//    memory buffer. You can return null from a resolver to indicate that the file was not found.
loader.AddResolver(name =>
{
	try
	{
		return File.ReadAllBytes(Path.Join(root, name));
	}
	catch (Exception e)
	{
		return null;
	}
});

// 3. Use the loader to obtain a segment. The loader will call your resolvers in order to read in the
//    file, and it will then perform some internal magic to load the segment. Since we set the
//    LoaderOptions.Download option when constructing the loader, we don't need to call Segment.Download
//    afterward. Otherwise, you do have to call it.
var segment = loader.GetSegment("YourSegment.sgt");

// 4. Create a new performance. The performance represents your main playback device. It handles all
//    the DirectMusic magic needed to produce music from your segments. You typically only need one
//    performance for your application. The first parameter here is the sample rate, defaulted to
//    44100 Hz.
var performance = Performance.Create(44100);

// 5. Instruct the performance to play a segment. This will set up the performance's internals so that
//    the following call to Performance.RenderPcm will start producing music. The performance renders
//    music on-demand, so as long as you don't call Performance.RenderPcm, you can consider playback to
//    be paused. To stop playing music, you can pass null as the first parameter.
//
//    The second parameter here is the timing. It tells the performance at which boundary to start playing
//    the new segment as to not interrupt the flow of music. The options are "instant", which ignores all
//    that and immediately plays the segment, "grid" which plays the segment at the next possible beat
//    subdivision, "beat" which plays the segment at the next beat and "measure" which plays it at the next
//    measure boundary.
//
//    The performance also supports transitions. To play those, use Performance.PlayTransition and see
//    its inline documentation for more information.
performance.PlaySegment(segment, Timing.Measure);

// 6. Finally, render some PCM! This will instruct the performance to start processing the underlying
//    DirectMusic messages and render the resulting PCM to the output buffer. In this case it will
//    render 1000000 stereo samples which is 500000 samples per channel.
//
//    This will advance the internal clock for as many ticks as required to render the requested number
//    of samples. No more, no less.
var pcm = new float[1_000_000];
performance.RenderPcm(pcm, true);

// 6.1. Write out the PCM data to some place where we can access it later. This could also just be some
//      audio output device or another library.
var bytes = new byte[pcm.Length * 4];
Buffer.BlockCopy(pcm, 0, bytes, 0, bytes.Length);
File.WriteAllBytes("output.pcm", bytes);

Contact

If you have any questions, or you just want to say hi, you can reach me via e-mail (me@lmichaelis.de) or on Discord either via DM but preferably in the Gothic VR and GMC Discords (@lmichaelis).

About

c# wrapper for an incomplete re-implementation of DirectMusic, Microsoft's adaptive soundtrack API for games delivered as part of Direct3D and DirectX

Topics

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages