/// <summary> /// /// </summary> /// <param name="parentModule"></param> /// <param name="noteOnEvent"></param> /// <param name="programNumber"></param> /// <param name="slot"></param> public C140Sound(C140 parentModule, C140SoundManager manager, TimbreBase timbre, int tindex, TaggedNoteOnEvent noteOnEvent, int slot, byte timbreIndex) : base(parentModule, manager, timbre, tindex, noteOnEvent, slot) { this.parentModule = parentModule; this.timbreIndex = timbreIndex; this.timbre = (C140Timbre)timbre; lastSoundType = this.timbre.SoundType; if (lastSoundType == SoundType.INST) { baseFreq = this.timbre.BaseFreqency; sampleRate = this.timbre.SampleRate; loopPoint = this.timbre.LoopPoint; loopEn = this.timbre.LoopEnable; } /* * else if (lastSoundType == SoundType.DRUM) * { * var pct = (C140PcmTimbre)parentModule.DrumSoundTable.PcmTimbres[noteOnEvent.NoteNumber]; * baseFreq = pct.BaseFreqency; * sampleRate = pct.SampleRate; * loopPoint = pct.LoopPoint; * loopEn = pct.LoopEnable; * }*/ }
/// <summary> /// /// </summary> public C140(uint unitNumber) : base(unitNumber) { Timbres = new C140Timbre[256]; for (int i = 0; i < 256; i++) { Timbres[i] = new C140Timbre(); } //DrumSoundTable = new C140PcmSoundTable(); setPresetInstruments(); this.soundManager = new C140SoundManager(this); f_read_byte_callback = new delg_callback(read_byte_callback); C140SetCallback(UnitNumber, f_read_byte_callback); GainLeft = DEFAULT_GAIN; GainRight = DEFAULT_GAIN; readSoundFontForTimbre = new ToolStripMenuItem("Import PCM from SF2 for &Timbre..."); readSoundFontForTimbre.Click += ReadSoundFontForTimbre_Click; readSoundFontForDrumTimbre = new ToolStripMenuItem("Import PCM from SF2 for &DrumTimbre..."); readSoundFontForDrumTimbre.Click += ReadSoundFontForDrumTimbre_Click; }
/// <summary> /// /// </summary> /// <param name="note"></param> public override SoundBase[] SoundOn(TaggedNoteOnEvent note) { List <SoundBase> rv = new List <SoundBase>(); var bts = parentModule.GetBaseTimbres(note); var ids = parentModule.GetBaseTimbreIndexes(note); int tindex = 0; for (int i = 0; i < bts.Length; i++) { C140Timbre timbre = (C140Timbre)bts[i]; tindex++; var emptySlot = searchEmptySlot(note); if (emptySlot.slot < 0) { continue; } C140Sound snd = new C140Sound(emptySlot.inst, this, timbre, tindex - 1, note, emptySlot.slot, (byte)ids[i]); instOnSounds.Add(snd); //HACK: store pcm data to local buffer to avoid "thread lock" if (timbre.SoundType == SoundType.INST) { lock (parentModule.tmpPcmDataTable) parentModule.tmpPcmDataTable[ids[i]] = timbre.PcmData; } /* * else if (timbre.SoundType == SoundType.DRUM) * { * var pct = (C140PcmTimbre)parentModule.DrumSoundTable.PcmTimbres[note.NoteNumber]; * lock (parentModule.tmpPcmDataTable) * parentModule.tmpPcmDataTable[note.NoteNumber + 128] = pct.C140PcmData; * } */ FormMain.OutputDebugLog(parentModule, "KeyOn INST ch" + emptySlot + " " + note.ToString()); rv.Add(snd); } for (int i = 0; i < rv.Count; i++) { var snd = rv[i]; if (!snd.IsDisposed) { ProcessKeyOn(snd); } else { rv.Remove(snd); i--; } } return(rv.ToArray()); }
/// <summary> /// /// </summary> /// <param name="offset"></param> private void loadPcm(int offset, bool drum) { var sf2 = new SF2(openFileDialog.FileName); var spl = sf2.SoundChunk.SMPLSubChunk.Samples; int tn = 0; int num = 0; foreach (var s in sf2.HydraChunk.SHDRSubChunk.Samples) { if (s.SampleType == SF2SampleLink.MonoSample || s.SampleType == SF2SampleLink.LeftSample) { var tim = new C140Timbre(); double baseFreq = 440.0 * Math.Pow(2.0, ((double)s.OriginalKey - 69.0) / 12.0); tim.BaseFreqency = baseFreq; tim.SampleRate = s.SampleRate; uint start = s.Start; uint end = s.End; if (s.LoopEnd < end && s.LoopStart < s.LoopEnd) { end = s.LoopEnd; } uint len = end - start + 1; if (len > 65535) { len = 65535; } uint loopP = s.LoopStart - s.Start; if (loopP > 65535) { loopP = 65535; } sbyte[] samples = new sbyte[len]; for (uint i = 0; i < len; i++) { samples[i] = (sbyte)(spl[start + i] >> 8); } tim.PcmData = samples; tim.LoopPoint = (ushort)loopP; tim.LoopEnable = s.LoopStart < s.LoopEnd; if (s.LoopStart < s.LoopEnd) { tim.SDS.ADSR.Enable = true; tim.SDS.ADSR.DR = 80; tim.SDS.ADSR.SL = 127; } if (drum) { DrumTimbres[tn].TimbreNumber = (ProgramAssignmentNumber)(tn + offset); DrumTimbres[tn].BaseNote = (NoteNames)(byte)Math.Round(MidiManager.CalcNoteNumberFromFrequency(tim.BaseFreqency)); } Timbres[tn + offset] = tim; num++; var nidx = s.SampleName.IndexOf('\0'); if (nidx >= 0) { tim.TimbreName = s.SampleName.Substring(0, nidx); } else { tim.TimbreName = s.SampleName; } tn++; if (tn == 128) { break; } } } }