Skip to content

Commit

Permalink
InfoChunk editing
Browse files Browse the repository at this point in the history
  • Loading branch information
Kermalis committed Aug 30, 2018
1 parent 4c1a2de commit 0aae6b2
Show file tree
Hide file tree
Showing 4 changed files with 240 additions and 88 deletions.
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@ A C# library that can read and write SF2 sound bank files.

----
# To Do:
* Adding info to InfoListChunk
* Prevent loading the terminal data
* Find a way to "public seal" SF2Chunk and SF2ListChunk
* Getting info such as samples, modulators and generators
* Separate chunks into their own files
* Separate chunks into their own files
* Certain generators must be in a specified index (KeyRange, VelRange, SampleID and Instrument) according to spec
81 changes: 37 additions & 44 deletions SoundFont2/SF2.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,23 +6,16 @@ namespace Kermalis.SoundFont2
public sealed class SF2
{
uint size;
InfoListChunk infoChunk;
SdtaListChunk soundChunk;
PdtaListChunk hydraChunk;

internal uint IBAGCount => hydraChunk.IBAGSubChunk.Count;
internal uint IGENCount => hydraChunk.IGENSubChunk.Count;
internal uint IMODCount => hydraChunk.IMODSubChunk.Count;
internal uint PBAGCount => hydraChunk.PBAGSubChunk.Count;
internal uint PGENCount => hydraChunk.PGENSubChunk.Count;
internal uint PMODCount => hydraChunk.PMODSubChunk.Count;
public readonly InfoListChunk InfoChunk;
public readonly SdtaListChunk SoundChunk;
public readonly PdtaListChunk HydraChunk;

// For creating
public SF2(string engine = "", string bank = "")
public SF2()
{
infoChunk = new InfoListChunk(this, engine, bank);
soundChunk = new SdtaListChunk(this);
hydraChunk = new PdtaListChunk(this);
InfoChunk = new InfoListChunk(this);
SoundChunk = new SdtaListChunk(this);
HydraChunk = new PdtaListChunk(this);
}

// For reading
Expand All @@ -39,9 +32,9 @@ public SF2(string path)
if (new string(chars) != "sfbk")
throw new InvalidDataException("sfbk header was not found at the expected offset.");

infoChunk = new InfoListChunk(this, reader);
soundChunk = new SdtaListChunk(this, reader);
hydraChunk = new PdtaListChunk(this, reader);
InfoChunk = new InfoListChunk(this, reader);
SoundChunk = new SdtaListChunk(this, reader);
HydraChunk = new PdtaListChunk(this, reader);
}
}

Expand All @@ -55,17 +48,17 @@ public void Save(string path)
writer.Write(size);
writer.Write("sfbk".ToCharArray());

infoChunk.Write(writer);
soundChunk.Write(writer);
hydraChunk.Write(writer);
InfoChunk.Write(writer);
SoundChunk.Write(writer);
HydraChunk.Write(writer);
}
}


