mirror of
https://github.com/ClassiCube/ClassiCube.git
synced 2025-09-16 11:06:06 -04:00
Read from the .wav files now, but still need to convert the old .bin to .wav list.
This commit is contained in:
parent
843da643c4
commit
3716e9f88e
@ -19,18 +19,16 @@ namespace ClassicalSharp.Audio {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void InitSound() {
|
void InitSound() {
|
||||||
if( digBoard == null )
|
if( digBoard == null ) InitSoundboards();
|
||||||
InitSoundboards();
|
|
||||||
|
|
||||||
monoOutputs = new IAudioOutput[maxSounds];
|
monoOutputs = new IAudioOutput[maxSounds];
|
||||||
stereoOutputs = new IAudioOutput[maxSounds];
|
stereoOutputs = new IAudioOutput[maxSounds];
|
||||||
}
|
}
|
||||||
|
|
||||||
void InitSoundboards() {
|
void InitSoundboards() {
|
||||||
digBoard = new Soundboard();
|
digBoard = new Soundboard();
|
||||||
digBoard.Init( "dig" );
|
digBoard.Init( "dig_", files );
|
||||||
stepBoard = new Soundboard();
|
stepBoard = new Soundboard();
|
||||||
stepBoard.Init( "step" );
|
stepBoard.Init( "step_", files );
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Tick( double delta ) {
|
public void Tick( double delta ) {
|
||||||
@ -45,13 +43,12 @@ namespace ClassicalSharp.Audio {
|
|||||||
if( type == SoundType.None || monoOutputs == null )
|
if( type == SoundType.None || monoOutputs == null )
|
||||||
return;
|
return;
|
||||||
Sound snd = board.PickRandomSound( type );
|
Sound snd = board.PickRandomSound( type );
|
||||||
snd.Metadata = board == digBoard ? (byte)1 : (byte)2;
|
|
||||||
chunk.Channels = snd.Channels;
|
chunk.Channels = snd.Channels;
|
||||||
chunk.Frequency = snd.SampleRate;
|
chunk.Frequency = snd.SampleRate;
|
||||||
chunk.BitsPerSample = snd.BitsPerSample;
|
chunk.BitsPerSample = snd.BitsPerSample;
|
||||||
chunk.BytesOffset = snd.Offset;
|
chunk.BytesOffset = 0;
|
||||||
chunk.BytesUsed = snd.Length;
|
chunk.BytesUsed = snd.Data.Length;
|
||||||
chunk.Data = board.Data;
|
chunk.Data = snd.Data;
|
||||||
|
|
||||||
if( snd.Channels == 1 )
|
if( snd.Channels == 1 )
|
||||||
PlayCurrentSound( monoOutputs );
|
PlayCurrentSound( monoOutputs );
|
||||||
|
@ -11,12 +11,15 @@ namespace ClassicalSharp.Audio {
|
|||||||
|
|
||||||
IAudioOutput musicOut;
|
IAudioOutput musicOut;
|
||||||
IAudioOutput[] monoOutputs, stereoOutputs;
|
IAudioOutput[] monoOutputs, stereoOutputs;
|
||||||
string[] musicFiles;
|
string[] files, musicFiles;
|
||||||
Thread musicThread;
|
Thread musicThread;
|
||||||
Game game;
|
Game game;
|
||||||
|
|
||||||
public AudioPlayer( Game game ) {
|
public AudioPlayer( Game game ) {
|
||||||
this.game = game;
|
this.game = game;
|
||||||
|
string path = Path.Combine( Program.AppDirectory, "audio" );
|
||||||
|
files = Directory.GetFiles( path );
|
||||||
|
|
||||||
game.UseMusic = Options.GetBool( OptionsKey.UseMusic, false );
|
game.UseMusic = Options.GetBool( OptionsKey.UseMusic, false );
|
||||||
SetMusic( game.UseMusic );
|
SetMusic( game.UseMusic );
|
||||||
game.UseSound = Options.GetBool( OptionsKey.UseSound, false );
|
game.UseSound = Options.GetBool( OptionsKey.UseSound, false );
|
||||||
@ -30,9 +33,19 @@ namespace ClassicalSharp.Audio {
|
|||||||
DisposeMusic();
|
DisposeMusic();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const StringComparison comp = StringComparison.OrdinalIgnoreCase;
|
||||||
void InitMusic() {
|
void InitMusic() {
|
||||||
string path = Path.Combine( Program.AppDirectory, "audio" );
|
int musicCount = 0;
|
||||||
musicFiles = Directory.GetFiles( path, "*.ogg" );
|
for( int i = 0; i < files.Length; i++ ) {
|
||||||
|
if( files[i].EndsWith( ".ogg", comp ) ) musicCount++;
|
||||||
|
}
|
||||||
|
|
||||||
|
musicFiles = new string[musicCount];
|
||||||
|
for( int i = 0, j = 0; i < files.Length; i++ ) {
|
||||||
|
if( !files[i].EndsWith( ".ogg", comp ) ) continue;
|
||||||
|
musicFiles[j] = files[i]; j++;
|
||||||
|
}
|
||||||
|
|
||||||
disposingMusic = false;
|
disposingMusic = false;
|
||||||
musicThread = MakeThread( DoMusicThread, ref musicOut,
|
musicThread = MakeThread( DoMusicThread, ref musicOut,
|
||||||
"ClassicalSharp.DoMusic" );
|
"ClassicalSharp.DoMusic" );
|
||||||
|
@ -8,89 +8,89 @@ namespace ClassicalSharp.Audio {
|
|||||||
public class Soundboard {
|
public class Soundboard {
|
||||||
|
|
||||||
public byte[] Data;
|
public byte[] Data;
|
||||||
internal List<Sound> rawSounds = new List<Sound>();
|
Dictionary<string, List<Sound>> allSounds = new Dictionary<string, List<Sound>>();
|
||||||
Dictionary<string, int> groupFlags = new Dictionary<string, int>();
|
|
||||||
Random rnd = new Random();
|
Random rnd = new Random();
|
||||||
|
|
||||||
static string[] soundNames;
|
static string[] soundNames;
|
||||||
static Soundboard() {
|
static Soundboard() {
|
||||||
soundNames = Enum.GetNames( typeof( SoundType ) );
|
soundNames = Enum.GetNames( typeof( SoundType ) );
|
||||||
for( int i = 0; i < soundNames.Length; i++ )
|
for( int i = 0; i < soundNames.Length; i++ )
|
||||||
soundNames[i] = soundNames[i].ToLower();
|
soundNames[i] = soundNames[i].ToLower();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Init( string group ) {
|
const StringComparison comp = StringComparison.OrdinalIgnoreCase;
|
||||||
string basePath = Path.Combine( Program.AppDirectory, "audio" );
|
public void Init( string group, string[] files ) {
|
||||||
string binPath = Path.Combine( basePath, group + ".bin" );
|
for( int i = 0; i < files.Length; i++ ) {
|
||||||
string txtPath = Path.Combine( basePath, group + ".txt" );
|
string name = Path.GetFileNameWithoutExtension( files[i] );
|
||||||
|
if( !name.StartsWith( group, comp )) continue;
|
||||||
Data = File.ReadAllBytes( binPath );
|
|
||||||
ReadMetadata( txtPath );
|
// Convert dig_grass1.wav to grass
|
||||||
rawSounds.Sort( (a, b) => a.Name.CompareTo( b.Name ) );
|
name = name.Substring( group.Length ).ToLower();
|
||||||
GetGroups();
|
name = name.Substring( 0, name.Length - 1 );
|
||||||
|
|
||||||
|
List<Sound> sounds = null;
|
||||||
|
if( !allSounds.TryGetValue( name, out sounds ) ) {
|
||||||
|
sounds = new List<Sound>();
|
||||||
|
allSounds[name] = sounds;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
Sound snd = ReadWave( files[i] );
|
||||||
|
sounds.Add( snd );
|
||||||
|
} catch ( Exception ex ) {
|
||||||
|
ErrorHandler.LogError( "Soundboard.ReadWave()", ex );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Sound ReadWave( string file ) {
|
||||||
|
using( FileStream fs = File.OpenRead( file ) )
|
||||||
|
using( BinaryReader r = new BinaryReader( fs ) )
|
||||||
|
{
|
||||||
|
CheckFourCC( r, "RIFF" );
|
||||||
|
r.ReadInt32(); // file size, but we don't care
|
||||||
|
CheckFourCC( r, "WAVE" );
|
||||||
|
Sound snd = new Sound();
|
||||||
|
|
||||||
|
CheckFourCC( r, "fmt " );
|
||||||
|
int size = r.ReadInt32();
|
||||||
|
if( r.ReadUInt16() != 1 )
|
||||||
|
throw new InvalidDataException( "Only PCM audio is supported." );
|
||||||
|
size -= 2;
|
||||||
|
|
||||||
|
snd.Channels = r.ReadUInt16(); size -= 2;
|
||||||
|
snd.SampleRate = r.ReadInt32(); size -= 4;
|
||||||
|
r.ReadInt32(); r.ReadUInt16(); size -= 6;
|
||||||
|
snd.BitsPerSample = r.ReadUInt16(); size -= 2;
|
||||||
|
if( size > 0 )
|
||||||
|
fs.Seek( size, SeekOrigin.Current );
|
||||||
|
|
||||||
|
CheckFourCC( r, "data" );
|
||||||
|
size = r.ReadInt32();
|
||||||
|
byte[] data = r.ReadBytes( size );
|
||||||
|
snd.Data = data;
|
||||||
|
return snd;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void CheckFourCC( BinaryReader r, string fourCC ) {
|
||||||
|
if( r.ReadByte() != (byte)fourCC[0] || r.ReadByte() != (byte)fourCC[1]
|
||||||
|
|| r.ReadByte() != (byte)fourCC[2] || r.ReadByte() != (byte)fourCC[3] )
|
||||||
|
throw new InvalidDataException( "Expected " + fourCC + " fourcc" );
|
||||||
}
|
}
|
||||||
|
|
||||||
public Sound PickRandomSound( SoundType type ) {
|
public Sound PickRandomSound( SoundType type ) {
|
||||||
if( type == SoundType.None )
|
if( type == SoundType.None ) return null;
|
||||||
return null;
|
|
||||||
string name = soundNames[(int)type];
|
string name = soundNames[(int)type];
|
||||||
int flags = groupFlags[name];
|
|
||||||
|
|
||||||
int offset = flags & 0xFFF, count = flags >> 12;
|
List<Sound> sounds;
|
||||||
return rawSounds[offset + rnd.Next( count )];
|
if( !allSounds.TryGetValue( name, out sounds ) ) return null;
|
||||||
}
|
return sounds[rnd.Next( sounds.Count )];
|
||||||
|
}
|
||||||
void ReadMetadata( string path ) {
|
|
||||||
using( StreamReader reader = new StreamReader( path ) ) {
|
|
||||||
string line;
|
|
||||||
while( (line = reader.ReadLine()) != null ) {
|
|
||||||
if( line.Length == 0 || line[0] == '#' ) continue;
|
|
||||||
string[] parts = line.Split( ',' );
|
|
||||||
if( parts.Length < 6 ) continue;
|
|
||||||
string name = parts[0].ToLower();
|
|
||||||
int sampleRate, bitsPerSample, channels;
|
|
||||||
int offset, length;
|
|
||||||
|
|
||||||
if( !Int32.TryParse( parts[1], out sampleRate ) ||
|
|
||||||
!Int32.TryParse( parts[2], out bitsPerSample ) ||
|
|
||||||
!Int32.TryParse( parts[3], out channels ) ||
|
|
||||||
!Int32.TryParse( parts[4], out offset ) ||
|
|
||||||
!Int32.TryParse( parts[5], out length ) )
|
|
||||||
continue;
|
|
||||||
Sound s = new Sound();
|
|
||||||
s.Name = name; s.SampleRate = sampleRate;
|
|
||||||
s.BitsPerSample = bitsPerSample; s.Channels = channels;
|
|
||||||
s.Offset = offset; s.Length = length;
|
|
||||||
rawSounds.Add( s );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void GetGroups() {
|
|
||||||
string last = Group( rawSounds[0].Name );
|
|
||||||
int offset = 0, count = 0;
|
|
||||||
for( int i = 0; i < rawSounds.Count; i++ ) {
|
|
||||||
string group = Group( rawSounds[i].Name );
|
|
||||||
if( group != last ) {
|
|
||||||
groupFlags[last] = (count << 12) | offset;
|
|
||||||
offset = i;
|
|
||||||
last = group;
|
|
||||||
count = 0;
|
|
||||||
}
|
|
||||||
count++;
|
|
||||||
}
|
|
||||||
groupFlags[last] = (count << 12) | offset;
|
|
||||||
}
|
|
||||||
|
|
||||||
string Group( string name ) {
|
|
||||||
return name.Substring( 0, name.Length - 1 );
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public class Sound {
|
public class Sound {
|
||||||
public string Name;
|
|
||||||
public int SampleRate, BitsPerSample, Channels;
|
public int SampleRate, BitsPerSample, Channels;
|
||||||
public int Offset, Length;
|
public byte[] Data;
|
||||||
public byte Metadata;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user