public static SampleSoundGenerator ImportFromVorbis(SampleGeneratingArgs args) { var generator = new SampleSoundGenerator(new VorbisWaveReader(args.Path)) { VolumeCorrection = (float)args.Volume }; return(generator); }
private static SampleSoundGenerator GetSampleContinuous(SampleHeader sh, Zone izone, byte[] sample, SampleGeneratingArgs args) { // Indices in sf2 are numbers of samples, not byte length. So double them int start = (int)sh.Start + izone.FullStartAddressOffset(); int end = (int)sh.End + izone.FullEndAddressOffset(); int startLoop = (int)sh.StartLoop + izone.FullStartLoopAddressOffset(); int endLoop = (int)sh.EndLoop + izone.FullEndLoopAddressOffset(); int length = end - start; int lengthBytes = length * 2; int loopLength = endLoop - startLoop; int loopLengthBytes = loopLength * 2; double lengthInSeconds = args.Length != -1 ? (args.Length / 1000) + 0.4 : length / (double)sh.SampleRate + 0.4; // Sample rate key correction int keyCorrection = args.Key != -1 ? args.Key - izone.Key() : 0; double factor = Math.Pow(2, keyCorrection / 12d); lengthInSeconds *= factor; int numberOfSamples = (int)Math.Ceiling(lengthInSeconds * sh.SampleRate); int numberOfLoopSamples = numberOfSamples - length; if (numberOfLoopSamples < 0) { return(GetSampleWithoutLoop(sh, izone, sample, args)); } int numberOfBytes = numberOfSamples * 2; byte[] buffer = new byte[numberOfBytes]; Array.Copy(sample, start * 2, buffer, 0, lengthBytes); for (int i = 0; i < (numberOfLoopSamples + loopLength - 1) / loopLength; i++) { Array.Copy(sample, startLoop * 2, buffer, lengthBytes + i * loopLengthBytes, Math.Min(loopLengthBytes, numberOfBytes - (lengthBytes + i * loopLengthBytes))); } var output = new SampleSoundGenerator(BufferToWaveStream(buffer, (uint)(sh.SampleRate * factor))) { FadeStart = lengthInSeconds - 0.4, FadeLength = 0.3 }; return(output); }
public static SampleSoundGenerator ImportSample(SampleGeneratingArgs args) { string path = args.Path; switch (Path.GetExtension(path)) { case ".sf2": { SoundFont sf2 = new SoundFont(path); SampleSoundGenerator wave = ImportFromSoundFont(args, sf2); GC.Collect(); return(wave); } case ".ogg": return(ImportFromVorbis(args)); default: return(ImportFromAudio(args)); } }
public static SampleSoundGenerator ImportSample(SampleGeneratingArgs args) { string path = args.Path; if (Path.GetExtension(path) == ".sf2") { SoundFont sf2 = new SoundFont(path); SampleSoundGenerator wave = ImportFromSoundFont(args, sf2); GC.Collect(); return(wave); } else if (Path.GetExtension(path) == ".ogg") { return(ImportFromVorbis(args)); } else { return(ImportFromAudio(args)); } }
private static SampleSoundGenerator GetSampleWithoutLoop(SampleHeader sh, Zone izone, byte[] sample, SampleGeneratingArgs args) { // Indices in sf2 are numbers of samples, not byte length. So double them int start = (int)sh.Start + izone.FullStartAddressOffset(); int end = (int)sh.End + izone.FullEndAddressOffset(); int length = end - start; double lengthInSeconds = args.Length != -1 ? (args.Length / 1000) + 0.4 : length / (double)sh.SampleRate; // Sample rate key correction int keyCorrection = args.Key != -1 ? args.Key - izone.Key() : 0; double factor = Math.Pow(2, keyCorrection / 12d); lengthInSeconds *= factor; lengthInSeconds = Math.Min(lengthInSeconds, length / (double)sh.SampleRate); int numberOfSamples = (int)Math.Ceiling(lengthInSeconds * sh.SampleRate); int numberOfBytes = numberOfSamples * 2; byte[] buffer = new byte[numberOfBytes]; Array.Copy(sample, start * 2, buffer, 0, numberOfBytes); var output = new SampleSoundGenerator(BufferToWaveStream(buffer, (uint)(sh.SampleRate * factor))); if (lengthInSeconds <= 0.4) { output.FadeStart = lengthInSeconds * 0.7; output.FadeLength = lengthInSeconds * 0.2; } else { output.FadeStart = lengthInSeconds - 0.4; output.FadeLength = 0.3; } return(output); }
// TODO: format soundfont import to detect file versions and types of files. public static SampleSoundGenerator ImportFromSoundFont(SampleGeneratingArgs args, SoundFont sf2) { SampleSoundGenerator wave = null; foreach (var preset in sf2.Presets) { if (preset.PatchNumber != args.Patch && args.Patch != -1) { continue; } if (preset.Bank != args.Bank && args.Bank != -1) { continue; } wave = ImportPreset(sf2, preset, args); if (wave != null) { break; } } return(wave ?? ImportInstruments(sf2, args)); }