Audio
395
0
Advertisement
Have to be a quick update as I'm out on the work night out in a bit but just wanted to write up my music system briefly.
It is common in a computer game to want to play a piece that has, for a random example, two sections of intro, then a section repeated twice, then another section, then loop back to the two repeated sections and proceed in this loop ad infinitum.
Obviously this is not possible with linear PCM data played start to finish and also contains lots of repeated data. Given the size of even 8 bit mono PCM data, this is a significant consideration.
What I've put together is the following system.
Once a track is working in Psycle, I create a new Psycle version that just contains each unique section in pretty much any order.
I then have a command line utility that reads a script that specifies the raw WAV file, the number of sections and a pattern of sequences to play the sections in, including the ability to loop back to a previous step in the pattern by index.
The tool produces a binary file containing all this information, including the raw PCM data.
The game runtime then has a system to load this information into a MusicBuffer which contains a two second streaming DirectSound buffer for playback. It builds on the previous streaming code I wrote but when it starts playing, it stores the position in the PCM array that the current section ends.
When it goes to write new data to the buffer as part of the streaming process, it checks to see if the current PCM position plus the size of the proposed chunk is greater than this end position. If so, it reads the next instruction from the pattern array (looping and re-reading if it encounters a loop instruction) then splits the update into the streaming buffer so that the remainder of the first section is written, then enough of the next section to fill the update chunk.
It then sets the current PCM position to the next byte in the PCM data and sets the current section end position to the start of the section plus the section size.
For simplicity, all sections need to be the same length so that section size can be deduced by simply dividing the PCM size by the number of sections specified in the file.
Thinking ahead, I may want to be able to trigger an "outro" pattern so that the music can end gracefully in response to game events, in which case some kind of system where the outro pattern is specified in the file and can be triggered by sending a signal to the music buffer to swap patterns at the next section end.
Seems to work pretty well so far, enables intros to music and infinite looping and prevents having to distribute and store in memory redundant PCM data so all a success so far.
Can't get too drunk tonight - going out with work for drinks is always fraught with peril, especially for a lager lout like me. Fingers crossed I don't wake up filled with regret or with worrying memory blanks in the morning.
Cheerio.
It is common in a computer game to want to play a piece that has, for a random example, two sections of intro, then a section repeated twice, then another section, then loop back to the two repeated sections and proceed in this loop ad infinitum.
Obviously this is not possible with linear PCM data played start to finish and also contains lots of repeated data. Given the size of even 8 bit mono PCM data, this is a significant consideration.
What I've put together is the following system.
Once a track is working in Psycle, I create a new Psycle version that just contains each unique section in pretty much any order.
I then have a command line utility that reads a script that specifies the raw WAV file, the number of sections and a pattern of sequences to play the sections in, including the ability to loop back to a previous step in the pattern by index.
The tool produces a binary file containing all this information, including the raw PCM data.
The game runtime then has a system to load this information into a MusicBuffer which contains a two second streaming DirectSound buffer for playback. It builds on the previous streaming code I wrote but when it starts playing, it stores the position in the PCM array that the current section ends.
When it goes to write new data to the buffer as part of the streaming process, it checks to see if the current PCM position plus the size of the proposed chunk is greater than this end position. If so, it reads the next instruction from the pattern array (looping and re-reading if it encounters a loop instruction) then splits the update into the streaming buffer so that the remainder of the first section is written, then enough of the next section to fill the update chunk.
It then sets the current PCM position to the next byte in the PCM data and sets the current section end position to the start of the section plus the section size.
For simplicity, all sections need to be the same length so that section size can be deduced by simply dividing the PCM size by the number of sections specified in the file.
Thinking ahead, I may want to be able to trigger an "outro" pattern so that the music can end gracefully in response to game events, in which case some kind of system where the outro pattern is specified in the file and can be triggered by sending a signal to the music buffer to swap patterns at the next section end.
Seems to work pretty well so far, enables intros to music and infinite looping and prevents having to distribute and store in memory redundant PCM data so all a success so far.
Can't get too drunk tonight - going out with work for drinks is always fraught with peril, especially for a lager lout like me. Fingers crossed I don't wake up filled with regret or with worrying memory blanks in the morning.
Cheerio.
Advertisement
Advertisement
Advertisement
Discussion