// Returns sample index
public uint AddSample(short[] pcm16, string name, bool bLoop, uint loopPos, uint sampleRate, byte originalKey, sbyte pitchCorrection)
{
uint start = soundChunk.SMPLSubChunk.AddSample(pcm16, bLoop, loopPos);
uint start = SoundChunk.SMPLSubChunk.AddSample(pcm16, bLoop, loopPos);
// If the sample is looped the standard requires us to add the 8 bytes from the start of the loop to the end
uint end, loopEnd, loopStart;

Expand All @@ -86,66 +79,66 @@ public uint AddSample(short[] pcm16, string name, bool bLoop, uint loopPos, uint
// Returns instrument index
public uint AddInstrument(string name)
{
return hydraChunk.INSTSubChunk.AddInstrument(new SF2Instrument(this)
return HydraChunk.INSTSubChunk.AddInstrument(new SF2Instrument(this)
{
InstrumentName = name,
InstrumentBagIndex = (ushort)IBAGCount
InstrumentBagIndex = (ushort)HydraChunk.IBAGSubChunk.Count
});
}
public void AddInstrumentBag()
{
hydraChunk.IBAGSubChunk.AddBag(new SF2Bag(this, false));
HydraChunk.IBAGSubChunk.AddBag(new SF2Bag(this, false));
}
public void AddInstrumentModulator()
{
hydraChunk.IMODSubChunk.AddModulator(new SF2ModulatorList(this));
HydraChunk.IMODSubChunk.AddModulator(new SF2ModulatorList(this));
}
public void AddInstrumentGenerator()
{
hydraChunk.IGENSubChunk.AddGenerator(new SF2GeneratorList(this));
HydraChunk.IGENSubChunk.AddGenerator(new SF2GeneratorList(this));
}
public void AddInstrumentGenerator(SF2Generator operation, SF2GeneratorAmount genAmountType)
public void AddInstrumentGenerator(SF2Generator generator, SF2GeneratorAmount amount)
{
hydraChunk.IGENSubChunk.AddGenerator(new SF2GeneratorList(this)
HydraChunk.IGENSubChunk.AddGenerator(new SF2GeneratorList(this)
{
Generator = operation,
GeneratorAmount = genAmountType
Generator = generator,
GeneratorAmount = amount
});
}
public void AddPreset(string name, ushort preset, ushort bank)
{
hydraChunk.PHDRSubChunk.AddPreset(new SF2PresetHeader(this)
HydraChunk.PHDRSubChunk.AddPreset(new SF2PresetHeader(this)
{
PresetName = name,
Preset = preset,
Bank = bank,
PresetBagIndex = (ushort)PBAGCount
PresetBagIndex = (ushort)HydraChunk.PBAGSubChunk.Count
});
}
public void AddPresetBag()
{
hydraChunk.PBAGSubChunk.AddBag(new SF2Bag(this, true));
HydraChunk.PBAGSubChunk.AddBag(new SF2Bag(this, true));
}
public void AddPresetModulator()
{
hydraChunk.PMODSubChunk.AddModulator(new SF2ModulatorList(this));
HydraChunk.PMODSubChunk.AddModulator(new SF2ModulatorList(this));
}
public void AddPresetGenerator()
{
hydraChunk.PGENSubChunk.AddGenerator(new SF2GeneratorList(this));
HydraChunk.PGENSubChunk.AddGenerator(new SF2GeneratorList(this));
}
public void AddPresetGenerator(SF2Generator operation, SF2GeneratorAmount genAmountType)
public void AddPresetGenerator(SF2Generator generator, SF2GeneratorAmount amount)
{
hydraChunk.PGENSubChunk.AddGenerator(new SF2GeneratorList(this)
HydraChunk.PGENSubChunk.AddGenerator(new SF2GeneratorList(this)
{
Generator = operation,
GeneratorAmount = genAmountType
Generator = generator,
GeneratorAmount = amount
});
}

uint AddSampleHeader(string name, uint start, uint end, uint loopStart, uint loopEnd, uint sampleRate, byte originalKey, sbyte pitchCorrection)
{
return hydraChunk.SHDRSubChunk.AddSample(new SF2SampleHeader(this)
return HydraChunk.SHDRSubChunk.AddSample(new SF2SampleHeader(this)
{
SampleName = name,
Start = start,
Expand All @@ -172,12 +165,12 @@ void AddTerminals()

internal void UpdateSize()
{
if (infoChunk == null || soundChunk == null || hydraChunk == null)
if (InfoChunk == null || SoundChunk == null || HydraChunk == null)
return;
size = 4
+ infoChunk.UpdateSize() + 8
+ soundChunk.UpdateSize() + 8
+ hydraChunk.UpdateSize() + 8;
+ InfoChunk.UpdateSize() + 8
+ SoundChunk.UpdateSize() + 8
+ HydraChunk.UpdateSize() + 8;
}
}
}
Loading

0 comments on commit 0aae6b2

Please sign in to comment.