DirectMusic 0.0.1
An incomplete re-implementation of DirectMusic, Microsoft's adaptive soundtrack API for games delivered as part of Direct3D and DirectX
Loading...
Searching...
No Matches
Segment

Structures and functions related to DirectMusic Segments. More...

Typedefs

typedef struct DmSegment DmSegment
 Represents a DirectMusic Segment.
 

Functions

DmSegmentDmSegment_retain (DmSegment *slf)
 Add one to the reference count of a segment.
 
void DmSegment_release (DmSegment *slf)
 Subtract one from the reference count of a segment.
 
DmResult DmSegment_download (DmSegment *slf, DmLoader *loader)
 Download all resources needed by the segment.
 
DmGuid const * DmSegment_getGuid (DmSegment const *slf)
 Get the GUID of the given segment.
 
char const * DmSegment_getName (DmSegment const *slf)
 Get the name of the given segment.
 
double DmSegment_getLength (DmSegment const *slf)
 Get the length of the given segment in seconds.
 
uint32_t DmSegment_getRepeats (DmSegment const *slf)
 Get the number of times the segment repeats.
 

Detailed Description

Structures and functions related to DirectMusic Segments.

Overview

Segments are the heart of all DirectMusic scores. They contain information about how to arrange the musical piece including, among other things, the tempo, which bands to use and how to integrate with the style. Exported segments usually have the file extension .sgt while DirectMusic Producer uses .sgp instead.

This library only supports what is known as Style-based Segments at the moment. This means, that only style, chord, command, band and tempo tracks are supported. All other tracks are ignored.

What exactly is a track?

DirectMusic is a dynamic system which selects and plays back music in real time. To do this, the composer specifies at least one set of distinct musical patterns known as a Style and at least one set of instruments called a Band as well as a set of tempos, commands and chords to be played back in real time. These components are all separated into so-called Tracks in which they are saved by timestamp. During playback, DirectMusic will process each track whenever its timestamp is reached and perform the action associated with it.

For example, a composer could create a segment which contains a tempo track with one entry per measure (the musical unit). During playback, the playback engine will then change the tempo at each measure to the value set by the composer. This applies to all five supported tracks, so a composer could, for example, also include band changes mid-playback.

Bands and band tracks

DirectMusic Bands are collections of instruments each assigned to a Performance Channel. Instruments are backed by [Downloadable Sound][dls] (_"DLS"_) files which contain wave-tables for one or more instruments, very similar to [SoundFont][sf2] files. At runtime, bands are loaded an unloaded according to the band track. It specifies which band should be active which timestamps.

Styles and style tracks

DirectMusic Styles contain the actual notes to be played by the instruments specified in the band. Each instrument is assigned one or more parts each containing one set of notes and possibly random variations. Parts are then combined into patterns, which contain multiple parts to be played at the same time. At runtime, the playback engine will select a pattern according to the command track of the segment which it will then start playing. To do this, the playback engine takes the notes of each part referenced by the pattern and assigns the notes to be played to each referenced instrument while taking into account the currently playing chord selected by the chord track and choosing a variation either, randomly, sequentially or otherwise as specified by the composer.

Why do I need to download a segment?

Styles the Downloadable Sounds referenced by the segment are stored in separate files. For the playback engine to have access to the data contained within, it needs to open and load the contents of these files. To avoid doing this during playback, since opening and loading files can take a few milliseconds (enough to notice playback stuttering), these files must be loaded before submitting the segment for playback. This should be done in a separate thread than the actual music rendering (see DmPerformance_renderPcm).

I've loaded a segment, how do I play the damn thing?

Playback is done using a DmPerformance object. See the documentation for Performance and DmPerformance_renderPcm for more details.

Typedef Documentation

◆ DmSegment

typedef struct DmSegment DmSegment

Represents a DirectMusic Segment.

Definition at line 286 of file dmusic.h.

Function Documentation

◆ DmSegment_download()

DmResult DmSegment_download ( DmSegment slf,
DmLoader loader 
)

Download all resources needed by the segment.

In order to play a segment, its internal resources, like references to styles and bands need to be resolved and downloaded. This is done by either calling DmSegment_download manually or by providing the DmLoader_DOWNLOAD flag when creating the loader.

Parameters
slf[in]The segment to download resources for.
loader[in]The loader to use for downloading resources
Returns
DmResult_SUCCESS if the operation completed and an error code if it did not.
Return values
DmResult_INVALID_ARGUMENTEither slf or loader was NULL.
DmResult_NOT_FOUNDAn internal resource required by the segment was not found.
DmResult_MUTEX_ERRORAn error occurred while trying to lock an internal mutex.
DmResult_MEMORY_EXHAUSTEDA dynamic memory allocation failed.

◆ DmSegment_getGuid()

DmGuid const * DmSegment_getGuid ( DmSegment const *  slf)

Get the GUID of the given segment.

Warning
The returned pointer is only valid for as long as a strong reference to the segment is held.
Parameters
slf[in]The segment to get the GUID of.
Returns
A read-only pointer to the segment's GUID or NULL if slf is NULL.

◆ DmSegment_getLength()

double DmSegment_getLength ( DmSegment const *  slf)

Get the length of the given segment in seconds.

The number of PCM samples required to render n seconds of the segment can be calculated like this: $n_{samples} = n \cdot x_{rate} \cdot n_{channels}$ where $x_{rate}$ is the sample rate to use (usually 44100 Hz) and $n_{channels}$ is the number of PCM output channels (1 for mono and 2 for stereo PCM).

Parameters
slf[in]The segment to get the length of.
Returns
The number of seconds one repeat of the segment takes.

◆ DmSegment_getName()

char const * DmSegment_getName ( DmSegment const *  slf)

Get the name of the given segment.

Note
The returned pointer is only valid for as long as a strong reference to the segment is held.
Parameters
slf[in]The segment to get the name of.
Returns
A read-only pointer to the segment's name in UTF-8 or NULL if slf is NULL.

◆ DmSegment_getRepeats()

uint32_t DmSegment_getRepeats ( DmSegment const *  slf)

Get the number of times the segment repeats.

Parameters
slf[in]The segment to get the number of repeats of.
Returns
The number of times the segment repeats or 0 if slf is NULL.

◆ DmSegment_release()

void DmSegment_release ( DmSegment slf)

Subtract one from the reference count of a segment.

If a call to this function reduces the reference count to zero, it also de-allocates the segment and releases any resources referenced by it.

Parameters
slf[in]The segment to release.

◆ DmSegment_retain()

DmSegment * DmSegment_retain ( DmSegment slf)

Add one to the reference count of a segment.

Parameters
slf[in]The segment to retain.
Returns
The same segment as was given in slf or NULL if slf is NULL.