changeset 829:b06c29386f63

6702956: OpenJDK: replace encumbered code (software synthesizer) 6717691: Update Gervill with post 1.0 fixes 6740210: Update Gervill with more post 1.0 fixes 6748247: Further update Gervill with still more post 1.0 fixes 6748251: Apply IcedTea midi sound patch 6758986: Gervill: Turn SoftJitterCorrector, SoftAudioPusher threads into a daemon threads Reviewed-by: ohair, darcy
author amenkov
date Mon, 19 Jan 2009 20:11:58 +0300
parents 2b8a0d8b5cbb
children cda097df492f
files make/common/Release.gmk make/common/internal/BinaryPlugs.gmk make/javax/sound/Makefile make/javax/sound/jsoundhs/FILES.gmk make/javax/sound/jsoundhs/Makefile make/javax/sound/jsoundhs/mapfile-vers src/share/classes/com/sun/media/sound/AbstractMidiDevice.java src/share/classes/com/sun/media/sound/AudioFileSoundbankReader.java src/share/classes/com/sun/media/sound/AudioFloatConverter.java src/share/classes/com/sun/media/sound/AudioFloatFormatConverter.java src/share/classes/com/sun/media/sound/AudioFloatInputStream.java src/share/classes/com/sun/media/sound/AudioSynthesizer.java src/share/classes/com/sun/media/sound/AudioSynthesizerPropertyInfo.java src/share/classes/com/sun/media/sound/DLSInfo.java src/share/classes/com/sun/media/sound/DLSInstrument.java src/share/classes/com/sun/media/sound/DLSModulator.java src/share/classes/com/sun/media/sound/DLSRegion.java src/share/classes/com/sun/media/sound/DLSSample.java src/share/classes/com/sun/media/sound/DLSSampleLoop.java src/share/classes/com/sun/media/sound/DLSSampleOptions.java src/share/classes/com/sun/media/sound/DLSSoundbank.java src/share/classes/com/sun/media/sound/DLSSoundbankReader.java src/share/classes/com/sun/media/sound/DirectAudioDevice.java src/share/classes/com/sun/media/sound/EmergencySoundbank.java src/share/classes/com/sun/media/sound/FFT.java src/share/classes/com/sun/media/sound/InvalidDataException.java src/share/classes/com/sun/media/sound/InvalidFormatException.java src/share/classes/com/sun/media/sound/JARSoundbankReader.java src/share/classes/com/sun/media/sound/ModelAbstractChannelMixer.java src/share/classes/com/sun/media/sound/ModelAbstractOscillator.java src/share/classes/com/sun/media/sound/ModelByteBuffer.java src/share/classes/com/sun/media/sound/ModelByteBufferWavetable.java src/share/classes/com/sun/media/sound/ModelChannelMixer.java src/share/classes/com/sun/media/sound/ModelConnectionBlock.java src/share/classes/com/sun/media/sound/ModelDestination.java src/share/classes/com/sun/media/sound/ModelDirectedPlayer.java src/share/classes/com/sun/media/sound/ModelDirector.java src/share/classes/com/sun/media/sound/ModelIdentifier.java src/share/classes/com/sun/media/sound/ModelInstrument.java src/share/classes/com/sun/media/sound/ModelInstrumentComparator.java src/share/classes/com/sun/media/sound/ModelMappedInstrument.java src/share/classes/com/sun/media/sound/ModelOscillator.java src/share/classes/com/sun/media/sound/ModelOscillatorStream.java src/share/classes/com/sun/media/sound/ModelPatch.java src/share/classes/com/sun/media/sound/ModelPerformer.java src/share/classes/com/sun/media/sound/ModelSource.java src/share/classes/com/sun/media/sound/ModelStandardDirector.java src/share/classes/com/sun/media/sound/ModelStandardTransform.java src/share/classes/com/sun/media/sound/ModelTransform.java src/share/classes/com/sun/media/sound/ModelWavetable.java src/share/classes/com/sun/media/sound/Platform.java src/share/classes/com/sun/media/sound/RIFFInvalidDataException.java src/share/classes/com/sun/media/sound/RIFFInvalidFormatException.java src/share/classes/com/sun/media/sound/RIFFReader.java src/share/classes/com/sun/media/sound/RIFFWriter.java src/share/classes/com/sun/media/sound/RealTimeSequencer.java src/share/classes/com/sun/media/sound/SF2GlobalRegion.java src/share/classes/com/sun/media/sound/SF2Instrument.java src/share/classes/com/sun/media/sound/SF2InstrumentRegion.java src/share/classes/com/sun/media/sound/SF2Layer.java src/share/classes/com/sun/media/sound/SF2LayerRegion.java src/share/classes/com/sun/media/sound/SF2Modulator.java src/share/classes/com/sun/media/sound/SF2Region.java src/share/classes/com/sun/media/sound/SF2Sample.java src/share/classes/com/sun/media/sound/SF2Soundbank.java src/share/classes/com/sun/media/sound/SF2SoundbankReader.java src/share/classes/com/sun/media/sound/SimpleInstrument.java src/share/classes/com/sun/media/sound/SimpleSoundbank.java src/share/classes/com/sun/media/sound/SoftAbstractResampler.java src/share/classes/com/sun/media/sound/SoftAudioBuffer.java src/share/classes/com/sun/media/sound/SoftAudioProcessor.java src/share/classes/com/sun/media/sound/SoftAudioPusher.java src/share/classes/com/sun/media/sound/SoftChannel.java src/share/classes/com/sun/media/sound/SoftChannelProxy.java src/share/classes/com/sun/media/sound/SoftChorus.java src/share/classes/com/sun/media/sound/SoftControl.java src/share/classes/com/sun/media/sound/SoftCubicResampler.java src/share/classes/com/sun/media/sound/SoftEnvelopeGenerator.java src/share/classes/com/sun/media/sound/SoftFilter.java src/share/classes/com/sun/media/sound/SoftInstrument.java src/share/classes/com/sun/media/sound/SoftJitterCorrector.java src/share/classes/com/sun/media/sound/SoftLanczosResampler.java src/share/classes/com/sun/media/sound/SoftLimiter.java src/share/classes/com/sun/media/sound/SoftLinearResampler.java src/share/classes/com/sun/media/sound/SoftLinearResampler2.java src/share/classes/com/sun/media/sound/SoftLowFrequencyOscillator.java src/share/classes/com/sun/media/sound/SoftMainMixer.java src/share/classes/com/sun/media/sound/SoftMidiAudioFileReader.java src/share/classes/com/sun/media/sound/SoftMixingClip.java src/share/classes/com/sun/media/sound/SoftMixingDataLine.java src/share/classes/com/sun/media/sound/SoftMixingMainMixer.java src/share/classes/com/sun/media/sound/SoftMixingMixer.java src/share/classes/com/sun/media/sound/SoftMixingMixerProvider.java src/share/classes/com/sun/media/sound/SoftMixingSourceDataLine.java src/share/classes/com/sun/media/sound/SoftPerformer.java src/share/classes/com/sun/media/sound/SoftPointResampler.java src/share/classes/com/sun/media/sound/SoftProcess.java src/share/classes/com/sun/media/sound/SoftProvider.java src/share/classes/com/sun/media/sound/SoftReceiver.java src/share/classes/com/sun/media/sound/SoftResampler.java src/share/classes/com/sun/media/sound/SoftResamplerStreamer.java src/share/classes/com/sun/media/sound/SoftReverb.java src/share/classes/com/sun/media/sound/SoftShortMessage.java src/share/classes/com/sun/media/sound/SoftSincResampler.java src/share/classes/com/sun/media/sound/SoftSynthesizer.java src/share/classes/com/sun/media/sound/SoftTuning.java src/share/classes/com/sun/media/sound/SoftVoice.java src/share/classes/com/sun/media/sound/WaveExtensibleFileReader.java src/share/classes/com/sun/media/sound/WaveFloatFileReader.java src/share/classes/com/sun/media/sound/WaveFloatFileWriter.java src/share/classes/com/sun/media/sound/services/javax.sound.midi.spi.MidiDeviceProvider src/share/classes/com/sun/media/sound/services/javax.sound.midi.spi.MidiFileReader src/share/classes/com/sun/media/sound/services/javax.sound.midi.spi.SoundbankReader src/share/classes/com/sun/media/sound/services/javax.sound.sampled.spi.AudioFileReader src/share/classes/com/sun/media/sound/services/javax.sound.sampled.spi.FormatConversionProvider src/share/classes/com/sun/media/sound/services/javax.sound.sampled.spi.MixerProvider src/share/lib/audio/soundbank.gm test/javax/sound/midi/Gervill/AudioFloatConverter/GetFormat.java test/javax/sound/midi/Gervill/AudioFloatConverter/ToFloatArray.java test/javax/sound/midi/Gervill/AudioFloatInputStream/Available.java test/javax/sound/midi/Gervill/AudioFloatInputStream/Close.java test/javax/sound/midi/Gervill/AudioFloatInputStream/GetFormat.java test/javax/sound/midi/Gervill/AudioFloatInputStream/GetFrameLength.java test/javax/sound/midi/Gervill/AudioFloatInputStream/MarkSupported.java test/javax/sound/midi/Gervill/AudioFloatInputStream/Read.java test/javax/sound/midi/Gervill/AudioFloatInputStream/ReadFloatArray.java test/javax/sound/midi/Gervill/AudioFloatInputStream/ReadFloatArrayIntInt.java test/javax/sound/midi/Gervill/AudioFloatInputStream/Reset.java test/javax/sound/midi/Gervill/AudioFloatInputStream/Skip.java test/javax/sound/midi/Gervill/DLSSoundbankReader/TestGetSoundbankFile.java test/javax/sound/midi/Gervill/DLSSoundbankReader/TestGetSoundbankInputStream.java test/javax/sound/midi/Gervill/DLSSoundbankReader/TestGetSoundbankInputStream2.java test/javax/sound/midi/Gervill/DLSSoundbankReader/TestGetSoundbankUrl.java test/javax/sound/midi/Gervill/DLSSoundbankReader/ding.dls test/javax/sound/midi/Gervill/EmergencySoundbank/TestCreateSoundbank.java test/javax/sound/midi/Gervill/ModelByteBuffer/GetInputStream.java test/javax/sound/midi/Gervill/ModelByteBuffer/GetRoot.java test/javax/sound/midi/Gervill/ModelByteBuffer/Load.java test/javax/sound/midi/Gervill/ModelByteBuffer/LoadAll.java test/javax/sound/midi/Gervill/ModelByteBuffer/NewModelByteBufferByteArray.java test/javax/sound/midi/Gervill/ModelByteBuffer/NewModelByteBufferByteArrayIntInt.java test/javax/sound/midi/Gervill/ModelByteBuffer/NewModelByteBufferFile.java test/javax/sound/midi/Gervill/ModelByteBuffer/NewModelByteBufferFileLongLong.java test/javax/sound/midi/Gervill/ModelByteBuffer/RandomFileInputStream/Available.java test/javax/sound/midi/Gervill/ModelByteBuffer/RandomFileInputStream/Close.java test/javax/sound/midi/Gervill/ModelByteBuffer/RandomFileInputStream/MarkReset.java test/javax/sound/midi/Gervill/ModelByteBuffer/RandomFileInputStream/MarkSupported.java test/javax/sound/midi/Gervill/ModelByteBuffer/RandomFileInputStream/Read.java test/javax/sound/midi/Gervill/ModelByteBuffer/RandomFileInputStream/ReadByte.java test/javax/sound/midi/Gervill/ModelByteBuffer/RandomFileInputStream/ReadByteIntInt.java test/javax/sound/midi/Gervill/ModelByteBuffer/RandomFileInputStream/Skip.java test/javax/sound/midi/Gervill/ModelByteBuffer/SubbufferLong.java test/javax/sound/midi/Gervill/ModelByteBuffer/SubbufferLongLong.java test/javax/sound/midi/Gervill/ModelByteBuffer/SubbufferLongLongBoolean.java test/javax/sound/midi/Gervill/ModelByteBuffer/Unload.java test/javax/sound/midi/Gervill/ModelByteBuffer/WriteTo.java test/javax/sound/midi/Gervill/ModelByteBufferWavetable/GetAttenuation.java test/javax/sound/midi/Gervill/ModelByteBufferWavetable/GetChannels.java test/javax/sound/midi/Gervill/ModelByteBufferWavetable/GetLoopLength.java test/javax/sound/midi/Gervill/ModelByteBufferWavetable/GetLoopStart.java test/javax/sound/midi/Gervill/ModelByteBufferWavetable/GetPitchCorrection.java test/javax/sound/midi/Gervill/ModelByteBufferWavetable/NewModelByteBufferWavetableModelByteBuffer.java test/javax/sound/midi/Gervill/ModelByteBufferWavetable/NewModelByteBufferWavetableModelByteBufferAudioFormat.java test/javax/sound/midi/Gervill/ModelByteBufferWavetable/NewModelByteBufferWavetableModelByteBufferAudioFormatFloat.java test/javax/sound/midi/Gervill/ModelByteBufferWavetable/NewModelByteBufferWavetableModelByteBufferFloat.java test/javax/sound/midi/Gervill/ModelByteBufferWavetable/Open.java test/javax/sound/midi/Gervill/ModelByteBufferWavetable/Set8BitExtensionBuffer.java test/javax/sound/midi/Gervill/ModelByteBufferWavetable/SetLoopType.java test/javax/sound/midi/Gervill/ModelDestination/NewModelDestination.java test/javax/sound/midi/Gervill/ModelDestination/NewModelDestinationModelIdentifier.java test/javax/sound/midi/Gervill/ModelDestination/SetIdentifier.java test/javax/sound/midi/Gervill/ModelDestination/SetTransform.java test/javax/sound/midi/Gervill/ModelIdentifier/EqualsObject.java test/javax/sound/midi/Gervill/ModelIdentifier/NewModelIdentifierString.java test/javax/sound/midi/Gervill/ModelIdentifier/NewModelIdentifierStringInt.java test/javax/sound/midi/Gervill/ModelIdentifier/NewModelIdentifierStringString.java test/javax/sound/midi/Gervill/ModelIdentifier/NewModelIdentifierStringStringInt.java test/javax/sound/midi/Gervill/ModelIdentifier/SetInstance.java test/javax/sound/midi/Gervill/ModelIdentifier/SetObject.java test/javax/sound/midi/Gervill/ModelIdentifier/SetVariable.java test/javax/sound/midi/Gervill/ModelPerformer/GetOscillators.java test/javax/sound/midi/Gervill/ModelPerformer/SetConnectionBlocks.java test/javax/sound/midi/Gervill/ModelPerformer/SetDefaultConnectionsEnabled.java test/javax/sound/midi/Gervill/ModelPerformer/SetExclusiveClass.java test/javax/sound/midi/Gervill/ModelPerformer/SetKeyFrom.java test/javax/sound/midi/Gervill/ModelPerformer/SetKeyTo.java test/javax/sound/midi/Gervill/ModelPerformer/SetName.java test/javax/sound/midi/Gervill/ModelPerformer/SetSelfNonExclusive.java test/javax/sound/midi/Gervill/ModelPerformer/SetVelFrom.java test/javax/sound/midi/Gervill/ModelPerformer/SetVelTo.java test/javax/sound/midi/Gervill/ModelSource/NewModelSource.java test/javax/sound/midi/Gervill/ModelSource/NewModelSourceModelIdentifier.java test/javax/sound/midi/Gervill/ModelSource/NewModelSourceModelIdentifierBoolean.java test/javax/sound/midi/Gervill/ModelSource/NewModelSourceModelIdentifierBooleanBoolean.java test/javax/sound/midi/Gervill/ModelSource/NewModelSourceModelIdentifierBooleanBooleanInt.java test/javax/sound/midi/Gervill/ModelSource/NewModelSourceModelIdentifierModelTransform.java test/javax/sound/midi/Gervill/ModelSource/SetIdentifier.java test/javax/sound/midi/Gervill/ModelSource/SetTransform.java test/javax/sound/midi/Gervill/ModelStandardTransform/NewModelStandardTransform.java test/javax/sound/midi/Gervill/ModelStandardTransform/NewModelStandardTransformBoolean.java test/javax/sound/midi/Gervill/ModelStandardTransform/NewModelStandardTransformBooleanBoolean.java test/javax/sound/midi/Gervill/ModelStandardTransform/NewModelStandardTransformBooleanBooleanInt.java test/javax/sound/midi/Gervill/ModelStandardTransform/SetDirection.java test/javax/sound/midi/Gervill/ModelStandardTransform/SetPolarity.java test/javax/sound/midi/Gervill/ModelStandardTransform/SetTransform.java test/javax/sound/midi/Gervill/ModelStandardTransform/TransformAbsolute.java test/javax/sound/midi/Gervill/ModelStandardTransform/TransformConcave.java test/javax/sound/midi/Gervill/ModelStandardTransform/TransformConvex.java test/javax/sound/midi/Gervill/ModelStandardTransform/TransformLinear.java test/javax/sound/midi/Gervill/ModelStandardTransform/TransformSwitch.java test/javax/sound/midi/Gervill/RiffReaderWriter/Available.java test/javax/sound/midi/Gervill/RiffReaderWriter/Close.java test/javax/sound/midi/Gervill/RiffReaderWriter/GetFilePointer.java test/javax/sound/midi/Gervill/RiffReaderWriter/GetSize.java test/javax/sound/midi/Gervill/RiffReaderWriter/HasNextChunk.java test/javax/sound/midi/Gervill/RiffReaderWriter/Read.java test/javax/sound/midi/Gervill/RiffReaderWriter/ReadByte.java test/javax/sound/midi/Gervill/RiffReaderWriter/ReadByteArrayIntInt.java test/javax/sound/midi/Gervill/RiffReaderWriter/ReadInt.java test/javax/sound/midi/Gervill/RiffReaderWriter/ReadLong.java test/javax/sound/midi/Gervill/RiffReaderWriter/ReadShort.java test/javax/sound/midi/Gervill/RiffReaderWriter/ReadString.java test/javax/sound/midi/Gervill/RiffReaderWriter/ReadUnsignedByte.java test/javax/sound/midi/Gervill/RiffReaderWriter/ReadUnsignedInt.java test/javax/sound/midi/Gervill/RiffReaderWriter/ReadUnsignedShort.java test/javax/sound/midi/Gervill/RiffReaderWriter/Skip.java test/javax/sound/midi/Gervill/RiffReaderWriter/WriteOutputStream.java test/javax/sound/midi/Gervill/SF2SoundbankReader/TestGetSoundbankFile.java test/javax/sound/midi/Gervill/SF2SoundbankReader/TestGetSoundbankInputStream.java test/javax/sound/midi/Gervill/SF2SoundbankReader/TestGetSoundbankInputStream2.java test/javax/sound/midi/Gervill/SF2SoundbankReader/TestGetSoundbankUrl.java test/javax/sound/midi/Gervill/SF2SoundbankReader/ding.sf2 test/javax/sound/midi/Gervill/SimpleInstrument/AddModelInstrument.java test/javax/sound/midi/Gervill/SimpleInstrument/AddModelInstrumentIntInt.java test/javax/sound/midi/Gervill/SimpleInstrument/AddModelInstrumentIntIntIntInt.java test/javax/sound/midi/Gervill/SimpleInstrument/AddModelInstrumentIntIntIntIntInt.java test/javax/sound/midi/Gervill/SimpleInstrument/AddModelPerformer.java test/javax/sound/midi/Gervill/SimpleInstrument/AddModelPerformerArray.java test/javax/sound/midi/Gervill/SimpleInstrument/AddModelPerformerArrayIntInt.java test/javax/sound/midi/Gervill/SimpleInstrument/AddModelPerformerArrayIntIntIntInt.java test/javax/sound/midi/Gervill/SimpleInstrument/AddModelPerformerArrayIntIntIntIntInt.java test/javax/sound/midi/Gervill/SimpleInstrument/AddModelPerformerIntInt.java test/javax/sound/midi/Gervill/SimpleInstrument/AddModelPerformerIntIntIntInt.java test/javax/sound/midi/Gervill/SimpleInstrument/AddModelPerformerIntIntIntIntInt.java test/javax/sound/midi/Gervill/SimpleInstrument/Clear.java test/javax/sound/midi/Gervill/SimpleInstrument/SetName.java test/javax/sound/midi/Gervill/SimpleInstrument/SetPatch.java test/javax/sound/midi/Gervill/SimpleSoundbank/AddInstrument.java test/javax/sound/midi/Gervill/SimpleSoundbank/AddResource.java test/javax/sound/midi/Gervill/SimpleSoundbank/GetInstrument.java test/javax/sound/midi/Gervill/SimpleSoundbank/RemoveInstrument.java test/javax/sound/midi/Gervill/SimpleSoundbank/SetDescription.java test/javax/sound/midi/Gervill/SimpleSoundbank/SetName.java test/javax/sound/midi/Gervill/SimpleSoundbank/SetVendor.java test/javax/sound/midi/Gervill/SimpleSoundbank/SetVersion.java test/javax/sound/midi/Gervill/SoftAudioBuffer/Array.java test/javax/sound/midi/Gervill/SoftAudioBuffer/Clear.java test/javax/sound/midi/Gervill/SoftAudioBuffer/Get.java test/javax/sound/midi/Gervill/SoftAudioBuffer/NewSoftAudioBuffer.java test/javax/sound/midi/Gervill/SoftAudioSynthesizer/DummySourceDataLine.java test/javax/sound/midi/Gervill/SoftAudioSynthesizer/GetFormat.java test/javax/sound/midi/Gervill/SoftAudioSynthesizer/GetPropertyInfo.java test/javax/sound/midi/Gervill/SoftAudioSynthesizer/Open.java test/javax/sound/midi/Gervill/SoftAudioSynthesizer/OpenStream.java test/javax/sound/midi/Gervill/SoftChannel/AllNotesOff.java test/javax/sound/midi/Gervill/SoftChannel/AllSoundOff.java test/javax/sound/midi/Gervill/SoftChannel/ChannelPressure.java test/javax/sound/midi/Gervill/SoftChannel/Controller.java test/javax/sound/midi/Gervill/SoftChannel/LocalControl.java test/javax/sound/midi/Gervill/SoftChannel/Mono.java test/javax/sound/midi/Gervill/SoftChannel/Mute.java test/javax/sound/midi/Gervill/SoftChannel/NoteOff.java test/javax/sound/midi/Gervill/SoftChannel/NoteOff2.java test/javax/sound/midi/Gervill/SoftChannel/NoteOn.java test/javax/sound/midi/Gervill/SoftChannel/Omni.java test/javax/sound/midi/Gervill/SoftChannel/PitchBend.java test/javax/sound/midi/Gervill/SoftChannel/PolyPressure.java test/javax/sound/midi/Gervill/SoftChannel/ProgramChange.java test/javax/sound/midi/Gervill/SoftChannel/ResetAllControllers.java test/javax/sound/midi/Gervill/SoftChannel/SoftTestUtils.java test/javax/sound/midi/Gervill/SoftChannel/Solo.java test/javax/sound/midi/Gervill/SoftCubicResampler/Interpolate.java test/javax/sound/midi/Gervill/SoftLanczosResampler/Interpolate.java test/javax/sound/midi/Gervill/SoftLimiter/ProcessAudio_replace_mix.java test/javax/sound/midi/Gervill/SoftLimiter/ProcessAudio_replace_mix_mono.java test/javax/sound/midi/Gervill/SoftLimiter/ProcessAudio_replace_mix_mono_overdrive.java test/javax/sound/midi/Gervill/SoftLimiter/ProcessAudio_replace_mix_overdrive.java test/javax/sound/midi/Gervill/SoftLimiter/ProcessAudio_replace_normal.java test/javax/sound/midi/Gervill/SoftLimiter/ProcessAudio_replace_normal_mono.java test/javax/sound/midi/Gervill/SoftLimiter/ProcessAudio_replace_overdrive.java test/javax/sound/midi/Gervill/SoftLimiter/ProcessAudio_replace_overdrive_mono.java test/javax/sound/midi/Gervill/SoftLinearResampler/Interpolate.java test/javax/sound/midi/Gervill/SoftLinearResampler2/Interpolate.java test/javax/sound/midi/Gervill/SoftPointResampler/Interpolate.java test/javax/sound/midi/Gervill/SoftProvider/GetDevice.java test/javax/sound/midi/Gervill/SoftReceiver/Close.java test/javax/sound/midi/Gervill/SoftReceiver/Send_ActiveSense.java test/javax/sound/midi/Gervill/SoftReceiver/Send_AllNotesOff.java test/javax/sound/midi/Gervill/SoftReceiver/Send_AllSoundOff.java test/javax/sound/midi/Gervill/SoftReceiver/Send_ChannelPressure.java test/javax/sound/midi/Gervill/SoftReceiver/Send_Controller.java test/javax/sound/midi/Gervill/SoftReceiver/Send_Mono.java test/javax/sound/midi/Gervill/SoftReceiver/Send_NoteOff.java test/javax/sound/midi/Gervill/SoftReceiver/Send_NoteOn.java test/javax/sound/midi/Gervill/SoftReceiver/Send_NoteOn_AllChannels.java test/javax/sound/midi/Gervill/SoftReceiver/Send_NoteOn_Delayed.java test/javax/sound/midi/Gervill/SoftReceiver/Send_NoteOn_Multiple.java test/javax/sound/midi/Gervill/SoftReceiver/Send_Omni.java test/javax/sound/midi/Gervill/SoftReceiver/Send_PitchBend.java test/javax/sound/midi/Gervill/SoftReceiver/Send_PolyPressure.java test/javax/sound/midi/Gervill/SoftReceiver/Send_ProgramChange.java test/javax/sound/midi/Gervill/SoftReceiver/Send_ResetAllControllers.java test/javax/sound/midi/Gervill/SoftReceiver/SoftTestUtils.java test/javax/sound/midi/Gervill/SoftSincResampler/Interpolate.java test/javax/sound/midi/Gervill/SoftSynthesizer/Close.java test/javax/sound/midi/Gervill/SoftSynthesizer/DummySourceDataLine.java test/javax/sound/midi/Gervill/SoftSynthesizer/GetAvailableInstruments.java test/javax/sound/midi/Gervill/SoftSynthesizer/GetChannels.java test/javax/sound/midi/Gervill/SoftSynthesizer/GetDefaultSoundbank.java test/javax/sound/midi/Gervill/SoftSynthesizer/GetDeviceInfo.java test/javax/sound/midi/Gervill/SoftSynthesizer/GetLatency.java test/javax/sound/midi/Gervill/SoftSynthesizer/GetLoadedInstruments.java test/javax/sound/midi/Gervill/SoftSynthesizer/GetMaxPolyphony.java test/javax/sound/midi/Gervill/SoftSynthesizer/GetMaxReceivers.java test/javax/sound/midi/Gervill/SoftSynthesizer/GetMaxTransmitters.java test/javax/sound/midi/Gervill/SoftSynthesizer/GetMicrosecondPosition.java test/javax/sound/midi/Gervill/SoftSynthesizer/GetReceiver.java test/javax/sound/midi/Gervill/SoftSynthesizer/GetReceiver2.java test/javax/sound/midi/Gervill/SoftSynthesizer/GetReceivers.java test/javax/sound/midi/Gervill/SoftSynthesizer/GetTransmitter.java test/javax/sound/midi/Gervill/SoftSynthesizer/GetTransmitters.java test/javax/sound/midi/Gervill/SoftSynthesizer/GetVoiceStatus.java test/javax/sound/midi/Gervill/SoftSynthesizer/ImplicitOpenClose.java test/javax/sound/midi/Gervill/SoftSynthesizer/IsOpen.java test/javax/sound/midi/Gervill/SoftSynthesizer/IsSoundbankSupported.java test/javax/sound/midi/Gervill/SoftSynthesizer/LoadAllInstruments.java test/javax/sound/midi/Gervill/SoftSynthesizer/LoadInstrument.java test/javax/sound/midi/Gervill/SoftSynthesizer/LoadInstruments.java test/javax/sound/midi/Gervill/SoftSynthesizer/Open.java test/javax/sound/midi/Gervill/SoftSynthesizer/OpenStream.java test/javax/sound/midi/Gervill/SoftSynthesizer/RemapInstrument.java test/javax/sound/midi/Gervill/SoftSynthesizer/TestRender1.java test/javax/sound/midi/Gervill/SoftSynthesizer/UnloadAllInstruments.java test/javax/sound/midi/Gervill/SoftSynthesizer/UnloadInstrument.java test/javax/sound/midi/Gervill/SoftSynthesizer/UnloadInstruments.java test/javax/sound/midi/Gervill/SoftSynthesizer/ding.sf2 test/javax/sound/midi/Gervill/SoftSynthesizer/expresso.mid test/javax/sound/midi/Gervill/SoftTuning/GetName.java test/javax/sound/midi/Gervill/SoftTuning/GetTuning.java test/javax/sound/midi/Gervill/SoftTuning/GetTuningInt.java test/javax/sound/midi/Gervill/SoftTuning/Load1.java test/javax/sound/midi/Gervill/SoftTuning/Load2.java test/javax/sound/midi/Gervill/SoftTuning/Load4.java test/javax/sound/midi/Gervill/SoftTuning/Load5.java test/javax/sound/midi/Gervill/SoftTuning/Load6.java test/javax/sound/midi/Gervill/SoftTuning/Load7.java test/javax/sound/midi/Gervill/SoftTuning/Load8.java test/javax/sound/midi/Gervill/SoftTuning/Load9.java test/javax/sound/midi/Gervill/SoftTuning/NewSoftTuning.java test/javax/sound/midi/Gervill/SoftTuning/NewSoftTuningByteArray.java test/javax/sound/midi/Gervill/SoftTuning/NewSoftTuningPatch.java test/javax/sound/midi/Gervill/SoftTuning/NewSoftTuningPatchByteArray.java
diffstat 362 files changed, 46203 insertions(+), 865 deletions(-) [+]
line wrap: on
line diff
--- a/make/common/Release.gmk	Thu Dec 25 20:43:44 2008 +0300
+++ b/make/common/Release.gmk	Mon Jan 19 20:11:58 2009 +0300
@@ -912,14 +912,6 @@
 	done
   ifeq ($(PLATFORM), windows)
 	@#
-	@# Audio soundbank - Bug# 4236400
-	@# Windows only: adding audio files to JDK's jre/lib directory.
-	@#
-	($(CD) $(LIBDIR) && $(TAR) cf - \
-	    `$(FIND) audio -depth -print`) | \
-	    ($(CD) $(JDK_IMAGE_DIR)/jre/lib && $(TAR) xf -)
-	@#
-	@#
 	@# lib/
 	@#
 	$(CP) $(LIBDIR)/$(LIB_PREFIX)jvm.$(LIB_SUFFIX) $(JDK_IMAGE_DIR)/lib
--- a/make/common/internal/BinaryPlugs.gmk	Thu Dec 25 20:43:44 2008 +0300
+++ b/make/common/internal/BinaryPlugs.gmk	Mon Jan 19 20:11:58 2009 +0300
@@ -29,9 +29,7 @@
 
 # Names of native shared libraries
 
-PLUG_JSOUND_LIBRARY=$(LIB_PREFIX)jsoundhs.$(LIBRARY_SUFFIX)
-PLUG_LIBRARY_NAMES = \
-    $(PLUG_JSOUND_LIBRARY)
+PLUG_LIBRARY_NAMES=
 
 # Sub-directory where native shared libraries are located (e.g. jre/bin or...)
 
@@ -74,62 +72,10 @@
 com/sun/jmx/snmp/daemon/SnmpTimerServer.class \
 com/sun/jmx/snmp/daemon/WaitQ.class
 
-PLUG_SOUND_CLASS_NAMES = \
-com/sun/media/sound/AbstractPlayer.class \
-com/sun/media/sound/CircularBuffer.class \
-com/sun/media/sound/HeadspaceInstrument.class \
-com/sun/media/sound/HeadspaceMixer\$$1.class \
-com/sun/media/sound/HeadspaceMixer\$$MidiLine.class \
-com/sun/media/sound/HeadspaceMixer\$$MidiLineInfo.class \
-com/sun/media/sound/HeadspaceMixer\$$MixerInfo.class \
-com/sun/media/sound/HeadspaceMixer\$$MixerReverbControl\$$MixerReverbType.class \
-com/sun/media/sound/HeadspaceMixer\$$MixerReverbControl.class \
-com/sun/media/sound/HeadspaceMixer.class \
-com/sun/media/sound/HeadspaceMixerProvider.class \
-com/sun/media/sound/HeadspaceSample.class \
-com/sun/media/sound/HeadspaceSoundbank.class \
-com/sun/media/sound/HsbParser.class \
-com/sun/media/sound/MixerClip\$$1.class \
-com/sun/media/sound/MixerClip\$$MixerClipApplyReverbControl.class \
-com/sun/media/sound/MixerClip\$$MixerClipGainControl.class \
-com/sun/media/sound/MixerClip\$$MixerClipMuteControl.class \
-com/sun/media/sound/MixerClip\$$MixerClipPanControl.class \
-com/sun/media/sound/MixerClip\$$MixerClipSampleRateControl.class \
-com/sun/media/sound/MixerClip.class \
-com/sun/media/sound/MixerMidiChannel.class \
-com/sun/media/sound/MixerSequencer\$$1.class \
-com/sun/media/sound/MixerSequencer\$$ControllerVectorElement.class \
-com/sun/media/sound/MixerSequencer\$$MixerSequencerInfo.class \
-com/sun/media/sound/MixerSequencer\$$RecordingTrack.class \
-com/sun/media/sound/MixerSequencer.class \
-com/sun/media/sound/MixerSequencerProvider.class \
-com/sun/media/sound/MixerSourceLine\$$1.class \
-com/sun/media/sound/MixerSourceLine\$$MixerSourceLineApplyReverbControl.class \
-com/sun/media/sound/MixerSourceLine\$$MixerSourceLineGainControl.class \
-com/sun/media/sound/MixerSourceLine\$$MixerSourceLineMuteControl.class \
-com/sun/media/sound/MixerSourceLine\$$MixerSourceLinePanControl.class \
-com/sun/media/sound/MixerSourceLine\$$MixerSourceLineSampleRateControl.class \
-com/sun/media/sound/MixerSourceLine.class \
-com/sun/media/sound/MixerSynth\$$1.class \
-com/sun/media/sound/MixerSynth\$$MixerSynthInfo.class \
-com/sun/media/sound/MixerSynth\$$SynthReceiver.class \
-com/sun/media/sound/MixerSynth.class \
-com/sun/media/sound/MixerSynthProvider.class \
-com/sun/media/sound/MixerThread.class \
-com/sun/media/sound/RmfFileReader.class \
-com/sun/media/sound/SimpleInputDevice\$$1.class \
-com/sun/media/sound/SimpleInputDevice\$$InputDeviceDataLine.class \
-com/sun/media/sound/SimpleInputDevice\$$InputDevicePort.class \
-com/sun/media/sound/SimpleInputDevice\$$InputDevicePortInfo.class \
-com/sun/media/sound/SimpleInputDevice.class \
-com/sun/media/sound/SimpleInputDeviceProvider\$$1.class \
-com/sun/media/sound/SimpleInputDeviceProvider\$$InputDeviceInfo.class \
-com/sun/media/sound/SimpleInputDeviceProvider.class
-
 # Class list temp files (used by both import and export of plugs)
 
 PLUG_TEMPDIR=$(ABS_TEMPDIR)/plugs
-PLUG_CLASS_AREAS = jmf sound
+PLUG_CLASS_AREAS = jmf
 PLUG_CLISTS = $(PLUG_CLASS_AREAS:%=$(PLUG_TEMPDIR)/%.clist)
 
 # Create jargs file command
@@ -147,18 +93,11 @@
 	@for i in $(PLUG_JMF_CLASS_NAMES) ; do \
 	  $(ECHO) "$$i" >> $@; \
 	done
-$(PLUG_TEMPDIR)/sound.clist:
-	@$(prep-target)
-	@for i in $(PLUG_SOUND_CLASS_NAMES) ; do \
-	  $(ECHO) "$$i" >> $@ ; \
-	done
 $(PLUG_TEMPDIR)/all.clist: $(PLUG_CLISTS)
 	@$(prep-target)
 	$(CAT) $(PLUG_CLISTS) > $@
 $(PLUG_TEMPDIR)/jmf.jargs: $(PLUG_TEMPDIR)/jmf.clist
 	$(plug-create-jargs)
-$(PLUG_TEMPDIR)/sound.jargs: $(PLUG_TEMPDIR)/sound.clist
-	$(plug-create-jargs)
 $(PLUG_TEMPDIR)/all.jargs: $(PLUG_TEMPDIR)/all.clist
 	$(plug-create-jargs)
 
@@ -193,25 +132,11 @@
 
 import-binary-plug-jmf-classes: $(PLUG_IMPORT_JARFILE) $(PLUG_TEMPDIR)/jmf.clist
 	$(call import-binary-plug-classes,$(PLUG_TEMPDIR)/jmf.clist)
-import-binary-plug-sound-classes: $(PLUG_IMPORT_JARFILE) $(PLUG_TEMPDIR)/sound.clist
-	$(call import-binary-plug-classes,$(PLUG_TEMPDIR)/sound.clist)
 
 # Import all classes from the jar file
 
 import-binary-plug-jar: \
-	     import-binary-plug-jmf-classes \
-	     import-binary-plug-sound-classes
-
-# Import native libraries
-
-$(LIB_LOCATION)/$(PLUG_JSOUND_LIBRARY): \
-    $(PLUG_IMPORT_DIR)/$(PLUG_LOCATION_SUBDIR)/$(PLUG_JSOUND_LIBRARY)
-	$(import-binary-plug-file)
-
-# Rules only used by lower level makefiles
-
-import-binary-plug-jsound-library: \
-    $(LIB_LOCATION)/$(PLUG_JSOUND_LIBRARY)
+	     import-binary-plug-jmf-classes
 
 # Binary plug start/complete messages
 
@@ -241,9 +166,7 @@
 	import-binary-plugs-libs \
 	import-binary-plugs \
 	import-binary-plug-jar \
-        import-binary-plug-jmf-classes \
-        import-binary-plug-sound-classes \
-        import-binary-plug-jsound-library
+	import-binary-plug-jmf-classes
 
 else # !OPENJDK
 
@@ -280,12 +203,6 @@
 	@$(java-vm-cleanup)
 export-binary-plugs-jar: $(PLUG_EXPORT_JARFILE)
 
-# Export native libraries
-
-$(PLUG_EXPORT_DIR)/$(PLUG_LOCATION_SUBDIR)/$(PLUG_JSOUND_LIBRARY): \
-    $(LIB_LOCATION)/$(PLUG_JSOUND_LIBRARY)
-	$(export-binary-plug-file)
-
 # Export binary plug start/complete messages
 
 export-binary-plugs-started:
--- a/make/javax/sound/Makefile	Thu Dec 25 20:43:44 2008 +0300
+++ b/make/javax/sound/Makefile	Mon Jan 19 20:11:58 2009 +0300
@@ -54,18 +54,6 @@
 AUTO_FILES_JAVA_DIRS = javax/sound com/sun/media/sound
 
 #
-# Specific to OpenJDK building
-#
-ifdef OPENJDK
-
-# copy closed .class files
-build: import-binary-plug-sound-classes 
-
-include $(BUILDDIR)/common/internal/BinaryPlugs.gmk
-
-endif # OPENJDK
-
-#
 # Files that just need cp.
 #
 SERVICEDIR = $(CLASSBINDIR)/META-INF/services
@@ -79,13 +67,11 @@
 	$(SERVICEDIR)/javax.sound.sampled.spi.AudioFileReader \
 	$(SERVICEDIR)/javax.sound.sampled.spi.FormatConversionProvider \
 	$(SERVICEDIR)/javax.sound.sampled.spi.MixerProvider \
-	$(LIBDIR)/audio/soundbank.gm \
 	$(LIBDIR)/sound.properties
 
 FILES_mkdirs = \
 	$(CLASSBINDIR)/META-INF \
-	$(CLASSBINDIR)/META-INF/services \
-	$(LIBDIR)/audio
+	$(CLASSBINDIR)/META-INF/services
 
 FILES_copydirs = \
 	$(CLASSBINDIR) \
@@ -96,11 +82,6 @@
 
 
 #
-# add "closed" library
-#
-SUBDIRS += jsoundhs
-
-#
 # system dependent flags
 #
 ifeq ($(PLATFORM), windows)
--- a/make/javax/sound/jsoundhs/FILES.gmk	Thu Dec 25 20:43:44 2008 +0300
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,91 +0,0 @@
-#
-# Copyright 2007 Sun Microsystems, Inc.  All Rights Reserved.
-# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
-#
-# This code is free software; you can redistribute it and/or modify it
-# under the terms of the GNU General Public License version 2 only, as
-# published by the Free Software Foundation.  Sun designates this
-# particular file as subject to the "Classpath" exception as provided
-# by Sun in the LICENSE file that accompanied this code.
-#
-# This code is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
-# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
-# version 2 for more details (a copy is included in the LICENSE file that
-# accompanied this code).
-#
-# You should have received a copy of the GNU General Public License version
-# 2 along with this work; if not, write to the Free Software Foundation,
-# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
-# CA 95054 USA or visit www.sun.com if you need additional information or
-# have any questions.
-#
-
-FILES_c = \
-	Utilities.c \
-	MixerThread.c \
-	HeadspaceMixer.c \
-	MixerClip.c \
-	MixerSourceLine.c \
-	SimpleInputDevice.c \
-	SimpleInputDeviceProvider.c \
-	HeadspaceSoundbank.c \
-	MixerMidiChannel.c \
-	AbstractPlayer.c \
-	MixerSequencer.c \
-	MixerSynth.c
-
-FILES_engine = \
-	DriverTools.c \
-	GenAudioCaptureStreams.c \
-	GenAudioStreams.c \
-	GenOutput.c \
-	GenPatch.c \
-	GenReverb.c \
-	GenSample.c \
-	GenSeq.c \
-	GenSetup.c \
-	GenSong.c \
-	GenSynth.c \
-	GenSynthFilters.c \
-	GenSynthInterp2.c \
-	GenSynthResample.c \
-	NewNewLZSS.c \
-	SampleTools.c \
-	SMOD_Volume_Scaler.c \
-	X_API.c \
-	X_Decompress.c \
-	X_IMA.c \
-	GenFiltersReverb.c \
-	GenInterp2Reverb.c \
-	GenSoundFiles.c \
-	SincResample.c
-
-FILES_solaris = \
-	HAE_API_SolarisOS.c \
-	HAE_API_SolarisOS_Capture.c
-
-FILES_linux = \
-	HAE_API_LinuxOS.c \
-	HAE_API_LinuxOS_Capture.c
-
-FILES_windows = \
-	HAE_API_WinOS.c \
-	HAE_API_WinOS_Capture.c \
-	HAE_API_WinOS_Synth.c
-
-FILES_export = \
-	com/sun/media/sound/AbstractPlayer.java \
-	com/sun/media/sound/HeadspaceMixer.java \
-	com/sun/media/sound/HeadspaceSoundbank.java \
-	com/sun/media/sound/MixerClip.java \
-	com/sun/media/sound/MixerMidiChannel.java \
-	com/sun/media/sound/MixerSequencer.java \
-	com/sun/media/sound/MixerSourceLine.java \
-	com/sun/media/sound/MixerSynth.java \
-	com/sun/media/sound/MixerThread.java \
-	com/sun/media/sound/SimpleInputDevice.java \
-	com/sun/media/sound/SimpleInputDeviceProvider.java
-
--- a/make/javax/sound/jsoundhs/Makefile	Thu Dec 25 20:43:44 2008 +0300
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,100 +0,0 @@
-#
-# Copyright 2007 Sun Microsystems, Inc.  All Rights Reserved.
-# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
-#
-# This code is free software; you can redistribute it and/or modify it
-# under the terms of the GNU General Public License version 2 only, as
-# published by the Free Software Foundation.  Sun designates this
-# particular file as subject to the "Classpath" exception as provided
-# by Sun in the LICENSE file that accompanied this code.
-#
-# This code is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
-# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
-# version 2 for more details (a copy is included in the LICENSE file that
-# accompanied this code).
-#
-# You should have received a copy of the GNU General Public License version
-# 2 along with this work; if not, write to the Free Software Foundation,
-# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
-# CA 95054 USA or visit www.sun.com if you need additional information or
-# have any questions.
-#
-
-BUILDDIR = ../../..
-PACKAGE = javax.sound
-LIBRARY = jsoundhs
-PRODUCT = sun
-CPLUSPLUSLIBRARY = true
-include $(BUILDDIR)/common/Defs.gmk
-
-# this Makefile compiles "closed" JavaSound library
-
-ifdef OPENJDK
-
-# precompiled lib will be copied by the rules in Library.gmk instead of compiling.
-USE_BINARY_PLUG_LIBRARY=true
-
-build: import-binary-plug-jsound-library
-
-include $(BUILDDIR)/common/internal/BinaryPlugs.gmk
-
-else # OPENJDK
-
-# include defines for sound
-include ../SoundDefs.gmk
-
-#
-# Add use of mapfile
-#
-FILES_m = mapfile-vers
-include $(BUILDDIR)/common/Mapfile-vers.gmk
-
-#
-# Files
-#
-include FILES.gmk
-
-FILES_c += $(FILES_engine) $(FILES_$(PLATFORM))
-
-#
-# Extra cc/linker flags.
-#
-# flags needed for all platforms
-CPPFLAGS += \
-	-DJAVA_SOUND -DJAVA_THREAD \
-	-I$(CLOSED_SHARE_SRC)/native/com/sun/media/sound \
-	-I$(CLOSED_SHARE_SRC)/native/com/sun/media/sound/engine
-
-# system dependent flags
-ifeq ($(PLATFORM), windows)
-  CPPFLAGS += 	-DUSE_DIRECTSOUND=0 \
-		-DUSE_EXTERNAL_SYNTH=TRUE
-  LDLIBS += winmm.lib
-endif # PLATFORM windows
-
-ifeq ($(PLATFORM), linux)
-endif # PLATFORM linux
-
-ifeq ($(PLATFORM), solaris)
-endif # PLATFORM solaris
-
-
-#
-# Add to the ambient VPATH.
-#
-vpath %.c $(CLOSED_SHARE_SRC)/native/com/sun/media/sound
-vpath %.c $(CLOSED_SHARE_SRC)/native/com/sun/media/sound/engine
-vpath %.c $(CLOSED_PLATFORM_SRC)/native/com/sun/media/sound/engine
-
-
-endif # OPENJDK
-
-
-#
-# Include rules
-#
-include $(BUILDDIR)/common/Library.gmk
-
--- a/make/javax/sound/jsoundhs/mapfile-vers	Thu Dec 25 20:43:44 2008 +0300
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,153 +0,0 @@
-#
-# Copyright 2007 Sun Microsystems, Inc.  All Rights Reserved.
-# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
-#
-# This code is free software; you can redistribute it and/or modify it
-# under the terms of the GNU General Public License version 2 only, as
-# published by the Free Software Foundation.  Sun designates this
-# particular file as subject to the "Classpath" exception as provided
-# by Sun in the LICENSE file that accompanied this code.
-#
-# This code is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
-# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
-# version 2 for more details (a copy is included in the LICENSE file that
-# accompanied this code).
-#
-# You should have received a copy of the GNU General Public License version
-# 2 along with this work; if not, write to the Free Software Foundation,
-# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
-# CA 95054 USA or visit www.sun.com if you need additional information or
-# have any questions.
-#
-
-# Define library interface.
-
-SUNWprivate_1.1 {
-	global:
-            Java_com_sun_media_sound_AbstractPlayer_nAddReceiver;
-            Java_com_sun_media_sound_AbstractPlayer_nClose;
-            Java_com_sun_media_sound_AbstractPlayer_nLoadInstrument;
-            Java_com_sun_media_sound_AbstractPlayer_nRemapInstrument;
-            Java_com_sun_media_sound_AbstractPlayer_nRemoveReceiver;
-            Java_com_sun_media_sound_AbstractPlayer_nUnloadInstrument;
-            Java_com_sun_media_sound_HeadspaceMixer_nAllocateVoices;
-            Java_com_sun_media_sound_HeadspaceMixer_nCloseMixer;
-            Java_com_sun_media_sound_HeadspaceMixer_nCreateLinkedStreams;
-            Java_com_sun_media_sound_HeadspaceMixer_nDrain;
-            Java_com_sun_media_sound_HeadspaceMixer_nFlush;
-            Java_com_sun_media_sound_HeadspaceMixer_nGetCpuLoad;
-            Java_com_sun_media_sound_HeadspaceMixer_nGetDefaultBufferSize;
-            Java_com_sun_media_sound_HeadspaceMixer_nGetLevel;
-            Java_com_sun_media_sound_HeadspaceMixer_nGetPosition;
-            Java_com_sun_media_sound_HeadspaceMixer_nGetTotalVoices;
-            Java_com_sun_media_sound_HeadspaceMixer_nOpenMixer;
-            Java_com_sun_media_sound_HeadspaceMixer_nPause;
-            Java_com_sun_media_sound_HeadspaceMixer_nResume;
-            Java_com_sun_media_sound_HeadspaceMixer_nSetInterpolation;
-            Java_com_sun_media_sound_HeadspaceMixer_nSetMixerFormat;
-            Java_com_sun_media_sound_HeadspaceMixer_nSetMixLevel;
-            Java_com_sun_media_sound_HeadspaceMixer_nSetReverb;
-            Java_com_sun_media_sound_HeadspaceMixer_nStartLinkedStreams;
-            Java_com_sun_media_sound_HeadspaceMixer_nStopLinkedStreams;
-            Java_com_sun_media_sound_HeadspaceSoundbank_nCloseResource;
-            Java_com_sun_media_sound_HeadspaceSoundbank_nGetInstruments;
-            Java_com_sun_media_sound_HeadspaceSoundbank_nGetName;
-            Java_com_sun_media_sound_HeadspaceSoundbank_nGetSamples;
-            Java_com_sun_media_sound_HeadspaceSoundbank_nGetVersionMajor;
-            Java_com_sun_media_sound_HeadspaceSoundbank_nGetVersionMinor;
-            Java_com_sun_media_sound_HeadspaceSoundbank_nGetVersionSubMinor;
-            Java_com_sun_media_sound_HeadspaceSoundbank_nOpenResource;
-            Java_com_sun_media_sound_HeadspaceSoundbank_nOpenResourceFromByteArray;
-            Java_com_sun_media_sound_MixerClip_nClose;
-            Java_com_sun_media_sound_MixerClip_nDrain;
-            Java_com_sun_media_sound_MixerClip_nFlush;
-            Java_com_sun_media_sound_MixerClip_nGetPosition;
-            Java_com_sun_media_sound_MixerClip_nOpen;
-            Java_com_sun_media_sound_MixerClip_nSetLinearGain;
-            Java_com_sun_media_sound_MixerClip_nSetPan;
-            Java_com_sun_media_sound_MixerClip_nSetSampleRate;
-            Java_com_sun_media_sound_MixerClip_nSetup;
-            Java_com_sun_media_sound_MixerClip_nStart;
-            Java_com_sun_media_sound_MixerClip_nStop;
-            Java_com_sun_media_sound_MixerMidiChannel_nAllNotesOff;
-            Java_com_sun_media_sound_MixerMidiChannel_nControlChange;
-            Java_com_sun_media_sound_MixerMidiChannel_nGetController;
-            Java_com_sun_media_sound_MixerMidiChannel_nGetPitchBend;
-            Java_com_sun_media_sound_MixerMidiChannel_nGetSolo;
-            Java_com_sun_media_sound_MixerMidiChannel_nNoteOff;
-            Java_com_sun_media_sound_MixerMidiChannel_nNoteOn;
-            Java_com_sun_media_sound_MixerMidiChannel_nProgramChange__JIIIJ;
-            Java_com_sun_media_sound_MixerMidiChannel_nProgramChange__JIIJ;
-            Java_com_sun_media_sound_MixerMidiChannel_nResetAllControllers;
-            Java_com_sun_media_sound_MixerMidiChannel_nSetMute;
-            Java_com_sun_media_sound_MixerMidiChannel_nSetPitchBend;
-            Java_com_sun_media_sound_MixerMidiChannel_nSetSolo;
-            Java_com_sun_media_sound_MixerSequencer_nAddControllerEventCallback;
-            Java_com_sun_media_sound_MixerSequencer_nGetMasterTempo;
-            Java_com_sun_media_sound_MixerSequencer_nGetSequenceMicrosecondLength;
-            Java_com_sun_media_sound_MixerSequencer_nGetSequencerMicrosecondPosition;
-            Java_com_sun_media_sound_MixerSequencer_nGetSequencerTickPosition;
-            Java_com_sun_media_sound_MixerSequencer_nGetSequenceTickLength;
-            Java_com_sun_media_sound_MixerSequencer_nGetTempoInBPM;
-            Java_com_sun_media_sound_MixerSequencer_nGetTempoInMPQ;
-            Java_com_sun_media_sound_MixerSequencer_nGetTrackMute;
-            Java_com_sun_media_sound_MixerSequencer_nGetTrackSolo;
-            Java_com_sun_media_sound_MixerSequencer_nOpenMidiSequencer;
-            Java_com_sun_media_sound_MixerSequencer_nOpenRmfSequencer;
-            Java_com_sun_media_sound_MixerSequencer_nPauseSequencer;
-            Java_com_sun_media_sound_MixerSequencer_nResumeSequencer;
-            Java_com_sun_media_sound_MixerSequencer_nSetMasterTempo;
-            Java_com_sun_media_sound_MixerSequencer_nSetSequencerMicrosecondPosition;
-            Java_com_sun_media_sound_MixerSequencer_nSetSequencerTickPosition;
-            Java_com_sun_media_sound_MixerSequencer_nSetTempoInBPM;
-            Java_com_sun_media_sound_MixerSequencer_nSetTempoInMPQ;
-            Java_com_sun_media_sound_MixerSequencer_nSetTrackMute;
-            Java_com_sun_media_sound_MixerSequencer_nSetTrackSolo;
-            Java_com_sun_media_sound_MixerSequencer_nStartSequencer;
-            Java_com_sun_media_sound_MixerSourceLine_nClose;
-            Java_com_sun_media_sound_MixerSourceLine_nDrain;
-            Java_com_sun_media_sound_MixerSourceLine_nFlush;
-            Java_com_sun_media_sound_MixerSourceLine_nGetLevel;
-            Java_com_sun_media_sound_MixerSourceLine_nGetPosition;
-            Java_com_sun_media_sound_MixerSourceLine_nOpen;
-            Java_com_sun_media_sound_MixerSourceLine_nPause;
-            Java_com_sun_media_sound_MixerSourceLine_nResume;
-            Java_com_sun_media_sound_MixerSourceLine_nSetLinearGain;
-            Java_com_sun_media_sound_MixerSourceLine_nSetPan;
-            Java_com_sun_media_sound_MixerSourceLine_nSetSampleRate;
-            Java_com_sun_media_sound_MixerSourceLine_nStart;
-            Java_com_sun_media_sound_MixerSynth_nCreateSynthesizer;
-            Java_com_sun_media_sound_MixerSynth_nDestroySynthesizer;
-            Java_com_sun_media_sound_MixerSynth_nGetLatency;
-            Java_com_sun_media_sound_MixerSynth_nLoadInstrument;
-            Java_com_sun_media_sound_MixerSynth_nRemapInstrument;
-            Java_com_sun_media_sound_MixerSynth_nStartSynthesizer;
-            Java_com_sun_media_sound_MixerSynth_nUnloadInstrument;
-            Java_com_sun_media_sound_MixerThread_runNative;
-            Java_com_sun_media_sound_SimpleInputDevice_nClose;
-            Java_com_sun_media_sound_SimpleInputDevice_nDrain;
-            Java_com_sun_media_sound_SimpleInputDevice_nFlush;
-            Java_com_sun_media_sound_SimpleInputDevice_nGetBufferSizeInFrames;
-            Java_com_sun_media_sound_SimpleInputDevice_nGetFormats;
-            Java_com_sun_media_sound_SimpleInputDevice_nGetNumPorts;
-            Java_com_sun_media_sound_SimpleInputDevice_nGetPortName;
-            Java_com_sun_media_sound_SimpleInputDevice_nGetPosition;
-            Java_com_sun_media_sound_SimpleInputDevice_nOpen;
-            Java_com_sun_media_sound_SimpleInputDevice_nPause;
-            Java_com_sun_media_sound_SimpleInputDevice_nResume;
-            Java_com_sun_media_sound_SimpleInputDevice_nStart;
-            Java_com_sun_media_sound_SimpleInputDevice_nStop;
-            Java_com_sun_media_sound_SimpleInputDevice_nSupportsChannels;
-            Java_com_sun_media_sound_SimpleInputDevice_nSupportsSampleRate;
-            Java_com_sun_media_sound_SimpleInputDevice_nSupportsSampleSizeInBits;
-            Java_com_sun_media_sound_SimpleInputDeviceProvider_nGetDescription;
-            Java_com_sun_media_sound_SimpleInputDeviceProvider_nGetName;
-            Java_com_sun_media_sound_SimpleInputDeviceProvider_nGetNumDevices;
-            Java_com_sun_media_sound_SimpleInputDeviceProvider_nGetVendor;
-            Java_com_sun_media_sound_SimpleInputDeviceProvider_nGetVersion;
-	local:
-	    *;
-};
--- a/src/share/classes/com/sun/media/sound/AbstractMidiDevice.java	Thu Dec 25 20:43:44 2008 +0300
+++ b/src/share/classes/com/sun/media/sound/AbstractMidiDevice.java	Mon Jan 19 20:11:58 2009 +0300
@@ -75,13 +75,6 @@
     /**
      * This is the device handle returned from native code
      */
-    /*
-     * $$rratta Solaris 64 bit holds pointer must be long
-     *
-     * $$mp 2003-08-07:
-     * 'id' is a really bad name. The variable should
-     * be called nativePointer or something similar.
-     */
     protected long id                   = 0;
 
 
@@ -586,7 +579,6 @@
 
         private ArrayList<Transmitter> transmitters = new ArrayList<Transmitter>();
         private MidiOutDevice.MidiOutReceiver midiOutReceiver;
-        private MixerSynth.SynthReceiver mixerSynthReceiver;
 
         // how many transmitters must be present for optimized
         // handling
@@ -621,22 +613,14 @@
                 if (midiOutReceiver == oldR) {
                     midiOutReceiver = null;
                 }
-                if (mixerSynthReceiver == oldR) {
-                    mixerSynthReceiver = null;
-                }
                 if (newR != null) {
                     if ((newR instanceof MidiOutDevice.MidiOutReceiver)
                         && (midiOutReceiver == null)) {
                         midiOutReceiver = ((MidiOutDevice.MidiOutReceiver) newR);
                     }
-                    if ((newR instanceof MixerSynth.SynthReceiver)
-                        && (mixerSynthReceiver == null)) {
-                        mixerSynthReceiver = ((MixerSynth.SynthReceiver) newR);
-                    }
                 }
                 optimizedReceiverCount =
-                      ((midiOutReceiver!=null)?1:0)
-                    + ((mixerSynthReceiver!=null)?1:0);
+                      ((midiOutReceiver!=null)?1:0);
             }
             // more potential for optimization here
         }
@@ -670,10 +654,6 @@
                             if (TRACE_TRANSMITTER) Printer.println("Sending packed message to MidiOutReceiver");
                             midiOutReceiver.sendPackedMidiMessage(packedMessage, timeStamp);
                         }
-                        if (mixerSynthReceiver != null) {
-                            if (TRACE_TRANSMITTER) Printer.println("Sending packed message to MixerSynthReceiver");
-                            mixerSynthReceiver.sendPackedMidiMessage(packedMessage, timeStamp);
-                        }
                     } else {
                         if (TRACE_TRANSMITTER) Printer.println("Sending packed message to "+size+" transmitter's receivers");
                         for (int i = 0; i < size; i++) {
@@ -682,9 +662,6 @@
                                 if (optimizedReceiverCount > 0) {
                                     if (receiver instanceof MidiOutDevice.MidiOutReceiver) {
                                         ((MidiOutDevice.MidiOutReceiver) receiver).sendPackedMidiMessage(packedMessage, timeStamp);
-                                    }
-                                    else if (receiver instanceof MixerSynth.SynthReceiver) {
-                                        ((MixerSynth.SynthReceiver) receiver).sendPackedMidiMessage(packedMessage, timeStamp);
                                     } else {
                                         receiver.send(new FastShortMessage(packedMessage), timeStamp);
                                     }
@@ -739,10 +716,6 @@
                         if (TRACE_TRANSMITTER) Printer.println("Sending MIDI message to MidiOutReceiver");
                         midiOutReceiver.send(message, timeStamp);
                     }
-                    if (mixerSynthReceiver != null) {
-                        if (TRACE_TRANSMITTER) Printer.println("Sending MIDI message to MixerSynthReceiver");
-                        mixerSynthReceiver.send(message, timeStamp);
-                    }
                 } else {
                     if (TRACE_TRANSMITTER) Printer.println("Sending MIDI message to "+size+" transmitter's receivers");
                     for (int i = 0; i < size; i++) {
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/classes/com/sun/media/sound/AudioFileSoundbankReader.java	Mon Jan 19 20:11:58 2009 +0300
@@ -0,0 +1,131 @@
+/*
+ * Copyright 2007 Sun Microsystems, Inc.  All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+package com.sun.media.sound;
+
+import java.io.ByteArrayOutputStream;
+import java.io.DataInputStream;
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.URL;
+
+import javax.sound.midi.InvalidMidiDataException;
+import javax.sound.midi.Soundbank;
+import javax.sound.midi.spi.SoundbankReader;
+import javax.sound.sampled.AudioInputStream;
+import javax.sound.sampled.AudioSystem;
+import javax.sound.sampled.UnsupportedAudioFileException;
+
+/**
+ * Soundbank reader that uses audio files as soundbanks.
+ *
+ * @author Karl Helgason
+ */
+public class AudioFileSoundbankReader extends SoundbankReader {
+
+    public Soundbank getSoundbank(URL url)
+            throws InvalidMidiDataException, IOException {
+        try {
+            AudioInputStream ais = AudioSystem.getAudioInputStream(url);
+            Soundbank sbk = getSoundbank(ais);
+            ais.close();
+            return sbk;
+        } catch (UnsupportedAudioFileException e) {
+            return null;
+        } catch (IOException e) {
+            return null;
+        }
+    }
+
+    public Soundbank getSoundbank(InputStream stream)
+            throws InvalidMidiDataException, IOException {
+        stream.mark(512);
+        try {
+            AudioInputStream ais = AudioSystem.getAudioInputStream(stream);
+            Soundbank sbk = getSoundbank(ais);
+            if (sbk != null)
+                return sbk;
+        } catch (UnsupportedAudioFileException e) {
+        } catch (IOException e) {
+        }
+        stream.reset();
+        return null;
+    }
+
+    public Soundbank getSoundbank(AudioInputStream ais)
+            throws InvalidMidiDataException, IOException {
+        try {
+            byte[] buffer;
+            if (ais.getFrameLength() == -1) {
+                ByteArrayOutputStream baos = new ByteArrayOutputStream();
+                byte[] buff = new byte[1024
+                        - (1024 % ais.getFormat().getFrameSize())];
+                int ret;
+                while ((ret = ais.read(buff)) != -1) {
+                    baos.write(buff, 0, ret);
+                }
+                ais.close();
+                buffer = baos.toByteArray();
+            } else {
+                buffer = new byte[(int) (ais.getFrameLength()
+                                    * ais.getFormat().getFrameSize())];
+                new DataInputStream(ais).readFully(buffer);
+            }
+            ModelByteBufferWavetable osc = new ModelByteBufferWavetable(
+                    new ModelByteBuffer(buffer), ais.getFormat(), -4800);
+            ModelPerformer performer = new ModelPerformer();
+            performer.getOscillators().add(osc);
+
+            SimpleSoundbank sbk = new SimpleSoundbank();
+            SimpleInstrument ins = new SimpleInstrument();
+            ins.add(performer);
+            sbk.addInstrument(ins);
+            return sbk;
+        } catch (Exception e) {
+            return null;
+        }
+    }
+
+    public Soundbank getSoundbank(File file)
+            throws InvalidMidiDataException, IOException {
+        try {
+            AudioInputStream ais = AudioSystem.getAudioInputStream(file);
+            ais.close();
+            ModelByteBufferWavetable osc = new ModelByteBufferWavetable(
+                    new ModelByteBuffer(file, 0, file.length()), -4800);
+            ModelPerformer performer = new ModelPerformer();
+            performer.getOscillators().add(osc);
+            SimpleSoundbank sbk = new SimpleSoundbank();
+            SimpleInstrument ins = new SimpleInstrument();
+            ins.add(performer);
+            sbk.addInstrument(ins);
+            return sbk;
+        } catch (UnsupportedAudioFileException e1) {
+            return null;
+        } catch (IOException e) {
+            return null;
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/classes/com/sun/media/sound/AudioFloatConverter.java	Mon Jan 19 20:11:58 2009 +0300
@@ -0,0 +1,1058 @@
+/*
+ * Copyright 2007 Sun Microsystems, Inc.  All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+package com.sun.media.sound;
+
+import java.nio.ByteBuffer;
+import java.nio.ByteOrder;
+import java.nio.DoubleBuffer;
+import java.nio.FloatBuffer;
+
+import javax.sound.sampled.AudioFormat;
+import javax.sound.sampled.AudioFormat.Encoding;
+
+/**
+ * This class is used to convert between 8,16,24,32,32+ bit signed/unsigned
+ * big/litle endian fixed/floating point byte buffers and float buffers.
+ *
+ * @author Karl Helgason
+ */
+public abstract class AudioFloatConverter {
+
+    public static final Encoding PCM_FLOAT = new Encoding("PCM_FLOAT");
+
+    /***************************************************************************
+     *
+     * LSB Filter, used filter least significant byte in samples arrays.
+     *
+     * Is used filter out data in lsb byte when SampleSizeInBits is not
+     * dividable by 8.
+     *
+     **************************************************************************/
+
+    private static class AudioFloatLSBFilter extends AudioFloatConverter {
+
+        private AudioFloatConverter converter;
+
+        final private int offset;
+
+        final private int stepsize;
+
+        final private byte mask;
+
+        private byte[] mask_buffer;
+
+        public AudioFloatLSBFilter(AudioFloatConverter converter,
+                AudioFormat format) {
+            int bits = format.getSampleSizeInBits();
+            boolean bigEndian = format.isBigEndian();
+            this.converter = converter;
+            stepsize = (bits + 7) / 8;
+            offset = bigEndian ? (stepsize - 1) : 0;
+            int lsb_bits = bits % 8;
+            if (lsb_bits == 0)
+                mask = (byte) 0x00;
+            else if (lsb_bits == 1)
+                mask = (byte) 0x80;
+            else if (lsb_bits == 2)
+                mask = (byte) 0xC0;
+            else if (lsb_bits == 3)
+                mask = (byte) 0xE0;
+            else if (lsb_bits == 4)
+                mask = (byte) 0xF0;
+            else if (lsb_bits == 5)
+                mask = (byte) 0xF8;
+            else if (lsb_bits == 6)
+                mask = (byte) 0xFC;
+            else if (lsb_bits == 7)
+                mask = (byte) 0xFE;
+            else
+                mask = (byte) 0xFF;
+        }
+
+        public byte[] toByteArray(float[] in_buff, int in_offset, int in_len,
+                byte[] out_buff, int out_offset) {
+            byte[] ret = converter.toByteArray(in_buff, in_offset, in_len,
+                    out_buff, out_offset);
+
+            int out_offset_end = in_len * stepsize;
+            for (int i = out_offset + offset; i < out_offset_end; i += stepsize) {
+                out_buff[i] = (byte) (out_buff[i] & mask);
+            }
+
+            return ret;
+        }
+
+        public float[] toFloatArray(byte[] in_buff, int in_offset,
+                float[] out_buff, int out_offset, int out_len) {
+            if (mask_buffer == null || mask_buffer.length < in_buff.length)
+                mask_buffer = new byte[in_buff.length];
+            System.arraycopy(in_buff, 0, mask_buffer, 0, in_buff.length);
+            int in_offset_end = out_len * stepsize;
+            for (int i = in_offset + offset; i < in_offset_end; i += stepsize) {
+                mask_buffer[i] = (byte) (mask_buffer[i] & mask);
+            }
+            float[] ret = converter.toFloatArray(mask_buffer, in_offset,
+                    out_buff, out_offset, out_len);
+            return ret;
+        }
+
+    }
+
+    /***************************************************************************
+     *
+     * 64 bit float, little/big-endian
+     *
+     **************************************************************************/
+
+    // PCM 64 bit float, little-endian
+    private static class AudioFloatConversion64L extends AudioFloatConverter {
+        ByteBuffer bytebuffer = null;
+
+        DoubleBuffer floatbuffer = null;
+
+        double[] double_buff = null;
+
+        public float[] toFloatArray(byte[] in_buff, int in_offset,
+                float[] out_buff, int out_offset, int out_len) {
+            int in_len = out_len * 8;
+            if (bytebuffer == null || bytebuffer.capacity() < in_len) {
+                bytebuffer = ByteBuffer.allocate(in_len).order(
+                        ByteOrder.LITTLE_ENDIAN);
+                floatbuffer = bytebuffer.asDoubleBuffer();
+            }
+            bytebuffer.position(0);
+            floatbuffer.position(0);
+            bytebuffer.put(in_buff, in_offset, in_len);
+            if (double_buff == null
+                    || double_buff.length < out_len + out_offset)
+                double_buff = new double[out_len + out_offset];
+            floatbuffer.get(double_buff, out_offset, out_len);
+            int out_offset_end = out_offset + out_len;
+            for (int i = out_offset; i < out_offset_end; i++) {
+                out_buff[i] = (float) double_buff[i];
+            }
+            return out_buff;
+        }
+
+        public byte[] toByteArray(float[] in_buff, int in_offset, int in_len,
+                byte[] out_buff, int out_offset) {
+            int out_len = in_len * 8;
+            if (bytebuffer == null || bytebuffer.capacity() < out_len) {
+                bytebuffer = ByteBuffer.allocate(out_len).order(
+                        ByteOrder.LITTLE_ENDIAN);
+                floatbuffer = bytebuffer.asDoubleBuffer();
+            }
+            floatbuffer.position(0);
+            bytebuffer.position(0);
+            if (double_buff == null || double_buff.length < in_offset + in_len)
+                double_buff = new double[in_offset + in_len];
+            int in_offset_end = in_offset + in_len;
+            for (int i = in_offset; i < in_offset_end; i++) {
+                double_buff[i] = in_buff[i];
+            }
+            floatbuffer.put(double_buff, in_offset, in_len);
+            bytebuffer.get(out_buff, out_offset, out_len);
+            return out_buff;
+        }
+    }
+
+    // PCM 64 bit float, big-endian
+    private static class AudioFloatConversion64B extends AudioFloatConverter {
+        ByteBuffer bytebuffer = null;
+
+        DoubleBuffer floatbuffer = null;
+
+        double[] double_buff = null;
+
+        public float[] toFloatArray(byte[] in_buff, int in_offset,
+                float[] out_buff, int out_offset, int out_len) {
+            int in_len = out_len * 8;
+            if (bytebuffer == null || bytebuffer.capacity() < in_len) {
+                bytebuffer = ByteBuffer.allocate(in_len).order(
+                        ByteOrder.BIG_ENDIAN);
+                floatbuffer = bytebuffer.asDoubleBuffer();
+            }
+            bytebuffer.position(0);
+            floatbuffer.position(0);
+            bytebuffer.put(in_buff, in_offset, in_len);
+            if (double_buff == null
+                    || double_buff.length < out_len + out_offset)
+                double_buff = new double[out_len + out_offset];
+            floatbuffer.get(double_buff, out_offset, out_len);
+            int out_offset_end = out_offset + out_len;
+            for (int i = out_offset; i < out_offset_end; i++) {
+                out_buff[i] = (float) double_buff[i];
+            }
+            return out_buff;
+        }
+
+        public byte[] toByteArray(float[] in_buff, int in_offset, int in_len,
+                byte[] out_buff, int out_offset) {
+            int out_len = in_len * 8;
+            if (bytebuffer == null || bytebuffer.capacity() < out_len) {
+                bytebuffer = ByteBuffer.allocate(out_len).order(
+                        ByteOrder.BIG_ENDIAN);
+                floatbuffer = bytebuffer.asDoubleBuffer();
+            }
+            floatbuffer.position(0);
+            bytebuffer.position(0);
+            if (double_buff == null || double_buff.length < in_offset + in_len)
+                double_buff = new double[in_offset + in_len];
+            int in_offset_end = in_offset + in_len;
+            for (int i = in_offset; i < in_offset_end; i++) {
+                double_buff[i] = in_buff[i];
+            }
+            floatbuffer.put(double_buff, in_offset, in_len);
+            bytebuffer.get(out_buff, out_offset, out_len);
+            return out_buff;
+        }
+    }
+
+    /***************************************************************************
+     *
+     * 32 bit float, little/big-endian
+     *
+     **************************************************************************/
+
+    // PCM 32 bit float, little-endian
+    private static class AudioFloatConversion32L extends AudioFloatConverter {
+        ByteBuffer bytebuffer = null;
+
+        FloatBuffer floatbuffer = null;
+
+        public float[] toFloatArray(byte[] in_buff, int in_offset,
+                float[] out_buff, int out_offset, int out_len) {
+            int in_len = out_len * 4;
+            if (bytebuffer == null || bytebuffer.capacity() < in_len) {
+                bytebuffer = ByteBuffer.allocate(in_len).order(
+                        ByteOrder.LITTLE_ENDIAN);
+                floatbuffer = bytebuffer.asFloatBuffer();
+            }
+            bytebuffer.position(0);
+            floatbuffer.position(0);
+            bytebuffer.put(in_buff, in_offset, in_len);
+            floatbuffer.get(out_buff, out_offset, out_len);
+            return out_buff;
+        }
+
+        public byte[] toByteArray(float[] in_buff, int in_offset, int in_len,
+                byte[] out_buff, int out_offset) {
+            int out_len = in_len * 4;
+            if (bytebuffer == null || bytebuffer.capacity() < out_len) {
+                bytebuffer = ByteBuffer.allocate(out_len).order(
+                        ByteOrder.LITTLE_ENDIAN);
+                floatbuffer = bytebuffer.asFloatBuffer();
+            }
+            floatbuffer.position(0);
+            bytebuffer.position(0);
+            floatbuffer.put(in_buff, in_offset, in_len);
+            bytebuffer.get(out_buff, out_offset, out_len);
+            return out_buff;
+        }
+    }
+
+    // PCM 32 bit float, big-endian
+    private static class AudioFloatConversion32B extends AudioFloatConverter {
+        ByteBuffer bytebuffer = null;
+
+        FloatBuffer floatbuffer = null;
+
+        public float[] toFloatArray(byte[] in_buff, int in_offset,
+                float[] out_buff, int out_offset, int out_len) {
+            int in_len = out_len * 4;
+            if (bytebuffer == null || bytebuffer.capacity() < in_len) {
+                bytebuffer = ByteBuffer.allocate(in_len).order(
+                        ByteOrder.BIG_ENDIAN);
+                floatbuffer = bytebuffer.asFloatBuffer();
+            }
+            bytebuffer.position(0);
+            floatbuffer.position(0);
+            bytebuffer.put(in_buff, in_offset, in_len);
+            floatbuffer.get(out_buff, out_offset, out_len);
+            return out_buff;
+        }
+
+        public byte[] toByteArray(float[] in_buff, int in_offset, int in_len,
+                byte[] out_buff, int out_offset) {
+            int out_len = in_len * 4;
+            if (bytebuffer == null || bytebuffer.capacity() < out_len) {
+                bytebuffer = ByteBuffer.allocate(out_len).order(
+                        ByteOrder.BIG_ENDIAN);
+                floatbuffer = bytebuffer.asFloatBuffer();
+            }
+            floatbuffer.position(0);
+            bytebuffer.position(0);
+            floatbuffer.put(in_buff, in_offset, in_len);
+            bytebuffer.get(out_buff, out_offset, out_len);
+            return out_buff;
+        }
+    }
+
+    /***************************************************************************
+     *
+     * 8 bit signed/unsigned
+     *
+     **************************************************************************/
+
+    // PCM 8 bit, signed
+    private static class AudioFloatConversion8S extends AudioFloatConverter {
+        public float[] toFloatArray(byte[] in_buff, int in_offset,
+                float[] out_buff, int out_offset, int out_len) {
+            int ix = in_offset;
+            int ox = out_offset;
+            for (int i = 0; i < out_len; i++)
+                out_buff[ox++] = in_buff[ix++] * (1.0f / 127.0f);
+            return out_buff;
+        }
+
+        public byte[] toByteArray(float[] in_buff, int in_offset, int in_len,
+                byte[] out_buff, int out_offset) {
+            int ix = in_offset;
+            int ox = out_offset;
+            for (int i = 0; i < in_len; i++)
+                out_buff[ox++] = (byte) (in_buff[ix++] * 127.0f);
+            return out_buff;
+        }
+    }
+
+    // PCM 8 bit, unsigned
+    private static class AudioFloatConversion8U extends AudioFloatConverter {
+        public float[] toFloatArray(byte[] in_buff, int in_offset,
+                float[] out_buff, int out_offset, int out_len) {
+            int ix = in_offset;
+            int ox = out_offset;
+            for (int i = 0; i < out_len; i++)
+                out_buff[ox++] = ((in_buff[ix++] & 0xFF) - 127)
+                        * (1.0f / 127.0f);
+            return out_buff;
+        }
+
+        public byte[] toByteArray(float[] in_buff, int in_offset, int in_len,
+                byte[] out_buff, int out_offset) {
+            int ix = in_offset;
+            int ox = out_offset;
+            for (int i = 0; i < in_len; i++)
+                out_buff[ox++] = (byte) (127 + in_buff[ix++] * 127.0f);
+            return out_buff;
+        }
+    }
+
+    /***************************************************************************
+     *
+     * 16 bit signed/unsigned, little/big-endian
+     *
+     **************************************************************************/
+
+    // PCM 16 bit, signed, little-endian
+    private static class AudioFloatConversion16SL extends AudioFloatConverter {
+        public float[] toFloatArray(byte[] in_buff, int in_offset,
+                float[] out_buff, int out_offset, int out_len) {
+            int ix = in_offset;
+            int len = out_offset + out_len;
+            for (int ox = out_offset; ox < len; ox++) {
+                out_buff[ox] = ((short) ((in_buff[ix++] & 0xFF) |
+                           (in_buff[ix++] << 8))) * (1.0f / 32767.0f);
+            }
+
+            return out_buff;
+        }
+
+        public byte[] toByteArray(float[] in_buff, int in_offset, int in_len,
+                byte[] out_buff, int out_offset) {
+            int ox = out_offset;
+            int len = in_offset + in_len;
+            for (int ix = in_offset; ix < len; ix++) {
+                int x = (int) (in_buff[ix] * 32767.0);
+                out_buff[ox++] = (byte) x;
+                out_buff[ox++] = (byte) (x >>> 8);
+            }
+            return out_buff;
+        }
+    }
+
+    // PCM 16 bit, signed, big-endian
+    private static class AudioFloatConversion16SB extends AudioFloatConverter {
+        public float[] toFloatArray(byte[] in_buff, int in_offset,
+                float[] out_buff, int out_offset, int out_len) {
+            int ix = in_offset;
+            int ox = out_offset;
+            for (int i = 0; i < out_len; i++) {
+                out_buff[ox++] = ((short) ((in_buff[ix++] << 8) |
+                        (in_buff[ix++] & 0xFF))) * (1.0f / 32767.0f);
+            }
+            return out_buff;
+        }
+
+        public byte[] toByteArray(float[] in_buff, int in_offset, int in_len,
+                byte[] out_buff, int out_offset) {
+            int ix = in_offset;
+            int ox = out_offset;
+            for (int i = 0; i < in_len; i++) {
+                int x = (int) (in_buff[ix++] * 32767.0);
+                out_buff[ox++] = (byte) (x >>> 8);
+                out_buff[ox++] = (byte) x;
+            }
+            return out_buff;
+        }
+    }
+
+    // PCM 16 bit, unsigned, little-endian
+    private static class AudioFloatConversion16UL extends AudioFloatConverter {
+        public float[] toFloatArray(byte[] in_buff, int in_offset,
+                float[] out_buff, int out_offset, int out_len) {
+            int ix = in_offset;
+            int ox = out_offset;
+            for (int i = 0; i < out_len; i++) {
+                int x = (in_buff[ix++] & 0xFF) | ((in_buff[ix++] & 0xFF) << 8);
+                out_buff[ox++] = (x - 32767) * (1.0f / 32767.0f);
+            }
+            return out_buff;
+        }
+
+        public byte[] toByteArray(float[] in_buff, int in_offset, int in_len,
+                byte[] out_buff, int out_offset) {
+            int ix = in_offset;
+            int ox = out_offset;
+            for (int i = 0; i < in_len; i++) {
+                int x = 32767 + (int) (in_buff[ix++] * 32767.0);
+                out_buff[ox++] = (byte) x;
+                out_buff[ox++] = (byte) (x >>> 8);
+            }
+            return out_buff;
+        }
+    }
+
+    // PCM 16 bit, unsigned, big-endian
+    private static class AudioFloatConversion16UB extends AudioFloatConverter {
+        public float[] toFloatArray(byte[] in_buff, int in_offset,
+                float[] out_buff, int out_offset, int out_len) {
+            int ix = in_offset;
+            int ox = out_offset;
+            for (int i = 0; i < out_len; i++) {
+                int x = ((in_buff[ix++] & 0xFF) << 8) | (in_buff[ix++] & 0xFF);
+                out_buff[ox++] = (x - 32767) * (1.0f / 32767.0f);
+            }
+            return out_buff;
+        }
+
+        public byte[] toByteArray(float[] in_buff, int in_offset, int in_len,
+                byte[] out_buff, int out_offset) {
+            int ix = in_offset;
+            int ox = out_offset;
+            for (int i = 0; i < in_len; i++) {
+                int x = 32767 + (int) (in_buff[ix++] * 32767.0);
+                out_buff[ox++] = (byte) (x >>> 8);
+                out_buff[ox++] = (byte) x;
+            }
+            return out_buff;
+        }
+    }
+
+    /***************************************************************************
+     *
+     * 24 bit signed/unsigned, little/big-endian
+     *
+     **************************************************************************/
+
+    // PCM 24 bit, signed, little-endian
+    private static class AudioFloatConversion24SL extends AudioFloatConverter {
+        public float[] toFloatArray(byte[] in_buff, int in_offset,
+                float[] out_buff, int out_offset, int out_len) {
+            int ix = in_offset;
+            int ox = out_offset;
+            for (int i = 0; i < out_len; i++) {
+                int x = (in_buff[ix++] & 0xFF) | ((in_buff[ix++] & 0xFF) << 8)
+                        | ((in_buff[ix++] & 0xFF) << 16);
+                if (x > 0x7FFFFF)
+                    x -= 0x1000000;
+                out_buff[ox++] = x * (1.0f / (float)0x7FFFFF);
+            }
+            return out_buff;
+        }
+
+        public byte[] toByteArray(float[] in_buff, int in_offset, int in_len,
+                byte[] out_buff, int out_offset) {
+            int ix = in_offset;
+            int ox = out_offset;
+            for (int i = 0; i < in_len; i++) {
+                int x = (int) (in_buff[ix++] * (float)0x7FFFFF);
+                if (x < 0)
+                    x += 0x1000000;
+                out_buff[ox++] = (byte) x;
+                out_buff[ox++] = (byte) (x >>> 8);
+                out_buff[ox++] = (byte) (x >>> 16);
+            }
+            return out_buff;
+        }
+    }
+
+    // PCM 24 bit, signed, big-endian
+    private static class AudioFloatConversion24SB extends AudioFloatConverter {
+        public float[] toFloatArray(byte[] in_buff, int in_offset,
+                float[] out_buff, int out_offset, int out_len) {
+            int ix = in_offset;
+            int ox = out_offset;
+            for (int i = 0; i < out_len; i++) {
+                int x = ((in_buff[ix++] & 0xFF) << 16)
+                        | ((in_buff[ix++] & 0xFF) << 8) | (in_buff[ix++] & 0xFF);
+                if (x > 0x7FFFFF)
+                    x -= 0x1000000;
+                out_buff[ox++] = x * (1.0f / (float)0x7FFFFF);
+            }
+            return out_buff;
+        }
+
+        public byte[] toByteArray(float[] in_buff, int in_offset, int in_len,
+                byte[] out_buff, int out_offset) {
+            int ix = in_offset;
+            int ox = out_offset;
+            for (int i = 0; i < in_len; i++) {
+                int x = (int) (in_buff[ix++] * (float)0x7FFFFF);
+                if (x < 0)
+                    x += 0x1000000;
+                out_buff[ox++] = (byte) (x >>> 16);
+                out_buff[ox++] = (byte) (x >>> 8);
+                out_buff[ox++] = (byte) x;
+            }
+            return out_buff;
+        }
+    }
+
+    // PCM 24 bit, unsigned, little-endian
+    private static class AudioFloatConversion24UL extends AudioFloatConverter {
+        public float[] toFloatArray(byte[] in_buff, int in_offset,
+                float[] out_buff, int out_offset, int out_len) {
+            int ix = in_offset;
+            int ox = out_offset;
+            for (int i = 0; i < out_len; i++) {
+                int x = (in_buff[ix++] & 0xFF) | ((in_buff[ix++] & 0xFF) << 8)
+                        | ((in_buff[ix++] & 0xFF) << 16);
+                x -= 0x7FFFFF;
+                out_buff[ox++] = x * (1.0f / (float)0x7FFFFF);
+            }
+            return out_buff;
+        }
+
+        public byte[] toByteArray(float[] in_buff, int in_offset, int in_len,
+                byte[] out_buff, int out_offset) {
+            int ix = in_offset;
+            int ox = out_offset;
+            for (int i = 0; i < in_len; i++) {
+                int x = (int) (in_buff[ix++] * (float)0x7FFFFF);
+                x += 0x7FFFFF;
+                out_buff[ox++] = (byte) x;
+                out_buff[ox++] = (byte) (x >>> 8);
+                out_buff[ox++] = (byte) (x >>> 16);
+            }
+            return out_buff;
+        }
+    }
+
+    // PCM 24 bit, unsigned, big-endian
+    private static class AudioFloatConversion24UB extends AudioFloatConverter {
+        public float[] toFloatArray(byte[] in_buff, int in_offset,
+                float[] out_buff, int out_offset, int out_len) {
+            int ix = in_offset;
+            int ox = out_offset;
+            for (int i = 0; i < out_len; i++) {
+                int x = ((in_buff[ix++] & 0xFF) << 16)
+                        | ((in_buff[ix++] & 0xFF) << 8) | (in_buff[ix++] & 0xFF);
+                x -= 0x7FFFFF;
+                out_buff[ox++] = x * (1.0f / (float)0x7FFFFF);
+            }
+            return out_buff;
+        }
+
+        public byte[] toByteArray(float[] in_buff, int in_offset, int in_len,
+                byte[] out_buff, int out_offset) {
+            int ix = in_offset;
+            int ox = out_offset;
+            for (int i = 0; i < in_len; i++) {
+                int x = (int) (in_buff[ix++] * (float)0x7FFFFF);
+                x += 0x7FFFFF;
+                out_buff[ox++] = (byte) (x >>> 16);
+                out_buff[ox++] = (byte) (x >>> 8);
+                out_buff[ox++] = (byte) x;
+            }
+            return out_buff;
+        }
+    }
+
+    /***************************************************************************
+     *
+     * 32 bit signed/unsigned, little/big-endian
+     *
+     **************************************************************************/
+
+    // PCM 32 bit, signed, little-endian
+    private static class AudioFloatConversion32SL extends AudioFloatConverter {
+        public float[] toFloatArray(byte[] in_buff, int in_offset,
+                float[] out_buff, int out_offset, int out_len) {
+            int ix = in_offset;
+            int ox = out_offset;
+            for (int i = 0; i < out_len; i++) {
+                int x = (in_buff[ix++] & 0xFF) | ((in_buff[ix++] & 0xFF) << 8) |
+                        ((in_buff[ix++] & 0xFF) << 16) |
+                        ((in_buff[ix++] & 0xFF) << 24);
+                out_buff[ox++] = x * (1.0f / (float)0x7FFFFFFF);
+            }
+            return out_buff;
+        }
+
+        public byte[] toByteArray(float[] in_buff, int in_offset, int in_len,
+                byte[] out_buff, int out_offset) {
+            int ix = in_offset;
+            int ox = out_offset;
+            for (int i = 0; i < in_len; i++) {
+                int x = (int) (in_buff[ix++] * (float)0x7FFFFFFF);
+                out_buff[ox++] = (byte) x;
+                out_buff[ox++] = (byte) (x >>> 8);
+                out_buff[ox++] = (byte) (x >>> 16);
+                out_buff[ox++] = (byte) (x >>> 24);
+            }
+            return out_buff;
+        }
+    }
+
+    // PCM 32 bit, signed, big-endian
+    private static class AudioFloatConversion32SB extends AudioFloatConverter {
+        public float[] toFloatArray(byte[] in_buff, int in_offset,
+                float[] out_buff, int out_offset, int out_len) {
+            int ix = in_offset;
+            int ox = out_offset;
+            for (int i = 0; i < out_len; i++) {
+                int x = ((in_buff[ix++] & 0xFF) << 24) |
+                        ((in_buff[ix++] & 0xFF) << 16) |
+                        ((in_buff[ix++] & 0xFF) << 8) | (in_buff[ix++] & 0xFF);
+                out_buff[ox++] = x * (1.0f / (float)0x7FFFFFFF);
+            }
+            return out_buff;
+        }
+
+        public byte[] toByteArray(float[] in_buff, int in_offset, int in_len,
+                byte[] out_buff, int out_offset) {
+            int ix = in_offset;
+            int ox = out_offset;
+            for (int i = 0; i < in_len; i++) {
+                int x = (int) (in_buff[ix++] * (float)0x7FFFFFFF);
+                out_buff[ox++] = (byte) (x >>> 24);
+                out_buff[ox++] = (byte) (x >>> 16);
+                out_buff[ox++] = (byte) (x >>> 8);
+                out_buff[ox++] = (byte) x;
+            }
+            return out_buff;
+        }
+    }
+
+    // PCM 32 bit, unsigned, little-endian
+    private static class AudioFloatConversion32UL extends AudioFloatConverter {
+        public float[] toFloatArray(byte[] in_buff, int in_offset,
+                float[] out_buff, int out_offset, int out_len) {
+            int ix = in_offset;
+            int ox = out_offset;
+            for (int i = 0; i < out_len; i++) {
+                int x = (in_buff[ix++] & 0xFF) | ((in_buff[ix++] & 0xFF) << 8) |
+                        ((in_buff[ix++] & 0xFF) << 16) |
+                        ((in_buff[ix++] & 0xFF) << 24);
+                x -= 0x7FFFFFFF;
+                out_buff[ox++] = x * (1.0f / (float)0x7FFFFFFF);
+            }
+            return out_buff;
+        }
+
+        public byte[] toByteArray(float[] in_buff, int in_offset, int in_len,
+                byte[] out_buff, int out_offset) {
+            int ix = in_offset;
+            int ox = out_offset;
+            for (int i = 0; i < in_len; i++) {
+                int x = (int) (in_buff[ix++] * (float)0x7FFFFFFF);
+                x += 0x7FFFFFFF;
+                out_buff[ox++] = (byte) x;
+                out_buff[ox++] = (byte) (x >>> 8);
+                out_buff[ox++] = (byte) (x >>> 16);
+                out_buff[ox++] = (byte) (x >>> 24);
+            }
+            return out_buff;
+        }
+    }
+
+    // PCM 32 bit, unsigned, big-endian
+    private static class AudioFloatConversion32UB extends AudioFloatConverter {
+
+        public float[] toFloatArray(byte[] in_buff, int in_offset,
+                float[] out_buff, int out_offset, int out_len) {
+            int ix = in_offset;
+            int ox = out_offset;
+            for (int i = 0; i < out_len; i++) {
+                int x = ((in_buff[ix++] & 0xFF) << 24) |
+                        ((in_buff[ix++] & 0xFF) << 16) |
+                        ((in_buff[ix++] & 0xFF) << 8) | (in_buff[ix++] & 0xFF);
+                x -= 0x7FFFFFFF;
+                out_buff[ox++] = x * (1.0f / (float)0x7FFFFFFF);
+            }
+            return out_buff;
+        }
+
+        public byte[] toByteArray(float[] in_buff, int in_offset, int in_len,
+                byte[] out_buff, int out_offset) {
+            int ix = in_offset;
+            int ox = out_offset;
+            for (int i = 0; i < in_len; i++) {
+                int x = (int) (in_buff[ix++] * (float)0x7FFFFFFF);
+                x += 0x7FFFFFFF;
+                out_buff[ox++] = (byte) (x >>> 24);
+                out_buff[ox++] = (byte) (x >>> 16);
+                out_buff[ox++] = (byte) (x >>> 8);
+                out_buff[ox++] = (byte) x;
+            }
+            return out_buff;
+        }
+    }
+
+    /***************************************************************************
+     *
+     * 32+ bit signed/unsigned, little/big-endian
+     *
+     **************************************************************************/
+
+    // PCM 32+ bit, signed, little-endian
+    private static class AudioFloatConversion32xSL extends AudioFloatConverter {
+
+        final int xbytes;
+
+        public AudioFloatConversion32xSL(int xbytes) {
+            this.xbytes = xbytes;
+        }
+
+        public float[] toFloatArray(byte[] in_buff, int in_offset,
+                float[] out_buff, int out_offset, int out_len) {
+            int ix = in_offset;
+            int ox = out_offset;
+            for (int i = 0; i < out_len; i++) {
+                ix += xbytes;
+                int x = (in_buff[ix++] & 0xFF) | ((in_buff[ix++] & 0xFF) << 8)
+                        | ((in_buff[ix++] & 0xFF) << 16)
+                        | ((in_buff[ix++] & 0xFF) << 24);
+                out_buff[ox++] = x * (1.0f / (float)0x7FFFFFFF);
+            }
+            return out_buff;
+        }
+
+        public byte[] toByteArray(float[] in_buff, int in_offset, int in_len,
+                byte[] out_buff, int out_offset) {
+            int ix = in_offset;
+            int ox = out_offset;
+            for (int i = 0; i < in_len; i++) {
+                int x = (int) (in_buff[ix++] * (float)0x7FFFFFFF);
+                for (int j = 0; j < xbytes; j++) {
+                    out_buff[ox++] = 0;
+                }
+                out_buff[ox++] = (byte) x;
+                out_buff[ox++] = (byte) (x >>> 8);
+                out_buff[ox++] = (byte) (x >>> 16);
+                out_buff[ox++] = (byte) (x >>> 24);
+            }
+            return out_buff;
+        }
+    }
+
+    // PCM 32+ bit, signed, big-endian
+    private static class AudioFloatConversion32xSB extends AudioFloatConverter {
+
+        final int xbytes;
+
+        public AudioFloatConversion32xSB(int xbytes) {
+            this.xbytes = xbytes;
+        }
+
+        public float[] toFloatArray(byte[] in_buff, int in_offset,
+                float[] out_buff, int out_offset, int out_len) {
+            int ix = in_offset;
+            int ox = out_offset;
+            for (int i = 0; i < out_len; i++) {
+                int x = ((in_buff[ix++] & 0xFF) << 24)
+                        | ((in_buff[ix++] & 0xFF) << 16)
+                        | ((in_buff[ix++] & 0xFF) << 8)
+                        | (in_buff[ix++] & 0xFF);
+                ix += xbytes;
+                out_buff[ox++] = x * (1.0f / (float)0x7FFFFFFF);
+            }
+            return out_buff;
+        }
+
+        public byte[] toByteArray(float[] in_buff, int in_offset, int in_len,
+                byte[] out_buff, int out_offset) {
+            int ix = in_offset;
+            int ox = out_offset;
+            for (int i = 0; i < in_len; i++) {
+                int x = (int) (in_buff[ix++] * (float)0x7FFFFFFF);
+                out_buff[ox++] = (byte) (x >>> 24);
+                out_buff[ox++] = (byte) (x >>> 16);
+                out_buff[ox++] = (byte) (x >>> 8);
+                out_buff[ox++] = (byte) x;
+                for (int j = 0; j < xbytes; j++) {
+                    out_buff[ox++] = 0;
+                }
+            }
+            return out_buff;
+        }
+    }
+
+    // PCM 32+ bit, unsigned, little-endian
+    private static class AudioFloatConversion32xUL extends AudioFloatConverter {
+
+        final int xbytes;
+
+        public AudioFloatConversion32xUL(int xbytes) {
+            this.xbytes = xbytes;
+        }
+
+        public float[] toFloatArray(byte[] in_buff, int in_offset,
+                float[] out_buff, int out_offset, int out_len) {
+            int ix = in_offset;
+            int ox = out_offset;
+            for (int i = 0; i < out_len; i++) {
+                ix += xbytes;
+                int x = (in_buff[ix++] & 0xFF) | ((in_buff[ix++] & 0xFF) << 8)
+                        | ((in_buff[ix++] & 0xFF) << 16)
+                        | ((in_buff[ix++] & 0xFF) << 24);
+                x -= 0x7FFFFFFF;
+                out_buff[ox++] = x * (1.0f / (float)0x7FFFFFFF);
+            }
+            return out_buff;
+        }
+
+        public byte[] toByteArray(float[] in_buff, int in_offset, int in_len,
+                byte[] out_buff, int out_offset) {
+            int ix = in_offset;
+            int ox = out_offset;
+            for (int i = 0; i < in_len; i++) {
+                int x = (int) (in_buff[ix++] * (float)0x7FFFFFFF);
+                x += 0x7FFFFFFF;
+                for (int j = 0; j < xbytes; j++) {
+                    out_buff[ox++] = 0;
+                }
+                out_buff[ox++] = (byte) x;
+                out_buff[ox++] = (byte) (x >>> 8);
+                out_buff[ox++] = (byte) (x >>> 16);
+                out_buff[ox++] = (byte) (x >>> 24);
+            }
+            return out_buff;
+        }
+    }
+
+    // PCM 32+ bit, unsigned, big-endian
+    private static class AudioFloatConversion32xUB extends AudioFloatConverter {
+
+        final int xbytes;
+
+        public AudioFloatConversion32xUB(int xbytes) {
+            this.xbytes = xbytes;
+        }
+
+        public float[] toFloatArray(byte[] in_buff, int in_offset,
+                float[] out_buff, int out_offset, int out_len) {
+            int ix = in_offset;
+            int ox = out_offset;
+            for (int i = 0; i < out_len; i++) {
+                int x = ((in_buff[ix++] & 0xFF) << 24) |
+                        ((in_buff[ix++] & 0xFF) << 16) |
+                        ((in_buff[ix++] & 0xFF) << 8) | (in_buff[ix++] & 0xFF);
+                ix += xbytes;
+                x -= 2147483647;
+                out_buff[ox++] = x * (1.0f / 2147483647.0f);
+            }
+            return out_buff;
+        }
+
+        public byte[] toByteArray(float[] in_buff, int in_offset, int in_len,
+                byte[] out_buff, int out_offset) {
+            int ix = in_offset;
+            int ox = out_offset;
+            for (int i = 0; i < in_len; i++) {
+                int x = (int) (in_buff[ix++] * 2147483647.0);
+                x += 2147483647;
+                out_buff[ox++] = (byte) (x >>> 24);
+                out_buff[ox++] = (byte) (x >>> 16);
+                out_buff[ox++] = (byte) (x >>> 8);
+                out_buff[ox++] = (byte) x;
+                for (int j = 0; j < xbytes; j++) {
+                    out_buff[ox++] = 0;
+                }
+            }
+            return out_buff;
+        }
+    }
+
+    public static AudioFloatConverter getConverter(AudioFormat format) {
+        AudioFloatConverter conv = null;
+        if (format.getFrameSize() == 0)
+            return null;
+        if (format.getFrameSize() !=
+                ((format.getSampleSizeInBits() + 7) / 8) * format.getChannels()) {
+            return null;
+        }
+        if (format.getEncoding().equals(Encoding.PCM_SIGNED)) {
+            if (format.isBigEndian()) {
+                if (format.getSampleSizeInBits() <= 8) {
+                    conv = new AudioFloatConversion8S();
+                } else if (format.getSampleSizeInBits() > 8 &&
+                      format.getSampleSizeInBits() <= 16) {
+                    conv = new AudioFloatConversion16SB();
+                } else if (format.getSampleSizeInBits() > 16 &&
+                      format.getSampleSizeInBits() <= 24) {
+                    conv = new AudioFloatConversion24SB();
+                } else if (format.getSampleSizeInBits() > 24 &&
+                      format.getSampleSizeInBits() <= 32) {
+                    conv = new AudioFloatConversion32SB();
+                } else if (format.getSampleSizeInBits() > 32) {
+                    conv = new AudioFloatConversion32xSB(((format
+                            .getSampleSizeInBits() + 7) / 8) - 4);
+                }
+            } else {
+                if (format.getSampleSizeInBits() <= 8) {
+                    conv = new AudioFloatConversion8S();
+                } else if (format.getSampleSizeInBits() > 8 &&
+                         format.getSampleSizeInBits() <= 16) {
+                    conv = new AudioFloatConversion16SL();
+                } else if (format.getSampleSizeInBits() > 16 &&
+                         format.getSampleSizeInBits() <= 24) {
+                    conv = new AudioFloatConversion24SL();
+                } else if (format.getSampleSizeInBits() > 24 &&
+                         format.getSampleSizeInBits() <= 32) {
+                    conv = new AudioFloatConversion32SL();
+                } else if (format.getSampleSizeInBits() > 32) {
+                    conv = new AudioFloatConversion32xSL(((format
+                            .getSampleSizeInBits() + 7) / 8) - 4);
+                }
+            }
+        } else if (format.getEncoding().equals(Encoding.PCM_UNSIGNED)) {
+            if (format.isBigEndian()) {
+                if (format.getSampleSizeInBits() <= 8) {
+                    conv = new AudioFloatConversion8U();
+                } else if (format.getSampleSizeInBits() > 8 &&
+                        format.getSampleSizeInBits() <= 16) {
+                    conv = new AudioFloatConversion16UB();
+                } else if (format.getSampleSizeInBits() > 16 &&
+                        format.getSampleSizeInBits() <= 24) {
+                    conv = new AudioFloatConversion24UB();
+                } else if (format.getSampleSizeInBits() > 24 &&
+                        format.getSampleSizeInBits() <= 32) {
+                    conv = new AudioFloatConversion32UB();
+                } else if (format.getSampleSizeInBits() > 32) {
+                    conv = new AudioFloatConversion32xUB(((
+                            format.getSampleSizeInBits() + 7) / 8) - 4);
+                }
+            } else {
+                if (format.getSampleSizeInBits() <= 8) {
+                    conv = new AudioFloatConversion8U();
+                } else if (format.getSampleSizeInBits() > 8 &&
+                        format.getSampleSizeInBits() <= 16) {
+                    conv = new AudioFloatConversion16UL();
+                } else if (format.getSampleSizeInBits() > 16 &&
+                        format.getSampleSizeInBits() <= 24) {
+                    conv = new AudioFloatConversion24UL();
+                } else if (format.getSampleSizeInBits() > 24 &&
+                        format.getSampleSizeInBits() <= 32) {
+                    conv = new AudioFloatConversion32UL();
+                } else if (format.getSampleSizeInBits() > 32) {
+                    conv = new AudioFloatConversion32xUL(((
+                            format.getSampleSizeInBits() + 7) / 8) - 4);
+                }
+            }
+        } else if (format.getEncoding().equals(PCM_FLOAT)) {
+            if (format.getSampleSizeInBits() == 32) {
+                if (format.isBigEndian())
+                    conv = new AudioFloatConversion32B();
+                else
+                    conv = new AudioFloatConversion32L();
+            } else if (format.getSampleSizeInBits() == 64) {
+                if (format.isBigEndian())
+                    conv = new AudioFloatConversion64B();
+                else
+                    conv = new AudioFloatConversion64L();
+            }
+
+        }
+
+        if ((format.getEncoding().equals(Encoding.PCM_SIGNED) ||
+                format.getEncoding().equals(Encoding.PCM_UNSIGNED)) &&
+                (format.getSampleSizeInBits() % 8 != 0)) {
+            conv = new AudioFloatLSBFilter(conv, format);
+        }
+
+        if (conv != null)
+            conv.format = format;
+        return conv;
+    }
+
+    private AudioFormat format;
+
+    public AudioFormat getFormat() {
+        return format;
+    }
+
+    public abstract float[] toFloatArray(byte[] in_buff, int in_offset,
+            float[] out_buff, int out_offset, int out_len);
+
+    public float[] toFloatArray(byte[] in_buff, float[] out_buff,
+            int out_offset, int out_len) {
+        return toFloatArray(in_buff, 0, out_buff, out_offset, out_len);
+    }
+
+    public float[] toFloatArray(byte[] in_buff, int in_offset,
+            float[] out_buff, int out_len) {
+        return toFloatArray(in_buff, in_offset, out_buff, 0, out_len);
+    }
+
+    public float[] toFloatArray(byte[] in_buff, float[] out_buff, int out_len) {
+        return toFloatArray(in_buff, 0, out_buff, 0, out_len);
+    }
+
+    public float[] toFloatArray(byte[] in_buff, float[] out_buff) {
+        return toFloatArray(in_buff, 0, out_buff, 0, out_buff.length);
+    }
+
+    public abstract byte[] toByteArray(float[] in_buff, int in_offset,
+            int in_len, byte[] out_buff, int out_offset);
+
+    public byte[] toByteArray(float[] in_buff, int in_len, byte[] out_buff,
+            int out_offset) {
+        return toByteArray(in_buff, 0, in_len, out_buff, out_offset);
+    }
+
+    public byte[] toByteArray(float[] in_buff, int in_offset, int in_len,
+            byte[] out_buff) {
+        return toByteArray(in_buff, in_offset, in_len, out_buff, 0);
+    }
+
+    public byte[] toByteArray(float[] in_buff, int in_len, byte[] out_buff) {
+        return toByteArray(in_buff, 0, in_len, out_buff, 0);
+    }
+
+    public byte[] toByteArray(float[] in_buff, byte[] out_buff) {
+        return toByteArray(in_buff, 0, in_buff.length, out_buff, 0);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/classes/com/sun/media/sound/AudioFloatFormatConverter.java	Mon Jan 19 20:11:58 2009 +0300
@@ -0,0 +1,617 @@
+/*
+ * Copyright 2008 Sun Microsystems, Inc.  All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+package com.sun.media.sound;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.ArrayList;
+import java.util.Arrays;
+
+import javax.sound.sampled.AudioFormat;
+import javax.sound.sampled.AudioInputStream;
+import javax.sound.sampled.AudioSystem;
+import javax.sound.sampled.AudioFormat.Encoding;
+import javax.sound.sampled.spi.FormatConversionProvider;
+
+/**
+ * This class is used to convert between 8,16,24,32 bit signed/unsigned
+ * big/litle endian fixed/floating stereo/mono/multi-channel audio streams and
+ * perform sample-rate conversion if needed.
+ *
+ * @author Karl Helgason
+ */
+public class AudioFloatFormatConverter extends FormatConversionProvider {
+
+    private static class AudioFloatFormatConverterInputStream extends
+            InputStream {
+        private AudioFloatConverter converter;
+
+        private AudioFloatInputStream stream;
+
+        private float[] readfloatbuffer;
+
+        private int fsize = 0;
+
+        public AudioFloatFormatConverterInputStream(AudioFormat targetFormat,
+                AudioFloatInputStream stream) {
+            this.stream = stream;
+            converter = AudioFloatConverter.getConverter(targetFormat);
+            fsize = ((targetFormat.getSampleSizeInBits() + 7) / 8);
+        }
+
+        public int read() throws IOException {
+            byte[] b = new byte[1];
+            int ret = read(b);
+            if (ret < 0)
+                return ret;
+            return b[0] & 0xFF;
+        }
+
+        public int read(byte[] b, int off, int len) throws IOException {
+
+            int flen = len / fsize;
+            if (readfloatbuffer == null || readfloatbuffer.length < flen)
+                readfloatbuffer = new float[flen];
+            int ret = stream.read(readfloatbuffer, 0, flen);
+            if (ret < 0)
+                return ret;
+            converter.toByteArray(readfloatbuffer, 0, ret, b, off);
+            return ret * fsize;
+        }
+
+        public int available() throws IOException {
+            int ret = stream.available();
+            if (ret < 0)
+                return ret;
+            return ret * fsize;
+        }
+
+        public void close() throws IOException {
+            stream.close();
+        }
+
+        public synchronized void mark(int readlimit) {
+            stream.mark(readlimit * fsize);
+        }
+
+        public boolean markSupported() {
+            return stream.markSupported();
+        }
+
+        public synchronized void reset() throws IOException {
+            stream.reset();
+        }
+
+        public long skip(long n) throws IOException {
+            long ret = stream.skip(n / fsize);
+            if (ret < 0)
+                return ret;
+            return ret * fsize;
+        }
+
+    }
+
+    private static class AudioFloatInputStreamChannelMixer extends
+            AudioFloatInputStream {
+
+        private int targetChannels;
+
+        private int sourceChannels;
+
+        private AudioFloatInputStream ais;
+
+        private AudioFormat targetFormat;
+
+        private float[] conversion_buffer;
+
+        public AudioFloatInputStreamChannelMixer(AudioFloatInputStream ais,
+                int targetChannels) {
+            this.sourceChannels = ais.getFormat().getChannels();
+            this.targetChannels = targetChannels;
+            this.ais = ais;
+            AudioFormat format = ais.getFormat();
+            targetFormat = new AudioFormat(format.getEncoding(), format
+                    .getSampleRate(), format.getSampleSizeInBits(),
+                    targetChannels, (format.getFrameSize() / sourceChannels)
+                            * targetChannels, format.getFrameRate(), format
+                            .isBigEndian());
+        }
+
+        public int available() throws IOException {
+            return (ais.available() / sourceChannels) * targetChannels;
+        }
+
+        public void close() throws IOException {
+            ais.close();
+        }
+
+        public AudioFormat getFormat() {
+            return targetFormat;
+        }
+
+        public long getFrameLength() {
+            return ais.getFrameLength();
+        }
+
+        public void mark(int readlimit) {
+            ais.mark((readlimit / targetChannels) * sourceChannels);
+        }
+
+        public boolean markSupported() {
+            return ais.markSupported();
+        }
+
+        public int read(float[] b, int off, int len) throws IOException {
+            int len2 = (len / targetChannels) * sourceChannels;
+            if (conversion_buffer == null || conversion_buffer.length < len2)
+                conversion_buffer = new float[len2];
+            int ret = ais.read(conversion_buffer, 0, len2);
+            if (ret < 0)
+                return ret;
+            if (sourceChannels == 1) {
+                int cs = targetChannels;
+                for (int c = 0; c < targetChannels; c++) {
+                    for (int i = 0, ix = off + c; i < len2; i++, ix += cs) {
+                        b[ix] = conversion_buffer[i];
+                        ;
+                    }
+                }
+            } else if (targetChannels == 1) {
+                int cs = sourceChannels;
+                for (int i = 0, ix = off; i < len2; i += cs, ix++) {
+                    b[ix] = conversion_buffer[i];
+                }
+                for (int c = 1; c < sourceChannels; c++) {
+                    for (int i = c, ix = off; i < len2; i += cs, ix++) {
+                        b[ix] += conversion_buffer[i];
+                        ;
+                    }
+                }
+                float vol = 1f / ((float) sourceChannels);
+                for (int i = 0, ix = off; i < len2; i += cs, ix++) {
+                    b[ix] *= vol;
+                }
+            } else {
+                int minChannels = Math.min(sourceChannels, targetChannels);
+                int off_len = off + len;
+                int ct = targetChannels;
+                int cs = sourceChannels;
+                for (int c = 0; c < minChannels; c++) {
+                    for (int i = off + c, ix = c; i < off_len; i += ct, ix += cs) {
+                        b[i] = conversion_buffer[ix];
+                    }
+                }
+                for (int c = minChannels; c < targetChannels; c++) {
+                    for (int i = off + c; i < off_len; i += ct) {
+                        b[i] = 0;
+                    }
+                }
+            }
+            return (ret / sourceChannels) * targetChannels;
+        }
+
+        public void reset() throws IOException {
+            ais.reset();
+        }
+
+        public long skip(long len) throws IOException {
+            long ret = ais.skip((len / targetChannels) * sourceChannels);
+            if (ret < 0)
+                return ret;
+            return (ret / sourceChannels) * targetChannels;
+        }
+
+    }
+
+    private static class AudioFloatInputStreamResampler extends
+            AudioFloatInputStream {
+
+        private AudioFloatInputStream ais;
+
+        private AudioFormat targetFormat;
+
+        private float[] skipbuffer;
+
+        private SoftAbstractResampler resampler;
+
+        private float[] pitch = new float[1];
+
+        private float[] ibuffer2;
+
+        private float[][] ibuffer;
+
+        private float ibuffer_index = 0;
+
+        private int ibuffer_len = 0;
+
+        private int nrofchannels = 0;
+
+        private float[][] cbuffer;
+
+        private int buffer_len = 512;
+
+        private int pad;
+
+        private int pad2;
+
+        private float[] ix = new float[1];
+
+        private int[] ox = new int[1];
+
+        private float[][] mark_ibuffer = null;
+
+        private float mark_ibuffer_index = 0;
+
+        private int mark_ibuffer_len = 0;
+
+        public AudioFloatInputStreamResampler(AudioFloatInputStream ais,
+                AudioFormat format) {
+            this.ais = ais;
+            AudioFormat sourceFormat = ais.getFormat();
+            targetFormat = new AudioFormat(sourceFormat.getEncoding(), format
+                    .getSampleRate(), sourceFormat.getSampleSizeInBits(),
+                    sourceFormat.getChannels(), sourceFormat.getFrameSize(),
+                    format.getSampleRate(), sourceFormat.isBigEndian());
+            nrofchannels = targetFormat.getChannels();
+            Object interpolation = format.getProperty("interpolation");
+            if (interpolation != null && (interpolation instanceof String)) {
+                String resamplerType = (String) interpolation;
+                if (resamplerType.equalsIgnoreCase("point"))
+                    this.resampler = new SoftPointResampler();
+                if (resamplerType.equalsIgnoreCase("linear"))
+                    this.resampler = new SoftLinearResampler2();
+                if (resamplerType.equalsIgnoreCase("linear1"))
+                    this.resampler = new SoftLinearResampler();
+                if (resamplerType.equalsIgnoreCase("linear2"))
+                    this.resampler = new SoftLinearResampler2();
+                if (resamplerType.equalsIgnoreCase("cubic"))
+                    this.resampler = new SoftCubicResampler();
+                if (resamplerType.equalsIgnoreCase("lanczos"))
+                    this.resampler = new SoftLanczosResampler();
+                if (resamplerType.equalsIgnoreCase("sinc"))
+                    this.resampler = new SoftSincResampler();
+            }
+            if (resampler == null)
+                resampler = new SoftLinearResampler2(); // new
+                                                        // SoftLinearResampler2();
+            pitch[0] = sourceFormat.getSampleRate() / format.getSampleRate();
+            pad = resampler.getPadding();
+            pad2 = pad * 2;
+            ibuffer = new float[nrofchannels][buffer_len + pad2];
+            ibuffer2 = new float[nrofchannels * buffer_len];
+            ibuffer_index = buffer_len + pad;
+            ibuffer_len = buffer_len;
+        }
+
+        public int available() throws IOException {
+            return 0;
+        }
+
+        public void close() throws IOException {
+            ais.close();
+        }
+
+        public AudioFormat getFormat() {
+            return targetFormat;
+        }
+
+        public long getFrameLength() {
+            return AudioSystem.NOT_SPECIFIED; // ais.getFrameLength();
+        }
+
+        public void mark(int readlimit) {
+            ais.mark((int) (readlimit * pitch[0]));
+            mark_ibuffer_index = ibuffer_index;
+            mark_ibuffer_len = ibuffer_len;
+            if (mark_ibuffer == null) {
+                mark_ibuffer = new float[ibuffer.length][ibuffer[0].length];
+            }
+            for (int c = 0; c < ibuffer.length; c++) {
+                float[] from = ibuffer[c];
+                float[] to = mark_ibuffer[c];
+                for (int i = 0; i < to.length; i++) {
+                    to[i] = from[i];
+                }
+            }
+        }
+
+        public boolean markSupported() {
+            return ais.markSupported();
+        }
+
+        private void readNextBuffer() throws IOException {
+
+            if (ibuffer_len == -1)
+                return;
+
+            for (int c = 0; c < nrofchannels; c++) {
+                float[] buff = ibuffer[c];
+                int buffer_len_pad = ibuffer_len + pad2;
+                for (int i = ibuffer_len, ix = 0; i < buffer_len_pad; i++, ix++) {
+                    buff[ix] = buff[i];
+                }
+            }
+
+            ibuffer_index -= (ibuffer_len);
+
+            ibuffer_len = ais.read(ibuffer2);
+            if (ibuffer_len >= 0) {
+                while (ibuffer_len < ibuffer2.length) {
+                    int ret = ais.read(ibuffer2, ibuffer_len, ibuffer2.length
+                            - ibuffer_len);
+                    if (ret == -1)
+                        break;
+                    ibuffer_len += ret;
+                }
+                Arrays.fill(ibuffer2, ibuffer_len, ibuffer2.length, 0);
+                ibuffer_len /= nrofchannels;
+            } else {
+                Arrays.fill(ibuffer2, 0, ibuffer2.length, 0);
+            }
+
+            int ibuffer2_len = ibuffer2.length;
+            for (int c = 0; c < nrofchannels; c++) {
+                float[] buff = ibuffer[c];
+                for (int i = c, ix = pad2; i < ibuffer2_len; i += nrofchannels, ix++) {
+                    buff[ix] = ibuffer2[i];
+                }
+            }
+
+        }
+
+        public int read(float[] b, int off, int len) throws IOException {
+
+            if (cbuffer == null || cbuffer[0].length < len / nrofchannels) {
+                cbuffer = new float[nrofchannels][len / nrofchannels];
+            }
+            if (ibuffer_len == -1)
+                return -1;
+            if (len < 0)
+                return 0;
+            int remain = len / nrofchannels;
+            int destPos = 0;
+            int in_end = ibuffer_len;
+            while (remain > 0) {
+                if (ibuffer_len >= 0) {
+                    if (ibuffer_index >= (ibuffer_len + pad))
+                        readNextBuffer();
+                    in_end = ibuffer_len + pad;
+                }
+
+                if (ibuffer_len < 0) {
+                    in_end = pad2;
+                    if (ibuffer_index >= in_end)
+                        break;
+                }
+
+                if (ibuffer_index < 0)
+                    break;
+                int preDestPos = destPos;
+                for (int c = 0; c < nrofchannels; c++) {
+                    ix[0] = ibuffer_index;
+                    ox[0] = destPos;
+                    float[] buff = ibuffer[c];
+                    resampler.interpolate(buff, ix, in_end, pitch, 0,
+                            cbuffer[c], ox, len / nrofchannels);
+                }
+                ibuffer_index = ix[0];
+                destPos = ox[0];
+                remain -= destPos - preDestPos;
+            }
+            for (int c = 0; c < nrofchannels; c++) {
+                int ix = 0;
+                float[] buff = cbuffer[c];
+                for (int i = c; i < b.length; i += nrofchannels) {
+                    b[i] = buff[ix++];
+                }
+            }
+            return len - remain * nrofchannels;
+        }
+
+        public void reset() throws IOException {
+            ais.reset();
+            if (mark_ibuffer == null)
+                return;
+            ibuffer_index = mark_ibuffer_index;
+            ibuffer_len = mark_ibuffer_len;
+            for (int c = 0; c < ibuffer.length; c++) {
+                float[] from = mark_ibuffer[c];
+                float[] to = ibuffer[c];
+                for (int i = 0; i < to.length; i++) {
+                    to[i] = from[i];
+                }
+            }
+
+        }
+
+        public long skip(long len) throws IOException {
+            if (len > 0)
+                return 0;
+            if (skipbuffer == null)
+                skipbuffer = new float[1024 * targetFormat.getFrameSize()];
+            float[] l_skipbuffer = skipbuffer;
+            long remain = len;
+            while (remain > 0) {
+                int ret = read(l_skipbuffer, 0, (int) Math.min(remain,
+                        skipbuffer.length));
+                if (ret < 0) {
+                    if (remain == len)
+                        return ret;
+                    break;
+                }
+                remain -= ret;
+            }
+            return len - remain;
+
+        }
+
+    }
+
+    private Encoding[] formats = { Encoding.PCM_SIGNED, Encoding.PCM_UNSIGNED,
+            AudioFloatConverter.PCM_FLOAT };
+
+    public AudioInputStream getAudioInputStream(Encoding targetEncoding,
+            AudioInputStream sourceStream) {
+        if (sourceStream.getFormat().getEncoding().equals(targetEncoding))
+            return sourceStream;
+        AudioFormat format = sourceStream.getFormat();
+        int channels = format.getChannels();
+        Encoding encoding = targetEncoding;
+        float samplerate = format.getSampleRate();
+        int bits = format.getSampleSizeInBits();
+        boolean bigendian = format.isBigEndian();
+        if (targetEncoding.equals(AudioFloatConverter.PCM_FLOAT))
+            bits = 32;
+        AudioFormat targetFormat = new AudioFormat(encoding, samplerate, bits,
+                channels, channels * bits / 8, samplerate, bigendian);
+        return getAudioInputStream(targetFormat, sourceStream);
+    }
+
+    public AudioInputStream getAudioInputStream(AudioFormat targetFormat,
+            AudioInputStream sourceStream) {
+        if (!isConversionSupported(targetFormat, sourceStream.getFormat()))
+            throw new IllegalArgumentException("Unsupported conversion: "
+                    + sourceStream.getFormat().toString() + " to "
+                    + targetFormat.toString());
+        return getAudioInputStream(targetFormat, AudioFloatInputStream
+                .getInputStream(sourceStream));
+    }
+
+    public AudioInputStream getAudioInputStream(AudioFormat targetFormat,
+            AudioFloatInputStream sourceStream) {
+
+        if (!isConversionSupported(targetFormat, sourceStream.getFormat()))
+            throw new IllegalArgumentException("Unsupported conversion: "
+                    + sourceStream.getFormat().toString() + " to "
+                    + targetFormat.toString());
+        if (targetFormat.getChannels() != sourceStream.getFormat()
+                .getChannels())
+            sourceStream = new AudioFloatInputStreamChannelMixer(sourceStream,
+                    targetFormat.getChannels());
+        if (Math.abs(targetFormat.getSampleRate()
+                - sourceStream.getFormat().getSampleRate()) > 0.000001)
+            sourceStream = new AudioFloatInputStreamResampler(sourceStream,
+                    targetFormat);
+        return new AudioInputStream(new AudioFloatFormatConverterInputStream(
+                targetFormat, sourceStream), targetFormat, sourceStream
+                .getFrameLength());
+    }
+
+    public Encoding[] getSourceEncodings() {
+        return new Encoding[] { Encoding.PCM_SIGNED, Encoding.PCM_UNSIGNED,
+                AudioFloatConverter.PCM_FLOAT };
+    }
+
+    public Encoding[] getTargetEncodings() {
+        return new Encoding[] { Encoding.PCM_SIGNED, Encoding.PCM_UNSIGNED,
+                AudioFloatConverter.PCM_FLOAT };
+    }
+
+    public Encoding[] getTargetEncodings(AudioFormat sourceFormat) {
+        if (AudioFloatConverter.getConverter(sourceFormat) == null)
+            return new Encoding[0];
+        return new Encoding[] { Encoding.PCM_SIGNED, Encoding.PCM_UNSIGNED,
+                AudioFloatConverter.PCM_FLOAT };
+    }
+
+    public AudioFormat[] getTargetFormats(Encoding targetEncoding,
+            AudioFormat sourceFormat) {
+        if (AudioFloatConverter.getConverter(sourceFormat) == null)
+            return new AudioFormat[0];
+        int channels = sourceFormat.getChannels();
+
+        ArrayList<AudioFormat> formats = new ArrayList<AudioFormat>();
+
+        if (targetEncoding.equals(Encoding.PCM_SIGNED))
+            formats.add(new AudioFormat(Encoding.PCM_SIGNED,
+                    AudioSystem.NOT_SPECIFIED, 8, channels, channels,
+                    AudioSystem.NOT_SPECIFIED, false));
+        if (targetEncoding.equals(Encoding.PCM_UNSIGNED))
+            formats.add(new AudioFormat(Encoding.PCM_UNSIGNED,
+                    AudioSystem.NOT_SPECIFIED, 8, channels, channels,
+                    AudioSystem.NOT_SPECIFIED, false));
+
+        for (int bits = 16; bits < 32; bits += 8) {
+            if (targetEncoding.equals(Encoding.PCM_SIGNED)) {
+                formats.add(new AudioFormat(Encoding.PCM_SIGNED,
+                        AudioSystem.NOT_SPECIFIED, bits, channels, channels
+                                * bits / 8, AudioSystem.NOT_SPECIFIED, false));
+                formats.add(new AudioFormat(Encoding.PCM_SIGNED,
+                        AudioSystem.NOT_SPECIFIED, bits, channels, channels
+                                * bits / 8, AudioSystem.NOT_SPECIFIED, true));
+            }
+            if (targetEncoding.equals(Encoding.PCM_UNSIGNED)) {
+                formats.add(new AudioFormat(Encoding.PCM_UNSIGNED,
+                        AudioSystem.NOT_SPECIFIED, bits, channels, channels
+                                * bits / 8, AudioSystem.NOT_SPECIFIED, true));
+                formats.add(new AudioFormat(Encoding.PCM_UNSIGNED,
+                        AudioSystem.NOT_SPECIFIED, bits, channels, channels
+                                * bits / 8, AudioSystem.NOT_SPECIFIED, false));
+            }
+        }
+
+        if (targetEncoding.equals(AudioFloatConverter.PCM_FLOAT)) {
+            formats.add(new AudioFormat(AudioFloatConverter.PCM_FLOAT,
+                    AudioSystem.NOT_SPECIFIED, 32, channels, channels * 4,
+                    AudioSystem.NOT_SPECIFIED, false));
+            formats.add(new AudioFormat(AudioFloatConverter.PCM_FLOAT,
+                    AudioSystem.NOT_SPECIFIED, 32, channels, channels * 4,
+                    AudioSystem.NOT_SPECIFIED, true));
+            formats.add(new AudioFormat(AudioFloatConverter.PCM_FLOAT,
+                    AudioSystem.NOT_SPECIFIED, 64, channels, channels * 8,
+                    AudioSystem.NOT_SPECIFIED, false));
+            formats.add(new AudioFormat(AudioFloatConverter.PCM_FLOAT,
+                    AudioSystem.NOT_SPECIFIED, 64, channels, channels * 8,
+                    AudioSystem.NOT_SPECIFIED, true));
+        }
+
+        return formats.toArray(new AudioFormat[formats.size()]);
+    }
+
+    public boolean isConversionSupported(AudioFormat targetFormat,
+            AudioFormat sourceFormat) {
+        if (AudioFloatConverter.getConverter(sourceFormat) == null)
+            return false;
+        if (AudioFloatConverter.getConverter(targetFormat) == null)
+            return false;
+        if (sourceFormat.getChannels() <= 0)
+            return false;
+        if (targetFormat.getChannels() <= 0)
+            return false;
+        return true;
+    }
+
+    public boolean isConversionSupported(Encoding targetEncoding,
+            AudioFormat sourceFormat) {
+        if (AudioFloatConverter.getConverter(sourceFormat) == null)
+            return false;
+        for (int i = 0; i < formats.length; i++) {
+            if (targetEncoding.equals(formats[i]))
+                return true;
+        }
+        return false;
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/classes/com/sun/media/sound/AudioFloatInputStream.java	Mon Jan 19 20:11:58 2009 +0300
@@ -0,0 +1,281 @@
+/*
+ * Copyright 2007 Sun Microsystems, Inc.  All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+package com.sun.media.sound;
+
+import java.io.ByteArrayInputStream;
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.URL;
+
+import javax.sound.sampled.AudioFormat;
+import javax.sound.sampled.AudioInputStream;
+import javax.sound.sampled.AudioSystem;
+import javax.sound.sampled.UnsupportedAudioFileException;
+
+/**
+ * This class is used to create AudioFloatInputStream from AudioInputStream and
+ * byte buffers.
+ *
+ * @author Karl Helgason
+ */
+public abstract class AudioFloatInputStream {
+
+    private static class BytaArrayAudioFloatInputStream
+            extends AudioFloatInputStream {
+
+        private int pos = 0;
+        private int markpos = 0;
+        private AudioFloatConverter converter;
+        private AudioFormat format;
+        private byte[] buffer;
+        private int buffer_offset;
+        private int buffer_len;
+        private int framesize_pc;
+
+        public BytaArrayAudioFloatInputStream(AudioFloatConverter converter,
+                byte[] buffer, int offset, int len) {
+            this.converter = converter;
+            this.format = converter.getFormat();
+            this.buffer = buffer;
+            this.buffer_offset = offset;
+            framesize_pc = format.getFrameSize() / format.getChannels();
+            this.buffer_len = len / framesize_pc;
+
+        }
+
+        public AudioFormat getFormat() {
+            return format;
+        }
+
+        public long getFrameLength() {
+            return buffer_len;// / format.getFrameSize();
+        }
+
+        public int read(float[] b, int off, int len) throws IOException {
+            if (b == null)
+                throw new NullPointerException();
+            if (off < 0 || len < 0 || len > b.length - off)
+                throw new IndexOutOfBoundsException();
+            if (pos >= buffer_len)
+                return -1;
+            if (len == 0)
+                return 0;
+            if (pos + len > buffer_len)
+                len = buffer_len - pos;
+            converter.toFloatArray(buffer, buffer_offset + pos * framesize_pc,
+                    b, off, len);
+            pos += len;
+            return len;
+        }
+
+        public long skip(long len) throws IOException {
+            if (pos >= buffer_len)
+                return -1;
+            if (len <= 0)
+                return 0;
+            if (pos + len > buffer_len)
+                len = buffer_len - pos;
+            pos += len;
+            return len;
+        }
+
+        public int available() throws IOException {
+            return buffer_len - pos;
+        }
+
+        public void close() throws IOException {
+        }
+
+        public void mark(int readlimit) {
+            markpos = pos;
+        }
+
+        public boolean markSupported() {
+            return true;
+        }
+
+        public void reset() throws IOException {
+            pos = markpos;
+        }
+    }
+
+    private static class DirectAudioFloatInputStream
+            extends AudioFloatInputStream {
+
+        private AudioInputStream stream;
+        private AudioFloatConverter converter;
+        private int framesize_pc; // framesize / channels
+        private byte[] buffer;
+
+        public DirectAudioFloatInputStream(AudioInputStream stream) {
+            converter = AudioFloatConverter.getConverter(stream.getFormat());
+            if (converter == null) {
+                AudioFormat format = stream.getFormat();
+                AudioFormat newformat;
+
+                AudioFormat[] formats = AudioSystem.getTargetFormats(
+                        AudioFormat.Encoding.PCM_SIGNED, format);
+                if (formats.length != 0) {
+                    newformat = formats[0];
+                } else {
+                    float samplerate = format.getSampleRate();
+                    int samplesizeinbits = format.getSampleSizeInBits();
+                    int framesize = format.getFrameSize();
+                    float framerate = format.getFrameRate();
+                    samplesizeinbits = 16;
+                    framesize = format.getChannels() * (samplesizeinbits / 8);
+                    framerate = samplerate;
+
+                    newformat = new AudioFormat(
+                            AudioFormat.Encoding.PCM_SIGNED, samplerate,
+                            samplesizeinbits, format.getChannels(), framesize,
+                            framerate, false);
+                }
+
+                stream = AudioSystem.getAudioInputStream(newformat, stream);
+                converter = AudioFloatConverter.getConverter(stream.getFormat());
+            }
+            framesize_pc = stream.getFormat().getFrameSize()
+                    / stream.getFormat().getChannels();
+            this.stream = stream;
+        }
+
+        public AudioFormat getFormat() {
+            return stream.getFormat();
+        }
+
+        public long getFrameLength() {
+            return stream.getFrameLength();
+        }
+
+        public int read(float[] b, int off, int len) throws IOException {
+            int b_len = len * framesize_pc;
+            if (buffer == null || buffer.length < b_len)
+                buffer = new byte[b_len];
+            int ret = stream.read(buffer, 0, b_len);
+            if (ret == -1)
+                return -1;
+            converter.toFloatArray(buffer, b, off, ret / framesize_pc);
+            return ret / framesize_pc;
+        }
+
+        public long skip(long len) throws IOException {
+            long b_len = len * framesize_pc;
+            long ret = stream.skip(b_len);
+            if (ret == -1)
+                return -1;
+            return ret / framesize_pc;
+        }
+
+        public int available() throws IOException {
+            return stream.available() / framesize_pc;
+        }
+
+        public void close() throws IOException {
+            stream.close();
+        }
+
+        public void mark(int readlimit) {
+            stream.mark(readlimit * framesize_pc);
+        }
+
+        public boolean markSupported() {
+            return stream.markSupported();
+        }
+
+        public void reset() throws IOException {
+            stream.reset();
+        }
+    }
+
+    public static AudioFloatInputStream getInputStream(URL url)
+            throws UnsupportedAudioFileException, IOException {
+        return new DirectAudioFloatInputStream(AudioSystem
+                .getAudioInputStream(url));
+    }
+
+    public static AudioFloatInputStream getInputStream(File file)
+            throws UnsupportedAudioFileException, IOException {
+        return new DirectAudioFloatInputStream(AudioSystem
+                .getAudioInputStream(file));
+    }
+
+    public static AudioFloatInputStream getInputStream(InputStream stream)
+            throws UnsupportedAudioFileException, IOException {
+        return new DirectAudioFloatInputStream(AudioSystem
+                .getAudioInputStream(stream));
+    }
+
+    public static AudioFloatInputStream getInputStream(
+            AudioInputStream stream) {
+        return new DirectAudioFloatInputStream(stream);
+    }
+
+    public static AudioFloatInputStream getInputStream(AudioFormat format,
+            byte[] buffer, int offset, int len) {
+        AudioFloatConverter converter = AudioFloatConverter
+                .getConverter(format);
+        if (converter != null)
+            return new BytaArrayAudioFloatInputStream(converter, buffer,
+                    offset, len);
+
+        InputStream stream = new ByteArrayInputStream(buffer, offset, len);
+        long aLen = format.getFrameSize() == AudioSystem.NOT_SPECIFIED
+                ? AudioSystem.NOT_SPECIFIED : len / format.getFrameSize();
+        AudioInputStream astream = new AudioInputStream(stream, format, aLen);
+        return getInputStream(astream);
+    }
+
+    public abstract AudioFormat getFormat();
+
+    public abstract long getFrameLength();
+
+    public abstract int read(float[] b, int off, int len) throws IOException;
+
+    public int read(float[] b) throws IOException {
+        return read(b, 0, b.length);
+    }
+
+    public float read() throws IOException {
+        float[] b = new float[1];
+        int ret = read(b, 0, 1);
+        if (ret == -1 || ret == 0)
+            return 0;
+        return b[0];
+    }
+
+    public abstract long skip(long len) throws IOException;
+
+    public abstract int available() throws IOException;
+
+    public abstract void close() throws IOException;
+
+    public abstract void mark(int readlimit);
+
+    public abstract boolean markSupported();
+
+    public abstract void reset() throws IOException;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/classes/com/sun/media/sound/AudioSynthesizer.java	Mon Jan 19 20:11:58 2009 +0300
@@ -0,0 +1,128 @@
+/*
+ * Copyright 2007 Sun Microsystems, Inc.  All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+package com.sun.media.sound;
+
+import java.util.Map;
+import javax.sound.midi.MidiUnavailableException;
+import javax.sound.midi.Synthesizer;
+import javax.sound.sampled.AudioFormat;
+import javax.sound.sampled.AudioInputStream;
+import javax.sound.sampled.SourceDataLine;
+
+/**
+ * <code>AudioSynthesizer</code> is a <code>Synthesizer</code>
+ * which renders it's output audio into <code>SourceDataLine</code>
+ * or <code>AudioInputStream</code>.
+ *
+ * @see MidiSystem#getSynthesizer
+ * @see Synthesizer
+ *
+ * @author Karl Helgason
+ */
+public interface AudioSynthesizer extends Synthesizer {
+
+    /**
+     * Obtains the current format (encoding, sample rate, number of channels,
+     * etc.) of the synthesizer audio data.
+     *
+     * <p>If the synthesizer is not open and has never been opened, it returns
+     * the default format.
+     *
+     * @return current audio data format
+     * @see AudioFormat
+     */
+    public AudioFormat getFormat();
+
+    /**
+     * Gets information about the possible properties for the synthesizer.
+     *
+     * @param info a proposed list of tag/value pairs that will be sent on open.
+     * @return an array of <code>AudioSynthesizerPropertyInfo</code> objects
+     * describing possible properties. This array may be an empty array if
+     * no properties are required.
+     */
+    public AudioSynthesizerPropertyInfo[] getPropertyInfo(
+            Map<String, Object> info);
+
+    /**
+     * Opens the synthesizer and starts rendering audio into
+     * <code>SourceDataLine</code>.
+     *
+     * <p>An application opening a synthesizer explicitly with this call
+     * has to close the synthesizer by calling {@link #close}. This is
+     * necessary to release system resources and allow applications to
+     * exit cleanly.
+     *
+     * <p>Note that some synthesizers, once closed, cannot be reopened.
+     * Attempts to reopen such a synthesizer will always result in
+     * a <code>MidiUnavailableException</code>.
+     *
+     * @param line which <code>AudioSynthesizer</code> writes output audio into.
+     * If <code>line</code> is null, then line from system default mixer is used.
+     * @param info a <code>Map<String,Object></code> object containing
+     * properties for additional configuration supported by synthesizer.
+     * If <code>info</code> is null then default settings are used.
+     *
+     * @throws MidiUnavailableException thrown if the synthesizer cannot be
+     * opened due to resource restrictions.
+     * @throws SecurityException thrown if the synthesizer cannot be
+     * opened due to security restrictions.
+     *
+     * @see #close
+     * @see #isOpen
+     */
+    public void open(SourceDataLine line, Map<String, Object> info)
+            throws MidiUnavailableException;
+
+    /**
+     * Opens the synthesizer and renders audio into returned
+     * <code>AudioInputStream</code>.
+     *
+     * <p>An application opening a synthesizer explicitly with this call
+     * has to close the synthesizer by calling {@link #close}. This is
+     * necessary to release system resources and allow applications to
+     * exit cleanly.
+     *
+     * <p>Note that some synthesizers, once closed, cannot be reopened.
+     * Attempts to reopen such a synthesizer will always result in
+     * a <code>MidiUnavailableException<code>.
+     *
+     * @param targetFormat specifies the <code>AudioFormat</code>
+     * used in returned <code>AudioInputStream</code>.
+     * @param info a <code>Map<String,Object></code> object containing
+     * properties for additional configuration supported by synthesizer.
+     * If <code>info</code> is null then default settings are used.
+     *
+     * @throws MidiUnavailableException thrown if the synthesizer cannot be
+     * opened due to resource restrictions.
+     * @throws SecurityException thrown if the synthesizer cannot be
+     * opened due to security restrictions.
+     *
+     * @see #close
+     * @see #isOpen
+     */
+    public AudioInputStream openStream(AudioFormat targetFormat,
+            Map<String, Object> info) throws MidiUnavailableException;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/classes/com/sun/media/sound/AudioSynthesizerPropertyInfo.java	Mon Jan 19 20:11:58 2009 +0300
@@ -0,0 +1,76 @@
+/*
+ * Copyright 2007 Sun Microsystems, Inc.  All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+package com.sun.media.sound;
+
+/**
+ * Information about property used in  opening <code>AudioSynthesizer</code>.
+ *
+ * @author Karl Helgason
+ */
+public class AudioSynthesizerPropertyInfo {
+
+    /**
+     * Constructs a <code>AudioSynthesizerPropertyInfo</code> object with a given
+     * name and value. The <code>description</code> and <code>choices</code>
+     * are intialized by <code>null</code> values.
+     *
+     * @param name the name of the property
+     * @param value the current value or class used for values.
+     *
+     */
+    public AudioSynthesizerPropertyInfo(String name, Object value) {
+        this.name = name;
+        this.value = value;
+        if (value instanceof Class)
+            valueClass = (Class)value;
+        else if (value != null)
+            valueClass = value.getClass();
+    }
+    /**
+     * The name of the property.
+     */
+    public String name;
+    /**
+     * A brief description of the property, which may be null.
+     */
+    public String description = null;
+    /**
+     * The <code>value</code> field specifies the current value of
+     * the property.
+     */
+    public Object value = null;
+    /**
+     * The <code>valueClass</code> field specifies class
+     * used in <code>value</code> field.
+     */
+    public Class valueClass = null;
+    /**
+     * An array of possible values if the value for the field
+     * <code>AudioSynthesizerPropertyInfo.value</code> may be selected
+     * from a particular set of values; otherwise null.
+     */
+    public Object[] choices = null;
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/classes/com/sun/media/sound/DLSInfo.java	Mon Jan 19 20:11:58 2009 +0300
@@ -0,0 +1,109 @@
+/*
+ * Copyright 2007 Sun Microsystems, Inc.  All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+package com.sun.media.sound;
+
+/**
+ * This class is used to store information  to describe soundbanks, instruments
+ * and samples. It is stored inside a "INFO" List Chunk inside DLS files.
+ *
+ * @author Karl Helgason
+ */
+public class DLSInfo {
+
+    /**
+     * (INAM) Title or subject.
+     */
+    public String name = "untitled";
+    /**
+     * (ICRD) Date of creation, the format is: YYYY-MM-DD.
+     *        For example 2007-01-01 for 1. january of year 2007.
+     */
+    public String creationDate = null;
+    /**
+     * (IENG) Name of engineer who created the object.
+     */
+    public String engineers = null;
+    /**
+     * (IPRD) Name of the product which the object is intended for.
+     */
+    public String product = null;
+    /**
+     * (ICOP) Copyright information.
+     */
+    public String copyright = null;
+    /**
+     * (ICMT) General comments. Doesn't contain newline characters.
+     */
+    public String comments = null;
+    /**
+     * (ISFT) Name of software package used to create the file.
+     */
+    public String tools = null;
+    /**
+     * (IARL) Where content is archived.
+     */
+    public String archival_location = null;
+    /**
+     * (IART) Artists of original content.
+     */
+    public String artist = null;
+    /**
+     * (ICMS) Names of persons or orginizations who commissioned the file.
+     */
+    public String commissioned = null;
+    /**
+     * (IGNR) Genre of the work.
+     *        Example: jazz, classical, rock, etc.
+     */
+    public String genre = null;
+    /**
+     * (IKEY) List of keyword that describe the content.
+     *        Examples: FX, bird, piano, etc.
+     */
+    public String keywords = null;
+    /**
+     * (IMED) Describes original medium of the data.
+     *        For example: record, CD, etc.
+     */
+    public String medium = null;
+    /**
+     * (ISBJ) Description of the content.
+     */
+    public String subject = null;
+    /**
+     * (ISRC) Name of person or orginization who supplied
+     *        orginal material for the file.
+     */
+    public String source = null;
+    /**
+     * (ISRF) Source media for sample data is from.
+     *        For example: CD, TV, etc.
+     */
+    public String source_form = null;
+    /**
+     * (ITCH) Technician who sample the file/object.
+     */
+    public String technician = null;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/classes/com/sun/media/sound/DLSInstrument.java	Mon Jan 19 20:11:58 2009 +0300
@@ -0,0 +1,448 @@
+/*
+ * Copyright 2007 Sun Microsystems, Inc.  All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+package com.sun.media.sound;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import javax.sound.midi.Patch;
+
+/**
+ * This class is used to store information to describe instrument.
+ * It contains list of regions and modulators.
+ * It is stored inside a "ins " List Chunk inside DLS files.
+ * In the DLS documentation a modulator is called articulator.
+ *
+ * @author Karl Helgason
+ */
+public class DLSInstrument extends ModelInstrument {
+
+    protected int preset = 0;
+    protected int bank = 0;
+    protected boolean druminstrument = false;
+    protected byte[] guid = null;
+    protected DLSInfo info = new DLSInfo();
+    protected List<DLSRegion> regions = new ArrayList<DLSRegion>();
+    protected List<DLSModulator> modulators = new ArrayList<DLSModulator>();
+
+    public DLSInstrument() {
+        super(null, null, null, null);
+    }
+
+    public DLSInstrument(DLSSoundbank soundbank) {
+        super(soundbank, null, null, null);
+    }
+
+    public DLSInfo getInfo() {
+        return info;
+    }
+
+    public String getName() {
+        return info.name;
+    }
+
+    public void setName(String name) {
+        info.name = name;
+    }
+
+    public ModelPatch getPatch() {
+        return new ModelPatch(bank, preset, druminstrument);
+    }
+
+    public void setPatch(Patch patch) {
+        if (patch instanceof ModelPatch && ((ModelPatch)patch).isPercussion()) {
+            druminstrument = true;
+            bank = patch.getBank();
+            preset = patch.getProgram();
+        } else {
+            druminstrument = false;
+            bank = patch.getBank();
+            preset = patch.getProgram();
+        }
+    }
+
+    public Object getData() {
+        return null;
+    }
+
+    public List<DLSRegion> getRegions() {
+        return regions;
+    }
+
+    public List<DLSModulator> getModulators() {
+        return modulators;
+    }
+
+    public String toString() {
+        if (druminstrument)
+            return "Drumkit: " + info.name
+                    + " bank #" + bank + " preset #" + preset;
+        else
+            return "Instrument: " + info.name
+                    + " bank #" + bank + " preset #" + preset;
+    }
+
+    private ModelIdentifier convertToModelDest(int dest) {
+        if (dest == DLSModulator.CONN_DST_NONE)
+            return null;
+        if (dest == DLSModulator.CONN_DST_GAIN)
+            return ModelDestination.DESTINATION_GAIN;
+        if (dest == DLSModulator.CONN_DST_PITCH)
+            return ModelDestination.DESTINATION_PITCH;
+        if (dest == DLSModulator.CONN_DST_PAN)
+            return ModelDestination.DESTINATION_PAN;
+
+        if (dest == DLSModulator.CONN_DST_LFO_FREQUENCY)
+            return ModelDestination.DESTINATION_LFO1_FREQ;
+        if (dest == DLSModulator.CONN_DST_LFO_STARTDELAY)
+            return ModelDestination.DESTINATION_LFO1_DELAY;
+
+        if (dest == DLSModulator.CONN_DST_EG1_ATTACKTIME)
+            return ModelDestination.DESTINATION_EG1_ATTACK;
+        if (dest == DLSModulator.CONN_DST_EG1_DECAYTIME)
+            return ModelDestination.DESTINATION_EG1_DECAY;
+        if (dest == DLSModulator.CONN_DST_EG1_RELEASETIME)
+            return ModelDestination.DESTINATION_EG1_RELEASE;
+        if (dest == DLSModulator.CONN_DST_EG1_SUSTAINLEVEL)
+            return ModelDestination.DESTINATION_EG1_SUSTAIN;
+
+        if (dest == DLSModulator.CONN_DST_EG2_ATTACKTIME)
+            return ModelDestination.DESTINATION_EG2_ATTACK;
+        if (dest == DLSModulator.CONN_DST_EG2_DECAYTIME)
+            return ModelDestination.DESTINATION_EG2_DECAY;
+        if (dest == DLSModulator.CONN_DST_EG2_RELEASETIME)
+            return ModelDestination.DESTINATION_EG2_RELEASE;
+        if (dest == DLSModulator.CONN_DST_EG2_SUSTAINLEVEL)
+            return ModelDestination.DESTINATION_EG2_SUSTAIN;
+
+        // DLS2 Destinations
+        if (dest == DLSModulator.CONN_DST_KEYNUMBER)
+            return ModelDestination.DESTINATION_KEYNUMBER;
+
+        if (dest == DLSModulator.CONN_DST_CHORUS)
+            return ModelDestination.DESTINATION_CHORUS;
+        if (dest == DLSModulator.CONN_DST_REVERB)
+            return ModelDestination.DESTINATION_REVERB;
+
+        if (dest == DLSModulator.CONN_DST_VIB_FREQUENCY)
+            return ModelDestination.DESTINATION_LFO2_FREQ;
+        if (dest == DLSModulator.CONN_DST_VIB_STARTDELAY)
+            return ModelDestination.DESTINATION_LFO2_DELAY;
+
+        if (dest == DLSModulator.CONN_DST_EG1_DELAYTIME)
+            return ModelDestination.DESTINATION_EG1_DELAY;
+        if (dest == DLSModulator.CONN_DST_EG1_HOLDTIME)
+            return ModelDestination.DESTINATION_EG1_HOLD;
+        if (dest == DLSModulator.CONN_DST_EG1_SHUTDOWNTIME)
+            return ModelDestination.DESTINATION_EG1_SHUTDOWN;
+
+        if (dest == DLSModulator.CONN_DST_EG2_DELAYTIME)
+            return ModelDestination.DESTINATION_EG2_DELAY;
+        if (dest == DLSModulator.CONN_DST_EG2_HOLDTIME)
+            return ModelDestination.DESTINATION_EG2_HOLD;
+
+        if (dest == DLSModulator.CONN_DST_FILTER_CUTOFF)
+            return ModelDestination.DESTINATION_FILTER_FREQ;
+        if (dest == DLSModulator.CONN_DST_FILTER_Q)
+            return ModelDestination.DESTINATION_FILTER_Q;
+
+        return null;
+    }
+
+    private ModelIdentifier convertToModelSrc(int src) {
+        if (src == DLSModulator.CONN_SRC_NONE)
+            return null;
+
+        if (src == DLSModulator.CONN_SRC_LFO)
+            return ModelSource.SOURCE_LFO1;
+        if (src == DLSModulator.CONN_SRC_KEYONVELOCITY)
+            return ModelSource.SOURCE_NOTEON_VELOCITY;
+        if (src == DLSModulator.CONN_SRC_KEYNUMBER)
+            return ModelSource.SOURCE_NOTEON_KEYNUMBER;
+        if (src == DLSModulator.CONN_SRC_EG1)
+            return ModelSource.SOURCE_EG1;
+        if (src == DLSModulator.CONN_SRC_EG2)
+            return ModelSource.SOURCE_EG2;
+        if (src == DLSModulator.CONN_SRC_PITCHWHEEL)
+            return ModelSource.SOURCE_MIDI_PITCH;
+        if (src == DLSModulator.CONN_SRC_CC1)
+            return new ModelIdentifier("midi_cc", "1", 0);
+        if (src == DLSModulator.CONN_SRC_CC7)
+            return new ModelIdentifier("midi_cc", "7", 0);
+        if (src == DLSModulator.CONN_SRC_CC10)
+            return new ModelIdentifier("midi_cc", "10", 0);
+        if (src == DLSModulator.CONN_SRC_CC11)
+            return new ModelIdentifier("midi_cc", "11", 0);
+        if (src == DLSModulator.CONN_SRC_RPN0)
+            return new ModelIdentifier("midi_rpn", "0", 0);
+        if (src == DLSModulator.CONN_SRC_RPN1)
+            return new ModelIdentifier("midi_rpn", "1", 0);
+
+        if (src == DLSModulator.CONN_SRC_POLYPRESSURE)
+            return ModelSource.SOURCE_MIDI_POLY_PRESSURE;
+        if (src == DLSModulator.CONN_SRC_CHANNELPRESSURE)
+            return ModelSource.SOURCE_MIDI_CHANNEL_PRESSURE;
+        if (src == DLSModulator.CONN_SRC_VIBRATO)
+            return ModelSource.SOURCE_LFO2;
+        if (src == DLSModulator.CONN_SRC_MONOPRESSURE)
+            return ModelSource.SOURCE_MIDI_CHANNEL_PRESSURE;
+
+        if (src == DLSModulator.CONN_SRC_CC91)
+            return new ModelIdentifier("midi_cc", "91", 0);
+        if (src == DLSModulator.CONN_SRC_CC93)
+            return new ModelIdentifier("midi_cc", "93", 0);
+
+        return null;
+    }
+
+    private ModelConnectionBlock convertToModel(DLSModulator mod) {
+        ModelIdentifier source = convertToModelSrc(mod.getSource());
+        ModelIdentifier control = convertToModelSrc(mod.getControl());
+        ModelIdentifier destination_id =
+                convertToModelDest(mod.getDestination());
+
+        int scale = mod.getScale();
+        double f_scale;
+        if (scale == Integer.MIN_VALUE)
+            f_scale = Double.NEGATIVE_INFINITY;
+        else
+            f_scale = scale / 65536.0;
+
+        if (destination_id != null) {
+            ModelSource src = null;
+            ModelSource ctrl = null;
+            ModelConnectionBlock block = new ModelConnectionBlock();
+            if (control != null) {
+                ModelSource s = new ModelSource();
+                if (control == ModelSource.SOURCE_MIDI_PITCH) {
+                    ((ModelStandardTransform)s.getTransform()).setPolarity(
+                            ModelStandardTransform.POLARITY_BIPOLAR);
+                } else if (control == ModelSource.SOURCE_LFO1
+                        || control == ModelSource.SOURCE_LFO2) {
+                    ((ModelStandardTransform)s.getTransform()).setPolarity(
+                            ModelStandardTransform.POLARITY_BIPOLAR);
+                }
+                s.setIdentifier(control);
+                block.addSource(s);
+                ctrl = s;
+            }
+            if (source != null) {
+                ModelSource s = new ModelSource();
+                if (source == ModelSource.SOURCE_MIDI_PITCH) {
+                    ((ModelStandardTransform)s.getTransform()).setPolarity(
+                            ModelStandardTransform.POLARITY_BIPOLAR);
+                } else if (source == ModelSource.SOURCE_LFO1
+                        || source == ModelSource.SOURCE_LFO2) {
+                    ((ModelStandardTransform)s.getTransform()).setPolarity(
+                            ModelStandardTransform.POLARITY_BIPOLAR);
+                }
+                s.setIdentifier(source);
+                block.addSource(s);
+                src = s;
+            }
+            ModelDestination destination = new ModelDestination();
+            destination.setIdentifier(destination_id);
+            block.setDestination(destination);
+
+            if (mod.getVersion() == 1) {
+                //if (mod.getTransform() ==  DLSModulator.CONN_TRN_CONCAVE) {
+                //    ((ModelStandardTransform)destination.getTransform())
+                //            .setTransform(
+                //            ModelStandardTransform.TRANSFORM_CONCAVE);
+                //}
+                if (mod.getTransform() == DLSModulator.CONN_TRN_CONCAVE) {
+                    if (src != null) {
+                        ((ModelStandardTransform)src.getTransform())
+                                .setTransform(
+                                    ModelStandardTransform.TRANSFORM_CONCAVE);
+                        ((ModelStandardTransform)src.getTransform())
+                                .setDirection(
+                                    ModelStandardTransform.DIRECTION_MAX2MIN);
+                    }
+                    if (ctrl != null) {
+                        ((ModelStandardTransform)ctrl.getTransform())
+                                .setTransform(
+                                    ModelStandardTransform.TRANSFORM_CONCAVE);
+                        ((ModelStandardTransform)ctrl.getTransform())
+                                .setDirection(
+                                    ModelStandardTransform.DIRECTION_MAX2MIN);
+                    }
+                }
+
+            } else if (mod.getVersion() == 2) {
+                int transform = mod.getTransform();
+                int src_transform_invert = (transform >> 15) & 1;
+                int src_transform_bipolar = (transform >> 14) & 1;
+                int src_transform = (transform >> 10) & 8;
+                int ctr_transform_invert = (transform >> 9) & 1;
+                int ctr_transform_bipolar = (transform >> 8) & 1;
+                int ctr_transform = (transform >> 4) & 8;
+
+
+                if (src != null) {
+                    int trans = ModelStandardTransform.TRANSFORM_LINEAR;
+                    if (src_transform == DLSModulator.CONN_TRN_SWITCH)
+                        trans = ModelStandardTransform.TRANSFORM_SWITCH;
+                    if (src_transform == DLSModulator.CONN_TRN_CONCAVE)
+                        trans = ModelStandardTransform.TRANSFORM_CONCAVE;
+                    if (src_transform == DLSModulator.CONN_TRN_CONVEX)
+                        trans = ModelStandardTransform.TRANSFORM_CONVEX;
+                    ((ModelStandardTransform)src.getTransform())
+                            .setTransform(trans);
+                    ((ModelStandardTransform)src.getTransform())
+                            .setPolarity(src_transform_bipolar == 1);
+                    ((ModelStandardTransform)src.getTransform())
+                            .setDirection(src_transform_invert == 1);
+
+                }
+
+                if (ctrl != null) {
+                    int trans = ModelStandardTransform.TRANSFORM_LINEAR;
+                    if (ctr_transform == DLSModulator.CONN_TRN_SWITCH)
+                        trans = ModelStandardTransform.TRANSFORM_SWITCH;
+                    if (ctr_transform == DLSModulator.CONN_TRN_CONCAVE)
+                        trans = ModelStandardTransform.TRANSFORM_CONCAVE;
+                    if (ctr_transform == DLSModulator.CONN_TRN_CONVEX)
+                        trans = ModelStandardTransform.TRANSFORM_CONVEX;
+                    ((ModelStandardTransform)ctrl.getTransform())
+                            .setTransform(trans);
+                    ((ModelStandardTransform)ctrl.getTransform())
+                            .setPolarity(ctr_transform_bipolar == 1);
+                    ((ModelStandardTransform)ctrl.getTransform())
+                            .setDirection(ctr_transform_invert == 1);
+                }
+
+                /* No output transforms are defined the DLS Level 2
+                int out_transform = transform % 8;
+                int trans = ModelStandardTransform.TRANSFORM_LINEAR;
+                if (out_transform == DLSModulator.CONN_TRN_SWITCH)
+                    trans = ModelStandardTransform.TRANSFORM_SWITCH;
+                if (out_transform == DLSModulator.CONN_TRN_CONCAVE)
+                    trans = ModelStandardTransform.TRANSFORM_CONCAVE;
+                if (out_transform == DLSModulator.CONN_TRN_CONVEX)
+                    trans = ModelStandardTransform.TRANSFORM_CONVEX;
+                if (ctrl != null) {
+                    ((ModelStandardTransform)destination.getTransform())
+                            .setTransform(trans);
+                }
+                */
+
+            }
+
+            block.setScale(f_scale);
+
+            return block;
+        }
+
+        return null;
+    }
+
+    public ModelPerformer[] getPerformers() {
+        List<ModelPerformer> performers = new ArrayList<ModelPerformer>();
+
+        Map<String, DLSModulator> modmap = new HashMap<String, DLSModulator>();
+        for (DLSModulator mod: getModulators()) {
+            modmap.put(mod.getSource() + "x" + mod.getControl() + "=" +
+                    mod.getDestination(), mod);
+        }
+
+        Map<String, DLSModulator> insmodmap =
+                new HashMap<String, DLSModulator>();
+
+        for (DLSRegion zone: regions) {
+            ModelPerformer performer = new ModelPerformer();
+            performer.setName(zone.getSample().getName());
+            performer.setSelfNonExclusive((zone.getFusoptions() &
+                    DLSRegion.OPTION_SELFNONEXCLUSIVE) != 0);
+            performer.setExclusiveClass(zone.getExclusiveClass());
+            performer.setKeyFrom(zone.getKeyfrom());
+            performer.setKeyTo(zone.getKeyto());
+            performer.setVelFrom(zone.getVelfrom());
+            performer.setVelTo(zone.getVelto());
+
+            insmodmap.clear();
+            insmodmap.putAll(modmap);
+            for (DLSModulator mod: zone.getModulators()) {
+                insmodmap.put(mod.getSource() + "x" + mod.getControl() + "=" +
+                        mod.getDestination(), mod);
+            }
+
+            List<ModelConnectionBlock> blocks = performer.getConnectionBlocks();
+            for (DLSModulator mod: insmodmap.values()) {
+                ModelConnectionBlock p = convertToModel(mod);
+                if (p != null)
+                    blocks.add(p);
+            }
+
+
+            DLSSample sample = zone.getSample();
+            DLSSampleOptions sampleopt = zone.getSampleoptions();
+            if (sampleopt == null)
+                sampleopt = sample.getSampleoptions();
+
+            ModelByteBuffer buff = sample.getDataBuffer();
+
+            float pitchcorrection = (-sampleopt.unitynote * 100) +
+                    sampleopt.finetune;
+
+            ModelByteBufferWavetable osc = new ModelByteBufferWavetable(buff,
+                    sample.getFormat(), pitchcorrection);
+            osc.setAttenuation(osc.getAttenuation() / 65536f);
+            if (sampleopt.getLoops().size() != 0) {
+                DLSSampleLoop loop = sampleopt.getLoops().get(0);
+                osc.setLoopStart((int)loop.getStart());
+                osc.setLoopLength((int)loop.getLength());
+                if (loop.getType() == DLSSampleLoop.LOOP_TYPE_FORWARD)
+                    osc.setLoopType(ModelWavetable.LOOP_TYPE_FORWARD);
+                if (loop.getType() == DLSSampleLoop.LOOP_TYPE_RELEASE)
+                    osc.setLoopType(ModelWavetable.LOOP_TYPE_RELEASE);
+                else
+                    osc.setLoopType(ModelWavetable.LOOP_TYPE_FORWARD);
+            }
+
+            performer.getConnectionBlocks().add(
+                    new ModelConnectionBlock(SoftFilter.FILTERTYPE_LP12,
+                        new ModelDestination(
+                            new ModelIdentifier("filter", "type", 1))));
+
+            performer.getOscillators().add(osc);
+
+            performers.add(performer);
+
+        }
+
+        return performers.toArray(new ModelPerformer[performers.size()]);
+    }
+
+    public byte[] getGuid() {
+        return guid;
+    }
+
+    public void setGuid(byte[] guid) {
+        this.guid = guid;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/classes/com/sun/media/sound/DLSModulator.java	Mon Jan 19 20:11:58 2009 +0300
@@ -0,0 +1,351 @@
+/*
+ * Copyright 2007 Sun Microsystems, Inc.  All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+package com.sun.media.sound;
+
+/**
+ * This class is used to store modulator/artiuclation data.
+ * A modulator connects one synthesizer source to
+ * a destination. For example a note on velocity
+ * can be mapped to the gain of the synthesized voice.
+ * It is stored as a "art1" or "art2" chunk inside DLS files.
+ *
+ * @author Karl Helgason
+ */
+public class DLSModulator {
+
+    // DLS1 Destinations
+    public static final int CONN_DST_NONE = 0x000; // 0
+    public static final int CONN_DST_GAIN = 0x001; // cB
+    public static final int CONN_DST_PITCH = 0x003; // cent
+    public static final int CONN_DST_PAN = 0x004; // 0.1%
+    public static final int CONN_DST_LFO_FREQUENCY = 0x104; // cent (default 5 Hz)
+    public static final int CONN_DST_LFO_STARTDELAY = 0x105; // timecent
+    public static final int CONN_DST_EG1_ATTACKTIME = 0x206; // timecent
+    public static final int CONN_DST_EG1_DECAYTIME = 0x207; // timecent
+    public static final int CONN_DST_EG1_RELEASETIME = 0x209; // timecent
+    public static final int CONN_DST_EG1_SUSTAINLEVEL = 0x20A; // 0.1%
+    public static final int CONN_DST_EG2_ATTACKTIME = 0x30A; // timecent
+    public static final int CONN_DST_EG2_DECAYTIME = 0x30B; // timecent
+    public static final int CONN_DST_EG2_RELEASETIME = 0x30D; // timecent
+    public static final int CONN_DST_EG2_SUSTAINLEVEL = 0x30E; // 0.1%
+    // DLS2 Destinations
+    public static final int CONN_DST_KEYNUMBER = 0x005;
+    public static final int CONN_DST_LEFT = 0x010; // 0.1%
+    public static final int CONN_DST_RIGHT = 0x011; // 0.1%
+    public static final int CONN_DST_CENTER = 0x012; // 0.1%
+    public static final int CONN_DST_LEFTREAR = 0x013; // 0.1%
+    public static final int CONN_DST_RIGHTREAR = 0x014; // 0.1%
+    public static final int CONN_DST_LFE_CHANNEL = 0x015; // 0.1%
+    public static final int CONN_DST_CHORUS = 0x080; // 0.1%
+    public static final int CONN_DST_REVERB = 0x081; // 0.1%
+    public static final int CONN_DST_VIB_FREQUENCY = 0x114; // cent
+    public static final int CONN_DST_VIB_STARTDELAY = 0x115; // dB
+    public static final int CONN_DST_EG1_DELAYTIME = 0x20B; // timecent
+    public static final int CONN_DST_EG1_HOLDTIME = 0x20C; // timecent
+    public static final int CONN_DST_EG1_SHUTDOWNTIME = 0x20D; // timecent
+    public static final int CONN_DST_EG2_DELAYTIME = 0x30F; // timecent
+    public static final int CONN_DST_EG2_HOLDTIME = 0x310; // timecent
+    public static final int CONN_DST_FILTER_CUTOFF = 0x500; // cent
+    public static final int CONN_DST_FILTER_Q = 0x501; // dB
+
+    // DLS1 Sources
+    public static final int CONN_SRC_NONE = 0x000; // 1
+    public static final int CONN_SRC_LFO = 0x001; // linear (sine wave)
+    public static final int CONN_SRC_KEYONVELOCITY = 0x002; // ??db or velocity??
+    public static final int CONN_SRC_KEYNUMBER = 0x003; // ??cent or keynumber??
+    public static final int CONN_SRC_EG1 = 0x004; // linear direct from eg
+    public static final int CONN_SRC_EG2 = 0x005; // linear direct from eg
+    public static final int CONN_SRC_PITCHWHEEL = 0x006; // linear -1..1
+    public static final int CONN_SRC_CC1 = 0x081; // linear 0..1
+    public static final int CONN_SRC_CC7 = 0x087; // linear 0..1
+    public static final int CONN_SRC_CC10 = 0x08A; // linear 0..1
+    public static final int CONN_SRC_CC11 = 0x08B; // linear 0..1
+    public static final int CONN_SRC_RPN0 = 0x100; // ?? // Pitch Bend Range
+    public static final int CONN_SRC_RPN1 = 0x101; // ?? // Fine Tune
+    public static final int CONN_SRC_RPN2 = 0x102; // ?? // Course Tune
+    // DLS2 Sources
+    public static final int CONN_SRC_POLYPRESSURE = 0x007; // linear 0..1
+    public static final int CONN_SRC_CHANNELPRESSURE = 0x008; // linear 0..1
+    public static final int CONN_SRC_VIBRATO = 0x009; // linear 0..1
+    public static final int CONN_SRC_MONOPRESSURE = 0x00A; // linear 0..1
+    public static final int CONN_SRC_CC91 = 0x0DB; // linear 0..1
+    public static final int CONN_SRC_CC93 = 0x0DD; // linear 0..1
+    // DLS1 Transforms
+    public static final int CONN_TRN_NONE = 0x000;
+    public static final int CONN_TRN_CONCAVE = 0x001;
+    // DLS2 Transforms
+    public static final int CONN_TRN_CONVEX = 0x002;
+    public static final int CONN_TRN_SWITCH = 0x003;
+    public static final int DST_FORMAT_CB = 1;
+    public static final int DST_FORMAT_CENT = 1;
+    public static final int DST_FORMAT_TIMECENT = 2;
+    public static final int DST_FORMAT_PERCENT = 3;
+    protected int source;
+    protected int control;
+    protected int destination;
+    protected int transform;
+    protected int scale;
+    protected int version = 1;
+
+    public int getControl() {
+        return control;
+    }
+
+    public void setControl(int control) {
+        this.control = control;
+    }
+
+    public static int getDestinationFormat(int destination) {
+
+        if (destination == CONN_DST_GAIN)
+            return DST_FORMAT_CB;
+        if (destination == CONN_DST_PITCH)
+            return DST_FORMAT_CENT;
+        if (destination == CONN_DST_PAN)
+            return DST_FORMAT_PERCENT;
+
+        if (destination == CONN_DST_LFO_FREQUENCY)
+            return DST_FORMAT_CENT;
+        if (destination == CONN_DST_LFO_STARTDELAY)
+            return DST_FORMAT_TIMECENT;
+
+        if (destination == CONN_DST_EG1_ATTACKTIME)
+            return DST_FORMAT_TIMECENT;
+        if (destination == CONN_DST_EG1_DECAYTIME)
+            return DST_FORMAT_TIMECENT;
+        if (destination == CONN_DST_EG1_RELEASETIME)
+            return DST_FORMAT_TIMECENT;
+        if (destination == CONN_DST_EG1_SUSTAINLEVEL)
+            return DST_FORMAT_PERCENT;
+
+        if (destination == CONN_DST_EG2_ATTACKTIME)
+            return DST_FORMAT_TIMECENT;
+        if (destination == CONN_DST_EG2_DECAYTIME)
+            return DST_FORMAT_TIMECENT;
+        if (destination == CONN_DST_EG2_RELEASETIME)
+            return DST_FORMAT_TIMECENT;
+        if (destination == CONN_DST_EG2_SUSTAINLEVEL)
+            return DST_FORMAT_PERCENT;
+
+        if (destination == CONN_DST_KEYNUMBER)
+            return DST_FORMAT_CENT; // NOT SURE WITHOUT DLS 2 SPEC
+        if (destination == CONN_DST_LEFT)
+            return DST_FORMAT_CB;
+        if (destination == CONN_DST_RIGHT)
+            return DST_FORMAT_CB;
+        if (destination == CONN_DST_CENTER)
+            return DST_FORMAT_CB;
+        if (destination == CONN_DST_LEFTREAR)
+            return DST_FORMAT_CB;
+        if (destination == CONN_DST_RIGHTREAR)
+            return DST_FORMAT_CB;
+        if (destination == CONN_DST_LFE_CHANNEL)
+            return DST_FORMAT_CB;
+        if (destination == CONN_DST_CHORUS)
+            return DST_FORMAT_PERCENT;
+        if (destination == CONN_DST_REVERB)
+            return DST_FORMAT_PERCENT;
+
+        if (destination == CONN_DST_VIB_FREQUENCY)
+            return DST_FORMAT_CENT;
+        if (destination == CONN_DST_VIB_STARTDELAY)
+            return DST_FORMAT_TIMECENT;
+
+        if (destination == CONN_DST_EG1_DELAYTIME)
+            return DST_FORMAT_TIMECENT;
+        if (destination == CONN_DST_EG1_HOLDTIME)
+            return DST_FORMAT_TIMECENT;
+        if (destination == CONN_DST_EG1_SHUTDOWNTIME)
+            return DST_FORMAT_TIMECENT;
+
+        if (destination == CONN_DST_EG2_DELAYTIME)
+            return DST_FORMAT_TIMECENT;
+        if (destination == CONN_DST_EG2_HOLDTIME)
+            return DST_FORMAT_TIMECENT;
+
+        if (destination == CONN_DST_FILTER_CUTOFF)
+            return DST_FORMAT_CENT;
+        if (destination == CONN_DST_FILTER_Q)
+            return DST_FORMAT_CB;
+
+        return -1;
+    }
+
+    public static String getDestinationName(int destination) {
+
+        if (destination == CONN_DST_GAIN)
+            return "gain";
+        if (destination == CONN_DST_PITCH)
+            return "pitch";
+        if (destination == CONN_DST_PAN)
+            return "pan";
+
+        if (destination == CONN_DST_LFO_FREQUENCY)
+            return "lfo1.freq";
+        if (destination == CONN_DST_LFO_STARTDELAY)
+            return "lfo1.delay";
+
+        if (destination == CONN_DST_EG1_ATTACKTIME)
+            return "eg1.attack";
+        if (destination == CONN_DST_EG1_DECAYTIME)
+            return "eg1.decay";
+        if (destination == CONN_DST_EG1_RELEASETIME)
+            return "eg1.release";
+        if (destination == CONN_DST_EG1_SUSTAINLEVEL)
+            return "eg1.sustain";
+
+        if (destination == CONN_DST_EG2_ATTACKTIME)
+            return "eg2.attack";
+        if (destination == CONN_DST_EG2_DECAYTIME)
+            return "eg2.decay";
+        if (destination == CONN_DST_EG2_RELEASETIME)
+            return "eg2.release";
+        if (destination == CONN_DST_EG2_SUSTAINLEVEL)
+            return "eg2.sustain";
+
+        if (destination == CONN_DST_KEYNUMBER)
+            return "keynumber";
+        if (destination == CONN_DST_LEFT)
+            return "left";
+        if (destination == CONN_DST_RIGHT)
+            return "right";
+        if (destination == CONN_DST_CENTER)
+            return "center";
+        if (destination == CONN_DST_LEFTREAR)
+            return "leftrear";
+        if (destination == CONN_DST_RIGHTREAR)
+            return "rightrear";
+        if (destination == CONN_DST_LFE_CHANNEL)
+            return "lfe_channel";
+        if (destination == CONN_DST_CHORUS)
+            return "chorus";
+        if (destination == CONN_DST_REVERB)
+            return "reverb";
+
+        if (destination == CONN_DST_VIB_FREQUENCY)
+            return "vib.freq";
+        if (destination == CONN_DST_VIB_STARTDELAY)
+            return "vib.delay";
+
+        if (destination == CONN_DST_EG1_DELAYTIME)
+            return "eg1.delay";
+        if (destination == CONN_DST_EG1_HOLDTIME)
+            return "eg1.hold";
+        if (destination == CONN_DST_EG1_SHUTDOWNTIME)
+            return "eg1.shutdown";
+
+        if (destination == CONN_DST_EG2_DELAYTIME)
+            return "eg2.delay";
+        if (destination == CONN_DST_EG2_HOLDTIME)
+            return "eg.2hold";
+
+        if (destination == CONN_DST_FILTER_CUTOFF)
+            return "filter.cutoff"; // NOT SURE WITHOUT DLS 2 SPEC
+        if (destination == CONN_DST_FILTER_Q)
+            return "filter.q"; // NOT SURE WITHOUT DLS 2 SPEC
+
+        return null;
+    }
+
+    public static String getSourceName(int source) {
+
+        if (source == CONN_SRC_NONE)
+            return "none";
+        if (source == CONN_SRC_LFO)
+            return "lfo";
+        if (source == CONN_SRC_KEYONVELOCITY)
+            return "keyonvelocity";
+        if (source == CONN_SRC_KEYNUMBER)
+            return "keynumber";
+        if (source == CONN_SRC_EG1)
+            return "eg1";
+        if (source == CONN_SRC_EG2)
+            return "eg2";
+        if (source == CONN_SRC_PITCHWHEEL)
+            return "pitchweel";
+        if (source == CONN_SRC_CC1)
+            return "cc1";
+        if (source == CONN_SRC_CC7)
+            return "cc7";
+        if (source == CONN_SRC_CC10)
+            return "c10";
+        if (source == CONN_SRC_CC11)
+            return "cc11";
+
+        if (source == CONN_SRC_POLYPRESSURE)
+            return "polypressure";
+        if (source == CONN_SRC_CHANNELPRESSURE)
+            return "channelpressure";
+        if (source == CONN_SRC_VIBRATO)
+            return "vibrato";
+        if (source == CONN_SRC_MONOPRESSURE)
+            return "monopressure";
+        if (source == CONN_SRC_CC91)
+            return "cc91";
+        if (source == CONN_SRC_CC93)
+            return "cc93";
+        return null;
+    }
+
+    public int getDestination() {
+        return destination;
+    }
+
+    public void setDestination(int destination) {
+        this.destination = destination;
+    }
+
+    public int getScale() {
+        return scale;
+    }
+
+    public void setScale(int scale) {
+        this.scale = scale;
+    }
+
+    public int getSource() {
+        return source;
+    }
+
+    public void setSource(int source) {
+        this.source = source;
+    }
+
+    public int getVersion() {
+        return version;
+    }
+
+    public void setVersion(int version) {
+        this.version = version;
+    }
+
+    public int getTransform() {
+        return transform;
+    }
+
+    public void setTransform(int transform) {
+        this.transform = transform;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/classes/com/sun/media/sound/DLSRegion.java	Mon Jan 19 20:11:58 2009 +0300
@@ -0,0 +1,150 @@
+/*
+ * Copyright 2007 Sun Microsystems, Inc.  All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+package com.sun.media.sound;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * This class is used to store region parts for instrument.
+ * A region has a velocity and key range which it response to.
+ * And it has a list of modulators/articulators which
+ * is used how to synthesize a single voice.
+ * It is stored inside a "rgn " List Chunk inside DLS files.
+ *
+ * @author Karl Helgason
+ */
+public class DLSRegion {
+
+    public final static int OPTION_SELFNONEXCLUSIVE = 0x0001;
+    protected List<DLSModulator> modulators = new ArrayList<DLSModulator>();
+    protected int keyfrom;
+    protected int keyto;
+    protected int velfrom;
+    protected int velto;
+    protected int options;
+    protected int exclusiveClass;
+    protected int fusoptions;
+    protected int phasegroup;
+    protected long channel;
+    protected DLSSample sample = null;
+    protected DLSSampleOptions sampleoptions;
+
+    public List<DLSModulator> getModulators() {
+        return modulators;
+    }
+
+    public long getChannel() {
+        return channel;
+    }
+
+    public void setChannel(long channel) {
+        this.channel = channel;
+    }
+
+    public int getExclusiveClass() {
+        return exclusiveClass;
+    }
+
+    public void setExclusiveClass(int exclusiveClass) {
+        this.exclusiveClass = exclusiveClass;
+    }
+
+    public int getFusoptions() {
+        return fusoptions;
+    }
+
+    public void setFusoptions(int fusoptions) {
+        this.fusoptions = fusoptions;
+    }
+
+    public int getKeyfrom() {
+        return keyfrom;
+    }
+
+    public void setKeyfrom(int keyfrom) {
+        this.keyfrom = keyfrom;
+    }
+
+    public int getKeyto() {
+        return keyto;
+    }
+
+    public void setKeyto(int keyto) {
+        this.keyto = keyto;
+    }
+
+    public int getOptions() {
+        return options;
+    }
+
+    public void setOptions(int options) {
+        this.options = options;
+    }
+
+    public int getPhasegroup() {
+        return phasegroup;
+    }
+
+    public void setPhasegroup(int phasegroup) {
+        this.phasegroup = phasegroup;
+    }
+
+    public DLSSample getSample() {
+        return sample;
+    }
+
+    public void setSample(DLSSample sample) {
+        this.sample = sample;
+    }
+
+    public int getVelfrom() {
+        return velfrom;
+    }
+
+    public void setVelfrom(int velfrom) {
+        this.velfrom = velfrom;
+    }
+
+    public int getVelto() {
+        return velto;
+    }
+
+    public void setVelto(int velto) {
+        this.velto = velto;
+    }
+
+    public void setModulators(List<DLSModulator> modulators) {
+        this.modulators = modulators;
+    }
+
+    public DLSSampleOptions getSampleoptions() {
+        return sampleoptions;
+    }
+
+    public void setSampleoptions(DLSSampleOptions sampleOptions) {
+        this.sampleoptions = sampleOptions;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/classes/com/sun/media/sound/DLSSample.java	Mon Jan 19 20:11:58 2009 +0300
@@ -0,0 +1,122 @@
+/*
+ * Copyright 2007 Sun Microsystems, Inc.  All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+package com.sun.media.sound;
+
+import java.io.InputStream;
+import javax.sound.midi.Soundbank;
+import javax.sound.midi.SoundbankResource;
+import javax.sound.sampled.AudioFormat;
+import javax.sound.sampled.AudioInputStream;
+
+/**
+ * This class is used to store the sample data itself.
+ * A sample is encoded as PCM audio stream
+ * and in DLS Level 1 files it is always a mono 8/16 bit stream.
+ * They are stored just like RIFF WAVE files are stored.
+ * It is stored inside a "wave" List Chunk inside DLS files.
+ *
+ * @author Karl Helgason
+ */
+public class DLSSample extends SoundbankResource {
+
+    protected byte[] guid = null;
+    protected DLSInfo info = new DLSInfo();
+    protected DLSSampleOptions sampleoptions;
+    protected ModelByteBuffer data;
+    protected AudioFormat format;
+
+    public DLSSample(Soundbank soundBank) {
+        super(soundBank, null, AudioInputStream.class);
+    }
+
+    public DLSSample() {
+        super(null, null, AudioInputStream.class);
+    }
+
+    public DLSInfo getInfo() {
+        return info;
+    }
+
+    public Object getData() {
+        AudioFormat format = getFormat();
+
+        InputStream is = data.getInputStream();
+        if (is == null)
+            return null;
+        return new AudioInputStream(is, format, data.capacity());
+    }
+
+    public ModelByteBuffer getDataBuffer() {
+        return data;
+    }
+
+    public AudioFormat getFormat() {
+        return format;
+    }
+
+    public void setFormat(AudioFormat format) {
+        this.format = format;
+    }
+
+    public void setData(ModelByteBuffer data) {
+        this.data = data;
+    }
+
+    public void setData(byte[] data) {
+        this.data = new ModelByteBuffer(data);
+    }
+
+    public void setData(byte[] data, int offset, int length) {
+        this.data = new ModelByteBuffer(data, offset, length);
+    }
+
+    public String getName() {
+        return info.name;
+    }
+
+    public void setName(String name) {
+        info.name = name;
+    }
+
+    public DLSSampleOptions getSampleoptions() {
+        return sampleoptions;
+    }
+
+    public void setSampleoptions(DLSSampleOptions sampleOptions) {
+        this.sampleoptions = sampleOptions;
+    }
+
+    public String toString() {
+        return "Sample: " + info.name;
+    }
+
+    public byte[] getGuid() {
+        return guid;
+    }
+
+    public void setGuid(byte[] guid) {
+        this.guid = guid;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/classes/com/sun/media/sound/DLSSampleLoop.java	Mon Jan 19 20:11:58 2009 +0300
@@ -0,0 +1,63 @@
+/*
+ * Copyright 2007 Sun Microsystems, Inc.  All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+package com.sun.media.sound;
+
+/**
+ * This class is used to store loop points inside DLSSampleOptions class.
+ *
+ * @author Karl Helgason
+ */
+public class DLSSampleLoop {
+
+    public final static int LOOP_TYPE_FORWARD = 0;
+    public final static int LOOP_TYPE_RELEASE = 1;
+    protected long type;
+    protected long start;
+    protected long length;
+
+    public long getLength() {
+        return length;
+    }
+
+    public void setLength(long length) {
+        this.length = length;
+    }
+
+    public long getStart() {
+        return start;
+    }
+
+    public void setStart(long start) {
+        this.start = start;
+    }
+
+    public long getType() {
+        return type;
+    }
+
+    public void setType(long type) {
+        this.type = type;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/classes/com/sun/media/sound/DLSSampleOptions.java	Mon Jan 19 20:11:58 2009 +0300
@@ -0,0 +1,80 @@
+/*
+ * Copyright 2007 Sun Microsystems, Inc.  All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+package com.sun.media.sound;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * This class stores options how to playback sampled data like pitch/tuning,
+ * attenuation and loops.
+ * It is stored as a "wsmp" chunk inside DLS files.
+ *
+ * @author Karl Helgason
+ */
+public class DLSSampleOptions {
+
+    protected int unitynote;
+    protected short finetune;
+    protected int attenuation;
+    protected long options;
+    protected List<DLSSampleLoop> loops = new ArrayList<DLSSampleLoop>();
+
+    public int getAttenuation() {
+        return attenuation;
+    }
+
+    public void setAttenuation(int attenuation) {
+        this.attenuation = attenuation;
+    }
+
+    public short getFinetune() {
+        return finetune;
+    }
+
+    public void setFinetune(short finetune) {
+        this.finetune = finetune;
+    }
+
+    public List<DLSSampleLoop> getLoops() {
+        return loops;
+    }
+
+    public long getOptions() {
+        return options;
+    }
+
+    public void setOptions(long options) {
+        this.options = options;
+    }
+
+    public int getUnitynote() {
+        return unitynote;
+    }
+
+    public void setUnitynote(int unitynote) {
+        this.unitynote = unitynote;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/classes/com/sun/media/sound/DLSSoundbank.java	Mon Jan 19 20:11:58 2009 +0300
@@ -0,0 +1,1287 @@
+/*
+ * Copyright 2007 Sun Microsystems, Inc.  All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+package com.sun.media.sound;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.net.URL;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Stack;
+
+import javax.sound.midi.Instrument;
+import javax.sound.midi.Patch;
+import javax.sound.midi.Soundbank;
+import javax.sound.midi.SoundbankResource;
+import javax.sound.sampled.AudioFormat;
+import javax.sound.sampled.AudioInputStream;
+import javax.sound.sampled.AudioSystem;
+import javax.sound.sampled.AudioFormat.Encoding;
+
+/**
+ * A DLS Level 1 and Level 2 soundbank reader (from files/url/streams).
+ *
+ * @author Karl Helgason
+ */
+public class DLSSoundbank implements Soundbank {
+
+    static private class DLSID {
+        long i1;
+        int s1;
+        int s2;
+        int x1;
+        int x2;
+        int x3;
+        int x4;
+        int x5;
+        int x6;
+        int x7;
+        int x8;
+
+        private DLSID() {
+        }
+
+        public DLSID(long i1, int s1, int s2, int x1, int x2, int x3, int x4,
+                int x5, int x6, int x7, int x8) {
+            this.i1 = i1;
+            this.s1 = s1;
+            this.s2 = s2;
+            this.x1 = x1;
+            this.x2 = x2;
+            this.x3 = x3;
+            this.x4 = x4;
+            this.x5 = x5;
+            this.x6 = x6;
+            this.x7 = x7;
+            this.x8 = x8;
+        }
+
+        public static DLSID read(RIFFReader riff) throws IOException {
+            DLSID d = new DLSID();
+            d.i1 = riff.readUnsignedInt();
+            d.s1 = riff.readUnsignedShort();
+            d.s2 = riff.readUnsignedShort();
+            d.x1 = riff.readUnsignedByte();
+            d.x2 = riff.readUnsignedByte();
+            d.x3 = riff.readUnsignedByte();
+            d.x4 = riff.readUnsignedByte();
+            d.x5 = riff.readUnsignedByte();
+            d.x6 = riff.readUnsignedByte();
+            d.x7 = riff.readUnsignedByte();
+            d.x8 = riff.readUnsignedByte();
+            return d;
+        }
+
+        public int hashCode() {
+            return (int)i1;
+        }
+
+        public boolean equals(Object obj) {
+            if (!(obj instanceof DLSID)) {
+                return false;
+            }
+            DLSID t = (DLSID) obj;
+            return i1 == t.i1 && s1 == t.s1 && s2 == t.s2
+                && x1 == t.x1 && x2 == t.x2 && x3 == t.x3 && x4 == t.x4
+                && x5 == t.x5 && x6 == t.x6 && x7 == t.x7 && x8 == t.x8;
+        }
+    }
+
+    /** X = X & Y */
+    private static final int DLS_CDL_AND = 0x0001;
+    /** X = X | Y */
+    private static final int DLS_CDL_OR = 0x0002;
+    /** X = X ^ Y */
+    private static final int DLS_CDL_XOR = 0x0003;
+    /** X = X + Y */
+    private static final int DLS_CDL_ADD = 0x0004;
+    /** X = X - Y */
+    private static final int DLS_CDL_SUBTRACT = 0x0005;
+    /** X = X * Y */
+    private static final int DLS_CDL_MULTIPLY = 0x0006;
+    /** X = X / Y */
+    private static final int DLS_CDL_DIVIDE = 0x0007;
+    /** X = X && Y */
+    private static final int DLS_CDL_LOGICAL_AND = 0x0008;
+    /** X = X || Y */
+    private static final int DLS_CDL_LOGICAL_OR = 0x0009;
+    /** X = (X < Y) */
+    private static final int DLS_CDL_LT = 0x000A;
+    /** X = (X <= Y) */
+    private static final int DLS_CDL_LE = 0x000B;
+    /** X = (X > Y) */
+    private static final int DLS_CDL_GT = 0x000C;
+    /** X = (X >= Y) */
+    private static final int DLS_CDL_GE = 0x000D;
+    /** X = (X == Y) */
+    private static final int DLS_CDL_EQ = 0x000E;
+    /** X = !X */
+    private static final int DLS_CDL_NOT = 0x000F;
+    /** 32-bit constant */
+    private static final int DLS_CDL_CONST = 0x0010;
+    /** 32-bit value returned from query */
+    private static final int DLS_CDL_QUERY = 0x0011;
+    /** 32-bit value returned from query */
+    private static final int DLS_CDL_QUERYSUPPORTED = 0x0012;
+
+    private static final DLSID DLSID_GMInHardware = new DLSID(0x178f2f24,
+            0xc364, 0x11d1, 0xa7, 0x60, 0x00, 0x00, 0xf8, 0x75, 0xac, 0x12);
+    private static final DLSID DLSID_GSInHardware = new DLSID(0x178f2f25,
+            0xc364, 0x11d1, 0xa7, 0x60, 0x00, 0x00, 0xf8, 0x75, 0xac, 0x12);
+    private static final DLSID DLSID_XGInHardware = new DLSID(0x178f2f26,
+            0xc364, 0x11d1, 0xa7, 0x60, 0x00, 0x00, 0xf8, 0x75, 0xac, 0x12);
+    private static final DLSID DLSID_SupportsDLS1 = new DLSID(0x178f2f27,
+            0xc364, 0x11d1, 0xa7, 0x60, 0x00, 0x00, 0xf8, 0x75, 0xac, 0x12);
+    private static final DLSID DLSID_SupportsDLS2 = new DLSID(0xf14599e5,
+            0x4689, 0x11d2, 0xaf, 0xa6, 0x0, 0xaa, 0x0, 0x24, 0xd8, 0xb6);
+    private static final DLSID DLSID_SampleMemorySize = new DLSID(0x178f2f28,
+            0xc364, 0x11d1, 0xa7, 0x60, 0x00, 0x00, 0xf8, 0x75, 0xac, 0x12);
+    private static final DLSID DLSID_ManufacturersID = new DLSID(0xb03e1181,
+            0x8095, 0x11d2, 0xa1, 0xef, 0x0, 0x60, 0x8, 0x33, 0xdb, 0xd8);
+    private static final DLSID DLSID_ProductID = new DLSID(0xb03e1182,
+            0x8095, 0x11d2, 0xa1, 0xef, 0x0, 0x60, 0x8, 0x33, 0xdb, 0xd8);
+    private static final DLSID DLSID_SamplePlaybackRate = new DLSID(0x2a91f713,
+            0xa4bf, 0x11d2, 0xbb, 0xdf, 0x0, 0x60, 0x8, 0x33, 0xdb, 0xd8);
+
+    private long major = -1;
+    private long minor = -1;
+
+    private DLSInfo info = new DLSInfo();
+
+    private List<DLSInstrument> instruments = new ArrayList<DLSInstrument>();
+    private List<DLSSample> samples = new ArrayList<DLSSample>();
+
+    private boolean largeFormat = false;
+    private File sampleFile;
+
+    public DLSSoundbank() {
+    }
+
+    public DLSSoundbank(URL url) throws IOException {
+        InputStream is = url.openStream();
+        try {
+            readSoundbank(is);
+        } finally {
+            is.close();
+        }
+    }
+
+    public DLSSoundbank(File file) throws IOException {
+        largeFormat = true;
+        sampleFile = file;
+        InputStream is = new FileInputStream(file);
+        try {
+            readSoundbank(is);
+        } finally {
+            is.close();
+        }
+    }
+
+    public DLSSoundbank(InputStream inputstream) throws IOException {
+        readSoundbank(inputstream);
+    }
+
+    private void readSoundbank(InputStream inputstream) throws IOException {
+        RIFFReader riff = new RIFFReader(inputstream);
+        if (!riff.getFormat().equals("RIFF")) {
+            throw new RIFFInvalidFormatException(
+                    "Input stream is not a valid RIFF stream!");
+        }
+        if (!riff.getType().equals("DLS ")) {
+            throw new RIFFInvalidFormatException(
+                    "Input stream is not a valid DLS soundbank!");
+        }
+        while (riff.hasNextChunk()) {
+            RIFFReader chunk = riff.nextChunk();
+            if (chunk.getFormat().equals("LIST")) {
+                if (chunk.getType().equals("INFO"))
+                    readInfoChunk(chunk);
+                if (chunk.getType().equals("lins"))
+                    readLinsChunk(chunk);
+                if (chunk.getType().equals("wvpl"))
+                    readWvplChunk(chunk);
+            } else {
+                if (chunk.getFormat().equals("cdl ")) {
+                    if (!readCdlChunk(chunk)) {
+                        throw new RIFFInvalidFormatException(
+                                "DLS file isn't supported!");
+                    }
+                }
+                if (chunk.getFormat().equals("colh")) {
+                    // skipped because we will load the entire bank into memory
+                    // long instrumentcount = chunk.readUnsignedInt();
+                    // System.out.println("instrumentcount = "+ instrumentcount);
+                }
+                if (chunk.getFormat().equals("ptbl")) {
+                    // Pool Table Chunk
+                    // skipped because we will load the entire bank into memory
+                }
+                if (chunk.getFormat().equals("vers")) {
+                    major = chunk.readUnsignedInt();
+                    minor = chunk.readUnsignedInt();
+                }
+            }
+        }
+
+        for (Map.Entry<DLSRegion, Long> entry : temp_rgnassign.entrySet()) {
+            entry.getKey().sample = samples.get((int)entry.getValue().longValue());
+        }
+
+        temp_rgnassign = null;
+    }
+
+    private boolean cdlIsQuerySupported(DLSID uuid) {
+        return uuid.equals(DLSID_GMInHardware)
+            || uuid.equals(DLSID_GSInHardware)
+            || uuid.equals(DLSID_XGInHardware)
+            || uuid.equals(DLSID_SupportsDLS1)
+            || uuid.equals(DLSID_SupportsDLS2)
+            || uuid.equals(DLSID_SampleMemorySize)
+            || uuid.equals(DLSID_ManufacturersID)
+            || uuid.equals(DLSID_ProductID)
+            || uuid.equals(DLSID_SamplePlaybackRate);
+    }
+
+    private long cdlQuery(DLSID uuid) {
+        if (uuid.equals(DLSID_GMInHardware))
+            return 1;
+        if (uuid.equals(DLSID_GSInHardware))
+            return 0;
+        if (uuid.equals(DLSID_XGInHardware))
+            return 0;
+        if (uuid.equals(DLSID_SupportsDLS1))
+            return 1;
+        if (uuid.equals(DLSID_SupportsDLS2))
+            return 1;
+        if (uuid.equals(DLSID_SampleMemorySize))
+            return Runtime.getRuntime().totalMemory();
+        if (uuid.equals(DLSID_ManufacturersID))
+            return 0;
+        if (uuid.equals(DLSID_ProductID))
+            return 0;
+        if (uuid.equals(DLSID_SamplePlaybackRate))
+            return 44100;
+        return 0;
+    }
+
+
+    // Reading cdl-ck Chunk
+    // "cdl " chunk can only appear inside : DLS,lart,lar2,rgn,rgn2
+    private boolean readCdlChunk(RIFFReader riff) throws IOException {
+
+        DLSID uuid;
+        long x;
+        long y;
+        Stack<Long> stack = new Stack<Long>();
+
+        while (riff.available() != 0) {
+            int opcode = riff.readUnsignedShort();
+            switch (opcode) {
+            case DLS_CDL_AND:
+                x = stack.pop();
+                y = stack.pop();
+                stack.push(Long.valueOf(((x != 0) && (y != 0)) ? 1 : 0));
+                break;
+            case DLS_CDL_OR:
+                x = stack.pop();
+                y = stack.pop();
+                stack.push(Long.valueOf(((x != 0) || (y != 0)) ? 1 : 0));
+                break;
+            case DLS_CDL_XOR:
+                x = stack.pop();
+                y = stack.pop();
+                stack.push(Long.valueOf(((x != 0) ^ (y != 0)) ? 1 : 0));
+                break;
+            case DLS_CDL_ADD:
+                x = stack.pop();
+                y = stack.pop();
+                stack.push(Long.valueOf(x + y));
+                break;
+            case DLS_CDL_SUBTRACT:
+                x = stack.pop();
+                y = stack.pop();
+                stack.push(Long.valueOf(x - y));
+                break;
+            case DLS_CDL_MULTIPLY:
+                x = stack.pop();
+                y = stack.pop();
+                stack.push(Long.valueOf(x * y));
+                break;
+            case DLS_CDL_DIVIDE:
+                x = stack.pop();
+                y = stack.pop();
+                stack.push(Long.valueOf(x / y));
+                break;
+            case DLS_CDL_LOGICAL_AND:
+                x = stack.pop();
+                y = stack.pop();
+                stack.push(Long.valueOf(((x != 0) && (y != 0)) ? 1 : 0));
+                break;
+            case DLS_CDL_LOGICAL_OR:
+                x = stack.pop();
+                y = stack.pop();
+                stack.push(Long.valueOf(((x != 0) || (y != 0)) ? 1 : 0));
+                break;
+            case DLS_CDL_LT:
+                x = stack.pop();
+                y = stack.pop();
+                stack.push(Long.valueOf((x < y) ? 1 : 0));
+                break;
+            case DLS_CDL_LE:
+                x = stack.pop();
+                y = stack.pop();
+                stack.push(Long.valueOf((x <= y) ? 1 : 0));
+                break;
+            case DLS_CDL_GT:
+                x = stack.pop();
+                y = stack.pop();
+                stack.push(Long.valueOf((x > y) ? 1 : 0));
+                break;
+            case DLS_CDL_GE:
+                x = stack.pop();
+                y = stack.pop();
+                stack.push(Long.valueOf((x >= y) ? 1 : 0));
+                break;
+            case DLS_CDL_EQ:
+                x = stack.pop();
+                y = stack.pop();
+                stack.push(Long.valueOf((x == y) ? 1 : 0));
+                break;
+            case DLS_CDL_NOT:
+                x = stack.pop();
+                y = stack.pop();
+                stack.push(Long.valueOf((x == 0) ? 1 : 0));
+                break;
+            case DLS_CDL_CONST:
+                stack.push(Long.valueOf(riff.readUnsignedInt()));
+                break;
+            case DLS_CDL_QUERY:
+                uuid = DLSID.read(riff);
+                stack.push(cdlQuery(uuid));
+                break;
+            case DLS_CDL_QUERYSUPPORTED:
+                uuid = DLSID.read(riff);
+                stack.push(Long.valueOf(cdlIsQuerySupported(uuid) ? 1 : 0));
+                break;
+            default:
+                break;
+            }
+        }
+        if (stack.isEmpty())
+            return false;
+
+        return stack.pop() == 1;
+    }
+
+    private void readInfoChunk(RIFFReader riff) throws IOException {
+        info.name = null;
+        while (riff.hasNextChunk()) {
+            RIFFReader chunk = riff.nextChunk();
+            String format = chunk.getFormat();
+            if (format.equals("INAM"))
+                info.name = chunk.readString(chunk.available());
+            else if (format.equals("ICRD"))
+                info.creationDate = chunk.readString(chunk.available());
+            else if (format.equals("IENG"))
+                info.engineers = chunk.readString(chunk.available());
+            else if (format.equals("IPRD"))
+                info.product = chunk.readString(chunk.available());
+            else if (format.equals("ICOP"))
+                info.copyright = chunk.readString(chunk.available());
+            else if (format.equals("ICMT"))
+                info.comments = chunk.readString(chunk.available());
+            else if (format.equals("ISFT"))
+                info.tools = chunk.readString(chunk.available());
+            else if (format.equals("IARL"))
+                info.archival_location = chunk.readString(chunk.available());
+            else if (format.equals("IART"))
+                info.artist = chunk.readString(chunk.available());
+            else if (format.equals("ICMS"))
+                info.commissioned = chunk.readString(chunk.available());
+            else if (format.equals("IGNR"))
+                info.genre = chunk.readString(chunk.available());
+            else if (format.equals("IKEY"))
+                info.keywords = chunk.readString(chunk.available());
+            else if (format.equals("IMED"))
+                info.medium = chunk.readString(chunk.available());
+            else if (format.equals("ISBJ"))
+                info.subject = chunk.readString(chunk.available());
+            else if (format.equals("ISRC"))
+                info.source = chunk.readString(chunk.available());
+            else if (format.equals("ISRF"))
+                info.source_form = chunk.readString(chunk.available());
+            else if (format.equals("ITCH"))
+                info.technician = chunk.readString(chunk.available());
+        }
+    }
+
+    private void readLinsChunk(RIFFReader riff) throws IOException {
+        while (riff.hasNextChunk()) {
+            RIFFReader chunk = riff.nextChunk();
+            if (chunk.getFormat().equals("LIST")) {
+                if (chunk.getType().equals("ins "))
+                    readInsChunk(chunk);
+            }
+        }
+    }
+
+    private void readInsChunk(RIFFReader riff) throws IOException {
+        DLSInstrument instrument = new DLSInstrument(this);
+
+        while (riff.hasNextChunk()) {
+            RIFFReader chunk = riff.nextChunk();
+            String format = chunk.getFormat();
+            if (format.equals("LIST")) {
+                if (chunk.getType().equals("INFO")) {
+                    readInsInfoChunk(instrument, chunk);
+                }
+                if (chunk.getType().equals("lrgn")) {
+                    while (chunk.hasNextChunk()) {
+                        RIFFReader subchunk = chunk.nextChunk();
+                        if (subchunk.getFormat().equals("LIST")) {
+                            if (subchunk.getType().equals("rgn ")) {
+                                DLSRegion split = new DLSRegion();
+                                if (readRgnChunk(split, subchunk))
+                                    instrument.getRegions().add(split);
+                            }
+                            if (subchunk.getType().equals("rgn2")) {
+                                // support for DLS level 2 regions
+                                DLSRegion split = new DLSRegion();
+                                if (readRgnChunk(split, subchunk))
+                                    instrument.getRegions().add(split);
+                            }
+                        }
+                    }
+                }
+                if (chunk.getType().equals("lart")) {
+                    List<DLSModulator> modlist = new ArrayList<DLSModulator>();
+                    while (chunk.hasNextChunk()) {
+                        RIFFReader subchunk = chunk.nextChunk();
+                        if (chunk.getFormat().equals("cdl ")) {
+                            if (!readCdlChunk(chunk)) {
+                                modlist.clear();
+                                break;
+                            }
+                        }
+                        if (subchunk.getFormat().equals("art1"))
+                            readArt1Chunk(modlist, subchunk);
+                    }
+                    instrument.getModulators().addAll(modlist);
+                }
+                if (chunk.getType().equals("lar2")) {
+                    // support for DLS level 2 ART
+                    List<DLSModulator> modlist = new ArrayList<DLSModulator>();
+                    while (chunk.hasNextChunk()) {
+                        RIFFReader subchunk = chunk.nextChunk();
+                        if (chunk.getFormat().equals("cdl ")) {
+                            if (!readCdlChunk(chunk)) {
+                                modlist.clear();
+                                break;
+                            }
+                        }
+                        if (subchunk.getFormat().equals("art2"))
+                            readArt2Chunk(modlist, subchunk);
+                    }
+                    instrument.getModulators().addAll(modlist);
+                }
+            } else {
+                if (format.equals("dlid")) {
+                    instrument.guid = new byte[16];
+                    chunk.readFully(instrument.guid);
+                }
+                if (format.equals("insh")) {
+                    chunk.readUnsignedInt(); // Read Region Count - ignored
+
+                    int bank = chunk.read();             // LSB
+                    bank += (chunk.read() & 127) << 7;   // MSB
+                    chunk.read(); // Read Reserved byte
+                    int drumins = chunk.read();          // Drum Instrument
+
+                    int id = chunk.read() & 127; // Read only first 7 bits
+                    chunk.read(); // Read Reserved byte
+                    chunk.read(); // Read Reserved byte
+                    chunk.read(); // Read Reserved byte
+
+                    instrument.bank = bank;
+                    instrument.preset = (int) id;
+                    instrument.druminstrument = (drumins & 128) > 0;
+                    //System.out.println("bank="+bank+" drumkit="+drumkit
+                    //        +" id="+id);
+                }
+
+            }
+        }
+        instruments.add(instrument);
+    }
+
+    private void readArt1Chunk(List<DLSModulator> modulators, RIFFReader riff)
+            throws IOException {
+        long size = riff.readUnsignedInt();
+        long count = riff.readUnsignedInt();
+
+        if (size - 8 != 0)
+            riff.skipBytes(size - 8);
+
+        for (int i = 0; i < count; i++) {
+            DLSModulator modulator = new DLSModulator();
+            modulator.version = 1;
+            modulator.source = riff.readUnsignedShort();
+            modulator.control = riff.readUnsignedShort();
+            modulator.destination = riff.readUnsignedShort();
+            modulator.transform = riff.readUnsignedShort();
+            modulator.scale = riff.readInt();
+            modulators.add(modulator);
+        }
+    }
+
+    private void readArt2Chunk(List<DLSModulator> modulators, RIFFReader riff)
+            throws IOException {
+        long size = riff.readUnsignedInt();
+        long count = riff.readUnsignedInt();
+
+        if (size - 8 != 0)
+            riff.skipBytes(size - 8);
+
+        for (int i = 0; i < count; i++) {
+            DLSModulator modulator = new DLSModulator();
+            modulator.version = 2;
+            modulator.source = riff.readUnsignedShort();
+            modulator.control = riff.readUnsignedShort();
+            modulator.destination = riff.readUnsignedShort();
+            modulator.transform = riff.readUnsignedShort();
+            modulator.scale = riff.readInt();
+            modulators.add(modulator);
+        }
+    }
+
+    private Map<DLSRegion, Long> temp_rgnassign = new HashMap<DLSRegion, Long>();
+
+    private boolean readRgnChunk(DLSRegion split, RIFFReader riff)
+            throws IOException {
+        while (riff.hasNextChunk()) {
+            RIFFReader chunk = riff.nextChunk();
+            String format = chunk.getFormat();
+            if (format.equals("LIST")) {
+                if (chunk.getType().equals("lart")) {
+                    List<DLSModulator> modlist = new ArrayList<DLSModulator>();
+                    while (chunk.hasNextChunk()) {
+                        RIFFReader subchunk = chunk.nextChunk();
+                        if (chunk.getFormat().equals("cdl ")) {
+                            if (!readCdlChunk(chunk)) {
+                                modlist.clear();
+                                break;
+                            }
+                        }
+                        if (subchunk.getFormat().equals("art1"))
+                            readArt1Chunk(modlist, subchunk);
+                    }
+                    split.getModulators().addAll(modlist);
+                }
+                if (chunk.getType().equals("lar2")) {
+                    // support for DLS level 2 ART
+                    List<DLSModulator> modlist = new ArrayList<DLSModulator>();
+                    while (chunk.hasNextChunk()) {
+                        RIFFReader subchunk = chunk.nextChunk();
+                        if (chunk.getFormat().equals("cdl ")) {
+                            if (!readCdlChunk(chunk)) {
+                                modlist.clear();
+                                break;
+                            }
+                        }
+                        if (subchunk.getFormat().equals("art2"))
+                            readArt2Chunk(modlist, subchunk);
+                    }
+                    split.getModulators().addAll(modlist);
+                }
+            } else {
+
+                if (format.equals("cdl ")) {
+                    if (!readCdlChunk(chunk))
+                        return false;
+                }
+                if (format.equals("rgnh")) {
+                    split.keyfrom = chunk.readUnsignedShort();
+                    split.keyto = chunk.readUnsignedShort();
+                    split.velfrom = chunk.readUnsignedShort();
+                    split.velto = chunk.readUnsignedShort();
+                    split.options = chunk.readUnsignedShort();
+                    split.exclusiveClass = chunk.readUnsignedShort();
+                }
+                if (format.equals("wlnk")) {
+                    split.fusoptions = chunk.readUnsignedShort();
+                    split.phasegroup = chunk.readUnsignedShort();
+                    split.channel = chunk.readUnsignedInt();
+                    long sampleid = chunk.readUnsignedInt();
+                    temp_rgnassign.put(split, sampleid);
+                }
+                if (format.equals("wsmp")) {
+                    split.sampleoptions = new DLSSampleOptions();
+                    readWsmpChunk(split.sampleoptions, chunk);
+                }
+            }
+        }
+        return true;
+    }
+
+    private void readWsmpChunk(DLSSampleOptions sampleOptions, RIFFReader riff)
+            throws IOException {
+        long size = riff.readUnsignedInt();
+        sampleOptions.unitynote = riff.readUnsignedShort();
+        sampleOptions.finetune = riff.readShort();
+        sampleOptions.attenuation = riff.readInt();
+        sampleOptions.options = riff.readUnsignedInt();
+        long loops = riff.readInt();
+
+        if (size > 20)
+            riff.skipBytes(size - 20);
+
+        for (int i = 0; i < loops; i++) {
+            DLSSampleLoop loop = new DLSSampleLoop();
+            long size2 = riff.readUnsignedInt();
+            loop.type = riff.readUnsignedInt();
+            loop.start = riff.readUnsignedInt();
+            loop.length = riff.readUnsignedInt();
+            sampleOptions.loops.add(loop);
+            if (size2 > 16)
+                riff.skipBytes(size2 - 16);
+        }
+    }
+
+    private void readInsInfoChunk(DLSInstrument dlsinstrument, RIFFReader riff)
+            throws IOException {
+        dlsinstrument.info.name = null;
+        while (riff.hasNextChunk()) {
+            RIFFReader chunk = riff.nextChunk();
+            String format = chunk.getFormat();
+            if (format.equals("INAM")) {
+                dlsinstrument.info.name = chunk.readString(chunk.available());
+            } else if (format.equals("ICRD")) {
+                dlsinstrument.info.creationDate =
+                        chunk.readString(chunk.available());
+            } else if (format.equals("IENG")) {
+                dlsinstrument.info.engineers =
+                        chunk.readString(chunk.available());
+            } else if (format.equals("IPRD")) {
+                dlsinstrument.info.product = chunk.readString(chunk.available());
+            } else if (format.equals("ICOP")) {
+                dlsinstrument.info.copyright =
+                        chunk.readString(chunk.available());
+            } else if (format.equals("ICMT")) {
+                dlsinstrument.info.comments =
+                        chunk.readString(chunk.available());
+            } else if (format.equals("ISFT")) {
+                dlsinstrument.info.tools = chunk.readString(chunk.available());
+            } else if (format.equals("IARL")) {
+                dlsinstrument.info.archival_location =
+                        chunk.readString(chunk.available());
+            } else if (format.equals("IART")) {
+                dlsinstrument.info.artist = chunk.readString(chunk.available());
+            } else if (format.equals("ICMS")) {
+                dlsinstrument.info.commissioned =
+                        chunk.readString(chunk.available());
+            } else if (format.equals("IGNR")) {
+                dlsinstrument.info.genre = chunk.readString(chunk.available());
+            } else if (format.equals("IKEY")) {
+                dlsinstrument.info.keywords =
+                        chunk.readString(chunk.available());
+            } else if (format.equals("IMED")) {
+                dlsinstrument.info.medium = chunk.readString(chunk.available());
+            } else if (format.equals("ISBJ")) {
+                dlsinstrument.info.subject = chunk.readString(chunk.available());
+            } else if (format.equals("ISRC")) {
+                dlsinstrument.info.source = chunk.readString(chunk.available());
+            } else if (format.equals("ISRF")) {
+                dlsinstrument.info.source_form =
+                        chunk.readString(chunk.available());
+            } else if (format.equals("ITCH")) {
+                dlsinstrument.info.technician =
+                        chunk.readString(chunk.available());
+            }
+        }
+    }
+
+    private void readWvplChunk(RIFFReader riff) throws IOException {
+        while (riff.hasNextChunk()) {
+            RIFFReader chunk = riff.nextChunk();
+            if (chunk.getFormat().equals("LIST")) {
+                if (chunk.getType().equals("wave"))
+                    readWaveChunk(chunk);
+            }
+        }
+    }
+
+    private void readWaveChunk(RIFFReader riff) throws IOException {
+        DLSSample sample = new DLSSample(this);
+
+        while (riff.hasNextChunk()) {
+            RIFFReader chunk = riff.nextChunk();
+            String format = chunk.getFormat();
+            if (format.equals("LIST")) {
+                if (chunk.getType().equals("INFO")) {
+                    readWaveInfoChunk(sample, chunk);
+                }
+            } else {
+                if (format.equals("dlid")) {
+                    sample.guid = new byte[16];
+                    chunk.readFully(sample.guid);
+                }
+
+                if (format.equals("fmt ")) {
+                    int sampleformat = chunk.readUnsignedShort();
+                    if (sampleformat != 1 && sampleformat != 3) {
+                        throw new RIFFInvalidDataException(
+                                "Only PCM samples are supported!");
+                    }
+                    int channels = chunk.readUnsignedShort();
+                    long samplerate = chunk.readUnsignedInt();
+                    // bytes per sec
+                    /* long framerate = */ chunk.readUnsignedInt();
+                    // block align, framesize
+                    int framesize = chunk.readUnsignedShort();
+                    int bits = chunk.readUnsignedShort();
+                    AudioFormat audioformat = null;
+                    if (sampleformat == 1) {
+                        if (bits == 8) {
+                            audioformat = new AudioFormat(
+                                    Encoding.PCM_UNSIGNED, samplerate, bits,
+                                    channels, framesize, samplerate, false);
+                        } else {
+                            audioformat = new AudioFormat(
+                                    Encoding.PCM_SIGNED, samplerate, bits,
+                                    channels, framesize, samplerate, false);
+                        }
+                    }
+                    if (sampleformat == 3) {
+                        audioformat = new AudioFormat(
+                                AudioFloatConverter.PCM_FLOAT, samplerate, bits,
+                                channels, framesize, samplerate, false);
+                    }
+
+                    sample.format = audioformat;
+                }
+
+                if (format.equals("data")) {
+                    if (largeFormat) {
+                        sample.setData(new ModelByteBuffer(sampleFile,
+                                chunk.getFilePointer(), chunk.available()));
+                    } else {
+                        byte[] buffer = new byte[chunk.available()];
+                        //  chunk.read(buffer);
+                        sample.setData(buffer);
+
+                        int read = 0;
+                        int avail = chunk.available();
+                        while (read != avail) {
+                            if (avail - read > 65536) {
+                                chunk.readFully(buffer, read, 65536);
+                                read += 65536;
+                            } else {
+                                chunk.readFully(buffer, read, avail - read);
+                                read = avail;
+                            }
+                        }
+                    }
+                }
+
+                if (format.equals("wsmp")) {
+                    sample.sampleoptions = new DLSSampleOptions();
+                    readWsmpChunk(sample.sampleoptions, chunk);
+                }
+            }
+        }
+
+        samples.add(sample);
+
+    }
+
+    private void readWaveInfoChunk(DLSSample dlssample, RIFFReader riff)
+            throws IOException {
+        dlssample.info.name = null;
+        while (riff.hasNextChunk()) {
+            RIFFReader chunk = riff.nextChunk();
+            String format = chunk.getFormat();
+            if (format.equals("INAM")) {
+                dlssample.info.name = chunk.readString(chunk.available());
+            } else if (format.equals("ICRD")) {
+                dlssample.info.creationDate =
+                        chunk.readString(chunk.available());
+            } else if (format.equals("IENG")) {
+                dlssample.info.engineers = chunk.readString(chunk.available());
+            } else if (format.equals("IPRD")) {
+                dlssample.info.product = chunk.readString(chunk.available());
+            } else if (format.equals("ICOP")) {
+                dlssample.info.copyright = chunk.readString(chunk.available());
+            } else if (format.equals("ICMT")) {
+                dlssample.info.comments = chunk.readString(chunk.available());
+            } else if (format.equals("ISFT")) {
+                dlssample.info.tools = chunk.readString(chunk.available());
+            } else if (format.equals("IARL")) {
+                dlssample.info.archival_location =
+                        chunk.readString(chunk.available());
+            } else if (format.equals("IART")) {
+                dlssample.info.artist = chunk.readString(chunk.available());
+            } else if (format.equals("ICMS")) {
+                dlssample.info.commissioned =
+                        chunk.readString(chunk.available());
+            } else if (format.equals("IGNR")) {
+                dlssample.info.genre = chunk.readString(chunk.available());
+            } else if (format.equals("IKEY")) {
+                dlssample.info.keywords = chunk.readString(chunk.available());
+            } else if (format.equals("IMED")) {
+                dlssample.info.medium = chunk.readString(chunk.available());
+            } else if (format.equals("ISBJ")) {
+                dlssample.info.subject = chunk.readString(chunk.available());
+            } else if (format.equals("ISRC")) {
+                dlssample.info.source = chunk.readString(chunk.available());
+            } else if (format.equals("ISRF")) {
+                dlssample.info.source_form = chunk.readString(chunk.available());
+            } else if (format.equals("ITCH")) {
+                dlssample.info.technician = chunk.readString(chunk.available());
+            }
+        }
+    }
+
+    public void save(String name) throws IOException {
+        writeSoundbank(new RIFFWriter(name, "DLS "));
+    }
+
+    public void save(File file) throws IOException {
+        writeSoundbank(new RIFFWriter(file, "DLS "));
+    }
+
+    public void save(OutputStream out) throws IOException {
+        writeSoundbank(new RIFFWriter(out, "DLS "));
+    }
+
+    private void writeSoundbank(RIFFWriter writer) throws IOException {
+        RIFFWriter colh_chunk = writer.writeChunk("colh");
+        colh_chunk.writeUnsignedInt(instruments.size());
+
+        if (major != -1 && minor != -1) {
+            RIFFWriter vers_chunk = writer.writeChunk("vers");
+            vers_chunk.writeUnsignedInt(major);
+            vers_chunk.writeUnsignedInt(minor);
+        }
+
+        writeInstruments(writer.writeList("lins"));
+
+        RIFFWriter ptbl = writer.writeChunk("ptbl");
+        ptbl.writeUnsignedInt(8);
+        ptbl.writeUnsignedInt(samples.size());
+        long ptbl_offset = writer.getFilePointer();
+        for (int i = 0; i < samples.size(); i++)
+            ptbl.writeUnsignedInt(0);
+
+        RIFFWriter wvpl = writer.writeList("wvpl");
+        long off = wvpl.getFilePointer();
+        List<Long> offsettable = new ArrayList<Long>();
+        for (DLSSample sample : samples) {
+            offsettable.add(Long.valueOf(wvpl.getFilePointer() - off));
+            writeSample(wvpl.writeList("wave"), sample);
+        }
+
+        // small cheat, we are going to rewrite data back in wvpl
+        long bak = writer.getFilePointer();
+        writer.seek(ptbl_offset);
+        writer.setWriteOverride(true);
+        for (Long offset : offsettable)
+            writer.writeUnsignedInt(offset.longValue());
+        writer.setWriteOverride(false);
+        writer.seek(bak);
+
+        writeInfo(writer.writeList("INFO"), info);
+
+        writer.close();
+    }
+
+    private void writeSample(RIFFWriter writer, DLSSample sample)
+            throws IOException {
+
+        AudioFormat audioformat = sample.getFormat();
+
+        Encoding encoding = audioformat.getEncoding();
+        float sampleRate = audioformat.getSampleRate();
+        int sampleSizeInBits = audioformat.getSampleSizeInBits();
+        int channels = audioformat.getChannels();
+        int frameSize = audioformat.getFrameSize();
+        float frameRate = audioformat.getFrameRate();
+        boolean bigEndian = audioformat.isBigEndian();
+
+        boolean convert_needed = false;
+
+        if (audioformat.getSampleSizeInBits() == 8) {
+            if (!encoding.equals(Encoding.PCM_UNSIGNED)) {
+                encoding = Encoding.PCM_UNSIGNED;
+                convert_needed = true;
+            }
+        } else {
+            if (!encoding.equals(Encoding.PCM_SIGNED)) {
+                encoding = Encoding.PCM_SIGNED;
+                convert_needed = true;
+            }
+            if (bigEndian) {
+                bigEndian = false;
+                convert_needed = true;
+            }
+        }
+
+        if (convert_needed) {
+            audioformat = new AudioFormat(encoding, sampleRate,
+                    sampleSizeInBits, channels, frameSize, frameRate, bigEndian);
+        }
+
+        // fmt
+        RIFFWriter fmt_chunk = writer.writeChunk("fmt ");
+        int sampleformat = 0;
+        if (audioformat.getEncoding().equals(Encoding.PCM_UNSIGNED))
+            sampleformat = 1;
+        else if (audioformat.getEncoding().equals(Encoding.PCM_SIGNED))
+            sampleformat = 1;
+        else if (audioformat.getEncoding().equals(AudioFloatConverter.PCM_FLOAT))
+            sampleformat = 3;
+
+        fmt_chunk.writeUnsignedShort(sampleformat);
+        fmt_chunk.writeUnsignedShort(audioformat.getChannels());
+        fmt_chunk.writeUnsignedInt((long) audioformat.getSampleRate());
+        long srate = ((long)audioformat.getFrameRate())*audioformat.getFrameSize();
+        fmt_chunk.writeUnsignedInt(srate);
+        fmt_chunk.writeUnsignedShort(audioformat.getFrameSize());
+        fmt_chunk.writeUnsignedShort(audioformat.getSampleSizeInBits());
+        fmt_chunk.write(0);
+        fmt_chunk.write(0);
+
+        writeSampleOptions(writer.writeChunk("wsmp"), sample.sampleoptions);
+
+        if (convert_needed) {
+            RIFFWriter data_chunk = writer.writeChunk("data");
+            AudioInputStream stream = AudioSystem.getAudioInputStream(
+                    audioformat, (AudioInputStream)sample.getData());
+            byte[] buff = new byte[1024];
+            int ret;
+            while ((ret = stream.read(buff)) != -1) {
+                data_chunk.write(buff, 0, ret);
+            }
+        } else {
+            RIFFWriter data_chunk = writer.writeChunk("data");
+            ModelByteBuffer databuff = sample.getDataBuffer();
+            databuff.writeTo(data_chunk);
+            /*
+            data_chunk.write(databuff.array(),
+            databuff.arrayOffset(),
+            databuff.capacity());
+             */
+        }
+
+        writeInfo(writer.writeList("INFO"), sample.info);
+    }
+
+    private void writeInstruments(RIFFWriter writer) throws IOException {
+        for (DLSInstrument instrument : instruments) {
+            writeInstrument(writer.writeList("ins "), instrument);
+        }
+    }
+
+    private void writeInstrument(RIFFWriter writer, DLSInstrument instrument)
+            throws IOException {
+
+        int art1_count = 0;
+        int art2_count = 0;
+        for (DLSModulator modulator : instrument.getModulators()) {
+            if (modulator.version == 1)
+                art1_count++;
+            if (modulator.version == 2)
+                art2_count++;
+        }
+        for (DLSRegion region : instrument.regions) {
+            for (DLSModulator modulator : region.getModulators()) {
+                if (modulator.version == 1)
+                    art1_count++;
+                if (modulator.version == 2)
+                    art2_count++;
+            }
+        }
+
+        int version = 1;
+        if (art2_count > 0)
+            version = 2;
+
+        RIFFWriter insh_chunk = writer.writeChunk("insh");
+        insh_chunk.writeUnsignedInt(instrument.getRegions().size());
+        insh_chunk.writeUnsignedInt(instrument.bank +
+                (instrument.druminstrument ? 2147483648L : 0));
+        insh_chunk.writeUnsignedInt(instrument.preset);
+
+        RIFFWriter lrgn = writer.writeList("lrgn");
+        for (DLSRegion region: instrument.regions)
+            writeRegion(lrgn, region, version);
+
+        writeArticulators(writer, instrument.getModulators());
+
+        writeInfo(writer.writeList("INFO"), instrument.info);
+
+    }
+
+    private void writeArticulators(RIFFWriter writer,
+            List<DLSModulator> modulators) throws IOException {
+        int art1_count = 0;
+        int art2_count = 0;
+        for (DLSModulator modulator : modulators) {
+            if (modulator.version == 1)
+                art1_count++;
+            if (modulator.version == 2)
+                art2_count++;
+        }
+        if (art1_count > 0) {
+            RIFFWriter lar1 = writer.writeList("lart");
+            RIFFWriter art1 = lar1.writeChunk("art1");
+            art1.writeUnsignedInt(8);
+            art1.writeUnsignedInt(art1_count);
+            for (DLSModulator modulator : modulators) {
+                if (modulator.version == 1) {
+                    art1.writeUnsignedShort(modulator.source);
+                    art1.writeUnsignedShort(modulator.control);
+                    art1.writeUnsignedShort(modulator.destination);
+                    art1.writeUnsignedShort(modulator.transform);
+                    art1.writeInt(modulator.scale);
+                }
+            }
+        }
+        if (art2_count > 0) {
+            RIFFWriter lar2 = writer.writeList("lar2");
+            RIFFWriter art2 = lar2.writeChunk("art2");
+            art2.writeUnsignedInt(8);
+            art2.writeUnsignedInt(art2_count);
+            for (DLSModulator modulator : modulators) {
+                if (modulator.version == 2) {
+                    art2.writeUnsignedShort(modulator.source);
+                    art2.writeUnsignedShort(modulator.control);
+                    art2.writeUnsignedShort(modulator.destination);
+                    art2.writeUnsignedShort(modulator.transform);
+                    art2.writeInt(modulator.scale);
+                }
+            }
+        }
+    }
+
+    private void writeRegion(RIFFWriter writer, DLSRegion region, int version)
+            throws IOException {
+        RIFFWriter rgns = null;
+        if (version == 1)
+            rgns = writer.writeList("rgn ");
+        if (version == 2)
+            rgns = writer.writeList("rgn2");
+        if (rgns == null)
+            return;
+
+        RIFFWriter rgnh = rgns.writeChunk("rgnh");
+        rgnh.writeUnsignedShort(region.keyfrom);
+        rgnh.writeUnsignedShort(region.keyto);
+        rgnh.writeUnsignedShort(region.velfrom);
+        rgnh.writeUnsignedShort(region.velto);
+        rgnh.writeUnsignedShort(region.options);
+        rgnh.writeUnsignedShort(region.exclusiveClass);
+
+        if (region.sampleoptions != null)
+            writeSampleOptions(rgns.writeChunk("wsmp"), region.sampleoptions);
+
+        if (region.sample != null) {
+            if (samples.indexOf(region.sample) != -1) {
+                RIFFWriter wlnk = rgns.writeChunk("wlnk");
+                wlnk.writeUnsignedShort(region.fusoptions);
+                wlnk.writeUnsignedShort(region.phasegroup);
+                wlnk.writeUnsignedInt(region.channel);
+                wlnk.writeUnsignedInt(samples.indexOf(region.sample));
+            }
+        }
+        writeArticulators(rgns, region.getModulators());
+        rgns.close();
+    }
+
+    private void writeSampleOptions(RIFFWriter wsmp,
+            DLSSampleOptions sampleoptions) throws IOException {
+        wsmp.writeUnsignedInt(20);
+        wsmp.writeUnsignedShort(sampleoptions.unitynote);
+        wsmp.writeShort(sampleoptions.finetune);
+        wsmp.writeInt(sampleoptions.attenuation);
+        wsmp.writeUnsignedInt(sampleoptions.options);
+        wsmp.writeInt(sampleoptions.loops.size());
+
+        for (DLSSampleLoop loop : sampleoptions.loops) {
+            wsmp.writeUnsignedInt(16);
+            wsmp.writeUnsignedInt(loop.type);
+            wsmp.writeUnsignedInt(loop.start);
+            wsmp.writeUnsignedInt(loop.length);
+        }
+    }
+
+    private void writeInfoStringChunk(RIFFWriter writer,
+            String name, String value) throws IOException {
+        if (value == null)
+            return;
+        RIFFWriter chunk = writer.writeChunk(name);
+        chunk.writeString(value);
+        int len = value.getBytes("ascii").length;
+        chunk.write(0);
+        len++;
+        if (len % 2 != 0)
+            chunk.write(0);
+    }
+
+    private void writeInfo(RIFFWriter writer, DLSInfo info) throws IOException {
+        writeInfoStringChunk(writer, "INAM", info.name);
+        writeInfoStringChunk(writer, "ICRD", info.creationDate);
+        writeInfoStringChunk(writer, "IENG", info.engineers);
+        writeInfoStringChunk(writer, "IPRD", info.product);
+        writeInfoStringChunk(writer, "ICOP", info.copyright);
+        writeInfoStringChunk(writer, "ICMT", info.comments);
+        writeInfoStringChunk(writer, "ISFT", info.tools);
+        writeInfoStringChunk(writer, "IARL", info.archival_location);
+        writeInfoStringChunk(writer, "IART", info.artist);
+        writeInfoStringChunk(writer, "ICMS", info.commissioned);
+        writeInfoStringChunk(writer, "IGNR", info.genre);
+        writeInfoStringChunk(writer, "IKEY", info.keywords);
+        writeInfoStringChunk(writer, "IMED", info.medium);
+        writeInfoStringChunk(writer, "ISBJ", info.subject);
+        writeInfoStringChunk(writer, "ISRC", info.source);
+        writeInfoStringChunk(writer, "ISRF", info.source_form);
+        writeInfoStringChunk(writer, "ITCH", info.technician);
+    }
+
+    public DLSInfo getInfo() {
+        return info;
+    }
+
+    public String getName() {
+        return info.name;
+    }
+
+    public String getVersion() {
+        return major + "." + minor;
+    }
+
+    public String getVendor() {
+        return info.engineers;
+    }
+
+    public String getDescription() {
+        return info.comments;
+    }
+
+    public void setName(String s) {
+        info.name = s;
+    }
+
+    public void setVendor(String s) {
+        info.engineers = s;
+    }
+
+    public void setDescription(String s) {
+        info.comments = s;
+    }
+
+    public SoundbankResource[] getResources() {
+        SoundbankResource[] resources = new SoundbankResource[samples.size()];
+        int j = 0;
+        for (int i = 0; i < samples.size(); i++)
+            resources[j++] = samples.get(i);
+        return resources;
+    }
+
+    public DLSInstrument[] getInstruments() {
+        DLSInstrument[] inslist_array =
+                instruments.toArray(new DLSInstrument[instruments.size()]);
+        Arrays.sort(inslist_array, new ModelInstrumentComparator());
+        return inslist_array;
+    }
+
+    public DLSSample[] getSamples() {
+        return samples.toArray(new DLSSample[samples.size()]);
+    }
+
+    public Instrument getInstrument(Patch patch) {
+        int program = patch.getProgram();
+        int bank = patch.getBank();
+        boolean percussion = false;
+        if (patch instanceof ModelPatch)
+            percussion = ((ModelPatch) patch).isPercussion();
+        for (Instrument instrument : instruments) {
+            Patch patch2 = instrument.getPatch();
+            int program2 = patch2.getProgram();
+            int bank2 = patch2.getBank();
+            if (program == program2 && bank == bank2) {
+                boolean percussion2 = false;
+                if (patch2 instanceof ModelPatch)
+                    percussion2 = ((ModelPatch) patch2).isPercussion();
+                if (percussion == percussion2)
+                    return instrument;
+            }
+        }
+        return null;
+    }
+
+    public void addResource(SoundbankResource resource) {
+        if (resource instanceof DLSInstrument)
+            instruments.add((DLSInstrument) resource);
+        if (resource instanceof DLSSample)
+            samples.add((DLSSample) resource);
+    }
+
+    public void removeResource(SoundbankResource resource) {
+        if (resource instanceof DLSInstrument)
+            instruments.remove((DLSInstrument) resource);
+        if (resource instanceof DLSSample)
+            samples.remove((DLSSample) resource);
+    }
+
+    public void addInstrument(DLSInstrument resource) {
+        instruments.add(resource);
+    }
+
+    public void removeInstrument(DLSInstrument resource) {
+        instruments.remove(resource);
+    }
+
+    public long getMajor() {
+        return major;
+    }
+
+    public void setMajor(long major) {
+        this.major = major;
+    }
+
+    public long getMinor() {
+        return minor;
+    }
+
+    public void setMinor(long minor) {
+        this.minor = minor;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/classes/com/sun/media/sound/DLSSoundbankReader.java	Mon Jan 19 20:11:58 2009 +0300
@@ -0,0 +1,74 @@
+/*
+ * Copyright 2007 Sun Microsystems, Inc.  All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+package com.sun.media.sound;
+
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.URL;
+import javax.sound.midi.InvalidMidiDataException;
+import javax.sound.midi.Soundbank;
+import javax.sound.midi.spi.SoundbankReader;
+
+/**
+ * This class is used to connect the DLSSoundBank class
+ * to the SoundbankReader SPI interface.
+ *
+ * @author Karl Helgason
+ */
+public class DLSSoundbankReader extends SoundbankReader {
+
+    public Soundbank getSoundbank(URL url)
+            throws InvalidMidiDataException, IOException {
+        try {
+            return new DLSSoundbank(url);
+        } catch (RIFFInvalidFormatException e) {
+            return null;
+        } catch(IOException ioe) {
+            return null;
+        }
+    }
+
+    public Soundbank getSoundbank(InputStream stream)
+            throws InvalidMidiDataException, IOException {
+        try {
+            stream.mark(512);
+            return new DLSSoundbank(stream);
+        } catch (RIFFInvalidFormatException e) {
+            stream.reset();
+            return null;
+        }
+    }
+
+    public Soundbank getSoundbank(File file)
+            throws InvalidMidiDataException, IOException {
+        try {
+            return new DLSSoundbank(file);
+        } catch (RIFFInvalidFormatException e) {
+            return null;
+        }
+    }
+}
--- a/src/share/classes/com/sun/media/sound/DirectAudioDevice.java	Thu Dec 25 20:43:44 2008 +0300
+++ b/src/share/classes/com/sun/media/sound/DirectAudioDevice.java	Mon Jan 19 20:11:58 2009 +0300
@@ -394,7 +394,12 @@
         private float leftGain, rightGain;
         protected volatile boolean noService = false; // do not run the nService method
 
+        // Guards all native calls.
         protected Object lockNative = new Object();
+        // Guards the lastOpened static variable in implOpen and implClose.
+        protected static Object lockLast = new Object();
+        // Keeps track of last opened line, see implOpen "trick".
+        protected static DirectDL lastOpened;
 
         // CONSTRUCTOR
         protected DirectDL(DataLine.Info info,
@@ -496,20 +501,50 @@
             // align buffer to full frames
             bufferSize = ((int) bufferSize / format.getFrameSize()) * format.getFrameSize();
 
-            id = nOpen(mixerIndex, deviceID, isSource,
-                       encoding,
-                       hardwareFormat.getSampleRate(),
-                       hardwareFormat.getSampleSizeInBits(),
-                       hardwareFormat.getFrameSize(),
-                       hardwareFormat.getChannels(),
-                       hardwareFormat.getEncoding().equals(AudioFormat.Encoding.PCM_SIGNED),
-                       hardwareFormat.isBigEndian(),
-                       bufferSize);
+            synchronized(lockLast) {
+                id = nOpen(mixerIndex, deviceID, isSource,
+                        encoding,
+                        hardwareFormat.getSampleRate(),
+                        hardwareFormat.getSampleSizeInBits(),
+                        hardwareFormat.getFrameSize(),
+                        hardwareFormat.getChannels(),
+                        hardwareFormat.getEncoding().equals(
+                            AudioFormat.Encoding.PCM_SIGNED),
+                        hardwareFormat.isBigEndian(),
+                        bufferSize);
 
-            if (id == 0) {
-                // TODO: nicer error messages...
-                throw new LineUnavailableException("line with format "+format+" not supported.");
+                if (id == 0) {
+                    // Bah... Dirty trick. The most likely cause is an application
+                    // already having a line open for this particular hardware
+                    // format and forgetting about it. If so, silently close that
+                    // implementation and try again. Unfortuantely we can only
+                    // open one line per hardware format currently.
+                    if (lastOpened != null
+                            && hardwareFormat.matches(lastOpened.hardwareFormat)) {
+                        lastOpened.implClose();
+                        lastOpened = null;
+
+                        id = nOpen(mixerIndex, deviceID, isSource,
+                                encoding,
+                                hardwareFormat.getSampleRate(),
+                                hardwareFormat.getSampleSizeInBits(),
+                                hardwareFormat.getFrameSize(),
+                                hardwareFormat.getChannels(),
+                                hardwareFormat.getEncoding().equals(
+                                    AudioFormat.Encoding.PCM_SIGNED),
+                                hardwareFormat.isBigEndian(),
+                                bufferSize);
+                    }
+
+                    if (id == 0) {
+                        // TODO: nicer error messages...
+                        throw new LineUnavailableException(
+                            "line with format "+format+" not supported.");
+                    }
+                }
+                lastOpened = this;
             }
+
             this.bufferSize = nGetBufferSize(id, isSource);
             if (this.bufferSize < 1) {
                 // this is an error!
@@ -580,12 +615,12 @@
             }
             synchronized (lockNative) {
                 nStop(id, isSource);
+
+                // need to set doIO to false before notifying the
+                // read/write thread, that's why isStartedRunning()
+                // cannot be used
+                doIO = false;
             }
-
-            // need to set doIO to false before notifying the
-            // read/write thread, that's why isStartedRunning()
-            // cannot be used
-            doIO = false;
             // wake up any waiting threads
             synchronized(lock) {
                 lock.notifyAll();
@@ -614,8 +649,12 @@
             doIO = false;
             long oldID = id;
             id = 0;
-            synchronized (lockNative) {
-                nClose(oldID, isSource);
+            synchronized (lockLast) {
+                synchronized (lockNative) {
+                    nClose(oldID, isSource);
+                    if (lastOpened == this)
+                      lastOpened = null;
+                }
             }
             bytePosition = 0;
             softwareConversionSize = 0;
@@ -630,7 +669,8 @@
             }
             int a = 0;
             synchronized (lockNative) {
-                a = nAvailable(id, isSource);
+                if (doIO)
+                    a = nAvailable(id, isSource);
             }
             return a;
         }
@@ -644,9 +684,9 @@
             int counter = 0;
             long startPos = getLongFramePosition();
             boolean posChanged = false;
-            while (!drained && doIO) {
+            while (!drained) {
                 synchronized (lockNative) {
-                    if ((id == 0) || !nIsStillDraining(id, isSource))
+                    if ((id == 0) || (!doIO) || !nIsStillDraining(id, isSource))
                         break;
                 }
                 // check every now and then for a new position
@@ -686,7 +726,7 @@
                     lock.notifyAll();
                 }
                 synchronized (lockNative) {
-                    if (id != 0) {
+                    if (id != 0 && doIO) {
                         // then flush native buffers
                         nFlush(id, isSource);
                     }
@@ -697,9 +737,10 @@
 
         // replacement for getFramePosition (see AbstractDataLine)
         public long getLongFramePosition() {
-            long pos;
+            long pos = 0;
             synchronized (lockNative) {
-                pos = nGetBytePosition(id, isSource, bytePosition);
+                if (doIO)
+                    pos = nGetBytePosition(id, isSource, bytePosition);
             }
             // hack because ALSA sometimes reports wrong framepos
             if (pos < 0) {
@@ -745,11 +786,12 @@
             }
             int written = 0;
             while (!flushing) {
-                int thisWritten;
+                int thisWritten = 0;
                 synchronized (lockNative) {
-                    thisWritten = nWrite(id, b, off, len,
-                            softwareConversionSize,
-                            leftGain, rightGain);
+                    if (doIO)
+                        thisWritten = nWrite(id, b, off, len,
+                                softwareConversionSize,
+                                leftGain, rightGain);
                     if (thisWritten < 0) {
                         // error in native layer
                         break;
@@ -972,9 +1014,10 @@
             }
             int read = 0;
             while (doIO && !flushing) {
-                int thisRead;
+                int thisRead = 0;
                 synchronized (lockNative) {
-                    thisRead = nRead(id, b, off, len, softwareConversionSize);
+                    if (doIO)
+                        thisRead = nRead(id, b, off, len, softwareConversionSize);
                     if (thisRead < 0) {
                         // error in native layer
                         break;
@@ -1209,7 +1252,8 @@
             // set new native position (if necessary)
             // this must come after the flush!
             synchronized (lockNative) {
-                nSetBytePosition(id, isSource, frames * frameSize);
+                if (doIO)
+                    nSetBytePosition(id, isSource, frames * frameSize);
             }
 
             if (Printer.debug) Printer.debug("  DirectClip.setFramePosition: "
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/classes/com/sun/media/sound/EmergencySoundbank.java	Mon Jan 19 20:11:58 2009 +0300
@@ -0,0 +1,2695 @@
+/*
+ * Copyright 2007 Sun Microsystems, Inc.  All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+package com.sun.media.sound;
+
+import java.util.Random;
+
+import javax.sound.midi.Patch;
+import javax.sound.sampled.AudioFormat;
+
+/**
+ * Emergency Soundbank generator.
+ * Used when no other default soundbank can be found.
+ *
+ * @author Karl Helgason
+ */
+public class EmergencySoundbank {
+
+    private final static String[] general_midi_instruments = {
+        "Acoustic Grand Piano",
+        "Bright Acoustic Piano",
+        "Electric Grand Piano",
+        "Honky-tonk Piano",
+        "Electric Piano 1",
+        "Electric Piano 2",
+        "Harpsichord",
+        "Clavi",
+        "Celesta",
+        "Glockenspiel",
+        "Music Box",
+        "Vibraphone",
+        "Marimba",
+        "Xylophone",
+        "Tubular Bells",
+        "Dulcimer",
+        "Drawbar Organ",
+        "Percussive Organ",
+        "Rock Organ",
+        "Church Organ",
+        "Reed Organ",
+        "Accordion",
+        "Harmonica",
+        "Tango Accordion",
+        "Acoustic Guitar (nylon)",
+        "Acoustic Guitar (steel)",
+        "Electric Guitar (jazz)",
+        "Electric Guitar (clean)",
+        "Electric Guitar (muted)",
+        "Overdriven Guitar",
+        "Distortion Guitar",
+        "Guitar harmonics",
+        "Acoustic Bass",
+        "Electric Bass (finger)",
+        "Electric Bass (pick)",
+        "Fretless Bass",
+        "Slap Bass 1",
+        "Slap Bass 2",
+        "Synth Bass 1",
+        "Synth Bass 2",
+        "Violin",
+        "Viola",
+        "Cello",
+        "Contrabass",
+        "Tremolo Strings",
+        "Pizzicato Strings",
+        "Orchestral Harp",
+        "Timpani",
+        "String Ensemble 1",
+        "String Ensemble 2",
+        "SynthStrings 1",
+        "SynthStrings 2",
+        "Choir Aahs",
+        "Voice Oohs",
+        "Synth Voice",
+        "Orchestra Hit",
+        "Trumpet",
+        "Trombone",
+        "Tuba",
+        "Muted Trumpet",
+        "French Horn",
+        "Brass Section",
+        "SynthBrass 1",
+        "SynthBrass 2",
+        "Soprano Sax",
+        "Alto Sax",
+        "Tenor Sax",
+        "Baritone Sax",
+        "Oboe",
+        "English Horn",
+        "Bassoon",
+        "Clarinet",
+        "Piccolo",
+        "Flute",
+        "Recorder",
+        "Pan Flute",
+        "Blown Bottle",
+        "Shakuhachi",
+        "Whistle",
+        "Ocarina",
+        "Lead 1 (square)",
+        "Lead 2 (sawtooth)",
+        "Lead 3 (calliope)",
+        "Lead 4 (chiff)",
+        "Lead 5 (charang)",
+        "Lead 6 (voice)",
+        "Lead 7 (fifths)",
+        "Lead 8 (bass + lead)",
+        "Pad 1 (new age)",
+        "Pad 2 (warm)",
+        "Pad 3 (polysynth)",
+        "Pad 4 (choir)",
+        "Pad 5 (bowed)",
+        "Pad 6 (metallic)",
+        "Pad 7 (halo)",
+        "Pad 8 (sweep)",
+        "FX 1 (rain)",
+        "FX 2 (soundtrack)",
+        "FX 3 (crystal)",
+        "FX 4 (atmosphere)",
+        "FX 5 (brightness)",
+        "FX 6 (goblins)",
+        "FX 7 (echoes)",
+        "FX 8 (sci-fi)",
+        "Sitar",
+        "Banjo",
+        "Shamisen",
+        "Koto",
+        "Kalimba",
+        "Bag pipe",
+        "Fiddle",
+        "Shanai",
+        "Tinkle Bell",
+        "Agogo",
+        "Steel Drums",
+        "Woodblock",
+        "Taiko Drum",
+        "Melodic Tom",
+        "Synth Drum",
+        "Reverse Cymbal",
+        "Guitar Fret Noise",
+        "Breath Noise",
+        "Seashore",
+        "Bird Tweet",
+        "Telephone Ring",
+        "Helicopter",
+        "Applause",
+        "Gunshot"
+    };
+
+    public static SF2Soundbank createSoundbank() throws Exception {
+        SF2Soundbank sf2 = new SF2Soundbank();
+        sf2.setName("Emergency GM sound set");
+        sf2.setVendor("Generated");
+        sf2.setDescription("Emergency generated soundbank");
+
+        /*
+         *  percussion instruments
+         */
+
+        SF2Layer bass_drum = new_bass_drum(sf2);
+        SF2Layer snare_drum = new_snare_drum(sf2);
+        SF2Layer tom = new_tom(sf2);
+        SF2Layer open_hihat = new_open_hihat(sf2);
+        SF2Layer closed_hihat = new_closed_hihat(sf2);
+        SF2Layer crash_cymbal = new_crash_cymbal(sf2);
+        SF2Layer side_stick = new_side_stick(sf2);
+
+        SF2Layer[] drums = new SF2Layer[128];
+        drums[35] = bass_drum;
+        drums[36] = bass_drum;
+        drums[38] = snare_drum;
+        drums[40] = snare_drum;
+        drums[41] = tom;
+        drums[43] = tom;
+        drums[45] = tom;
+        drums[47] = tom;
+        drums[48] = tom;
+        drums[50] = tom;
+        drums[42] = closed_hihat;
+        drums[44] = closed_hihat;
+        drums[46] = open_hihat;
+        drums[49] = crash_cymbal;
+        drums[51] = crash_cymbal;
+        drums[52] = crash_cymbal;
+        drums[55] = crash_cymbal;
+        drums[57] = crash_cymbal;
+        drums[59] = crash_cymbal;
+
+        // Use side_stick for missing drums:
+        drums[37] = side_stick;
+        drums[39] = side_stick;
+        drums[53] = side_stick;
+        drums[54] = side_stick;
+        drums[56] = side_stick;
+        drums[58] = side_stick;
+        drums[69] = side_stick;
+        drums[70] = side_stick;
+        drums[75] = side_stick;
+        drums[60] = side_stick;
+        drums[61] = side_stick;
+        drums[62] = side_stick;
+        drums[63] = side_stick;
+        drums[64] = side_stick;
+        drums[65] = side_stick;
+        drums[66] = side_stick;
+        drums[67] = side_stick;
+        drums[68] = side_stick;
+        drums[71] = side_stick;
+        drums[72] = side_stick;
+        drums[73] = side_stick;
+        drums[74] = side_stick;
+        drums[76] = side_stick;
+        drums[77] = side_stick;
+        drums[78] = side_stick;
+        drums[79] = side_stick;
+        drums[80] = side_stick;
+        drums[81] = side_stick;
+
+
+        SF2Instrument drum_instrument = new SF2Instrument(sf2);
+        drum_instrument.setName("Standard Kit");
+        drum_instrument.setPatch(new ModelPatch(0, 0, true));
+        sf2.addInstrument(drum_instrument);
+        for (int i = 0; i < drums.length; i++) {
+            if (drums[i] != null) {
+                SF2InstrumentRegion region = new SF2InstrumentRegion();
+                region.setLayer(drums[i]);
+                region.putBytes(SF2InstrumentRegion.GENERATOR_KEYRANGE,
+                        new byte[]{(byte) i, (byte) i});
+                drum_instrument.getRegions().add(region);
+            }
+        }
+
+
+        /*
+         *  melodic instruments
+         */
+
+        SF2Layer gpiano = new_gpiano(sf2);
+        SF2Layer gpiano2 = new_gpiano2(sf2);
+        SF2Layer gpiano_hammer = new_piano_hammer(sf2);
+        SF2Layer piano1 = new_piano1(sf2);
+        SF2Layer epiano1 = new_epiano1(sf2);
+        SF2Layer epiano2 = new_epiano2(sf2);
+
+        SF2Layer guitar = new_guitar1(sf2);
+        SF2Layer guitar_pick = new_guitar_pick(sf2);
+        SF2Layer guitar_dist = new_guitar_dist(sf2);
+        SF2Layer bass1 = new_bass1(sf2);
+        SF2Layer bass2 = new_bass2(sf2);
+        SF2Layer synthbass = new_synthbass(sf2);
+        SF2Layer string2 = new_string2(sf2);
+        SF2Layer orchhit = new_orchhit(sf2);
+        SF2Layer choir = new_choir(sf2);
+        SF2Layer solostring = new_solostring(sf2);
+        SF2Layer organ = new_organ(sf2);
+        SF2Layer ch_organ = new_ch_organ(sf2);
+        SF2Layer bell = new_bell(sf2);
+        SF2Layer flute = new_flute(sf2);
+
+        SF2Layer timpani = new_timpani(sf2);
+        SF2Layer melodic_toms = new_melodic_toms(sf2);
+        SF2Layer trumpet = new_trumpet(sf2);
+        SF2Layer trombone = new_trombone(sf2);
+        SF2Layer brass_section = new_brass_section(sf2);
+        SF2Layer horn = new_horn(sf2);
+        SF2Layer sax = new_sax(sf2);
+        SF2Layer oboe = new_oboe(sf2);
+        SF2Layer bassoon = new_bassoon(sf2);
+        SF2Layer clarinet = new_clarinet(sf2);
+        SF2Layer reverse_cymbal = new_reverse_cymbal(sf2);
+
+        SF2Layer defaultsound = piano1;
+
+        newInstrument(sf2, "Piano", new Patch(0, 0), gpiano, gpiano_hammer);
+        newInstrument(sf2, "Piano", new Patch(0, 1), gpiano2, gpiano_hammer);
+        newInstrument(sf2, "Piano", new Patch(0, 2), piano1);
+        {
+            SF2Instrument ins = newInstrument(sf2, "Honky-tonk Piano",
+                    new Patch(0, 3), piano1, piano1);
+            SF2InstrumentRegion region = ins.getRegions().get(0);
+            region.putInteger(SF2Region.GENERATOR_INITIALFILTERFC, 80);
+            region.putInteger(SF2Region.GENERATOR_FINETUNE, 30);
+            region = ins.getRegions().get(1);
+            region.putInteger(SF2Region.GENERATOR_INITIALFILTERFC, 30);
+        }
+        newInstrument(sf2, "Rhodes", new Patch(0, 4), epiano2);
+        newInstrument(sf2, "Rhodes", new Patch(0, 5), epiano2);
+        newInstrument(sf2, "Clavinet", new Patch(0, 6), epiano1);
+        newInstrument(sf2, "Clavinet", new Patch(0, 7), epiano1);
+        newInstrument(sf2, "Rhodes", new Patch(0, 8), epiano2);
+        newInstrument(sf2, "Bell", new Patch(0, 9), bell);
+        newInstrument(sf2, "Bell", new Patch(0, 10), bell);
+        newInstrument(sf2, "Vibraphone", new Patch(0, 11), bell);
+        newInstrument(sf2, "Marimba", new Patch(0, 12), bell);
+        newInstrument(sf2, "Marimba", new Patch(0, 13), bell);
+        newInstrument(sf2, "Bell", new Patch(0, 14), bell);
+        newInstrument(sf2, "Rock Organ", new Patch(0, 15), organ);
+        newInstrument(sf2, "Rock Organ", new Patch(0, 16), organ);
+        newInstrument(sf2, "Perc Organ", new Patch(0, 17), organ);
+        newInstrument(sf2, "Rock Organ", new Patch(0, 18), organ);
+        newInstrument(sf2, "Church Organ", new Patch(0, 19), ch_organ);
+        newInstrument(sf2, "Accordion", new Patch(0, 20), organ);
+        newInstrument(sf2, "Accordion", new Patch(0, 21), organ);
+        newInstrument(sf2, "Accordion", new Patch(0, 22), organ);
+        newInstrument(sf2, "Accordion", new Patch(0, 23), organ);
+        newInstrument(sf2, "Guitar", new Patch(0, 24), guitar, guitar_pick);
+        newInstrument(sf2, "Guitar", new Patch(0, 25), guitar, guitar_pick);
+        newInstrument(sf2, "Guitar", new Patch(0, 26), guitar, guitar_pick);
+        newInstrument(sf2, "Guitar", new Patch(0, 27), guitar, guitar_pick);
+        newInstrument(sf2, "Guitar", new Patch(0, 28), guitar, guitar_pick);
+        newInstrument(sf2, "Distorted Guitar", new Patch(0, 29), guitar_dist);
+        newInstrument(sf2, "Distorted Guitar", new Patch(0, 30), guitar_dist);
+        newInstrument(sf2, "Guitar", new Patch(0, 31), guitar, guitar_pick);
+        newInstrument(sf2, "Finger Bass", new Patch(0, 32), bass1);
+        newInstrument(sf2, "Finger Bass", new Patch(0, 33), bass1);
+        newInstrument(sf2, "Finger Bass", new Patch(0, 34), bass1);
+        newInstrument(sf2, "Frettless Bass", new Patch(0, 35), bass2);
+        newInstrument(sf2, "Frettless Bass", new Patch(0, 36), bass2);
+        newInstrument(sf2, "Frettless Bass", new Patch(0, 37), bass2);
+        newInstrument(sf2, "Synth Bass1", new Patch(0, 38), synthbass);
+        newInstrument(sf2, "Synth Bass2", new Patch(0, 39), synthbass);
+        newInstrument(sf2, "Solo String", new Patch(0, 40), string2, solostring);
+        newInstrument(sf2, "Solo String", new Patch(0, 41), string2, solostring);
+        newInstrument(sf2, "Solo String", new Patch(0, 42), string2, solostring);
+        newInstrument(sf2, "Solo String", new Patch(0, 43), string2, solostring);
+        newInstrument(sf2, "Solo String", new Patch(0, 44), string2, solostring);
+        newInstrument(sf2, "Def", new Patch(0, 45), defaultsound);
+        newInstrument(sf2, "Harp", new Patch(0, 46), bell);
+        newInstrument(sf2, "Timpani", new Patch(0, 47), timpani);
+        newInstrument(sf2, "Strings", new Patch(0, 48), string2);
+        SF2Instrument slow_strings =
+                newInstrument(sf2, "Slow Strings", new Patch(0, 49), string2);
+        SF2InstrumentRegion region = slow_strings.getRegions().get(0);
+        region.putInteger(SF2Region.GENERATOR_ATTACKVOLENV, 2500);
+        region.putInteger(SF2Region.GENERATOR_RELEASEVOLENV, 2000);
+        newInstrument(sf2, "Synth Strings", new Patch(0, 50), string2);
+        newInstrument(sf2, "Synth Strings", new Patch(0, 51), string2);
+
+
+        newInstrument(sf2, "Choir", new Patch(0, 52), choir);
+        newInstrument(sf2, "Choir", new Patch(0, 53), choir);
+        newInstrument(sf2, "Choir", new Patch(0, 54), choir);
+        {
+            SF2Instrument ins = newInstrument(sf2, "Orch Hit",
+                    new Patch(0, 55), orchhit, orchhit, timpani);
+            region = ins.getRegions().get(0);
+            region.putInteger(SF2Region.GENERATOR_COARSETUNE, -12);
+            region.putInteger(SF2Region.GENERATOR_INITIALATTENUATION, -100);
+        }
+        newInstrument(sf2, "Trumpet", new Patch(0, 56), trumpet);
+        newInstrument(sf2, "Trombone", new Patch(0, 57), trombone);
+        newInstrument(sf2, "Trombone", new Patch(0, 58), trombone);
+        newInstrument(sf2, "Trumpet", new Patch(0, 59), trumpet);
+        newInstrument(sf2, "Horn", new Patch(0, 60), horn);
+        newInstrument(sf2, "Brass Section", new Patch(0, 61), brass_section);
+        newInstrument(sf2, "Brass Section", new Patch(0, 62), brass_section);
+        newInstrument(sf2, "Brass Section", new Patch(0, 63), brass_section);
+        newInstrument(sf2, "Sax", new Patch(0, 64), sax);
+        newInstrument(sf2, "Sax", new Patch(0, 65), sax);
+        newInstrument(sf2, "Sax", new Patch(0, 66), sax);
+        newInstrument(sf2, "Sax", new Patch(0, 67), sax);
+        newInstrument(sf2, "Oboe", new Patch(0, 68), oboe);
+        newInstrument(sf2, "Horn", new Patch(0, 69), horn);
+        newInstrument(sf2, "Bassoon", new Patch(0, 70), bassoon);
+        newInstrument(sf2, "Clarinet", new Patch(0, 71), clarinet);
+        newInstrument(sf2, "Flute", new Patch(0, 72), flute);
+        newInstrument(sf2, "Flute", new Patch(0, 73), flute);
+        newInstrument(sf2, "Flute", new Patch(0, 74), flute);
+        newInstrument(sf2, "Flute", new Patch(0, 75), flute);
+        newInstrument(sf2, "Flute", new Patch(0, 76), flute);
+        newInstrument(sf2, "Flute", new Patch(0, 77), flute);
+        newInstrument(sf2, "Flute", new Patch(0, 78), flute);
+        newInstrument(sf2, "Flute", new Patch(0, 79), flute);
+        newInstrument(sf2, "Organ", new Patch(0, 80), organ);
+        newInstrument(sf2, "Organ", new Patch(0, 81), organ);
+        newInstrument(sf2, "Flute", new Patch(0, 82), flute);
+        newInstrument(sf2, "Organ", new Patch(0, 83), organ);
+        newInstrument(sf2, "Organ", new Patch(0, 84), organ);
+        newInstrument(sf2, "Choir", new Patch(0, 85), choir);
+        newInstrument(sf2, "Organ", new Patch(0, 86), organ);
+        newInstrument(sf2, "Organ", new Patch(0, 87), organ);
+        newInstrument(sf2, "Synth Strings", new Patch(0, 88), string2);
+        newInstrument(sf2, "Organ", new Patch(0, 89), organ);
+        newInstrument(sf2, "Def", new Patch(0, 90), defaultsound);
+        newInstrument(sf2, "Choir", new Patch(0, 91), choir);
+        newInstrument(sf2, "Organ", new Patch(0, 92), organ);
+        newInstrument(sf2, "Organ", new Patch(0, 93), organ);
+        newInstrument(sf2, "Organ", new Patch(0, 94), organ);
+        newInstrument(sf2, "Organ", new Patch(0, 95), organ);
+        newInstrument(sf2, "Organ", new Patch(0, 96), organ);
+        newInstrument(sf2, "Organ", new Patch(0, 97), organ);
+        newInstrument(sf2, "Bell", new Patch(0, 98), bell);
+        newInstrument(sf2, "Organ", new Patch(0, 99), organ);
+        newInstrument(sf2, "Organ", new Patch(0, 100), organ);
+        newInstrument(sf2, "Organ", new Patch(0, 101), organ);
+        newInstrument(sf2, "Def", new Patch(0, 102), defaultsound);
+        newInstrument(sf2, "Synth Strings", new Patch(0, 103), string2);
+        newInstrument(sf2, "Def", new Patch(0, 104), defaultsound);
+        newInstrument(sf2, "Def", new Patch(0, 105), defaultsound);
+        newInstrument(sf2, "Def", new Patch(0, 106), defaultsound);
+        newInstrument(sf2, "Def", new Patch(0, 107), defaultsound);
+        newInstrument(sf2, "Marimba", new Patch(0, 108), bell);
+        newInstrument(sf2, "Sax", new Patch(0, 109), sax);
+        newInstrument(sf2, "Solo String", new Patch(0, 110), string2, solostring);
+        newInstrument(sf2, "Oboe", new Patch(0, 111), oboe);
+        newInstrument(sf2, "Bell", new Patch(0, 112), bell);
+        newInstrument(sf2, "Melodic Toms", new Patch(0, 113), melodic_toms);
+        newInstrument(sf2, "Marimba", new Patch(0, 114), bell);
+        newInstrument(sf2, "Melodic Toms", new Patch(0, 115), melodic_toms);
+        newInstrument(sf2, "Melodic Toms", new Patch(0, 116), melodic_toms);
+        newInstrument(sf2, "Melodic Toms", new Patch(0, 117), melodic_toms);
+        newInstrument(sf2, "Reverse Cymbal", new Patch(0, 118), reverse_cymbal);
+        newInstrument(sf2, "Reverse Cymbal", new Patch(0, 119), reverse_cymbal);
+        newInstrument(sf2, "Guitar", new Patch(0, 120), guitar);
+        newInstrument(sf2, "Def", new Patch(0, 121), defaultsound);
+        {
+            SF2Instrument ins = newInstrument(sf2, "Seashore/Reverse Cymbal",
+                    new Patch(0, 122), reverse_cymbal);
+            region = ins.getRegions().get(0);
+            region.putInteger(SF2Region.GENERATOR_SUSTAINVOLENV, 1000);
+            region.putInteger(SF2Region.GENERATOR_DECAYVOLENV, 18500);
+            region.putInteger(SF2Region.GENERATOR_RELEASEVOLENV, 4500);
+            region.putInteger(SF2Region.GENERATOR_INITIALFILTERFC, -4500);
+        }
+        {
+            SF2Instrument ins = newInstrument(sf2, "Bird/Flute",
+                    new Patch(0, 123), flute);
+            region = ins.getRegions().get(0);
+            region.putInteger(SF2Region.GENERATOR_COARSETUNE, 24);
+            region.putInteger(SF2Region.GENERATOR_DECAYVOLENV, -3000);
+            region.putInteger(SF2Region.GENERATOR_SUSTAINVOLENV, 1000);
+        }
+        newInstrument(sf2, "Def", new Patch(0, 124), side_stick);
+        {
+            SF2Instrument ins = newInstrument(sf2, "Seashore/Reverse Cymbal",
+                    new Patch(0, 125), reverse_cymbal);
+            region = ins.getRegions().get(0);
+            region.putInteger(SF2Region.GENERATOR_SUSTAINVOLENV, 1000);
+            region.putInteger(SF2Region.GENERATOR_DECAYVOLENV, 18500);
+            region.putInteger(SF2Region.GENERATOR_RELEASEVOLENV, 4500);
+            region.putInteger(SF2Region.GENERATOR_INITIALFILTERFC, -4500);
+        }
+        newInstrument(sf2, "Applause/crash_cymbal",
+                new Patch(0, 126), crash_cymbal);
+        newInstrument(sf2, "Gunshot/side_stick", new Patch(0, 127), side_stick);
+
+        for (SF2Instrument instrument : sf2.getInstruments()) {
+            Patch patch = instrument.getPatch();
+            if (patch instanceof ModelPatch) {
+                if (((ModelPatch) patch).isPercussion())
+                    continue;
+            }
+            instrument.setName(general_midi_instruments[patch.getProgram()]);
+        }
+
+        return sf2;
+
+    }
+
+    public static SF2Layer new_bell(SF2Soundbank sf2) {
+        Random random = new Random(102030201);
+        int x = 8;
+        int fftsize = 4096 * x;
+        double[] data = new double[fftsize * 2];
+        double base = x * 25;
+        double start_w = 0.01;
+        double end_w = 0.05;
+        double start_a = 0.2;
+        double end_a = 0.00001;
+        double a = start_a;
+        double a_step = Math.pow(end_a / start_a, 1.0 / 40.0);
+        for (int i = 0; i < 40; i++) {
+            double detune = 1 + (random.nextDouble() * 2 - 1) * 0.01;
+            double w = start_w + (end_w - start_w) * (i / 40.0);
+            complexGaussianDist(data, base * (i + 1) * detune, w, a);
+            a *= a_step;
+        }
+        SF2Sample sample = newSimpleFFTSample(sf2, "EPiano", data, base);
+        SF2Layer layer = newLayer(sf2, "EPiano", sample);
+        SF2Region region = layer.getRegions().get(0);
+        region.putInteger(SF2Region.GENERATOR_SAMPLEMODES, 1);
+        region.putInteger(SF2Region.GENERATOR_ATTACKVOLENV, -12000);
+        region.putInteger(SF2Region.GENERATOR_RELEASEVOLENV, 0);
+        region.putInteger(SF2Region.GENERATOR_DECAYVOLENV, 4000);
+        region.putInteger(SF2Region.GENERATOR_SUSTAINVOLENV, 1000);
+        region.putInteger(SF2Region.GENERATOR_ATTACKMODENV, 1200);
+        region.putInteger(SF2Region.GENERATOR_RELEASEMODENV, 12000);
+        region.putInteger(SF2Region.GENERATOR_MODENVTOFILTERFC, -9000);
+        region.putInteger(SF2Region.GENERATOR_INITIALFILTERFC, 16000);
+        return layer;
+    }
+
+    public static SF2Layer new_guitar1(SF2Soundbank sf2) {
+
+        int x = 8;
+        int fftsize = 4096 * x;
+        double[] data = new double[fftsize * 2];
+        double base = x * 25;
+        double start_w = 0.01;
+        double end_w = 0.01;
+        double start_a = 2;
+        double end_a = 0.01;
+        double a = start_a;
+        double a_step = Math.pow(end_a / start_a, 1.0 / 40.0);
+
+        double[] aa = new double[40];
+        for (int i = 0; i < 40; i++) {
+            aa[i] = a;
+            a *= a_step;
+        }
+
+        aa[0] = 2;
+        aa[1] = 0.5;
+        aa[2] = 0.45;
+        aa[3] = 0.2;
+        aa[4] = 1;
+        aa[5] = 0.5;
+        aa[6] = 2;
+        aa[7] = 1;
+        aa[8] = 0.5;
+        aa[9] = 1;
+        aa[9] = 0.5;
+        aa[10] = 0.2;
+        aa[11] = 1;
+        aa[12] = 0.7;
+        aa[13] = 0.5;
+        aa[14] = 1;
+
+        for (int i = 0; i < 40; i++) {
+            double w = start_w + (end_w - start_w) * (i / 40.0);
+            complexGaussianDist(data, base * (i + 1), w, aa[i]);
+        }
+
+        SF2Sample sample = newSimpleFFTSample(sf2, "Guitar", data, base);
+        SF2Layer layer = newLayer(sf2, "Guitar", sample);
+        SF2Region region = layer.getRegions().get(0);
+        region.putInteger(SF2Region.GENERATOR_SAMPLEMODES, 1);
+        region.putInteger(SF2Region.GENERATOR_ATTACKVOLENV, -12000);
+        region.putInteger(SF2Region.GENERATOR_RELEASEVOLENV, 0);
+        region.putInteger(SF2Region.GENERATOR_DECAYVOLENV, 2400);
+        region.putInteger(SF2Region.GENERATOR_SUSTAINVOLENV, 1000);
+
+        region.putInteger(SF2Region.GENERATOR_ATTACKMODENV, -100);
+        region.putInteger(SF2Region.GENERATOR_RELEASEMODENV, 12000);
+        region.putInteger(SF2Region.GENERATOR_MODENVTOFILTERFC, -6000);
+        region.putInteger(SF2Region.GENERATOR_INITIALFILTERFC, 16000);
+        region.putInteger(SF2Region.GENERATOR_INITIALATTENUATION, -20);
+        return layer;
+    }
+
+    public static SF2Layer new_guitar_dist(SF2Soundbank sf2) {
+
+        int x = 8;
+        int fftsize = 4096 * x;
+        double[] data = new double[fftsize * 2];
+        double base = x * 25;
+        double start_w = 0.01;
+        double end_w = 0.01;
+        double start_a = 2;
+        double end_a = 0.01;
+        double a = start_a;
+        double a_step = Math.pow(end_a / start_a, 1.0 / 40.0);
+
+        double[] aa = new double[40];
+        for (int i = 0; i < 40; i++) {
+            aa[i] = a;
+            a *= a_step;
+        }
+
+        aa[0] = 5;
+        aa[1] = 2;
+        aa[2] = 0.45;
+        aa[3] = 0.2;
+        aa[4] = 1;
+        aa[5] = 0.5;
+        aa[6] = 2;
+        aa[7] = 1;
+        aa[8] = 0.5;
+        aa[9] = 1;
+        aa[9] = 0.5;
+        aa[10] = 0.2;
+        aa[11] = 1;
+        aa[12] = 0.7;
+        aa[13] = 0.5;
+        aa[14] = 1;
+
+        for (int i = 0; i < 40; i++) {
+            double w = start_w + (end_w - start_w) * (i / 40.0);
+            complexGaussianDist(data, base * (i + 1), w, aa[i]);
+        }
+
+
+        SF2Sample sample = newSimpleFFTSample_dist(sf2, "Distorted Guitar",
+                data, base, 10000.0);
+
+
+        SF2Layer layer = newLayer(sf2, "Distorted Guitar", sample);
+        SF2Region region = layer.getRegions().get(0);
+        region.putInteger(SF2Region.GENERATOR_SAMPLEMODES, 1);
+        region.putInteger(SF2Region.GENERATOR_ATTACKVOLENV, -12000);
+        region.putInteger(SF2Region.GENERATOR_RELEASEVOLENV, 0);
+        //region.putInteger(SF2Region.GENERATOR_DECAYVOLENV, 2400);
+        //region.putInteger(SF2Region.GENERATOR_SUSTAINVOLENV, 200);
+
+        //region.putInteger(SF2Region.GENERATOR_ATTACKMODENV, -100);
+        //region.putInteger(SF2Region.GENERATOR_RELEASEMODENV, 12000);
+        //region.putInteger(SF2Region.GENERATOR_MODENVTOFILTERFC, -1000);
+        region.putInteger(SF2Region.GENERATOR_INITIALFILTERFC, 8000);
+        //region.putInteger(SF2Region.GENERATOR_INITIALATTENUATION, -20);
+        return layer;
+    }
+
+    public static SF2Layer new_guitar_pick(SF2Soundbank sf2) {
+
+        double datab[];
+
+        // Make treble part
+        {
+            int m = 2;
+            int fftlen = 4096 * m;
+            double[] data = new double[2 * fftlen];
+            Random random = new Random(3049912);
+            for (int i = 0; i < data.length; i += 2)
+                data[i] = (2.0 * (random.nextDouble() - 0.5));
+            fft(data);
+            // Remove all negative frequency
+            for (int i = fftlen / 2; i < data.length; i++)
+                data[i] = 0;
+            for (int i = 0; i < 2048 * m; i++) {
+                data[i] *= Math.exp(-Math.abs((i - 23) / ((double) m)) * 1.2)
+                        + Math.exp(-Math.abs((i - 40) / ((double) m)) * 0.9);
+            }
+            randomPhase(data, new Random(3049912));
+            ifft(data);
+            normalize(data, 0.8);
+            data = realPart(data);
+            double gain = 1.0;
+            for (int i = 0; i < data.length; i++) {
+                data[i] *= gain;
+                gain *= 0.9994;
+            }
+            datab = data;
+
+            fadeUp(data, 80);
+        }
+
+        SF2Sample sample = newSimpleDrumSample(sf2, "Guitar Noise", datab);
+
+        SF2Layer layer = new SF2Layer(sf2);
+        layer.setName("Guitar Noise");
+
+        SF2GlobalRegion global = new SF2GlobalRegion();
+        layer.setGlobalZone(global);
+        sf2.addResource(layer);
+
+        SF2LayerRegion region = new SF2LayerRegion();
+        region.putInteger(SF2Region.GENERATOR_RELEASEVOLENV, 12000);
+        //region.putInteger(SF2Region.GENERATOR_SCALETUNING, 0);
+//        region.putInteger(SF2Region.GENERATOR_INITIALATTENUATION, -100);
+/*
+        region.putInteger(SF2Region.GENERATOR_ATTACKMODENV, 0);
+        region.putInteger(SF2Region.GENERATOR_SUSTAINMODENV, 1000);
+        region.putInteger(SF2Region.GENERATOR_RELEASEMODENV, 12000);
+        region.putInteger(SF2Region.GENERATOR_MODENVTOFILTERFC, -11000);
+        region.putInteger(SF2Region.GENERATOR_INITIALFILTERFC, 12000);
+         */
+
+        region.setSample(sample);
+        layer.getRegions().add(region);
+
+        return layer;
+    }
+
+    public static SF2Layer new_gpiano(SF2Soundbank sf2) {
+        //Random random = new Random(302030201);
+        int x = 8;
+        int fftsize = 4096 * x;
+        double[] data = new double[fftsize * 2];
+        double base = x * 25;
+        double start_a = 0.2;
+        double end_a = 0.001;
+        double a = start_a;
+        double a_step = Math.pow(end_a / start_a, 1.0 / 15.0);
+
+        double[] aa = new double[30];
+        for (int i = 0; i < 30; i++) {
+            aa[i] = a;
+            a *= a_step;
+        }
+
+        aa[0] *= 2;
+        //aa[2] *= 0.1;
+        aa[4] *= 2;
+
+
+        aa[12] *= 0.9;
+        aa[13] *= 0.7;
+        for (int i = 14; i < 30; i++) {
+            aa[i] *= 0.5;
+        }
+
+
+        for (int i = 0; i < 30; i++) {
+            //double detune = 1 + (random.nextDouble()*2 - 1)*0.0001;
+            double w = 0.2;
+            double ai = aa[i];
+            if (i > 10) {
+                w = 5;
+                ai *= 10;
+            }
+            int adjust = 0;
+            if (i > 5) {
+                adjust = (i - 5) * 7;
+            }
+            complexGaussianDist(data, base * (i + 1) + adjust, w, ai);
+        }
+
+        SF2Sample sample = newSimpleFFTSample(sf2, "Grand Piano", data, base, 200);
+        SF2Layer layer = newLayer(sf2, "Grand Piano", sample);
+        SF2Region region = layer.getRegions().get(0);
+        region.putInteger(SF2Region.GENERATOR_SAMPLEMODES, 1);
+        region.putInteger(SF2Region.GENERATOR_ATTACKVOLENV, -7000);
+        region.putInteger(SF2Region.GENERATOR_RELEASEVOLENV, 0);
+        region.putInteger(SF2Region.GENERATOR_DECAYVOLENV, 4000);
+        region.putInteger(SF2Region.GENERATOR_SUSTAINVOLENV, 1000);
+        region.putInteger(SF2Region.GENERATOR_ATTACKMODENV, -6000);
+        region.putInteger(SF2Region.GENERATOR_RELEASEMODENV, 12000);
+        region.putInteger(SF2Region.GENERATOR_MODENVTOFILTERFC, -5500);
+        region.putInteger(SF2Region.GENERATOR_INITIALFILTERFC, 18000);
+        return layer;
+    }
+
+    public static SF2Layer new_gpiano2(SF2Soundbank sf2) {
+        //Random random = new Random(302030201);
+        int x = 8;
+        int fftsize = 4096 * x;
+        double[] data = new double[fftsize * 2];
+        double base = x * 25;
+        double start_a = 0.2;
+        double end_a = 0.001;
+        double a = start_a;
+        double a_step = Math.pow(end_a / start_a, 1.0 / 20.0);
+
+        double[] aa = new double[30];
+        for (int i = 0; i < 30; i++) {
+            aa[i] = a;
+            a *= a_step;
+        }
+
+        aa[0] *= 1;
+        //aa[2] *= 0.1;
+        aa[4] *= 2;
+
+
+        aa[12] *= 0.9;
+        aa[13] *= 0.7;
+        for (int i = 14; i < 30; i++) {
+            aa[i] *= 0.5;
+        }
+
+
+        for (int i = 0; i < 30; i++) {
+            //double detune = 1 + (random.nextDouble()*2 - 1)*0.0001;
+            double w = 0.2;
+            double ai = aa[i];
+            if (i > 10) {
+                w = 5;
+                ai *= 10;
+            }
+            int adjust = 0;
+            if (i > 5) {
+                adjust = (i - 5) * 7;
+            }
+            complexGaussianDist(data, base * (i + 1) + adjust, w, ai);
+        }
+
+        SF2Sample sample = newSimpleFFTSample(sf2, "Grand Piano", data, base, 200);
+        SF2Layer layer = newLayer(sf2, "Grand Piano", sample);
+        SF2Region region = layer.getRegions().get(0);
+        region.putInteger(SF2Region.GENERATOR_SAMPLEMODES, 1);
+        region.putInteger(SF2Region.GENERATOR_ATTACKVOLENV, -7000);
+        region.putInteger(SF2Region.GENERATOR_RELEASEVOLENV, 0);
+        region.putInteger(SF2Region.GENERATOR_DECAYVOLENV, 4000);
+        region.putInteger(SF2Region.GENERATOR_SUSTAINVOLENV, 1000);
+        region.putInteger(SF2Region.GENERATOR_ATTACKMODENV, -6000);
+        region.putInteger(SF2Region.GENERATOR_RELEASEMODENV, 12000);
+        region.putInteger(SF2Region.GENERATOR_MODENVTOFILTERFC, -5500);
+        region.putInteger(SF2Region.GENERATOR_INITIALFILTERFC, 18000);
+        return layer;
+    }
+
+    public static SF2Layer new_piano_hammer(SF2Soundbank sf2) {
+
+        double datab[];
+
+        // Make treble part
+        {
+            int m = 2;
+            int fftlen = 4096 * m;
+            double[] data = new double[2 * fftlen];
+            Random random = new Random(3049912);
+            for (int i = 0; i < data.length; i += 2)
+                data[i] = (2.0 * (random.nextDouble() - 0.5));
+            fft(data);
+            // Remove all negative frequency
+            for (int i = fftlen / 2; i < data.length; i++)
+                data[i] = 0;
+            for (int i = 0; i < 2048 * m; i++)
+                data[i] *= Math.exp(-Math.abs((i - 37) / ((double) m)) * 0.05);
+            randomPhase(data, new Random(3049912));
+            ifft(data);
+            normalize(data, 0.6);
+            data = realPart(data);
+            double gain = 1.0;
+            for (int i = 0; i < data.length; i++) {
+                data[i] *= gain;
+                gain *= 0.9997;
+            }
+            datab = data;
+
+            fadeUp(data, 80);
+        }
+
+        SF2Sample sample = newSimpleDrumSample(sf2, "Piano Hammer", datab);
+
+        SF2Layer layer = new SF2Layer(sf2);
+        layer.setName("Piano Hammer");
+
+        SF2GlobalRegion global = new SF2GlobalRegion();
+        layer.setGlobalZone(global);
+        sf2.addResource(layer);
+
+        SF2LayerRegion region = new SF2LayerRegion();
+        region.putInteger(SF2Region.GENERATOR_RELEASEVOLENV, 12000);
+        //region.putInteger(SF2Region.GENERATOR_SCALETUNING, 0);
+/*
+        region.putInteger(SF2Region.GENERATOR_ATTACKMODENV, 0);
+        region.putInteger(SF2Region.GENERATOR_SUSTAINMODENV, 1000);
+        region.putInteger(SF2Region.GENERATOR_RELEASEMODENV, 12000);
+        region.putInteger(SF2Region.GENERATOR_MODENVTOFILTERFC, -11000);
+        region.putInteger(SF2Region.GENERATOR_INITIALFILTERFC, 12000);
+         */
+
+        region.setSample(sample);
+        layer.getRegions().add(region);
+
+        return layer;
+    }
+
+    public static SF2Layer new_piano1(SF2Soundbank sf2) {
+        //Random random = new Random(302030201);
+        int x = 8;
+        int fftsize = 4096 * x;
+        double[] data = new double[fftsize * 2];
+        double base = x * 25;
+        double start_a = 0.2;
+        double end_a = 0.0001;
+        double a = start_a;
+        double a_step = Math.pow(end_a / start_a, 1.0 / 40.0);
+
+        double[] aa = new double[30];
+        for (int i = 0; i < 30; i++) {
+            aa[i] = a;
+            a *= a_step;
+        }
+
+        aa[0] *= 5;
+        aa[2] *= 0.1;
+        aa[7] *= 5;
+
+
+        for (int i = 0; i < 30; i++) {
+            //double detune = 1 + (random.nextDouble()*2 - 1)*0.0001;
+            double w = 0.2;
+            double ai = aa[i];
+            if (i > 12) {
+                w = 5;
+                ai *= 10;
+            }
+            int adjust = 0;
+            if (i > 5) {
+                adjust = (i - 5) * 7;
+            }
+            complexGaussianDist(data, base * (i + 1) + adjust, w, ai);
+        }
+
+        complexGaussianDist(data, base * (15.5), 1, 0.1);
+        complexGaussianDist(data, base * (17.5), 1, 0.01);
+
+        SF2Sample sample = newSimpleFFTSample(sf2, "EPiano", data, base, 200);
+        SF2Layer layer = newLayer(sf2, "EPiano", sample);
+        SF2Region region = layer.getRegions().get(0);
+        region.putInteger(SF2Region.GENERATOR_SAMPLEMODES, 1);
+        region.putInteger(SF2Region.GENERATOR_ATTACKVOLENV, -12000);
+        region.putInteger(SF2Region.GENERATOR_RELEASEVOLENV, 0);
+        region.putInteger(SF2Region.GENERATOR_DECAYVOLENV, 4000);
+        region.putInteger(SF2Region.GENERATOR_SUSTAINVOLENV, 1000);
+        region.putInteger(SF2Region.GENERATOR_ATTACKMODENV, -1200);
+        region.putInteger(SF2Region.GENERATOR_RELEASEMODENV, 12000);
+        region.putInteger(SF2Region.GENERATOR_MODENVTOFILTERFC, -5500);
+        region.putInteger(SF2Region.GENERATOR_INITIALFILTERFC, 16000);
+        return layer;
+    }
+
+    public static SF2Layer new_epiano1(SF2Soundbank sf2) {
+        Random random = new Random(302030201);
+        int x = 8;
+        int fftsize = 4096 * x;
+        double[] data = new double[fftsize * 2];
+        double base = x * 25;
+        double start_w = 0.05;
+        double end_w = 0.05;
+        double start_a = 0.2;
+        double end_a = 0.0001;
+        double a = start_a;
+        double a_step = Math.pow(end_a / start_a, 1.0 / 40.0);
+        for (int i = 0; i < 40; i++) {
+            double detune = 1 + (random.nextDouble() * 2 - 1) * 0.0001;
+            double w = start_w + (end_w - start_w) * (i / 40.0);
+            complexGaussianDist(data, base * (i + 1) * detune, w, a);
+            a *= a_step;
+        }
+
+
+
+        SF2Sample sample = newSimpleFFTSample(sf2, "EPiano", data, base);
+        SF2Layer layer = newLayer(sf2, "EPiano", sample);
+        SF2Region region = layer.getRegions().get(0);
+        region.putInteger(SF2Region.GENERATOR_SAMPLEMODES, 1);
+        region.putInteger(SF2Region.GENERATOR_ATTACKVOLENV, -12000);
+        region.putInteger(SF2Region.GENERATOR_RELEASEVOLENV, 0);
+        region.putInteger(SF2Region.GENERATOR_DECAYVOLENV, 4000);
+        region.putInteger(SF2Region.GENERATOR_SUSTAINVOLENV, 1000);
+        region.putInteger(SF2Region.GENERATOR_ATTACKMODENV, 1200);
+        region.putInteger(SF2Region.GENERATOR_RELEASEMODENV, 12000);
+        region.putInteger(SF2Region.GENERATOR_MODENVTOFILTERFC, -9000);
+        region.putInteger(SF2Region.GENERATOR_INITIALFILTERFC, 16000);
+        return layer;
+    }
+
+    public static SF2Layer new_epiano2(SF2Soundbank sf2) {
+        Random random = new Random(302030201);
+        int x = 8;
+        int fftsize = 4096 * x;
+        double[] data = new double[fftsize * 2];
+        double base = x * 25;
+        double start_w = 0.01;
+        double end_w = 0.05;
+        double start_a = 0.2;
+        double end_a = 0.00001;
+        double a = start_a;
+        double a_step = Math.pow(end_a / start_a, 1.0 / 40.0);
+        for (int i = 0; i < 40; i++) {
+            double detune = 1 + (random.nextDouble() * 2 - 1) * 0.0001;
+            double w = start_w + (end_w - start_w) * (i / 40.0);
+            complexGaussianDist(data, base * (i + 1) * detune, w, a);
+            a *= a_step;
+        }
+
+        SF2Sample sample = newSimpleFFTSample(sf2, "EPiano", data, base);
+        SF2Layer layer = newLayer(sf2, "EPiano", sample);
+        SF2Region region = layer.getRegions().get(0);
+        region.putInteger(SF2Region.GENERATOR_SAMPLEMODES, 1);
+        region.putInteger(SF2Region.GENERATOR_ATTACKVOLENV, -12000);
+        region.putInteger(SF2Region.GENERATOR_RELEASEVOLENV, 0);
+        region.putInteger(SF2Region.GENERATOR_DECAYVOLENV, 8000);
+        region.putInteger(SF2Region.GENERATOR_SUSTAINVOLENV, 1000);
+        region.putInteger(SF2Region.GENERATOR_ATTACKMODENV, 2400);
+        region.putInteger(SF2Region.GENERATOR_RELEASEMODENV, 12000);
+        region.putInteger(SF2Region.GENERATOR_MODENVTOFILTERFC, -9000);
+        region.putInteger(SF2Region.GENERATOR_INITIALFILTERFC, 16000);
+        region.putInteger(SF2Region.GENERATOR_INITIALATTENUATION, -100);
+        return layer;
+    }
+
+    public static SF2Layer new_bass1(SF2Soundbank sf2) {
+        int x = 8;
+        int fftsize = 4096 * x;
+        double[] data = new double[fftsize * 2];
+        double base = x * 25;
+        double start_w = 0.05;
+        double end_w = 0.05;
+        double start_a = 0.2;
+        double end_a = 0.02;
+        double a = start_a;
+        double a_step = Math.pow(end_a / start_a, 1.0 / 25.0);
+
+        double[] aa = new double[25];
+        for (int i = 0; i < 25; i++) {
+            aa[i] = a;
+            a *= a_step;
+        }
+
+        aa[0] *= 8;
+        aa[1] *= 4;
+        aa[3] *= 8;
+        aa[5] *= 8;
+
+        for (int i = 0; i < 25; i++) {
+            double w = start_w + (end_w - start_w) * (i / 40.0);
+            complexGaussianDist(data, base * (i + 1), w, aa[i]);
+        }
+
+
+        SF2Sample sample = newSimpleFFTSample(sf2, "Bass", data, base);
+        SF2Layer layer = newLayer(sf2, "Bass", sample);
+        SF2Region region = layer.getRegions().get(0);
+        region.putInteger(SF2Region.GENERATOR_SAMPLEMODES, 1);
+        region.putInteger(SF2Region.GENERATOR_ATTACKVOLENV, -12000);
+        region.putInteger(SF2Region.GENERATOR_RELEASEVOLENV, 0);
+        region.putInteger(SF2Region.GENERATOR_DECAYVOLENV, 4000);
+        region.putInteger(SF2Region.GENERATOR_SUSTAINVOLENV, 1000);
+        region.putInteger(SF2Region.GENERATOR_ATTACKMODENV, -3000);
+        region.putInteger(SF2Region.GENERATOR_RELEASEMODENV, 12000);
+        region.putInteger(SF2Region.GENERATOR_MODENVTOFILTERFC, -5000);
+        region.putInteger(SF2Region.GENERATOR_INITIALFILTERFC, 11000);
+        region.putInteger(SF2Region.GENERATOR_INITIALATTENUATION, -100);
+        return layer;
+    }
+
+    public static SF2Layer new_synthbass(SF2Soundbank sf2) {
+        int x = 8;
+        int fftsize = 4096 * x;
+        double[] data = new double[fftsize * 2];
+        double base = x * 25;
+        double start_w = 0.05;
+        double end_w = 0.05;
+        double start_a = 0.2;
+        double end_a = 0.02;
+        double a = start_a;
+        double a_step = Math.pow(end_a / start_a, 1.0 / 25.0);
+
+        double[] aa = new double[25];
+        for (int i = 0; i < 25; i++) {
+            aa[i] = a;
+            a *= a_step;
+        }
+
+        aa[0] *= 16;
+        aa[1] *= 4;
+        aa[3] *= 16;
+        aa[5] *= 8;
+
+        for (int i = 0; i < 25; i++) {
+            double w = start_w + (end_w - start_w) * (i / 40.0);
+            complexGaussianDist(data, base * (i + 1), w, aa[i]);
+        }
+
+
+        SF2Sample sample = newSimpleFFTSample(sf2, "Bass", data, base);
+        SF2Layer layer = newLayer(sf2, "Bass", sample);
+        SF2Region region = layer.getRegions().get(0);
+        region.putInteger(SF2Region.GENERATOR_SAMPLEMODES, 1);
+        region.putInteger(SF2Region.GENERATOR_ATTACKVOLENV, -12000);
+        region.putInteger(SF2Region.GENERATOR_RELEASEVOLENV, 0);
+        region.putInteger(SF2Region.GENERATOR_DECAYVOLENV, 4000);
+        region.putInteger(SF2Region.GENERATOR_SUSTAINVOLENV, 1000);
+        region.putInteger(SF2Region.GENERATOR_ATTACKMODENV, -3000);
+        region.putInteger(SF2Region.GENERATOR_RELEASEMODENV, 12000);
+        region.putInteger(SF2Region.GENERATOR_MODENVTOFILTERFC, -3000);
+        region.putInteger(SF2Region.GENERATOR_INITIALFILTERQ, 100);
+        region.putInteger(SF2Region.GENERATOR_INITIALFILTERFC, 8000);
+        region.putInteger(SF2Region.GENERATOR_INITIALATTENUATION, -100);
+        return layer;
+    }
+
+    public static SF2Layer new_bass2(SF2Soundbank sf2) {
+        int x = 8;
+        int fftsize = 4096 * x;
+        double[] data = new double[fftsize * 2];
+        double base = x * 25;
+        double start_w = 0.05;
+        double end_w = 0.05;
+        double start_a = 0.2;
+        double end_a = 0.002;
+        double a = start_a;
+        double a_step = Math.pow(end_a / start_a, 1.0 / 25.0);
+
+        double[] aa = new double[25];
+        for (int i = 0; i < 25; i++) {
+            aa[i] = a;
+            a *= a_step;
+        }
+
+        aa[0] *= 8;
+        aa[1] *= 4;
+        aa[3] *= 8;
+        aa[5] *= 8;
+
+        for (int i = 0; i < 25; i++) {
+            double w = start_w + (end_w - start_w) * (i / 40.0);
+            complexGaussianDist(data, base * (i + 1), w, aa[i]);
+        }
+
+
+        SF2Sample sample = newSimpleFFTSample(sf2, "Bass2", data, base);
+        SF2Layer layer = newLayer(sf2, "Bass2", sample);
+        SF2Region region = layer.getRegions().get(0);
+        region.putInteger(SF2Region.GENERATOR_SAMPLEMODES, 1);
+        region.putInteger(SF2Region.GENERATOR_ATTACKVOLENV, -8000);
+        region.putInteger(SF2Region.GENERATOR_RELEASEVOLENV, 0);
+        region.putInteger(SF2Region.GENERATOR_DECAYVOLENV, 4000);
+        region.putInteger(SF2Region.GENERATOR_SUSTAINVOLENV, 1000);
+        region.putInteger(SF2Region.GENERATOR_ATTACKMODENV, -6000);
+        region.putInteger(SF2Region.GENERATOR_RELEASEMODENV, 12000);
+        region.putInteger(SF2Region.GENERATOR_INITIALFILTERFC, 5000);
+        region.putInteger(SF2Region.GENERATOR_INITIALATTENUATION, -100);
+        return layer;
+    }
+
+    public static SF2Layer new_solostring(SF2Soundbank sf2) {
+        int x = 8;
+        int fftsize = 4096 * x;
+        double[] data = new double[fftsize * 2];
+        double base = x * 25;
+        double start_w = 2;
+        double end_w = 2;
+        double start_a = 0.2;
+        double end_a = 0.01;
+
+        double[] aa = new double[18];
+        double a = start_a;
+        double a_step = Math.pow(end_a / start_a, 1.0 / 40.0);
+        for (int i = 0; i < aa.length; i++) {
+            a *= a_step;
+            aa[i] = a;
+        }
+
+        aa[0] *= 5;
+        aa[1] *= 5;
+        aa[2] *= 5;
+        aa[3] *= 4;
+        aa[4] *= 4;
+        aa[5] *= 3;
+        aa[6] *= 3;
+        aa[7] *= 2;
+
+        for (int i = 0; i < aa.length; i++) {
+            double w = start_w + (end_w - start_w) * (i / 40.0);
+            complexGaussianDist(data, base * (i + 1), w, a);
+        }
+        SF2Sample sample = newSimpleFFTSample(sf2, "Strings", data, base);
+        SF2Layer layer = newLayer(sf2, "Strings", sample);
+        SF2Region region = layer.getRegions().get(0);
+        region.putInteger(SF2Region.GENERATOR_SAMPLEMODES, 1);
+        region.putInteger(SF2Region.GENERATOR_ATTACKVOLENV, -5000);
+        region.putInteger(SF2Region.GENERATOR_RELEASEVOLENV, 1000);
+        region.putInteger(SF2Region.GENERATOR_DECAYVOLENV, 4000);
+        region.putInteger(SF2Region.GENERATOR_SUSTAINVOLENV, -100);
+        region.putInteger(SF2Region.GENERATOR_INITIALFILTERFC, 9500);
+        region.putInteger(SF2Region.GENERATOR_FREQVIBLFO, -1000);
+        region.putInteger(SF2Region.GENERATOR_VIBLFOTOPITCH, 15);
+        return layer;
+
+    }
+
+    public static SF2Layer new_orchhit(SF2Soundbank sf2) {
+        int x = 8;
+        int fftsize = 4096 * x;
+        double[] data = new double[fftsize * 2];
+        double base = x * 25;
+        double start_w = 2;
+        double end_w = 80;
+        double start_a = 0.2;
+        double end_a = 0.001;
+        double a = start_a;
+        double a_step = Math.pow(end_a / start_a, 1.0 / 40.0);
+        for (int i = 0; i < 40; i++) {
+            double w = start_w + (end_w - start_w) * (i / 40.0);
+            complexGaussianDist(data, base * (i + 1), w, a);
+            a *= a_step;
+        }
+        complexGaussianDist(data, base * 4, 300, 1);
+
+
+        SF2Sample sample = newSimpleFFTSample(sf2, "Och Strings", data, base);
+        SF2Layer layer = newLayer(sf2, "Och Strings", sample);
+        SF2Region region = layer.getRegions().get(0);
+        region.putInteger(SF2Region.GENERATOR_SAMPLEMODES, 1);
+        region.putInteger(SF2Region.GENERATOR_ATTACKVOLENV, -5000);
+        region.putInteger(SF2Region.GENERATOR_RELEASEVOLENV, 200);
+        region.putInteger(SF2Region.GENERATOR_DECAYVOLENV, 200);
+        region.putInteger(SF2Region.GENERATOR_SUSTAINVOLENV, 1000);
+        region.putInteger(SF2Region.GENERATOR_INITIALFILTERFC, 9500);
+        return layer;
+
+    }
+
+    public static SF2Layer new_string2(SF2Soundbank sf2) {
+        int x = 8;
+        int fftsize = 4096 * x;
+        double[] data = new double[fftsize * 2];
+        double base = x * 25;
+        double start_w = 2;
+        double end_w = 80;
+        double start_a = 0.2;
+        double end_a = 0.001;
+        double a = start_a;
+        double a_step = Math.pow(end_a / start_a, 1.0 / 40.0);
+        for (int i = 0; i < 40; i++) {
+            double w = start_w + (end_w - start_w) * (i / 40.0);
+            complexGaussianDist(data, base * (i + 1), w, a);
+            a *= a_step;
+        }
+        SF2Sample sample = newSimpleFFTSample(sf2, "Strings", data, base);
+        SF2Layer layer = newLayer(sf2, "Strings", sample);
+        SF2Region region = layer.getRegions().get(0);
+        region.putInteger(SF2Region.GENERATOR_SAMPLEMODES, 1);
+        region.putInteger(SF2Region.GENERATOR_ATTACKVOLENV, -5000);
+        region.putInteger(SF2Region.GENERATOR_RELEASEVOLENV, 1000);
+        region.putInteger(SF2Region.GENERATOR_DECAYVOLENV, 4000);
+        region.putInteger(SF2Region.GENERATOR_SUSTAINVOLENV, -100);
+        region.putInteger(SF2Region.GENERATOR_INITIALFILTERFC, 9500);
+        return layer;
+
+    }
+
+    public static SF2Layer new_choir(SF2Soundbank sf2) {
+        int x = 8;
+        int fftsize = 4096 * x;
+        double[] data = new double[fftsize * 2];
+        double base = x * 25;
+        double start_w = 2;
+        double end_w = 80;
+        double start_a = 0.2;
+        double end_a = 0.001;
+        double a = start_a;
+        double a_step = Math.pow(end_a / start_a, 1.0 / 40.0);
+        double[] aa = new double[40];
+        for (int i = 0; i < aa.length; i++) {
+            a *= a_step;
+            aa[i] = a;
+        }
+
+        aa[5] *= 0.1;
+        aa[6] *= 0.01;
+        aa[7] *= 0.1;
+        aa[8] *= 0.1;
+
+        for (int i = 0; i < aa.length; i++) {
+            double w = start_w + (end_w - start_w) * (i / 40.0);
+            complexGaussianDist(data, base * (i + 1), w, aa[i]);
+        }
+        SF2Sample sample = newSimpleFFTSample(sf2, "Strings", data, base);
+        SF2Layer layer = newLayer(sf2, "Strings", sample);
+        SF2Region region = layer.getRegions().get(0);
+        region.putInteger(SF2Region.GENERATOR_SAMPLEMODES, 1);
+        region.putInteger(SF2Region.GENERATOR_ATTACKVOLENV, -5000);
+        region.putInteger(SF2Region.GENERATOR_RELEASEVOLENV, 1000);
+        region.putInteger(SF2Region.GENERATOR_DECAYVOLENV, 4000);
+        region.putInteger(SF2Region.GENERATOR_SUSTAINVOLENV, -100);
+        region.putInteger(SF2Region.GENERATOR_INITIALFILTERFC, 9500);
+        return layer;
+
+    }
+
+    public static SF2Layer new_organ(SF2Soundbank sf2) {
+        Random random = new Random(102030201);
+        int x = 1;
+        int fftsize = 4096 * x;
+        double[] data = new double[fftsize * 2];
+        double base = x * 15;
+        double start_w = 0.01;
+        double end_w = 0.01;
+        double start_a = 0.2;
+        double end_a = 0.001;
+        double a = start_a;
+        double a_step = Math.pow(end_a / start_a, 1.0 / 40.0);
+
+        for (int i = 0; i < 12; i++) {
+            double w = start_w + (end_w - start_w) * (i / 40.0);
+            complexGaussianDist(data, base * (i + 1), w,
+                    a * (0.5 + 3 * (random.nextDouble())));
+            a *= a_step;
+        }
+        SF2Sample sample = newSimpleFFTSample(sf2, "Organ", data, base);
+        SF2Layer layer = newLayer(sf2, "Organ", sample);
+        SF2Region region = layer.getRegions().get(0);
+        region.putInteger(SF2Region.GENERATOR_SAMPLEMODES, 1);
+        region.putInteger(SF2Region.GENERATOR_ATTACKVOLENV, -6000);
+        region.putInteger(SF2Region.GENERATOR_RELEASEVOLENV, -1000);
+        region.putInteger(SF2Region.GENERATOR_DECAYVOLENV, 4000);
+        region.putInteger(SF2Region.GENERATOR_SUSTAINVOLENV, -100);
+        region.putInteger(SF2Region.GENERATOR_INITIALFILTERFC, 9500);
+        return layer;
+
+    }
+
+    public static SF2Layer new_ch_organ(SF2Soundbank sf2) {
+        int x = 1;
+        int fftsize = 4096 * x;
+        double[] data = new double[fftsize * 2];
+        double base = x * 15;
+        double start_w = 0.01;
+        double end_w = 0.01;
+        double start_a = 0.2;
+        double end_a = 0.001;
+        double a = start_a;
+        double a_step = Math.pow(end_a / start_a, 1.0 / 60.0);
+
+        double[] aa = new double[60];
+        for (int i = 0; i < aa.length; i++) {
+            a *= a_step;
+            aa[i] = a;
+        }
+
+        aa[0] *= 5;
+        aa[1] *= 2;
+        aa[2] = 0;
+        aa[4] = 0;
+        aa[5] = 0;
+        aa[7] *= 7;
+        aa[9] = 0;
+        aa[10] = 0;
+        aa[12] = 0;
+        aa[15] *= 7;
+        aa[18] = 0;
+        aa[20] = 0;
+        aa[24] = 0;
+        aa[27] *= 5;
+        aa[29] = 0;
+        aa[30] = 0;
+        aa[33] = 0;
+        aa[36] *= 4;
+        aa[37] = 0;
+        aa[39] = 0;
+        aa[42] = 0;
+        aa[43] = 0;
+        aa[47] = 0;
+        aa[50] *= 4;
+        aa[52] = 0;
+        aa[55] = 0;
+        aa[57] = 0;
+
+
+        aa[10] *= 0.1;
+        aa[11] *= 0.1;
+        aa[12] *= 0.1;
+        aa[13] *= 0.1;
+
+        aa[17] *= 0.1;
+        aa[18] *= 0.1;
+        aa[19] *= 0.1;
+        aa[20] *= 0.1;
+
+        for (int i = 0; i < 60; i++) {
+            double w = start_w + (end_w - start_w) * (i / 40.0);
+            complexGaussianDist(data, base * (i + 1), w, aa[i]);
+            a *= a_step;
+        }
+        SF2Sample sample = newSimpleFFTSample(sf2, "Organ", data, base);
+        SF2Layer layer = newLayer(sf2, "Organ", sample);
+        SF2Region region = layer.getRegions().get(0);
+        region.putInteger(SF2Region.GENERATOR_SAMPLEMODES, 1);
+        region.putInteger(SF2Region.GENERATOR_ATTACKVOLENV, -10000);
+        region.putInteger(SF2Region.GENERATOR_RELEASEVOLENV, -1000);
+        return layer;
+
+    }
+
+    public static SF2Layer new_flute(SF2Soundbank sf2) {
+        int x = 8;
+        int fftsize = 4096 * x;
+        double[] data = new double[fftsize * 2];
+        double base = x * 15;
+
+        complexGaussianDist(data, base * 1, 0.001, 0.5);
+        complexGaussianDist(data, base * 2, 0.001, 0.5);
+        complexGaussianDist(data, base * 3, 0.001, 0.5);
+        complexGaussianDist(data, base * 4, 0.01, 0.5);
+
+        complexGaussianDist(data, base * 4, 100, 120);
+        complexGaussianDist(data, base * 6, 100, 40);
+        complexGaussianDist(data, base * 8, 100, 80);
+
+        complexGaussianDist(data, base * 5, 0.001, 0.05);
+        complexGaussianDist(data, base * 6, 0.001, 0.06);
+        complexGaussianDist(data, base * 7, 0.001, 0.04);
+        complexGaussianDist(data, base * 8, 0.005, 0.06);
+        complexGaussianDist(data, base * 9, 0.005, 0.06);
+        complexGaussianDist(data, base * 10, 0.01, 0.1);
+        complexGaussianDist(data, base * 11, 0.08, 0.7);
+        complexGaussianDist(data, base * 12, 0.08, 0.6);
+        complexGaussianDist(data, base * 13, 0.08, 0.6);
+        complexGaussianDist(data, base * 14, 0.08, 0.6);
+        complexGaussianDist(data, base * 15, 0.08, 0.5);
+        complexGaussianDist(data, base * 16, 0.08, 0.5);
+        complexGaussianDist(data, base * 17, 0.08, 0.2);
+
+
+        complexGaussianDist(data, base * 1, 10, 8);
+        complexGaussianDist(data, base * 2, 10, 8);
+        complexGaussianDist(data, base * 3, 10, 8);
+        complexGaussianDist(data, base * 4, 10, 8);
+        complexGaussianDist(data, base * 5, 10, 8);
+        complexGaussianDist(data, base * 6, 20, 9);
+        complexGaussianDist(data, base * 7, 20, 9);
+        complexGaussianDist(data, base * 8, 20, 9);
+        complexGaussianDist(data, base * 9, 20, 8);
+        complexGaussianDist(data, base * 10, 30, 8);
+        complexGaussianDist(data, base * 11, 30, 9);
+        complexGaussianDist(data, base * 12, 30, 9);
+        complexGaussianDist(data, base * 13, 30, 8);
+        complexGaussianDist(data, base * 14, 30, 8);
+        complexGaussianDist(data, base * 15, 30, 7);
+        complexGaussianDist(data, base * 16, 30, 7);
+        complexGaussianDist(data, base * 17, 30, 6);
+
+        SF2Sample sample = newSimpleFFTSample(sf2, "Flute", data, base);
+        SF2Layer layer = newLayer(sf2, "Flute", sample);
+        SF2Region region = layer.getRegions().get(0);
+        region.putInteger(SF2Region.GENERATOR_SAMPLEMODES, 1);
+        region.putInteger(SF2Region.GENERATOR_ATTACKVOLENV, -6000);
+        region.putInteger(SF2Region.GENERATOR_RELEASEVOLENV, -1000);
+        region.putInteger(SF2Region.GENERATOR_DECAYVOLENV, 4000);
+        region.putInteger(SF2Region.GENERATOR_SUSTAINVOLENV, -100);
+        region.putInteger(SF2Region.GENERATOR_INITIALFILTERFC, 9500);
+        return layer;
+
+    }
+
+    public static SF2Layer new_horn(SF2Soundbank sf2) {
+        int x = 8;
+        int fftsize = 4096 * x;
+        double[] data = new double[fftsize * 2];
+        double base = x * 15;
+
+        double start_a = 0.5;
+        double end_a = 0.00000000001;
+        double a = start_a;
+        double a_step = Math.pow(end_a / start_a, 1.0 / 40.0);
+        for (int i = 0; i < 40; i++) {
+            if (i == 0)
+                complexGaussianDist(data, base * (i + 1), 0.1, a * 0.2);
+            else
+                complexGaussianDist(data, base * (i + 1), 0.1, a);
+            a *= a_step;
+        }
+
+        complexGaussianDist(data, base * 2, 100, 1);
+
+
+        SF2Sample sample = newSimpleFFTSample(sf2, "Horn", data, base);
+        SF2Layer layer = newLayer(sf2, "Horn", sample);
+        SF2Region region = layer.getRegions().get(0);
+        region.putInteger(SF2Region.GENERATOR_SAMPLEMODES, 1);
+        region.putInteger(SF2Region.GENERATOR_ATTACKVOLENV, -6000);
+        region.putInteger(SF2Region.GENERATOR_RELEASEVOLENV, -1000);
+        region.putInteger(SF2Region.GENERATOR_DECAYVOLENV, 4000);
+        region.putInteger(SF2Region.GENERATOR_SUSTAINVOLENV, -100);
+
+        region.putInteger(SF2Region.GENERATOR_ATTACKMODENV, -500);
+        region.putInteger(SF2Region.GENERATOR_RELEASEMODENV, 12000);
+        region.putInteger(SF2Region.GENERATOR_MODENVTOFILTERFC, 5000);
+        region.putInteger(SF2Region.GENERATOR_INITIALFILTERFC, 4500);
+        return layer;
+
+    }
+
+    public static SF2Layer new_trumpet(SF2Soundbank sf2) {
+        int x = 8;
+        int fftsize = 4096 * x;
+        double[] data = new double[fftsize * 2];
+        double base = x * 15;
+
+        double start_a = 0.5;
+        double end_a = 0.00001;
+        double a = start_a;
+        double a_step = Math.pow(end_a / start_a, 1.0 / 80.0);
+        double[] aa = new double[80];
+        for (int i = 0; i < 80; i++) {
+            aa[i] = a;
+            a *= a_step;
+        }
+
+        aa[0] *= 0.05;
+        aa[1] *= 0.2;
+        aa[2] *= 0.5;
+        aa[3] *= 0.85;
+
+        for (int i = 0; i < 80; i++) {
+            complexGaussianDist(data, base * (i + 1), 0.1, aa[i]);
+        }
+
+        complexGaussianDist(data, base * 5, 300, 3);
+
+
+        SF2Sample sample = newSimpleFFTSample(sf2, "Trumpet", data, base);
+        SF2Layer layer = newLayer(sf2, "Trumpet", sample);
+        SF2Region region = layer.getRegions().get(0);
+        region.putInteger(SF2Region.GENERATOR_SAMPLEMODES, 1);
+        region.putInteger(SF2Region.GENERATOR_ATTACKVOLENV, -10000);
+        region.putInteger(SF2Region.GENERATOR_RELEASEVOLENV, 0);
+        region.putInteger(SF2Region.GENERATOR_DECAYVOLENV, 4000);
+        region.putInteger(SF2Region.GENERATOR_SUSTAINVOLENV, -100);
+
+        region.putInteger(SF2Region.GENERATOR_ATTACKMODENV, -4000);
+        region.putInteger(SF2Region.GENERATOR_RELEASEMODENV, -2500);
+        region.putInteger(SF2Region.GENERATOR_MODENVTOFILTERFC, 5000);
+        region.putInteger(SF2Region.GENERATOR_INITIALFILTERFC, 4500);
+        region.putInteger(SF2Region.GENERATOR_INITIALFILTERQ, 10);
+        return layer;
+
+    }
+
+    public static SF2Layer new_brass_section(SF2Soundbank sf2) {
+        int x = 8;
+        int fftsize = 4096 * x;
+        double[] data = new double[fftsize * 2];
+        double base = x * 15;
+
+        double start_a = 0.5;
+        double end_a = 0.005;
+        double a = start_a;
+        double a_step = Math.pow(end_a / start_a, 1.0 / 30.0);
+        double[] aa = new double[30];
+        for (int i = 0; i < 30; i++) {
+            aa[i] = a;
+            a *= a_step;
+        }
+
+        aa[0] *= 0.8;
+        aa[1] *= 0.9;
+
+        double w = 5;
+        for (int i = 0; i < 30; i++) {
+            complexGaussianDist(data, base * (i + 1), 0.1 * w, aa[i] * w);
+            w += 6; //*= w_step;
+        }
+
+        complexGaussianDist(data, base * 6, 300, 2);
+
+
+        SF2Sample sample = newSimpleFFTSample(sf2, "Brass Section", data, base);
+        SF2Layer layer = newLayer(sf2, "Brass Section", sample);
+        SF2Region region = layer.getRegions().get(0);
+        region.putInteger(SF2Region.GENERATOR_SAMPLEMODES, 1);
+        region.putInteger(SF2Region.GENERATOR_ATTACKVOLENV, -9200);
+        region.putInteger(SF2Region.GENERATOR_RELEASEVOLENV, -1000);
+        region.putInteger(SF2Region.GENERATOR_DECAYVOLENV, 4000);
+        region.putInteger(SF2Region.GENERATOR_SUSTAINVOLENV, -100);
+
+        region.putInteger(SF2Region.GENERATOR_ATTACKMODENV, -3000);
+        region.putInteger(SF2Region.GENERATOR_RELEASEMODENV, 12000);
+        region.putInteger(SF2Region.GENERATOR_MODENVTOFILTERFC, 5000);
+        region.putInteger(SF2Region.GENERATOR_INITIALFILTERFC, 4500);
+        return layer;
+
+    }
+
+    public static SF2Layer new_trombone(SF2Soundbank sf2) {
+        int x = 8;
+        int fftsize = 4096 * x;
+        double[] data = new double[fftsize * 2];
+        double base = x * 15;
+
+        double start_a = 0.5;
+        double end_a = 0.001;
+        double a = start_a;
+        double a_step = Math.pow(end_a / start_a, 1.0 / 80.0);
+        double[] aa = new double[80];
+        for (int i = 0; i < 80; i++) {
+            aa[i] = a;
+            a *= a_step;
+        }
+
+        aa[0] *= 0.3;
+        aa[1] *= 0.7;
+
+        for (int i = 0; i < 80; i++) {
+            complexGaussianDist(data, base * (i + 1), 0.1, aa[i]);
+        }
+
+        complexGaussianDist(data, base * 6, 300, 2);
+
+
+        SF2Sample sample = newSimpleFFTSample(sf2, "Trombone", data, base);
+        SF2Layer layer = newLayer(sf2, "Trombone", sample);
+        SF2Region region = layer.getRegions().get(0);
+        region.putInteger(SF2Region.GENERATOR_SAMPLEMODES, 1);
+        region.putInteger(SF2Region.GENERATOR_ATTACKVOLENV, -8000);
+        region.putInteger(SF2Region.GENERATOR_RELEASEVOLENV, -1000);
+        region.putInteger(SF2Region.GENERATOR_DECAYVOLENV, 4000);
+        region.putInteger(SF2Region.GENERATOR_SUSTAINVOLENV, -100);
+
+        region.putInteger(SF2Region.GENERATOR_ATTACKMODENV, -2000);
+        region.putInteger(SF2Region.GENERATOR_RELEASEMODENV, 12000);
+        region.putInteger(SF2Region.GENERATOR_MODENVTOFILTERFC, 5000);
+        region.putInteger(SF2Region.GENERATOR_INITIALFILTERFC, 4500);
+        region.putInteger(SF2Region.GENERATOR_INITIALFILTERQ, 10);
+        return layer;
+
+    }
+
+    public static SF2Layer new_sax(SF2Soundbank sf2) {
+        int x = 8;
+        int fftsize = 4096 * x;
+        double[] data = new double[fftsize * 2];
+        double base = x * 15;
+
+        double start_a = 0.5;
+        double end_a = 0.01;
+        double a = start_a;
+        double a_step = Math.pow(end_a / start_a, 1.0 / 40.0);
+        for (int i = 0; i < 40; i++) {
+            if (i == 0 || i == 2)
+                complexGaussianDist(data, base * (i + 1), 0.1, a * 4);
+            else
+                complexGaussianDist(data, base * (i + 1), 0.1, a);
+            a *= a_step;
+        }
+
+        complexGaussianDist(data, base * 4, 200, 1);
+
+        SF2Sample sample = newSimpleFFTSample(sf2, "Sax", data, base);
+        SF2Layer layer = newLayer(sf2, "Sax", sample);
+        SF2Region region = layer.getRegions().get(0);
+        region.putInteger(SF2Region.GENERATOR_SAMPLEMODES, 1);
+        region.putInteger(SF2Region.GENERATOR_ATTACKVOLENV, -6000);
+        region.putInteger(SF2Region.GENERATOR_RELEASEVOLENV, -1000);
+        region.putInteger(SF2Region.GENERATOR_DECAYVOLENV, 4000);
+        region.putInteger(SF2Region.GENERATOR_SUSTAINVOLENV, -100);
+
+        region.putInteger(SF2Region.GENERATOR_ATTACKMODENV, -3000);
+        region.putInteger(SF2Region.GENERATOR_RELEASEMODENV, 12000);
+        region.putInteger(SF2Region.GENERATOR_MODENVTOFILTERFC, 5000);
+        region.putInteger(SF2Region.GENERATOR_INITIALFILTERFC, 4500);
+        return layer;
+
+    }
+
+    public static SF2Layer new_oboe(SF2Soundbank sf2) {
+        int x = 8;
+        int fftsize = 4096 * x;
+        double[] data = new double[fftsize * 2];
+        double base = x * 15;
+
+        complexGaussianDist(data, base * 5, 100, 80);
+
+
+        complexGaussianDist(data, base * 1, 0.01, 0.53);
+        complexGaussianDist(data, base * 2, 0.01, 0.51);
+        complexGaussianDist(data, base * 3, 0.01, 0.48);
+        complexGaussianDist(data, base * 4, 0.01, 0.49);
+        complexGaussianDist(data, base * 5, 0.01, 5);
+        complexGaussianDist(data, base * 6, 0.01, 0.51);
+        complexGaussianDist(data, base * 7, 0.01, 0.50);
+        complexGaussianDist(data, base * 8, 0.01, 0.59);
+        complexGaussianDist(data, base * 9, 0.01, 0.61);
+        complexGaussianDist(data, base * 10, 0.01, 0.52);
+        complexGaussianDist(data, base * 11, 0.01, 0.49);
+        complexGaussianDist(data, base * 12, 0.01, 0.51);
+        complexGaussianDist(data, base * 13, 0.01, 0.48);
+        complexGaussianDist(data, base * 14, 0.01, 0.51);
+        complexGaussianDist(data, base * 15, 0.01, 0.46);
+        complexGaussianDist(data, base * 16, 0.01, 0.35);
+        complexGaussianDist(data, base * 17, 0.01, 0.20);
+        complexGaussianDist(data, base * 18, 0.01, 0.10);
+        complexGaussianDist(data, base * 19, 0.01, 0.5);
+        complexGaussianDist(data, base * 20, 0.01, 0.1);
+
+
+        SF2Sample sample = newSimpleFFTSample(sf2, "Oboe", data, base);
+        SF2Layer layer = newLayer(sf2, "Oboe", sample);
+        SF2Region region = layer.getRegions().get(0);
+        region.putInteger(SF2Region.GENERATOR_SAMPLEMODES, 1);
+        region.putInteger(SF2Region.GENERATOR_ATTACKVOLENV, -6000);
+        region.putInteger(SF2Region.GENERATOR_RELEASEVOLENV, -1000);
+        region.putInteger(SF2Region.GENERATOR_DECAYVOLENV, 4000);
+        region.putInteger(SF2Region.GENERATOR_SUSTAINVOLENV, -100);
+        region.putInteger(SF2Region.GENERATOR_INITIALFILTERFC, 9500);
+        return layer;
+
+    }
+
+    public static SF2Layer new_bassoon(SF2Soundbank sf2) {
+        int x = 8;
+        int fftsize = 4096 * x;
+        double[] data = new double[fftsize * 2];
+        double base = x * 15;
+
+        complexGaussianDist(data, base * 2, 100, 40);
+        complexGaussianDist(data, base * 4, 100, 20);
+
+        complexGaussianDist(data, base * 1, 0.01, 0.53);
+        complexGaussianDist(data, base * 2, 0.01, 5);
+        complexGaussianDist(data, base * 3, 0.01, 0.51);
+        complexGaussianDist(data, base * 4, 0.01, 0.48);
+        complexGaussianDist(data, base * 5, 0.01, 1.49);
+        complexGaussianDist(data, base * 6, 0.01, 0.51);
+        complexGaussianDist(data, base * 7, 0.01, 0.50);
+        complexGaussianDist(data, base * 8, 0.01, 0.59);
+        complexGaussianDist(data, base * 9, 0.01, 0.61);
+        complexGaussianDist(data, base * 10, 0.01, 0.52);
+        complexGaussianDist(data, base * 11, 0.01, 0.49);
+        complexGaussianDist(data, base * 12, 0.01, 0.51);
+        complexGaussianDist(data, base * 13, 0.01, 0.48);
+        complexGaussianDist(data, base * 14, 0.01, 0.51);
+        complexGaussianDist(data, base * 15, 0.01, 0.46);
+        complexGaussianDist(data, base * 16, 0.01, 0.35);
+        complexGaussianDist(data, base * 17, 0.01, 0.20);
+        complexGaussianDist(data, base * 18, 0.01, 0.10);
+        complexGaussianDist(data, base * 19, 0.01, 0.5);
+        complexGaussianDist(data, base * 20, 0.01, 0.1);
+
+
+        SF2Sample sample = newSimpleFFTSample(sf2, "Flute", data, base);
+        SF2Layer layer = newLayer(sf2, "Flute", sample);
+        SF2Region region = layer.getRegions().get(0);
+        region.putInteger(SF2Region.GENERATOR_SAMPLEMODES, 1);
+        region.putInteger(SF2Region.GENERATOR_ATTACKVOLENV, -6000);
+        region.putInteger(SF2Region.GENERATOR_RELEASEVOLENV, -1000);
+        region.putInteger(SF2Region.GENERATOR_DECAYVOLENV, 4000);
+        region.putInteger(SF2Region.GENERATOR_SUSTAINVOLENV, -100);
+        region.putInteger(SF2Region.GENERATOR_INITIALFILTERFC, 9500);
+        return layer;
+
+    }
+
+    public static SF2Layer new_clarinet(SF2Soundbank sf2) {
+        int x = 8;
+        int fftsize = 4096 * x;
+        double[] data = new double[fftsize * 2];
+        double base = x * 15;
+
+        complexGaussianDist(data, base * 1, 0.001, 0.5);
+        complexGaussianDist(data, base * 2, 0.001, 0.02);
+        complexGaussianDist(data, base * 3, 0.001, 0.2);
+        complexGaussianDist(data, base * 4, 0.01, 0.1);
+
+        complexGaussianDist(data, base * 4, 100, 60);
+        complexGaussianDist(data, base * 6, 100, 20);
+        complexGaussianDist(data, base * 8, 100, 20);
+
+        complexGaussianDist(data, base * 5, 0.001, 0.1);
+        complexGaussianDist(data, base * 6, 0.001, 0.09);
+        complexGaussianDist(data, base * 7, 0.001, 0.02);
+        complexGaussianDist(data, base * 8, 0.005, 0.16);
+        complexGaussianDist(data, base * 9, 0.005, 0.96);
+        complexGaussianDist(data, base * 10, 0.01, 0.9);
+        complexGaussianDist(data, base * 11, 0.08, 1.2);
+        complexGaussianDist(data, base * 12, 0.08, 1.8);
+        complexGaussianDist(data, base * 13, 0.08, 1.6);
+        complexGaussianDist(data, base * 14, 0.08, 1.2);
+        complexGaussianDist(data, base * 15, 0.08, 0.9);
+        complexGaussianDist(data, base * 16, 0.08, 0.5);
+        complexGaussianDist(data, base * 17, 0.08, 0.2);
+
+
+        complexGaussianDist(data, base * 1, 10, 8);
+        complexGaussianDist(data, base * 2, 10, 8);
+        complexGaussianDist(data, base * 3, 10, 8);
+        complexGaussianDist(data, base * 4, 10, 8);
+        complexGaussianDist(data, base * 5, 10, 8);
+        complexGaussianDist(data, base * 6, 20, 9);
+        complexGaussianDist(data, base * 7, 20, 9);
+        complexGaussianDist(data, base * 8, 20, 9);
+        complexGaussianDist(data, base * 9, 20, 8);
+        complexGaussianDist(data, base * 10, 30, 8);
+        complexGaussianDist(data, base * 11, 30, 9);
+        complexGaussianDist(data, base * 12, 30, 9);
+        complexGaussianDist(data, base * 13, 30, 8);
+        complexGaussianDist(data, base * 14, 30, 8);
+        complexGaussianDist(data, base * 15, 30, 7);
+        complexGaussianDist(data, base * 16, 30, 7);
+        complexGaussianDist(data, base * 17, 30, 6);
+
+        SF2Sample sample = newSimpleFFTSample(sf2, "Clarinet", data, base);
+        SF2Layer layer = newLayer(sf2, "Clarinet", sample);
+        SF2Region region = layer.getRegions().get(0);
+        region.putInteger(SF2Region.GENERATOR_SAMPLEMODES, 1);
+        region.putInteger(SF2Region.GENERATOR_ATTACKVOLENV, -6000);
+        region.putInteger(SF2Region.GENERATOR_RELEASEVOLENV, -1000);
+        region.putInteger(SF2Region.GENERATOR_DECAYVOLENV, 4000);
+        region.putInteger(SF2Region.GENERATOR_SUSTAINVOLENV, -100);
+        region.putInteger(SF2Region.GENERATOR_INITIALFILTERFC, 9500);
+        return layer;
+
+    }
+
+    public static SF2Layer new_timpani(SF2Soundbank sf2) {
+
+        double datab[];
+        double datah[];
+
+        // Make Bass Part
+        {
+            int fftlen = 4096 * 8;
+            double[] data = new double[2 * fftlen];
+            double base = 48;
+            complexGaussianDist(data, base * 2, 0.2, 1);
+            complexGaussianDist(data, base * 3, 0.2, 0.7);
+            complexGaussianDist(data, base * 5, 10, 1);
+            complexGaussianDist(data, base * 6, 9, 1);
+            complexGaussianDist(data, base * 8, 15, 1);
+            complexGaussianDist(data, base * 9, 18, 0.8);
+            complexGaussianDist(data, base * 11, 21, 0.5);
+            complexGaussianDist(data, base * 13, 28, 0.3);
+            complexGaussianDist(data, base * 14, 22, 0.1);
+            randomPhase(data, new Random(3049912));
+            ifft(data);
+            normalize(data, 0.5);
+            data = realPart(data);
+
+            double d_len = data.length;
+            for (int i = 0; i < data.length; i++) {
+                double g = (1.0 - (i / d_len));
+                data[i] *= g * g;
+            }
+            fadeUp(data, 40);
+            datab = data;
+        }
+
+        // Make treble part
+        {
+            int fftlen = 4096 * 4;
+            double[] data = new double[2 * fftlen];
+            Random random = new Random(3049912);
+            for (int i = 0; i < data.length; i += 2) {
+                data[i] = (2.0 * (random.nextDouble() - 0.5)) * 0.1;
+            }
+            fft(data);
+            // Remove all negative frequency
+            for (int i = fftlen / 2; i < data.length; i++)
+                data[i] = 0;
+            for (int i = 1024 * 4; i < 2048 * 4; i++)
+                data[i] = 1.0 - (i - 4096) / 4096.0;
+            for (int i = 0; i < 300; i++) {
+                double g = (1.0 - (i / 300.0));
+                data[i] *= 1.0 + 20 * g * g;
+            }
+            for (int i = 0; i < 24; i++)
+                data[i] = 0;
+            randomPhase(data, new Random(3049912));
+            ifft(data);
+            normalize(data, 0.9);
+            data = realPart(data);
+            double gain = 1.0;
+            for (int i = 0; i < data.length; i++) {
+                data[i] *= gain;
+                gain *= 0.9998;
+            }
+            datah = data;
+        }
+
+        for (int i = 0; i < datah.length; i++)
+            datab[i] += datah[i] * 0.02;
+
+        normalize(datab, 0.9);
+
+        SF2Sample sample = newSimpleDrumSample(sf2, "Timpani", datab);
+
+        SF2Layer layer = new SF2Layer(sf2);
+        layer.setName("Timpani");
+
+        SF2GlobalRegion global = new SF2GlobalRegion();
+        layer.setGlobalZone(global);
+        sf2.addResource(layer);
+
+        SF2LayerRegion region = new SF2LayerRegion();
+        region.putInteger(SF2Region.GENERATOR_RELEASEVOLENV, 12000);
+        region.putInteger(SF2Region.GENERATOR_INITIALATTENUATION, -100);
+        region.setSample(sample);
+        layer.getRegions().add(region);
+
+        return layer;
+    }
+
+    public static SF2Layer new_melodic_toms(SF2Soundbank sf2) {
+
+        double datab[];
+        double datah[];
+
+        // Make Bass Part
+        {
+            int fftlen = 4096 * 4;
+            double[] data = new double[2 * fftlen];
+            complexGaussianDist(data, 30, 0.5, 1);
+            randomPhase(data, new Random(3049912));
+            ifft(data);
+            normalize(data, 0.8);
+            data = realPart(data);
+
+            double d_len = data.length;
+            for (int i = 0; i < data.length; i++)
+                data[i] *= (1.0 - (i / d_len));
+            datab = data;
+        }
+
+        // Make treble part
+        {
+            int fftlen = 4096 * 4;
+            double[] data = new double[2 * fftlen];
+            Random random = new Random(3049912);
+            for (int i = 0; i < data.length; i += 2)
+                data[i] = (2.0 * (random.nextDouble() - 0.5)) * 0.1;
+            fft(data);
+            // Remove all negative frequency
+            for (int i = fftlen / 2; i < data.length; i++)
+                data[i] = 0;
+            for (int i = 1024 * 4; i < 2048 * 4; i++)
+                data[i] = 1.0 - (i - 4096) / 4096.0;
+            for (int i = 0; i < 200; i++) {
+                double g = (1.0 - (i / 200.0));
+                data[i] *= 1.0 + 20 * g * g;
+            }
+            for (int i = 0; i < 30; i++)
+                data[i] = 0;
+            randomPhase(data, new Random(3049912));
+            ifft(data);
+            normalize(data, 0.9);
+            data = realPart(data);
+            double gain = 1.0;
+            for (int i = 0; i < data.length; i++) {
+                data[i] *= gain;
+                gain *= 0.9996;
+            }
+            datah = data;
+        }
+
+        for (int i = 0; i < datah.length; i++)
+            datab[i] += datah[i] * 0.5;
+        for (int i = 0; i < 5; i++)
+            datab[i] *= i / 5.0;
+
+        normalize(datab, 0.99);
+
+        SF2Sample sample = newSimpleDrumSample(sf2, "Melodic Toms", datab);
+        sample.setOriginalPitch(63);
+
+        SF2Layer layer = new SF2Layer(sf2);
+        layer.setName("Melodic Toms");
+
+        SF2GlobalRegion global = new SF2GlobalRegion();
+        layer.setGlobalZone(global);
+        sf2.addResource(layer);
+
+        SF2LayerRegion region = new SF2LayerRegion();
+        region.putInteger(SF2Region.GENERATOR_RELEASEVOLENV, 12000);
+        //region.putInteger(SF2Region.GENERATOR_SCALETUNING, 0);
+        region.putInteger(SF2Region.GENERATOR_INITIALATTENUATION, -100);
+        region.setSample(sample);
+        layer.getRegions().add(region);
+
+        return layer;
+    }
+
+    public static SF2Layer new_reverse_cymbal(SF2Soundbank sf2) {
+        double datah[];
+        {
+            int fftlen = 4096 * 4;
+            double[] data = new double[2 * fftlen];
+            Random random = new Random(3049912);
+            for (int i = 0; i < data.length; i += 2)
+                data[i] = (2.0 * (random.nextDouble() - 0.5));
+            for (int i = fftlen / 2; i < data.length; i++)
+                data[i] = 0;
+            for (int i = 0; i < 100; i++)
+                data[i] = 0;
+
+            for (int i = 0; i < 512 * 2; i++) {
+                double gain = (i / (512.0 * 2.0));
+                data[i] = 1 - gain;
+            }
+            datah = data;
+        }
+
+        SF2Sample sample = newSimpleFFTSample(sf2, "Reverse Cymbal",
+                datah, 100, 20);
+
+        SF2Layer layer = new SF2Layer(sf2);
+        layer.setName("Reverse Cymbal");
+
+        SF2GlobalRegion global = new SF2GlobalRegion();
+        layer.setGlobalZone(global);
+        sf2.addResource(layer);
+
+        SF2LayerRegion region = new SF2LayerRegion();
+        region.putInteger(SF2Region.GENERATOR_ATTACKVOLENV, -200);
+        region.putInteger(SF2Region.GENERATOR_DECAYVOLENV, -12000);
+        region.putInteger(SF2Region.GENERATOR_SAMPLEMODES, 1);
+        region.putInteger(SF2Region.GENERATOR_RELEASEVOLENV, -1000);
+        region.putInteger(SF2Region.GENERATOR_SUSTAINVOLENV, 1000);
+        region.setSample(sample);
+        layer.getRegions().add(region);
+
+        return layer;
+    }
+
+    public static SF2Layer new_snare_drum(SF2Soundbank sf2) {
+
+        double datab[];
+        double datah[];
+
+        // Make Bass Part
+        {
+            int fftlen = 4096 * 4;
+            double[] data = new double[2 * fftlen];
+            complexGaussianDist(data, 24, 0.5, 1);
+            randomPhase(data, new Random(3049912));
+            ifft(data);
+            normalize(data, 0.5);
+            data = realPart(data);
+
+            double d_len = data.length;
+            for (int i = 0; i < data.length; i++)
+                data[i] *= (1.0 - (i / d_len));
+            datab = data;
+        }
+
+        // Make treble part
+        {
+            int fftlen = 4096 * 4;
+            double[] data = new double[2 * fftlen];
+            Random random = new Random(3049912);
+            for (int i = 0; i < data.length; i += 2)
+                data[i] = (2.0 * (random.nextDouble() - 0.5)) * 0.1;
+            fft(data);
+            // Remove all negative frequency
+            for (int i = fftlen / 2; i < data.length; i++)
+                data[i] = 0;
+            for (int i = 1024 * 4; i < 2048 * 4; i++)
+                data[i] = 1.0 - (i - 4096) / 4096.0;
+            for (int i = 0; i < 300; i++) {
+                double g = (1.0 - (i / 300.0));
+                data[i] *= 1.0 + 20 * g * g;
+            }
+            for (int i = 0; i < 24; i++)
+                data[i] = 0;
+            randomPhase(data, new Random(3049912));
+            ifft(data);
+            normalize(data, 0.9);
+            data = realPart(data);
+            double gain = 1.0;
+            for (int i = 0; i < data.length; i++) {
+                data[i] *= gain;
+                gain *= 0.9998;
+            }
+            datah = data;
+        }
+
+        for (int i = 0; i < datah.length; i++)
+            datab[i] += datah[i];
+        for (int i = 0; i < 5; i++)
+            datab[i] *= i / 5.0;
+
+        SF2Sample sample = newSimpleDrumSample(sf2, "Snare Drum", datab);
+
+        SF2Layer layer = new SF2Layer(sf2);
+        layer.setName("Snare Drum");
+
+        SF2GlobalRegion global = new SF2GlobalRegion();