From f98664ba3d5966a736dd5cf45329e542be5fece8 Mon Sep 17 00:00:00 2001 From: Mark Heath Date: Sat, 14 Feb 2015 08:31:50 +0000 Subject: [PATCH] adding SampleToWaveProvider254 to Win 8 project --- ..svnbridge/.svnbridge | 19 + .build/MSBuild.Community.Tasks.dll | Bin 0 -> 626176 bytes .build/MSBuild.Community.Tasks.targets | 147 + .hgignore | 14 + AudioFileInspector/AboutForm.Designer.cs | 144 + AudioFileInspector/AboutForm.cs | 71 + AudioFileInspector/AboutForm.resx | 120 + AudioFileInspector/AudioFileInspector.csproj | 186 ++ .../AudioFileInspectorForm.Designer.cs | 203 ++ AudioFileInspector/AudioFileInspectorForm.cs | 229 ++ .../AudioFileInspectorForm.resx | 123 + AudioFileInspector/FileAssociations.cs | 379 +++ .../FileInspectors/CakewalkMapInspector.cs | 32 + .../FileInspectors/MidiFileInspector.cs | 78 + .../FileInspectors/Mp3FileInspector.cs | 56 + .../FileInspectors/SoundFontInspector.cs | 69 + .../FileInspectors/WaveFileInspector.cs | 149 + AudioFileInspector/FindForm.Designer.cs | 88 + AudioFileInspector/FindForm.cs | 29 + AudioFileInspector/FindForm.resx | 120 + AudioFileInspector/IAudioFileInspector.cs | 13 + AudioFileInspector/InstallScript.nsi | 154 + AudioFileInspector/OptionsForm.Designer.cs | 94 + AudioFileInspector/OptionsForm.cs | 87 + AudioFileInspector/OptionsForm.resx | 120 + AudioFileInspector/Program.cs | 65 + AudioFileInspector/Properties/AssemblyInfo.cs | 77 + .../Properties/Resources.Designer.cs | 63 + AudioFileInspector/Properties/Resources.resx | 117 + .../Properties/Settings.Designer.cs | 26 + .../Properties/Settings.settings | 7 + AudioFileInspector/audio_file_inspector.html | 84 + Build.proj | 65 + BuildProcessTemplates/DefaultTemplate.xaml | 602 ++++ BuildProcessTemplates/UpgradeTemplate.xaml | 76 + ...del.Composition.Initialization.Desktop.dll | Bin 0 -> 25600 bytes Lib/MEF/System.ComponentModel.Composition.dll | Bin 0 -> 238080 bytes Lib/MEF/readme.txt | 2 + Lib/NSpeex/NSpeex.dll | Bin 0 -> 118272 bytes MidiFileConverter/AboutForm.Designer.cs | 144 + MidiFileConverter/AboutForm.cs | 71 + MidiFileConverter/AboutForm.resx | 120 + .../AdvancedOptionsForm.Designer.cs | 169 + MidiFileConverter/AdvancedOptionsForm.cs | 45 + MidiFileConverter/AdvancedOptionsForm.resx | 120 + MidiFileConverter/InstallScript.nsi | 153 + MidiFileConverter/MainForm.Designer.cs | 449 +++ MidiFileConverter/MainForm.cs | 376 +++ MidiFileConverter/MainForm.resx | 123 + MidiFileConverter/MidiConverter.cs | 483 +++ MidiFileConverter/MidiFileConverter.csproj | 169 + .../MidiFileConverter.csproj.vspscc | 10 + MidiFileConverter/NamingRule.cs | 110 + MidiFileConverter/NamingRules.xml | 76 + MidiFileConverter/OutputMidiType.cs | 13 + MidiFileConverter/Program.cs | 20 + MidiFileConverter/ProgressEventArgs.cs | 81 + MidiFileConverter/Properties/AssemblyInfo.cs | 89 + .../Properties/Resources.Designer.cs | 63 + MidiFileConverter/Properties/Resources.resx | 117 + .../Properties/Settings.Designer.cs | 218 ++ .../Properties/Settings.settings | 54 + MidiFileConverter/app.config | 60 + MidiFileConverter/midi_file_converter.html | 307 ++ MixDiff/AboutForm.Designer.cs | 144 + MixDiff/AboutForm.cs | 71 + MixDiff/AboutForm.resx | 120 + MixDiff/Images.Designer.cs | 143 + MixDiff/Images.resx | 145 + MixDiff/MixDiff.csproj | 202 ++ MixDiff/MixDiff.csproj.vspscc | 10 + MixDiff/MixDiffForm.Designer.cs | 491 +++ MixDiff/MixDiffForm.cs | 612 ++++ MixDiff/MixDiffForm.resx | 135 + MixDiff/MixDiffStream.cs | 123 + MixDiff/MixdownInfo.cs | 73 + MixDiff/Program.cs | 20 + MixDiff/Properties/AssemblyInfo.cs | 79 + MixDiff/Properties/Resources.Designer.cs | 63 + MixDiff/Properties/Resources.resx | 117 + MixDiff/Properties/Settings.Designer.cs | 62 + MixDiff/Properties/Settings.settings | 15 + MixDiff/PropertiesForm.Designer.cs | 168 + MixDiff/PropertiesForm.cs | 55 + MixDiff/PropertiesForm.resx | 120 + MixDiff/Resources/Back.png | Bin 0 -> 236 bytes MixDiff/Resources/Forward.png | Bin 0 -> 236 bytes MixDiff/Resources/Loop.png | Bin 0 -> 369 bytes MixDiff/Resources/Pause.png | Bin 0 -> 156 bytes MixDiff/Resources/Play.png | Bin 0 -> 199 bytes MixDiff/Resources/Rewind.png | Bin 0 -> 237 bytes MixDiff/Resources/Shuffle.png | Bin 0 -> 201 bytes MixDiff/Resources/Stop.png | Bin 0 -> 148 bytes MixDiff/SettingsForm.Designer.cs | 143 + MixDiff/SettingsForm.cs | 74 + MixDiff/SettingsForm.resx | 120 + MixDiff/app.config | 21 + NAudio.Win8/NAudio.Win8.csproj | 801 +++++ NAudio.Win8/Properties/AssemblyInfo.cs | 29 + NAudio.Win8/Wave/WaveExtensionMethods.cs | 35 + .../Wave/WaveInputs/WasapiCaptureRT.cs | 346 +++ NAudio.Win8/Wave/WaveOutputs/IWavePlayer.cs | 53 + NAudio.Win8/Wave/WaveOutputs/WasapiOutRT.cs | 647 ++++ .../Interop/BufferTypes/INSSBuffer.cs | 47 + .../Interop/BufferTypes/INSSBuffer2.cs | 47 + .../Interop/BufferTypes/INSSBuffer3.cs | 54 + .../Interop/BufferTypes/INSSBuffer4.cs | 60 + .../BufferTypes/IWMSBufferAllocator.cs | 43 + NAudio.WindowsMediaFormat/Interop/Codec.cs | 56 + .../Interop/CodecFormat.cs | 73 + .../CommonTypes/IWMBandwidthSharing.cs | 50 + .../Interop/CommonTypes/IWMCodecInfo.cs | 28 + .../Interop/CommonTypes/IWMCodecInfo2.cs | 53 + .../Interop/CommonTypes/IWMCodecInfo3 .cs | 93 + .../Interop/CommonTypes/IWMHeaderInfo.cs | 86 + .../Interop/CommonTypes/IWMHeaderInfo2.cs | 86 + .../Interop/CommonTypes/IWMHeaderInfo3.cs | 125 + .../Interop/CommonTypes/IWMIndexer.cs | 43 + .../Interop/CommonTypes/IWMIndexer2.cs | 48 + .../Interop/CommonTypes/IWMInputMediaProps.cs | 49 + .../Interop/CommonTypes/IWMMediaProps.cs | 45 + .../Interop/CommonTypes/IWMMetadataEditor.cs | 43 + .../Interop/CommonTypes/IWMMetadataEditor2.cs | 44 + .../Interop/CommonTypes/IWMMutualExclusion.cs | 46 + .../CommonTypes/IWMMutualExclusion2.cs | 71 + .../CommonTypes/IWMOutputMediaProps.cs | 49 + .../Interop/CommonTypes/IWMStatusCallback.cs | 44 + .../Interop/CommonTypes/IWMStreamList.cs | 44 + .../CommonTypes/IWMStreamPrioritization.cs | 43 + .../Interop/CommonTypes/IWMVideoMediaProps.cs | 50 + .../Interop/CommonTypes/WMT_ATTR_DATATYPE.cs | 46 + .../CommonTypes/WMT_CODEC_INFO_TYPE.cs | 39 + .../Interop/CommonTypes/WMT_INDEXER_TYPE.cs | 39 + .../Interop/CommonTypes/WMT_INDEX_TYPE.cs | 38 + .../Interop/CommonTypes/WMT_NET_PROTOCOL.cs | 35 + .../Interop/CommonTypes/WMT_OFFSET_FORMAT.cs | 41 + .../Interop/CommonTypes/WMT_PLAY_MODE.cs | 41 + .../Interop/CommonTypes/WMT_RIGHTS.cs | 55 + .../Interop/CommonTypes/WMT_STATUS.cs | 123 + .../Interop/CommonTypes/WMT_STORAGE_FORMAT.cs | 37 + .../CommonTypes/WMT_STREAM_SELECTION.cs | 36 + .../WMT_TIMECODE_EXTENSION_DATA.cs | 43 + .../Interop/CommonTypes/WMT_TRANSPORT_TYPE.cs | 37 + .../Interop/CommonTypes/WMT_VERSION.cs | 41 + .../Interop/CommonTypes/WM_MEDIA_TYPE.cs | 55 + .../CommonTypes/WM_STREAM_PRIORITY_RECORD.cs | 40 + NAudio.WindowsMediaFormat/Interop/Enums.cs | 115 + .../Interop/MediaTypes.cs | 86 + .../Interop/NSSBuffer.cs | 257 ++ .../Interop/ProfilesTypes/IWMProfile.cs | 59 + .../Interop/ProfilesTypes/IWMProfile2.cs | 62 + .../Interop/ProfilesTypes/IWMProfile3.cs | 76 + .../ProfilesTypes/IWMProfileManager.cs | 49 + .../ProfilesTypes/IWMProfileManager2.cs | 53 + .../IWMProfileManagerLanguage.cs | 39 + .../Interop/ProfilesTypes/IWMStreamConfig.cs | 50 + .../Interop/ProfilesTypes/IWMStreamConfig2.cs | 66 + .../Interop/ProfilesTypes/IWMStreamConfig3.cs | 70 + .../Interop/ReaderTypes/IWMReader.cs | 58 + .../Interop/ReaderTypes/IWMReaderAdvanced.cs | 59 + .../Interop/ReaderTypes/IWMReaderAdvanced2.cs | 101 + .../Interop/ReaderTypes/IWMReaderAdvanced3.cs | 108 + .../Interop/ReaderTypes/IWMReaderAdvanced4.cs | 125 + .../ReaderTypes/IWMReaderAllocatorEx.cs | 52 + .../Interop/ReaderTypes/IWMReaderCallback.cs | 51 + .../Interop/ReaderTypes/IWMSyncReader.cs | 83 + .../Interop/ReaderTypes/IWMSyncReader2.cs | 96 + .../ReaderTypes/WM_READER_CLIENTINFO.cs | 49 + .../ReaderTypes/WM_READER_STATISTICS.cs | 41 + .../Interop/WMFFunctions.cs | 502 +++ .../Interop/WMHeaderInfo.cs | 658 ++++ .../Interop/WMStreamConfig.cs | 192 ++ .../Interop/WmProfile.cs | 167 + .../Interop/WmaStream.cs | 627 ++++ .../Interop/WmaWriter.cs | 253 ++ .../Interop/WriterTypes/IWMWriter.cs | 58 + .../Interop/WriterTypes/IWMWriterAdvanced.cs | 56 + .../Interop/WriterTypes/IWMWriterAdvanced2.cs | 67 + .../Interop/WriterTypes/IWMWriterAdvanced3.cs | 71 + .../Interop/WriterTypes/IWMWriterFileSink.cs | 46 + .../Interop/WriterTypes/IWMWriterFileSink2.cs | 54 + .../Interop/WriterTypes/IWMWriterFileSink3.cs | 65 + .../WriterTypes/IWMWriterNetworkSink.cs | 54 + .../WriterTypes/IWMWriterPreprocess.cs | 49 + .../Interop/WriterTypes/IWMWriterPushSink.cs | 50 + .../Interop/WriterTypes/IWMWriterSink.cs | 43 + .../Interop/WriterTypes/WMT_BUFFER_SEGMENT.cs | 38 + .../WriterTypes/WMT_FILESINK_DATA_UNIT.cs | 42 + .../WriterTypes/WMT_PAYLOAD_FRAGMENT.cs | 37 + .../WriterTypes/WM_WRITER_STATISTICS.cs | 46 + .../WriterTypes/WM_WRITER_STATISTICS_EX.cs | 42 + .../NAudio.WindowsMediaFormat.csproj | 187 ++ .../Properties/AssemblyInfo.cs | 36 + NAudio.WindowsMediaFormat/WmaFileReader.cs | 138 + NAudio.WindowsMediaFormat/app.config | 3 + NAudio.Wma.nuspec | 23 + NAudio.nuspec | 23 + NAudio.proj | 90 + NAudio.sln | 169 + NAudio.sln.DotSettings | 6 + NAudio/Changes.xml | 975 ++++++ NAudio/Codecs/ALawDecoder.cs | 63 + NAudio/Codecs/ALawEncoder.cs | 65 + NAudio/Codecs/G722Codec.cs | 628 ++++ NAudio/Codecs/MuLawDecoder.cs | 60 + NAudio/Codecs/MuLawEncoder.cs | 53 + NAudio/CoreAudioApi/AudioCaptureClient.cs | 85 + NAudio/CoreAudioApi/AudioClient.cs | 303 ++ NAudio/CoreAudioApi/AudioClientBufferFlags.cs | 29 + NAudio/CoreAudioApi/AudioClientProperties.cs | 30 + NAudio/CoreAudioApi/AudioClientShareMode.cs | 19 + NAudio/CoreAudioApi/AudioClientStreamFlags.cs | 32 + .../CoreAudioApi/AudioClientStreamOptions.cs | 17 + NAudio/CoreAudioApi/AudioClockClient.cs | 128 + NAudio/CoreAudioApi/AudioEndpointVolume.cs | 210 ++ .../AudioEndpointVolumeCallback.cs | 73 + .../AudioEndpointVolumeChannel.cs | 78 + .../AudioEndpointVolumeChannels.cs | 76 + ...AudioEndpointVolumeNotificationDelegate.cs | 32 + .../AudioEndpointVolumeStepInformation.cs | 57 + .../AudioEndpointVolumeVolumeRange.cs | 67 + NAudio/CoreAudioApi/AudioMeterInformation.cs | 83 + .../AudioMeterInformationChannels.cs | 70 + NAudio/CoreAudioApi/AudioRenderClient.cs | 56 + NAudio/CoreAudioApi/AudioSessionControl.cs | 156 + .../AudioSessionEventsCallback.cs | 119 + NAudio/CoreAudioApi/AudioSessionManager.cs | 70 + NAudio/CoreAudioApi/AudioStreamCategory.cs | 41 + .../AudioVolumeNotificationData.cs | 93 + NAudio/CoreAudioApi/DataFlow.cs | 29 + NAudio/CoreAudioApi/DeviceState.cs | 55 + .../CoreAudioApi/EEndpointHardwareSupport.cs | 45 + .../AudioVolumeNotificationDataStruct.cs | 52 + NAudio/CoreAudioApi/Interfaces/Blob.cs | 49 + NAudio/CoreAudioApi/Interfaces/ClsCtx.cs | 39 + NAudio/CoreAudioApi/Interfaces/ErrorCodes.cs | 57 + .../Interfaces/IAudioCaptureClient.cs | 34 + .../CoreAudioApi/Interfaces/IAudioClient.cs | 60 + .../CoreAudioApi/Interfaces/IAudioClock2.cs | 35 + .../Interfaces/IAudioEndpointVolume.cs | 52 + .../IAudioEndpointVolumeCallback.cs | 39 + .../Interfaces/IAudioMeterInformation.cs | 36 + .../Interfaces/IAudioRenderClient.cs | 17 + .../Interfaces/IAudioSessionControl.cs | 122 + .../Interfaces/IAudioSessionEvents.cs | 177 ++ .../Interfaces/IAudioSessionEventsHandler.cs | 17 + .../Interfaces/IAudioSessionManager.cs | 61 + NAudio/CoreAudioApi/Interfaces/IMMDevice.cs | 23 + .../Interfaces/IMMDeviceCollection.cs | 15 + .../Interfaces/IMMDeviceEnumerator.cs | 23 + NAudio/CoreAudioApi/Interfaces/IMMEndpoint.cs | 17 + .../Interfaces/IMMNotificationClient.cs | 43 + .../CoreAudioApi/Interfaces/IPropertyStore.cs | 21 + .../Interfaces/ISimpleAudioVolume.cs | 75 + .../Interfaces/MMDeviceEnumeratorComObject.cs | 15 + .../Interfaces/StorageAccessMode.cs | 16 + NAudio/CoreAudioApi/MMDevice.cs | 258 ++ NAudio/CoreAudioApi/MMDeviceCollection.cs | 95 + NAudio/CoreAudioApi/MMDeviceEnumerator.cs | 109 + NAudio/CoreAudioApi/PropVariant.cs | 210 ++ NAudio/CoreAudioApi/PropertyKey.cs | 28 + NAudio/CoreAudioApi/PropertyKeys.cs | 84 + NAudio/CoreAudioApi/PropertyStore.cs | 141 + NAudio/CoreAudioApi/PropertyStoreProperty.cs | 61 + NAudio/CoreAudioApi/Role.cs | 26 + NAudio/CoreAudioApi/SimpleAudioVolume.cs | 89 + NAudio/Dmo/AudioMediaSubtypes.cs | 73 + NAudio/Dmo/DmoDescriptor.cs | 31 + NAudio/Dmo/DmoEnumFlags.cs | 13 + NAudio/Dmo/DmoEnumerator.cs | 61 + NAudio/Dmo/DmoGuids.cs | 33 + NAudio/Dmo/DmoHResults.cs | 19 + NAudio/Dmo/DmoInputDataBufferFlags.cs | 30 + NAudio/Dmo/DmoInputStatusFlags.cs | 13 + NAudio/Dmo/DmoInterop.cs | 33 + NAudio/Dmo/DmoMediaType.cs | 168 + NAudio/Dmo/DmoOutputDataBuffer.cs | 111 + NAudio/Dmo/DmoOutputDataBufferFlags.cs | 34 + NAudio/Dmo/DmoPartialMediaType.cs | 27 + NAudio/Dmo/DmoProcessOutputFlags.cs | 22 + NAudio/Dmo/DmoSetTypeFlags.cs | 14 + NAudio/Dmo/IEnumDmo.cs | 22 + NAudio/Dmo/IMediaBuffer.cs | 44 + NAudio/Dmo/IMediaObject.cs | 86 + NAudio/Dmo/IMediaParamInfo.cs | 37 + NAudio/Dmo/IWMResamplerProps.cs | 26 + NAudio/Dmo/InputStreamInfoFlags.cs | 16 + NAudio/Dmo/MediaBuffer.cs | 144 + NAudio/Dmo/MediaObject.cs | 492 +++ NAudio/Dmo/MediaObjectSizeInfo.cs | 47 + NAudio/Dmo/MediaParamInfo.cs | 66 + NAudio/Dmo/MediaTypes.cs | 74 + NAudio/Dmo/OutputStreamInfoFlags.cs | 16 + NAudio/Dmo/ResamplerMediaObject.cs | 87 + NAudio/Dmo/WindowsMediaMp3Decoder.cs | 90 + NAudio/Dsp/BiQuadFilter.cs | 322 ++ NAudio/Dsp/Complex.cs | 21 + NAudio/Dsp/EnvelopeDetector.cs | 108 + NAudio/Dsp/EnvelopeGenerator.cs | 244 ++ NAudio/Dsp/FastFourierTransform.cs | 124 + NAudio/Dsp/ImpulseResponseConvolution.cs | 46 + NAudio/Dsp/SimpleCompressor.cs | 89 + NAudio/Dsp/SimpleGate.cs | 73 + NAudio/Dsp/WdlResampler.cs | 708 +++++ NAudio/FileFormats/Map/CakewalkDrumMapping.cs | 54 + NAudio/FileFormats/Map/CakewalkMapFile.cs | 167 + NAudio/FileFormats/Map/MapBlockHeader.cs | 34 + NAudio/FileFormats/Mp3/ChannelMode.cs | 30 + .../Mp3/DmoMp3FrameDecompressor.cs | 112 + .../FileFormats/Mp3/IMp3FrameDecompressor.cs | 31 + NAudio/FileFormats/Mp3/Id3v2Tag.cs | 237 ++ NAudio/FileFormats/Mp3/Mp3Frame.cs | 280 ++ .../FileFormats/Mp3/Mp3FrameDecompressor.cs | 95 + NAudio/FileFormats/Mp3/MpegLayer.cs | 29 + NAudio/FileFormats/Mp3/MpegVersion.cs | 29 + NAudio/FileFormats/Mp3/XingHeader.cs | 188 ++ NAudio/FileFormats/Sfz/SfzFileReader.cs | 111 + NAudio/FileFormats/SoundFont/Generator.cs | 136 + .../FileFormats/SoundFont/GeneratorBuilder.cs | 59 + NAudio/FileFormats/SoundFont/GeneratorEnum.cs | 133 + NAudio/FileFormats/SoundFont/InfoChunk.cs | 282 ++ NAudio/FileFormats/SoundFont/Instrument.cs | 54 + .../SoundFont/InstrumentBuilder.cs | 66 + NAudio/FileFormats/SoundFont/Modulator.cs | 114 + .../FileFormats/SoundFont/ModulatorBuilder.cs | 38 + NAudio/FileFormats/SoundFont/ModulatorType.cs | 101 + NAudio/FileFormats/SoundFont/Preset.cs | 92 + NAudio/FileFormats/SoundFont/PresetBuilder.cs | 63 + NAudio/FileFormats/SoundFont/PresetsChunk.cs | 136 + NAudio/FileFormats/SoundFont/RiffChunk.cs | 164 + NAudio/FileFormats/SoundFont/SFSampleLink.cs | 41 + NAudio/FileFormats/SoundFont/SFVersion.cs | 44 + .../FileFormats/SoundFont/SFVersionBuilder.cs | 43 + .../FileFormats/SoundFont/SampleDataChunk.cs | 28 + NAudio/FileFormats/SoundFont/SampleHeader.cs | 61 + .../SoundFont/SampleHeaderBuilder.cs | 54 + NAudio/FileFormats/SoundFont/SampleMode.cs | 27 + NAudio/FileFormats/SoundFont/SoundFont.cs | 132 + .../FileFormats/SoundFont/StructureBuilder.cs | 39 + NAudio/FileFormats/SoundFont/Zone.cs | 57 + NAudio/FileFormats/SoundFont/ZoneBuilder.cs | 59 + NAudio/FileFormats/Wav/WaveFileChunkReader.cs | 165 + NAudio/Gui/Fader.cs | 222 ++ NAudio/Gui/Fader.resx | 42 + NAudio/Gui/PanSlider.cs | 151 + NAudio/Gui/PanSlider.resx | 130 + NAudio/Gui/Pot.Designer.cs | 45 + NAudio/Gui/Pot.cs | 181 ++ NAudio/Gui/Pot.resx | 120 + NAudio/Gui/VolumeMeter.Designer.cs | 36 + NAudio/Gui/VolumeMeter.cs | 122 + NAudio/Gui/VolumeSlider.cs | 150 + NAudio/Gui/VolumeSlider.resx | 130 + NAudio/Gui/WaveViewer.cs | 147 + NAudio/Gui/WaveViewer.resx | 42 + NAudio/Gui/WaveformPainter.Designer.cs | 36 + NAudio/Gui/WaveformPainter.cs | 101 + NAudio/MediaFoundation/AudioSubtypes.cs | 163 + NAudio/MediaFoundation/IMFActivate.cs | 185 ++ NAudio/MediaFoundation/IMFAttributes.cs | 170 + NAudio/MediaFoundation/IMFByteStream.cs | 103 + NAudio/MediaFoundation/IMFCollection.cs | 44 + NAudio/MediaFoundation/IMFMediaBuffer.cs | 34 + NAudio/MediaFoundation/IMFMediaEvent.cs | 208 ++ NAudio/MediaFoundation/IMFMediaType.cs | 197 ++ .../IMFReadWriteClassFactory.cs | 32 + NAudio/MediaFoundation/IMFSample.cs | 239 ++ NAudio/MediaFoundation/IMFSinkWriter.cs | 59 + NAudio/MediaFoundation/IMFSourceReader.cs | 100 + NAudio/MediaFoundation/IMFTransform.cs | 256 ++ .../MediaFoundation/MFT_INPUT_STREAM_INFO.cs | 35 + NAudio/MediaFoundation/MFT_MESSAGE_TYPE.cs | 53 + .../MediaFoundation/MFT_OUTPUT_DATA_BUFFER.cs | 28 + .../MediaFoundation/MFT_OUTPUT_STREAM_INFO.cs | 24 + .../MediaFoundation/MFT_REGISTER_TYPE_INFO.cs | 21 + .../MF_SINK_WRITER_STATISTICS.cs | 79 + NAudio/MediaFoundation/MediaEventType.cs | 437 +++ .../MediaFoundationAttributes.cs | 286 ++ .../MediaFoundation/MediaFoundationErrors.cs | 2764 +++++++++++++++++ .../MediaFoundation/MediaFoundationHelpers.cs | 156 + .../MediaFoundation/MediaFoundationInterop.cs | 146 + .../MediaFoundationTransform.cs | 286 ++ .../MediaFoundationTransformCategories.cs | 64 + NAudio/MediaFoundation/MediaType.cs | 150 + NAudio/MediaFoundation/MediaTypes.cs | 64 + NAudio/MediaFoundation/_MFT_ENUM_FLAG.cs | 48 + .../_MFT_INPUT_STATUS_FLAGS.cs | 20 + .../_MFT_INPUT_STREAM_INFO_FLAGS.cs | 48 + .../_MFT_OUTPUT_DATA_BUFFER_FLAGS.cs | 33 + .../_MFT_OUTPUT_STATUS_FLAGS.cs | 20 + .../_MFT_OUTPUT_STREAM_INFO_FLAGS.cs | 52 + .../_MFT_PROCESS_OUTPUT_FLAGS.cs | 24 + .../_MFT_PROCESS_OUTPUT_STATUS.cs | 20 + NAudio/MediaFoundation/_MFT_SET_TYPE_FLAGS.cs | 20 + NAudio/Midi/ChannelAfterTouchEvent.cs | 66 + NAudio/Midi/ControlChangeEvent.cs | 120 + NAudio/Midi/KeySignatureEvent.cs | 85 + NAudio/Midi/MetaEvent.cs | 139 + NAudio/Midi/MetaEventType.cs | 47 + NAudio/Midi/MidiCommandCode.cs | 39 + NAudio/Midi/MidiController.cs | 42 + NAudio/Midi/MidiEvent.cs | 392 +++ NAudio/Midi/MidiEventCollection.cs | 322 ++ NAudio/Midi/MidiEventComparer.cs | 50 + NAudio/Midi/MidiFile.cs | 270 ++ NAudio/Midi/MidiIn.cs | 162 + NAudio/Midi/MidiInCapabilities.cs | 71 + NAudio/Midi/MidiInMessageEventArgs.cs | 44 + NAudio/Midi/MidiInterop.cs | 277 ++ NAudio/Midi/MidiMessage.cs | 90 + NAudio/Midi/MidiOut.cs | 162 + NAudio/Midi/MidiOutCapabilities.cs | 181 ++ NAudio/Midi/MidiOutTechnology.cs | 26 + NAudio/Midi/NoteEvent.cs | 185 ++ NAudio/Midi/NoteOnEvent.cs | 145 + NAudio/Midi/PatchChangeEvent.cs | 119 + NAudio/Midi/PitchWheelChangeEvent.cs | 99 + NAudio/Midi/SequencerSpecificEvent.cs | 79 + NAudio/Midi/SmpteOffsetEvent.cs | 101 + NAudio/Midi/SysexEvent.cs | 75 + NAudio/Midi/TempoEvent.cs | 82 + NAudio/Midi/TextEvent.cs | 76 + NAudio/Midi/TimeSignatureEvent.cs | 152 + NAudio/Midi/TrackSequenceNumberEvent.cs | 52 + NAudio/Mixer/BooleanMixerControl.cs | 55 + NAudio/Mixer/CustomMixerControl.cs | 32 + NAudio/Mixer/ListTextMixerControl.cs | 34 + NAudio/Mixer/Mixer.cs | 118 + NAudio/Mixer/MixerControl.cs | 377 +++ NAudio/Mixer/MixerControlType.cs | 111 + NAudio/Mixer/MixerFlags.cs | 123 + NAudio/Mixer/MixerInterop.cs | 267 ++ NAudio/Mixer/MixerLine.cs | 288 ++ NAudio/Mixer/MixerLineComponentType.cs | 114 + NAudio/Mixer/MixerSource.cs | 131 + NAudio/Mixer/SignedMixerControl.cs | 99 + NAudio/Mixer/UnsignedMixerControl.cs | 108 + NAudio/NAudio.csproj | 551 ++++ NAudio/NAudio.csproj.vspscc | 10 + NAudio/NAudio.ruleset | 7 + NAudio/Properties/AssemblyInfo.cs | 36 + NAudio/Utils/BufferHelpers.cs | 42 + NAudio/Utils/ByteArrayExtensions.cs | 84 + NAudio/Utils/ByteEncoding.cs | 86 + NAudio/Utils/ChunkIdentifier.cs | 26 + NAudio/Utils/CircularBuffer.cs | 143 + NAudio/Utils/Decibels.cs | 39 + NAudio/Utils/FieldDescriptionAttribute.cs | 33 + NAudio/Utils/FieldDescriptionHelper.cs | 43 + NAudio/Utils/HResult.cs | 77 + NAudio/Utils/IEEE.cs | 147 + NAudio/Utils/IgnoreDisposeStream.cs | 135 + NAudio/Utils/MergeSort.cs | 76 + NAudio/Utils/NativeMethods.cs | 24 + NAudio/Utils/ProgressLog.Designer.cs | 62 + NAudio/Utils/ProgressLog.cs | 76 + NAudio/Utils/ProgressLog.resx | 120 + NAudio/Utils/WavePositionExtensions.cs | 21 + NAudio/Wave/Asio/ASIODriver.cs | 461 +++ NAudio/Wave/Asio/ASIODriverExt.cs | 398 +++ NAudio/Wave/Asio/ASIOSampleConvertor.cs | 343 ++ NAudio/Wave/Asio/ASIOStructures.cs | 216 ++ NAudio/Wave/Asio/AsioDriverCapability.cs | 31 + NAudio/Wave/Asio/AsioSampleType.cs | 98 + NAudio/Wave/Compression/AcmDriver.cs | 355 +++ NAudio/Wave/Compression/AcmDriverAddFlags.cs | 31 + NAudio/Wave/Compression/AcmDriverDetails.cs | 104 + .../AcmDriverDetailsSupportFlags.cs | 26 + NAudio/Wave/Compression/AcmDriverEnumFlags.cs | 19 + NAudio/Wave/Compression/AcmFormat.cs | 73 + NAudio/Wave/Compression/AcmFormatChoose.cs | 89 + .../Compression/AcmFormatChooseStyleFlags.cs | 39 + NAudio/Wave/Compression/AcmFormatDetails.cs | 50 + NAudio/Wave/Compression/AcmFormatEnumFlags.cs | 63 + .../Wave/Compression/AcmFormatSuggestFlags.cs | 31 + NAudio/Wave/Compression/AcmFormatTag.cs | 69 + .../Wave/Compression/AcmFormatTagDetails.cs | 49 + NAudio/Wave/Compression/AcmInterop.cs | 187 ++ NAudio/Wave/Compression/AcmMetrics.cs | 44 + NAudio/Wave/Compression/AcmStream.cs | 250 ++ .../Wave/Compression/AcmStreamConvertFlags.cs | 23 + NAudio/Wave/Compression/AcmStreamHeader.cs | 128 + .../Compression/AcmStreamHeaderStatusFlags.cs | 23 + .../Wave/Compression/AcmStreamHeaderStruct.cs | 41 + NAudio/Wave/Compression/AcmStreamOpenFlags.cs | 51 + NAudio/Wave/Compression/AcmStreamSizeFlags.cs | 18 + NAudio/Wave/Compression/WaveFilter.cs | 30 + NAudio/Wave/MmeInterop/Manufacturers.cs | 376 +++ NAudio/Wave/MmeInterop/MmException.cs | 53 + NAudio/Wave/MmeInterop/MmResult.cs | 85 + NAudio/Wave/MmeInterop/MmTime.cs | 45 + NAudio/Wave/MmeInterop/WaveCallbackInfo.cs | 117 + .../Wave/MmeInterop/WaveCallbackStrategy.cs | 29 + NAudio/Wave/MmeInterop/WaveHeader.cs | 30 + NAudio/Wave/MmeInterop/WaveHeaderFlags.cs | 39 + NAudio/Wave/MmeInterop/WaveInCapabilities.cs | 121 + NAudio/Wave/MmeInterop/WaveInEventArgs.cs | 41 + NAudio/Wave/MmeInterop/WaveInterop.cs | 164 + NAudio/Wave/MmeInterop/WaveOutCapabilities.cs | 217 ++ NAudio/Wave/MmeInterop/WaveOutSupport.cs | 24 + NAudio/Wave/MmeInterop/WaveWindow.cs | 78 + .../ISampleChunkConverter.cs | 18 + .../Mono16SampleChunkConverter.cs | 47 + .../Mono24SampleChunkConverter.cs | 46 + .../Mono8SampleChunkConverter.cs | 46 + .../MonoFloatSampleChunkConverter.cs | 46 + .../Stereo16SampleChunkConverter.cs | 47 + .../Stereo24SampleChunkConverter.cs | 49 + .../Stereo8SampleChunkConverter.cs | 45 + .../StereoFloatSampleChunkConverter.cs | 46 + .../SampleProviders/AdsrSampleProvider.cs | 91 + .../FadeInOutSampleProvider.cs | 150 + .../SampleProviders/MeteringSampleProvider.cs | 105 + .../SampleProviders/MixingSampleProvider.cs | 181 ++ .../MonoToStereoSampleProvider.cs | 66 + .../MultiplexingSampleProvider.cs | 172 + .../NotifyingSampleProvider.cs | 62 + .../SampleProviders/OffsetSampleProvider.cs | 255 ++ .../SampleProviders/PanningSampleProvider.cs | 220 ++ .../Pcm16BitToSampleProvider.cs | 40 + .../Pcm24BitToSampleProvider.cs | 41 + .../Pcm32BitToSampleProvider.cs | 42 + .../Pcm8BitToSampleProvider.cs | 40 + NAudio/Wave/SampleProviders/SampleChannel.cs | 86 + .../SampleProviderConverterBase.cs | 60 + .../SampleProviderConverters.cs | 59 + .../SampleProviders/SampleToWaveProvider.cs | 47 + .../SampleProviders/SampleToWaveProvider16.cs | 81 + .../SampleProviders/SampleToWaveProvider24.cs | 85 + .../Wave/SampleProviders/SignalGenerator.cs | 291 ++ .../SampleProviders/VolumeSampleProvider.cs | 60 + .../SampleProviders/WaveToSampleProvider.cs | 41 + .../SampleProviders/WaveToSampleProvider64.cs | 42 + .../WdlResamplingSampleProvider.cs | 57 + NAudio/Wave/WaveExtensionMethods.cs | 37 + NAudio/Wave/WaveFormats/AdpcmWaveFormat.cs | 117 + NAudio/Wave/WaveFormats/Gsm610WaveFormat.cs | 48 + NAudio/Wave/WaveFormats/ImaAdpcmWaveFormat.cs | 42 + NAudio/Wave/WaveFormats/Mp3WaveFormat.cs | 90 + NAudio/Wave/WaveFormats/OggWaveFormat.cs | 14 + .../Wave/WaveFormats/TrueSpeechWaveFormat.cs | 48 + NAudio/Wave/WaveFormats/WaveFormat.cs | 389 +++ .../WaveFormats/WaveFormatCustomMarshaler.cs | 70 + NAudio/Wave/WaveFormats/WaveFormatEncoding.cs | 434 +++ .../Wave/WaveFormats/WaveFormatExtensible.cs | 98 + .../Wave/WaveFormats/WaveFormatExtraData.cs | 60 + NAudio/Wave/WaveFormats/WmaWaveFormat.cs | 35 + NAudio/Wave/WaveInputs/IWaveIn.cs | 37 + NAudio/Wave/WaveInputs/WasapiCapture.cs | 342 ++ .../Wave/WaveInputs/WasapiLoopbackCapture.cs | 58 + NAudio/Wave/WaveInputs/WaveIn.cs | 308 ++ NAudio/Wave/WaveInputs/WaveInEvent.cs | 260 ++ NAudio/Wave/WaveOutputs/AiffFileWriter.cs | 376 +++ .../AsioAudioAvailableEventArgs.cs | 135 + NAudio/Wave/WaveOutputs/AsioOut.cs | 407 +++ NAudio/Wave/WaveOutputs/CueWaveFileWriter.cs | 67 + NAudio/Wave/WaveOutputs/DirectSoundOut.cs | 881 ++++++ NAudio/Wave/WaveOutputs/IWaveBuffer.cs | 70 + NAudio/Wave/WaveOutputs/IWavePlayer.cs | 65 + NAudio/Wave/WaveOutputs/IWaveProvider.cs | 25 + NAudio/Wave/WaveOutputs/IWaveProviderFloat.cs | 28 + .../WaveOutputs/MediaFoundationEncoder.cs | 306 ++ NAudio/Wave/WaveOutputs/PlaybackState.cs | 25 + NAudio/Wave/WaveOutputs/StoppedEventArgs.cs | 28 + NAudio/Wave/WaveOutputs/WasapiOut.cs | 431 +++ NAudio/Wave/WaveOutputs/WaveBuffer.cs | 242 ++ NAudio/Wave/WaveOutputs/WaveFileWriter.cs | 427 +++ NAudio/Wave/WaveOutputs/WaveOut.cs | 441 +++ NAudio/Wave/WaveOutputs/WaveOutEvent.cs | 374 +++ .../WaveProviders/BufferedWaveProvider.cs | 127 + .../WaveProviders/MediaFoundationResampler.cs | 177 ++ .../WaveProviders/MixingWaveProvider32.cs | 154 + .../WaveProviders/MonoToStereoProvider16.cs | 82 + .../WaveProviders/MultiplexingWaveProvider.cs | 183 ++ .../WaveProviders/StereoToMonoProvider16.cs | 84 + .../WaveProviders/VolumeWaveProvider16.cs | 86 + .../WaveProviders/Wave16toFloatProvider.cs | 78 + .../WaveProviders/WaveFloatTo16Provider.cs | 85 + NAudio/Wave/WaveProviders/WaveInProvider.cs | 49 + NAudio/Wave/WaveProviders/WaveProvider16.cs | 67 + NAudio/Wave/WaveProviders/WaveProvider32.cs | 69 + NAudio/Wave/WaveProviders/WaveRecorder.cs | 57 + NAudio/Wave/WaveStreams/AiffFileReader.cs | 330 ++ NAudio/Wave/WaveStreams/AudioFileReader.cs | 165 + .../WaveStreams/BlockAlignReductionStream.cs | 178 ++ NAudio/Wave/WaveStreams/CueList.cs | 299 ++ NAudio/Wave/WaveStreams/CueWaveFileReader.cs | 38 + NAudio/Wave/WaveStreams/ISampleNotifier.cs | 41 + .../Wave/WaveStreams/MediaFoundationReader.cs | 325 ++ NAudio/Wave/WaveStreams/Mp3FileReader.cs | 440 +++ .../Wave/WaveStreams/RawSourceWaveStream.cs | 68 + NAudio/Wave/WaveStreams/ResamplerDmoStream.cs | 199 ++ NAudio/Wave/WaveStreams/RiffChunk.cs | 47 + .../WaveStreams/SimpleCompressorStream.cs | 317 ++ NAudio/Wave/WaveStreams/Wave32To16Stream.cs | 191 ++ NAudio/Wave/WaveStreams/WaveChannel32.cs | 288 ++ NAudio/Wave/WaveStreams/WaveFileReader.cs | 260 ++ .../WaveStreams/WaveFormatConversionStream.cs | 276 ++ NAudio/Wave/WaveStreams/WaveInBuffer.cs | 158 + NAudio/Wave/WaveStreams/WaveMixerStream32.cs | 269 ++ NAudio/Wave/WaveStreams/WaveOffsetStream.cs | 251 ++ NAudio/Wave/WaveStreams/WaveOutBuffer.cs | 161 + NAudio/Wave/WaveStreams/WaveStream.cs | 139 + NAudioDemo/AcmDemo/AcmPanel.Designer.cs | 153 + NAudioDemo/AcmDemo/AcmPanel.cs | 283 ++ NAudioDemo/AcmDemo/AcmPanel.resx | 120 + .../AsioDirectPanel.Designer.cs | 143 + NAudioDemo/AsioDirectDemo/AsioDirectPanel.cs | 147 + .../AsioDirectDemo/AsioDirectPanel.resx | 127 + .../AsioRecordingPanel.Designer.cs | 226 ++ .../AsioRecordingDemo/AsioRecordingPanel.cs | 198 ++ .../AsioRecordingDemo/AsioRecordingPanel.resx | 123 + NAudioDemo/AudioPlaybackDemo/AsioOutPlugin.cs | 42 + .../AsioOutSettingsPanel.Designer.cs | 71 + .../AudioPlaybackDemo/AsioOutSettingsPanel.cs | 49 + .../AsioOutSettingsPanel.resx | 120 + .../AudioPlaybackPanel.Designer.cs | 341 ++ .../AudioPlaybackDemo/AudioPlaybackPanel.cs | 275 ++ .../AudioPlaybackDemo/AudioPlaybackPanel.resx | 126 + .../AudioPlaybackPanelPlugin.cs | 29 + .../AudioPlaybackDemo/DirectSoundOutPlugin.cs | 48 + .../DirectSoundOutSettingsPanel.Designer.cs | 58 + .../DirectSoundOutSettingsPanel.cs | 33 + .../DirectSoundOutSettingsPanel.resx | 120 + .../AudioPlaybackDemo/IOutputDevicePlugin.cs | 18 + .../AudioPlaybackDemo/WasapiOutPlugin.cs | 49 + .../WasapiOutSettingsPanel.Designer.cs | 85 + .../WasapiOutSettingsPanel.cs | 58 + .../WasapiOutSettingsPanel.resx | 120 + NAudioDemo/AudioPlaybackDemo/WaveOutPlugin.cs | 61 + .../WaveOutSettingsPanel.Designer.cs | 83 + .../AudioPlaybackDemo/WaveOutSettingsPanel.cs | 62 + .../WaveOutSettingsPanel.resx | 120 + .../FadeInOutDemo/FadeInOutPanel.Designer.cs | 185 ++ NAudioDemo/FadeInOutDemo/FadeInOutPanel.cs | 164 + NAudioDemo/FadeInOutDemo/FadeInOutPanel.resx | 123 + NAudioDemo/FadeInOutDemo/FadeInOutPlugin.cs | 22 + NAudioDemo/INAudioDemoPlugin.cs | 13 + NAudioDemo/Images.Designer.cs | 126 + NAudioDemo/Images.resx | 148 + NAudioDemo/LoopStream.cs | 73 + NAudioDemo/MainForm.Designer.cs | 102 + NAudioDemo/MainForm.cs | 63 + NAudioDemo/MainForm.resx | 120 + .../MediaFoundationDemoPanel.Designer.cs | 177 ++ .../MediaFoundationDemoPanel.cs | 142 + .../MediaFoundationDemoPanel.resx | 129 + .../MediaFoundationDemo/WasapiOutGuiThread.cs | 310 ++ NAudioDemo/MidiInDemo/MidiInPanel.Designer.cs | 179 ++ NAudioDemo/MidiInDemo/MidiInPanel.cs | 182 ++ NAudioDemo/MidiInDemo/MidiInPanel.resx | 123 + .../MP3StreamingPanel.Designer.cs | 179 ++ .../Mp3StreamingDemo/MP3StreamingPanel.cs | 300 ++ .../Mp3StreamingDemo/MP3StreamingPanel.resx | 123 + .../Mp3StreamingDemo/ReadFullyStream.cs | 101 + NAudioDemo/NAudioDemo.csproj | 347 +++ NAudioDemo/NAudioDemo.csproj.DotSettings | 2 + NAudioDemo/NAudioDemo.csproj.user | 6 + NAudioDemo/NetworkChatDemo/ALawChatCodec.cs | 72 + NAudioDemo/NetworkChatDemo/AcmChatCodec.cs | 109 + NAudioDemo/NetworkChatDemo/G722ChatCodec.cs | 78 + NAudioDemo/NetworkChatDemo/Gsm610ChatCodec.cs | 18 + .../NetworkChatDemo/INetworkChatCodec.cs | 34 + .../MicrosoftAdpcmChatCodec.cs | 18 + NAudioDemo/NetworkChatDemo/MuLawChatCodec.cs | 73 + .../NetworkChatPanel.Designer.cs | 154 + .../NetworkChatDemo/NetworkChatPanel.cs | 189 ++ .../NetworkChatDemo/NetworkChatPanel.resx | 120 + NAudioDemo/NetworkChatDemo/SpeexChatCodec.cs | 121 + .../NetworkChatDemo/TrueSpeechChatCodec.cs | 28 + .../UncompressedPcmChatCodec.cs | 40 + NAudioDemo/Program.cs | 29 + NAudioDemo/Properties/AssemblyInfo.cs | 33 + NAudioDemo/Properties/Resources.Designer.cs | 63 + NAudioDemo/Properties/Resources.resx | 117 + NAudioDemo/Properties/Settings.Designer.cs | 38 + NAudioDemo/Properties/Settings.settings | 9 + .../RecordingDemo/RecordingPanel.Designer.cs | 246 ++ NAudioDemo/RecordingDemo/RecordingPanel.cs | 228 ++ NAudioDemo/RecordingDemo/RecordingPanel.resx | 123 + NAudioDemo/Resources/Back.png | Bin 0 -> 236 bytes NAudioDemo/Resources/Forward.png | Bin 0 -> 236 bytes NAudioDemo/Resources/Loop.png | Bin 0 -> 369 bytes NAudioDemo/Resources/Open.png | Bin 0 -> 743 bytes NAudioDemo/Resources/Pause.png | Bin 0 -> 156 bytes NAudioDemo/Resources/Play.png | Bin 0 -> 199 bytes NAudioDemo/Resources/Rewind.png | Bin 0 -> 237 bytes NAudioDemo/Resources/Shuffle.png | Bin 0 -> 201 bytes NAudioDemo/Resources/Stop.png | Bin 0 -> 148 bytes .../GeneratorPanel.Designer.cs | 585 ++++ .../SignalGeneratorDemo/GeneratorPanel.cs | 371 +++ .../SignalGeneratorDemo/GeneratorPanel.resx | 120 + .../SignalGeneratorDemo/GeneratorPlugIn.cs | 19 + .../SimplePlaybackPanel.Designer.cs | 174 ++ .../SimplePlaybackDemo/SimplePlaybackPanel.cs | 183 ++ .../SimplePlaybackPanel.resx | 123 + .../SimplePlaybackPlugin.cs | 23 + NAudioDemo/app.config | 15 + NAudioTests/Acm/AcmDriverTests.cs | 106 + NAudioTests/Acm/GsmEncodeTest.cs | 48 + .../Acm/WaveFormatConversionStreamTests.cs | 168 + NAudioTests/Aiff/AiffReaderTests.cs | 51 + NAudioTests/DirectSound/DirectSoundTests.cs | 23 + .../Dmo/DmoMp3FrameDecompressorTests.cs | 113 + NAudioTests/Dmo/DmoTests.cs | 50 + NAudioTests/Dmo/ResamplerDmoStreamTests.cs | 141 + NAudioTests/Dmo/ResamplerDmoTests.cs | 201 ++ .../MediaFoundationReaderTests.cs | 30 + NAudioTests/Midi/MidiEventCollectionTest.cs | 95 + .../Midi/PitchWheelChangeEventTests.cs | 45 + NAudioTests/Mixer/MixerApiTests.cs | 121 + NAudioTests/Mp3/Mp3FileReaderTests.cs | 43 + NAudioTests/Mp3/Mp3FrameTests.cs | 63 + NAudioTests/NAudioTests.csproj | 176 ++ NAudioTests/NAudioTests.csproj.vspscc | 10 + NAudioTests/NAudioTests.nunit | 7 + NAudioTests/Properties/AssemblyInfo.cs | 35 + NAudioTests/StopwatchExtensions.cs | 29 + NAudioTests/Utils/BlockAlignedWaveStream.cs | 71 + NAudioTests/Utils/ByteEncodingTests.cs | 34 + NAudioTests/Utils/NullWaveStream.cs | 46 + NAudioTests/Utils/OSUtils.cs | 26 + .../Utils/SampleProviderTestHelpers.cs | 28 + NAudioTests/Wasapi/AudioClientTests.cs | 227 ++ NAudioTests/Wasapi/MMDeviceEnumeratorTests.cs | 97 + .../WaveFormats/AdpcmWaveFormatTests.cs | 52 + NAudioTests/WaveIn/WaveInDevicesTests.cs | 59 + .../BlockAlignmentReductionStreamTests.cs | 83 + .../WaveStreams/BufferedWaveProviderTests.cs | 35 + .../WaveStreams/ChunkIdentifierTests.cs | 30 + .../WaveStreams/CircularBufferTests.cs | 137 + .../FadeInOutSampleProviderTests.cs | 124 + .../WaveStreams/MixingSampleProviderTests.cs | 71 + .../MonoToStereoProvider16Tests.cs | 49 + .../MultiplexingSampleProviderTests.cs | 241 ++ .../MultiplexingWaveProviderTests.cs | 313 ++ .../WaveStreams/OffsetSampleProviderTests.cs | 251 ++ .../SampleToWaveProvider24Tests.cs | 28 + .../StereoToMonoProvider16Tests.cs | 53 + NAudioTests/WaveStreams/TestSampleProvider.cs | 37 + NAudioTests/WaveStreams/TestWaveProvider.cs | 36 + .../WaveStreams/VolumeWaveProvider16Tests.cs | 95 + NAudioTests/WaveStreams/WaveChannel32Tests.cs | 29 + .../WaveStreams/WaveFileReaderTests.cs | 157 + .../WaveStreams/WaveFileWriterTests.cs | 115 + .../WdlResamplingSampleProviderTests.cs | 86 + NAudioTests/WindowsMedia/WindowsMediaTests.cs | 114 + NAudioTests/packages.config | 6 + NAudioWin8Demo/App.xaml | 20 + NAudioWin8Demo/App.xaml.cs | 90 + NAudioWin8Demo/Assets/Logo.png | Bin 0 -> 801 bytes NAudioWin8Demo/Assets/SmallLogo.png | Bin 0 -> 329 bytes NAudioWin8Demo/Assets/SplashScreen.png | Bin 0 -> 2146 bytes NAudioWin8Demo/Assets/StoreLogo.png | Bin 0 -> 429 bytes NAudioWin8Demo/Common/StandardStyles.xaml | 1829 +++++++++++ NAudioWin8Demo/DelegateCommand.cs | 48 + NAudioWin8Demo/MainPage.xaml | 23 + NAudioWin8Demo/MainPage.xaml.cs | 39 + NAudioWin8Demo/MainPageViewModel.cs | 175 ++ NAudioWin8Demo/MediaFoundationReaderRT.cs | 66 + NAudioWin8Demo/NAudioWin8Demo.csproj | 160 + .../NAudioWin8Demo_TemporaryKey.pfx | Bin 0 -> 2504 bytes NAudioWin8Demo/Package.appxmanifest | 28 + NAudioWin8Demo/Properties/AssemblyInfo.cs | 29 + NAudioWin8Demo/ViewModelBase.cs | 16 + NAudioWpfDemo/App.xaml | 8 + NAudioWpfDemo/App.xaml.cs | 30 + .../AudioPlaybackDemo/AudioPlayback.cs | 117 + .../AudioPlaybackDemoPlugin.cs | 47 + .../AudioPlaybackDemoView.xaml | 35 + .../AudioPlaybackDemoView.xaml.cs | 27 + .../AudioPlaybackViewModel.cs | 124 + .../AudioPlaybackDemo/IVisualizationPlugin.cs | 18 + .../PolygonWaveFormVisualization.cs | 35 + .../PolylineWaveFormVisualization.cs | 34 + .../AudioPlaybackDemo/SampleAggregator.cs | 121 + .../SpectrumAnalyzerVisualization.cs | 35 + .../AudioPlaybackDemo/WaveformVisual.cs | 114 + NAudioWpfDemo/DrumMachineDemo/DrumKit.cs | 40 + .../DrumMachineDemo/DrumMachineDemoPlugin.cs | 43 + .../DrumMachineDemo/DrumMachineDemoView.xaml | 22 + .../DrumMachineDemoView.xaml.cs | 27 + .../DrumMachineDemoViewModel.cs | 79 + NAudioWpfDemo/DrumMachineDemo/DrumPattern.cs | 48 + .../DrumMachineDemo/DrumPatternEditor.xaml | 11 + .../DrumMachineDemo/DrumPatternEditor.xaml.cs | 136 + .../DrumPatternSampleProvider.cs | 58 + .../DrumMachineDemo/MusicSampleProvider.cs | 71 + .../DrumMachineDemo/PatternSequencer.cs | 91 + .../DrumMachineDemo/PatternSequencerTests.cs | 242 ++ NAudioWpfDemo/DrumMachineDemo/SampleSource.cs | 55 + .../EnumMftDemo.cs | 25 + .../EnumMftView.xaml | 16 + .../EnumMftView.xaml.cs | 27 + .../EnumMftViewModel.cs | 92 + .../EqualizationDemoPlugin.cs | 42 + .../EqualizationDemoView.xaml | 42 + .../EqualizationDemoView.xaml.cs | 17 + .../EqualizationDemoViewModel.cs | 220 ++ NAudioWpfDemo/EqualizationDemo/Equalizer.cs | 76 + .../EqualizationDemo/EqualizerBand.cs | 9 + NAudioWpfDemo/IModule.cs | 15 + NAudioWpfDemo/IWaveFormRenderer.cs | 12 + NAudioWpfDemo/MainWindow.xaml | 23 + NAudioWpfDemo/MainWindow.xaml.cs | 17 + NAudioWpfDemo/MainWindowViewModel.cs | 56 + .../MediaFoundationEncodePlugin.cs | 23 + .../MediaFoundationEncodeView.xaml | 39 + .../MediaFoundationEncodeView.xaml.cs | 27 + .../MediaFoundationEncodeViewModel.cs | 258 ++ .../MediaTypeViewModel.cs | 71 + .../MediaFoundationPlaybackPlugin.cs | 23 + .../MediaFoundationPlaybackView.xaml | 28 + .../MediaFoundationPlaybackView.xaml.cs | 27 + .../MediaFoundationPlaybackViewModel.cs | 253 ++ .../MediaFoundationEncodePlugin.cs | 20 + .../MediaFoundationResampleView.xaml | 31 + .../MediaFoundationResampleView.xaml.cs | 27 + .../MediaFoundationResampleViewModel.cs | 267 ++ NAudioWpfDemo/ModuleBase.cs | 39 + NAudioWpfDemo/NAudioWpfDemo.csproj | 348 +++ NAudioWpfDemo/PolygonWaveFormControl.xaml | 9 + NAudioWpfDemo/PolygonWaveFormControl.xaml.cs | 119 + NAudioWpfDemo/PolylineWaveFormControl.xaml | 8 + NAudioWpfDemo/PolylineWaveFormControl.xaml.cs | 110 + NAudioWpfDemo/Properties/AssemblyInfo.cs | 55 + .../Properties/Resources.Designer.cs | 63 + NAudioWpfDemo/Properties/Resources.resx | 117 + NAudioWpfDemo/Properties/Settings.Designer.cs | 26 + NAudioWpfDemo/Properties/Settings.settings | 7 + NAudioWpfDemo/SpectrumAnalyser.xaml | 8 + NAudioWpfDemo/SpectrumAnalyser.xaml.cs | 104 + NAudioWpfDemo/ViewModel/DelegateCommand.cs | 55 + NAudioWpfDemo/ViewModel/RelayCommand.cs | 59 + NAudioWpfDemo/ViewModel/ViewModelBase.cs | 19 + .../WasapiCaptureDemo/RecordingsView.xaml | 22 + .../WasapiCaptureDemo/RecordingsView.xaml.cs | 27 + .../WasapiCaptureDemo/RecordingsViewModel.cs | 86 + .../WasapiCaptureDemoPlugin.cs | 42 + .../WasapiCaptureDemoView.xaml | 43 + .../WasapiCaptureDemoView.xaml.cs | 17 + .../WasapiCaptureViewModel.cs | 286 ++ NAudioWpfDemo/WaveFormControl.xaml | 10 + NAudioWpfDemo/WaveFormControl.xaml.cs | 109 + NAudioWpfDemo/app.config | 3 + NAudioWpfDemo/packages.config | 4 + SampleData/Drums/closed-hat-trimmed.wav | Bin 0 -> 14466 bytes SampleData/Drums/crash-trimmed.wav | Bin 0 -> 175916 bytes SampleData/Drums/kick-trimmed.wav | Bin 0 -> 66172 bytes SampleData/Drums/open-hat-trimmed.wav | Bin 0 -> 132740 bytes SampleData/Drums/snare-trimmed.wav | Bin 0 -> 48936 bytes Tools/NuGet.exe | Bin 0 -> 692736 bytes build.bat | 1 + license.txt | 31 + readme.txt | 86 + zipdemo.py | 32 + 856 files changed, 92618 insertions(+) create mode 100644 ..svnbridge/.svnbridge create mode 100644 .build/MSBuild.Community.Tasks.dll create mode 100644 .build/MSBuild.Community.Tasks.targets create mode 100644 .hgignore create mode 100644 AudioFileInspector/AboutForm.Designer.cs create mode 100644 AudioFileInspector/AboutForm.cs create mode 100644 AudioFileInspector/AboutForm.resx create mode 100644 AudioFileInspector/AudioFileInspector.csproj create mode 100644 AudioFileInspector/AudioFileInspectorForm.Designer.cs create mode 100644 AudioFileInspector/AudioFileInspectorForm.cs create mode 100644 AudioFileInspector/AudioFileInspectorForm.resx create mode 100644 AudioFileInspector/FileAssociations.cs create mode 100644 AudioFileInspector/FileInspectors/CakewalkMapInspector.cs create mode 100644 AudioFileInspector/FileInspectors/MidiFileInspector.cs create mode 100644 AudioFileInspector/FileInspectors/Mp3FileInspector.cs create mode 100644 AudioFileInspector/FileInspectors/SoundFontInspector.cs create mode 100644 AudioFileInspector/FileInspectors/WaveFileInspector.cs create mode 100644 AudioFileInspector/FindForm.Designer.cs create mode 100644 AudioFileInspector/FindForm.cs create mode 100644 AudioFileInspector/FindForm.resx create mode 100644 AudioFileInspector/IAudioFileInspector.cs create mode 100644 AudioFileInspector/InstallScript.nsi create mode 100644 AudioFileInspector/OptionsForm.Designer.cs create mode 100644 AudioFileInspector/OptionsForm.cs create mode 100644 AudioFileInspector/OptionsForm.resx create mode 100644 AudioFileInspector/Program.cs create mode 100644 AudioFileInspector/Properties/AssemblyInfo.cs create mode 100644 AudioFileInspector/Properties/Resources.Designer.cs create mode 100644 AudioFileInspector/Properties/Resources.resx create mode 100644 AudioFileInspector/Properties/Settings.Designer.cs create mode 100644 AudioFileInspector/Properties/Settings.settings create mode 100644 AudioFileInspector/audio_file_inspector.html create mode 100644 Build.proj create mode 100644 BuildProcessTemplates/DefaultTemplate.xaml create mode 100644 BuildProcessTemplates/UpgradeTemplate.xaml create mode 100644 Lib/MEF/Microsoft.ComponentModel.Composition.Initialization.Desktop.dll create mode 100644 Lib/MEF/System.ComponentModel.Composition.dll create mode 100644 Lib/MEF/readme.txt create mode 100644 Lib/NSpeex/NSpeex.dll create mode 100644 MidiFileConverter/AboutForm.Designer.cs create mode 100644 MidiFileConverter/AboutForm.cs create mode 100644 MidiFileConverter/AboutForm.resx create mode 100644 MidiFileConverter/AdvancedOptionsForm.Designer.cs create mode 100644 MidiFileConverter/AdvancedOptionsForm.cs create mode 100644 MidiFileConverter/AdvancedOptionsForm.resx create mode 100644 MidiFileConverter/InstallScript.nsi create mode 100644 MidiFileConverter/MainForm.Designer.cs create mode 100644 MidiFileConverter/MainForm.cs create mode 100644 MidiFileConverter/MainForm.resx create mode 100644 MidiFileConverter/MidiConverter.cs create mode 100644 MidiFileConverter/MidiFileConverter.csproj create mode 100644 MidiFileConverter/MidiFileConverter.csproj.vspscc create mode 100644 MidiFileConverter/NamingRule.cs create mode 100644 MidiFileConverter/NamingRules.xml create mode 100644 MidiFileConverter/OutputMidiType.cs create mode 100644 MidiFileConverter/Program.cs create mode 100644 MidiFileConverter/ProgressEventArgs.cs create mode 100644 MidiFileConverter/Properties/AssemblyInfo.cs create mode 100644 MidiFileConverter/Properties/Resources.Designer.cs create mode 100644 MidiFileConverter/Properties/Resources.resx create mode 100644 MidiFileConverter/Properties/Settings.Designer.cs create mode 100644 MidiFileConverter/Properties/Settings.settings create mode 100644 MidiFileConverter/app.config create mode 100644 MidiFileConverter/midi_file_converter.html create mode 100644 MixDiff/AboutForm.Designer.cs create mode 100644 MixDiff/AboutForm.cs create mode 100644 MixDiff/AboutForm.resx create mode 100644 MixDiff/Images.Designer.cs create mode 100644 MixDiff/Images.resx create mode 100644 MixDiff/MixDiff.csproj create mode 100644 MixDiff/MixDiff.csproj.vspscc create mode 100644 MixDiff/MixDiffForm.Designer.cs create mode 100644 MixDiff/MixDiffForm.cs create mode 100644 MixDiff/MixDiffForm.resx create mode 100644 MixDiff/MixDiffStream.cs create mode 100644 MixDiff/MixdownInfo.cs create mode 100644 MixDiff/Program.cs create mode 100644 MixDiff/Properties/AssemblyInfo.cs create mode 100644 MixDiff/Properties/Resources.Designer.cs create mode 100644 MixDiff/Properties/Resources.resx create mode 100644 MixDiff/Properties/Settings.Designer.cs create mode 100644 MixDiff/Properties/Settings.settings create mode 100644 MixDiff/PropertiesForm.Designer.cs create mode 100644 MixDiff/PropertiesForm.cs create mode 100644 MixDiff/PropertiesForm.resx create mode 100644 MixDiff/Resources/Back.png create mode 100644 MixDiff/Resources/Forward.png create mode 100644 MixDiff/Resources/Loop.png create mode 100644 MixDiff/Resources/Pause.png create mode 100644 MixDiff/Resources/Play.png create mode 100644 MixDiff/Resources/Rewind.png create mode 100644 MixDiff/Resources/Shuffle.png create mode 100644 MixDiff/Resources/Stop.png create mode 100644 MixDiff/SettingsForm.Designer.cs create mode 100644 MixDiff/SettingsForm.cs create mode 100644 MixDiff/SettingsForm.resx create mode 100644 MixDiff/app.config create mode 100644 NAudio.Win8/NAudio.Win8.csproj create mode 100644 NAudio.Win8/Properties/AssemblyInfo.cs create mode 100644 NAudio.Win8/Wave/WaveExtensionMethods.cs create mode 100644 NAudio.Win8/Wave/WaveInputs/WasapiCaptureRT.cs create mode 100644 NAudio.Win8/Wave/WaveOutputs/IWavePlayer.cs create mode 100644 NAudio.Win8/Wave/WaveOutputs/WasapiOutRT.cs create mode 100644 NAudio.WindowsMediaFormat/Interop/BufferTypes/INSSBuffer.cs create mode 100644 NAudio.WindowsMediaFormat/Interop/BufferTypes/INSSBuffer2.cs create mode 100644 NAudio.WindowsMediaFormat/Interop/BufferTypes/INSSBuffer3.cs create mode 100644 NAudio.WindowsMediaFormat/Interop/BufferTypes/INSSBuffer4.cs create mode 100644 NAudio.WindowsMediaFormat/Interop/BufferTypes/IWMSBufferAllocator.cs create mode 100644 NAudio.WindowsMediaFormat/Interop/Codec.cs create mode 100644 NAudio.WindowsMediaFormat/Interop/CodecFormat.cs create mode 100644 NAudio.WindowsMediaFormat/Interop/CommonTypes/IWMBandwidthSharing.cs create mode 100644 NAudio.WindowsMediaFormat/Interop/CommonTypes/IWMCodecInfo.cs create mode 100644 NAudio.WindowsMediaFormat/Interop/CommonTypes/IWMCodecInfo2.cs create mode 100644 NAudio.WindowsMediaFormat/Interop/CommonTypes/IWMCodecInfo3 .cs create mode 100644 NAudio.WindowsMediaFormat/Interop/CommonTypes/IWMHeaderInfo.cs create mode 100644 NAudio.WindowsMediaFormat/Interop/CommonTypes/IWMHeaderInfo2.cs create mode 100644 NAudio.WindowsMediaFormat/Interop/CommonTypes/IWMHeaderInfo3.cs create mode 100644 NAudio.WindowsMediaFormat/Interop/CommonTypes/IWMIndexer.cs create mode 100644 NAudio.WindowsMediaFormat/Interop/CommonTypes/IWMIndexer2.cs create mode 100644 NAudio.WindowsMediaFormat/Interop/CommonTypes/IWMInputMediaProps.cs create mode 100644 NAudio.WindowsMediaFormat/Interop/CommonTypes/IWMMediaProps.cs create mode 100644 NAudio.WindowsMediaFormat/Interop/CommonTypes/IWMMetadataEditor.cs create mode 100644 NAudio.WindowsMediaFormat/Interop/CommonTypes/IWMMetadataEditor2.cs create mode 100644 NAudio.WindowsMediaFormat/Interop/CommonTypes/IWMMutualExclusion.cs create mode 100644 NAudio.WindowsMediaFormat/Interop/CommonTypes/IWMMutualExclusion2.cs create mode 100644 NAudio.WindowsMediaFormat/Interop/CommonTypes/IWMOutputMediaProps.cs create mode 100644 NAudio.WindowsMediaFormat/Interop/CommonTypes/IWMStatusCallback.cs create mode 100644 NAudio.WindowsMediaFormat/Interop/CommonTypes/IWMStreamList.cs create mode 100644 NAudio.WindowsMediaFormat/Interop/CommonTypes/IWMStreamPrioritization.cs create mode 100644 NAudio.WindowsMediaFormat/Interop/CommonTypes/IWMVideoMediaProps.cs create mode 100644 NAudio.WindowsMediaFormat/Interop/CommonTypes/WMT_ATTR_DATATYPE.cs create mode 100644 NAudio.WindowsMediaFormat/Interop/CommonTypes/WMT_CODEC_INFO_TYPE.cs create mode 100644 NAudio.WindowsMediaFormat/Interop/CommonTypes/WMT_INDEXER_TYPE.cs create mode 100644 NAudio.WindowsMediaFormat/Interop/CommonTypes/WMT_INDEX_TYPE.cs create mode 100644 NAudio.WindowsMediaFormat/Interop/CommonTypes/WMT_NET_PROTOCOL.cs create mode 100644 NAudio.WindowsMediaFormat/Interop/CommonTypes/WMT_OFFSET_FORMAT.cs create mode 100644 NAudio.WindowsMediaFormat/Interop/CommonTypes/WMT_PLAY_MODE.cs create mode 100644 NAudio.WindowsMediaFormat/Interop/CommonTypes/WMT_RIGHTS.cs create mode 100644 NAudio.WindowsMediaFormat/Interop/CommonTypes/WMT_STATUS.cs create mode 100644 NAudio.WindowsMediaFormat/Interop/CommonTypes/WMT_STORAGE_FORMAT.cs create mode 100644 NAudio.WindowsMediaFormat/Interop/CommonTypes/WMT_STREAM_SELECTION.cs create mode 100644 NAudio.WindowsMediaFormat/Interop/CommonTypes/WMT_TIMECODE_EXTENSION_DATA.cs create mode 100644 NAudio.WindowsMediaFormat/Interop/CommonTypes/WMT_TRANSPORT_TYPE.cs create mode 100644 NAudio.WindowsMediaFormat/Interop/CommonTypes/WMT_VERSION.cs create mode 100644 NAudio.WindowsMediaFormat/Interop/CommonTypes/WM_MEDIA_TYPE.cs create mode 100644 NAudio.WindowsMediaFormat/Interop/CommonTypes/WM_STREAM_PRIORITY_RECORD.cs create mode 100644 NAudio.WindowsMediaFormat/Interop/Enums.cs create mode 100644 NAudio.WindowsMediaFormat/Interop/MediaTypes.cs create mode 100644 NAudio.WindowsMediaFormat/Interop/NSSBuffer.cs create mode 100644 NAudio.WindowsMediaFormat/Interop/ProfilesTypes/IWMProfile.cs create mode 100644 NAudio.WindowsMediaFormat/Interop/ProfilesTypes/IWMProfile2.cs create mode 100644 NAudio.WindowsMediaFormat/Interop/ProfilesTypes/IWMProfile3.cs create mode 100644 NAudio.WindowsMediaFormat/Interop/ProfilesTypes/IWMProfileManager.cs create mode 100644 NAudio.WindowsMediaFormat/Interop/ProfilesTypes/IWMProfileManager2.cs create mode 100644 NAudio.WindowsMediaFormat/Interop/ProfilesTypes/IWMProfileManagerLanguage.cs create mode 100644 NAudio.WindowsMediaFormat/Interop/ProfilesTypes/IWMStreamConfig.cs create mode 100644 NAudio.WindowsMediaFormat/Interop/ProfilesTypes/IWMStreamConfig2.cs create mode 100644 NAudio.WindowsMediaFormat/Interop/ProfilesTypes/IWMStreamConfig3.cs create mode 100644 NAudio.WindowsMediaFormat/Interop/ReaderTypes/IWMReader.cs create mode 100644 NAudio.WindowsMediaFormat/Interop/ReaderTypes/IWMReaderAdvanced.cs create mode 100644 NAudio.WindowsMediaFormat/Interop/ReaderTypes/IWMReaderAdvanced2.cs create mode 100644 NAudio.WindowsMediaFormat/Interop/ReaderTypes/IWMReaderAdvanced3.cs create mode 100644 NAudio.WindowsMediaFormat/Interop/ReaderTypes/IWMReaderAdvanced4.cs create mode 100644 NAudio.WindowsMediaFormat/Interop/ReaderTypes/IWMReaderAllocatorEx.cs create mode 100644 NAudio.WindowsMediaFormat/Interop/ReaderTypes/IWMReaderCallback.cs create mode 100644 NAudio.WindowsMediaFormat/Interop/ReaderTypes/IWMSyncReader.cs create mode 100644 NAudio.WindowsMediaFormat/Interop/ReaderTypes/IWMSyncReader2.cs create mode 100644 NAudio.WindowsMediaFormat/Interop/ReaderTypes/WM_READER_CLIENTINFO.cs create mode 100644 NAudio.WindowsMediaFormat/Interop/ReaderTypes/WM_READER_STATISTICS.cs create mode 100644 NAudio.WindowsMediaFormat/Interop/WMFFunctions.cs create mode 100644 NAudio.WindowsMediaFormat/Interop/WMHeaderInfo.cs create mode 100644 NAudio.WindowsMediaFormat/Interop/WMStreamConfig.cs create mode 100644 NAudio.WindowsMediaFormat/Interop/WmProfile.cs create mode 100644 NAudio.WindowsMediaFormat/Interop/WmaStream.cs create mode 100644 NAudio.WindowsMediaFormat/Interop/WmaWriter.cs create mode 100644 NAudio.WindowsMediaFormat/Interop/WriterTypes/IWMWriter.cs create mode 100644 NAudio.WindowsMediaFormat/Interop/WriterTypes/IWMWriterAdvanced.cs create mode 100644 NAudio.WindowsMediaFormat/Interop/WriterTypes/IWMWriterAdvanced2.cs create mode 100644 NAudio.WindowsMediaFormat/Interop/WriterTypes/IWMWriterAdvanced3.cs create mode 100644 NAudio.WindowsMediaFormat/Interop/WriterTypes/IWMWriterFileSink.cs create mode 100644 NAudio.WindowsMediaFormat/Interop/WriterTypes/IWMWriterFileSink2.cs create mode 100644 NAudio.WindowsMediaFormat/Interop/WriterTypes/IWMWriterFileSink3.cs create mode 100644 NAudio.WindowsMediaFormat/Interop/WriterTypes/IWMWriterNetworkSink.cs create mode 100644 NAudio.WindowsMediaFormat/Interop/WriterTypes/IWMWriterPreprocess.cs create mode 100644 NAudio.WindowsMediaFormat/Interop/WriterTypes/IWMWriterPushSink.cs create mode 100644 NAudio.WindowsMediaFormat/Interop/WriterTypes/IWMWriterSink.cs create mode 100644 NAudio.WindowsMediaFormat/Interop/WriterTypes/WMT_BUFFER_SEGMENT.cs create mode 100644 NAudio.WindowsMediaFormat/Interop/WriterTypes/WMT_FILESINK_DATA_UNIT.cs create mode 100644 NAudio.WindowsMediaFormat/Interop/WriterTypes/WMT_PAYLOAD_FRAGMENT.cs create mode 100644 NAudio.WindowsMediaFormat/Interop/WriterTypes/WM_WRITER_STATISTICS.cs create mode 100644 NAudio.WindowsMediaFormat/Interop/WriterTypes/WM_WRITER_STATISTICS_EX.cs create mode 100644 NAudio.WindowsMediaFormat/NAudio.WindowsMediaFormat.csproj create mode 100644 NAudio.WindowsMediaFormat/Properties/AssemblyInfo.cs create mode 100644 NAudio.WindowsMediaFormat/WmaFileReader.cs create mode 100644 NAudio.WindowsMediaFormat/app.config create mode 100644 NAudio.Wma.nuspec create mode 100644 NAudio.nuspec create mode 100644 NAudio.proj create mode 100644 NAudio.sln create mode 100644 NAudio.sln.DotSettings create mode 100644 NAudio/Changes.xml create mode 100644 NAudio/Codecs/ALawDecoder.cs create mode 100644 NAudio/Codecs/ALawEncoder.cs create mode 100644 NAudio/Codecs/G722Codec.cs create mode 100644 NAudio/Codecs/MuLawDecoder.cs create mode 100644 NAudio/Codecs/MuLawEncoder.cs create mode 100644 NAudio/CoreAudioApi/AudioCaptureClient.cs create mode 100644 NAudio/CoreAudioApi/AudioClient.cs create mode 100644 NAudio/CoreAudioApi/AudioClientBufferFlags.cs create mode 100644 NAudio/CoreAudioApi/AudioClientProperties.cs create mode 100644 NAudio/CoreAudioApi/AudioClientShareMode.cs create mode 100644 NAudio/CoreAudioApi/AudioClientStreamFlags.cs create mode 100644 NAudio/CoreAudioApi/AudioClientStreamOptions.cs create mode 100644 NAudio/CoreAudioApi/AudioClockClient.cs create mode 100644 NAudio/CoreAudioApi/AudioEndpointVolume.cs create mode 100644 NAudio/CoreAudioApi/AudioEndpointVolumeCallback.cs create mode 100644 NAudio/CoreAudioApi/AudioEndpointVolumeChannel.cs create mode 100644 NAudio/CoreAudioApi/AudioEndpointVolumeChannels.cs create mode 100644 NAudio/CoreAudioApi/AudioEndpointVolumeNotificationDelegate.cs create mode 100644 NAudio/CoreAudioApi/AudioEndpointVolumeStepInformation.cs create mode 100644 NAudio/CoreAudioApi/AudioEndpointVolumeVolumeRange.cs create mode 100644 NAudio/CoreAudioApi/AudioMeterInformation.cs create mode 100644 NAudio/CoreAudioApi/AudioMeterInformationChannels.cs create mode 100644 NAudio/CoreAudioApi/AudioRenderClient.cs create mode 100644 NAudio/CoreAudioApi/AudioSessionControl.cs create mode 100644 NAudio/CoreAudioApi/AudioSessionEventsCallback.cs create mode 100644 NAudio/CoreAudioApi/AudioSessionManager.cs create mode 100644 NAudio/CoreAudioApi/AudioStreamCategory.cs create mode 100644 NAudio/CoreAudioApi/AudioVolumeNotificationData.cs create mode 100644 NAudio/CoreAudioApi/DataFlow.cs create mode 100644 NAudio/CoreAudioApi/DeviceState.cs create mode 100644 NAudio/CoreAudioApi/EEndpointHardwareSupport.cs create mode 100644 NAudio/CoreAudioApi/Interfaces/AudioVolumeNotificationDataStruct.cs create mode 100644 NAudio/CoreAudioApi/Interfaces/Blob.cs create mode 100644 NAudio/CoreAudioApi/Interfaces/ClsCtx.cs create mode 100644 NAudio/CoreAudioApi/Interfaces/ErrorCodes.cs create mode 100644 NAudio/CoreAudioApi/Interfaces/IAudioCaptureClient.cs create mode 100644 NAudio/CoreAudioApi/Interfaces/IAudioClient.cs create mode 100644 NAudio/CoreAudioApi/Interfaces/IAudioClock2.cs create mode 100644 NAudio/CoreAudioApi/Interfaces/IAudioEndpointVolume.cs create mode 100644 NAudio/CoreAudioApi/Interfaces/IAudioEndpointVolumeCallback.cs create mode 100644 NAudio/CoreAudioApi/Interfaces/IAudioMeterInformation.cs create mode 100644 NAudio/CoreAudioApi/Interfaces/IAudioRenderClient.cs create mode 100644 NAudio/CoreAudioApi/Interfaces/IAudioSessionControl.cs create mode 100644 NAudio/CoreAudioApi/Interfaces/IAudioSessionEvents.cs create mode 100644 NAudio/CoreAudioApi/Interfaces/IAudioSessionEventsHandler.cs create mode 100644 NAudio/CoreAudioApi/Interfaces/IAudioSessionManager.cs create mode 100644 NAudio/CoreAudioApi/Interfaces/IMMDevice.cs create mode 100644 NAudio/CoreAudioApi/Interfaces/IMMDeviceCollection.cs create mode 100644 NAudio/CoreAudioApi/Interfaces/IMMDeviceEnumerator.cs create mode 100644 NAudio/CoreAudioApi/Interfaces/IMMEndpoint.cs create mode 100644 NAudio/CoreAudioApi/Interfaces/IMMNotificationClient.cs create mode 100644 NAudio/CoreAudioApi/Interfaces/IPropertyStore.cs create mode 100644 NAudio/CoreAudioApi/Interfaces/ISimpleAudioVolume.cs create mode 100644 NAudio/CoreAudioApi/Interfaces/MMDeviceEnumeratorComObject.cs create mode 100644 NAudio/CoreAudioApi/Interfaces/StorageAccessMode.cs create mode 100644 NAudio/CoreAudioApi/MMDevice.cs create mode 100644 NAudio/CoreAudioApi/MMDeviceCollection.cs create mode 100644 NAudio/CoreAudioApi/MMDeviceEnumerator.cs create mode 100644 NAudio/CoreAudioApi/PropVariant.cs create mode 100644 NAudio/CoreAudioApi/PropertyKey.cs create mode 100644 NAudio/CoreAudioApi/PropertyKeys.cs create mode 100644 NAudio/CoreAudioApi/PropertyStore.cs create mode 100644 NAudio/CoreAudioApi/PropertyStoreProperty.cs create mode 100644 NAudio/CoreAudioApi/Role.cs create mode 100644 NAudio/CoreAudioApi/SimpleAudioVolume.cs create mode 100644 NAudio/Dmo/AudioMediaSubtypes.cs create mode 100644 NAudio/Dmo/DmoDescriptor.cs create mode 100644 NAudio/Dmo/DmoEnumFlags.cs create mode 100644 NAudio/Dmo/DmoEnumerator.cs create mode 100644 NAudio/Dmo/DmoGuids.cs create mode 100644 NAudio/Dmo/DmoHResults.cs create mode 100644 NAudio/Dmo/DmoInputDataBufferFlags.cs create mode 100644 NAudio/Dmo/DmoInputStatusFlags.cs create mode 100644 NAudio/Dmo/DmoInterop.cs create mode 100644 NAudio/Dmo/DmoMediaType.cs create mode 100644 NAudio/Dmo/DmoOutputDataBuffer.cs create mode 100644 NAudio/Dmo/DmoOutputDataBufferFlags.cs create mode 100644 NAudio/Dmo/DmoPartialMediaType.cs create mode 100644 NAudio/Dmo/DmoProcessOutputFlags.cs create mode 100644 NAudio/Dmo/DmoSetTypeFlags.cs create mode 100644 NAudio/Dmo/IEnumDmo.cs create mode 100644 NAudio/Dmo/IMediaBuffer.cs create mode 100644 NAudio/Dmo/IMediaObject.cs create mode 100644 NAudio/Dmo/IMediaParamInfo.cs create mode 100644 NAudio/Dmo/IWMResamplerProps.cs create mode 100644 NAudio/Dmo/InputStreamInfoFlags.cs create mode 100644 NAudio/Dmo/MediaBuffer.cs create mode 100644 NAudio/Dmo/MediaObject.cs create mode 100644 NAudio/Dmo/MediaObjectSizeInfo.cs create mode 100644 NAudio/Dmo/MediaParamInfo.cs create mode 100644 NAudio/Dmo/MediaTypes.cs create mode 100644 NAudio/Dmo/OutputStreamInfoFlags.cs create mode 100644 NAudio/Dmo/ResamplerMediaObject.cs create mode 100644 NAudio/Dmo/WindowsMediaMp3Decoder.cs create mode 100644 NAudio/Dsp/BiQuadFilter.cs create mode 100644 NAudio/Dsp/Complex.cs create mode 100644 NAudio/Dsp/EnvelopeDetector.cs create mode 100644 NAudio/Dsp/EnvelopeGenerator.cs create mode 100644 NAudio/Dsp/FastFourierTransform.cs create mode 100644 NAudio/Dsp/ImpulseResponseConvolution.cs create mode 100644 NAudio/Dsp/SimpleCompressor.cs create mode 100644 NAudio/Dsp/SimpleGate.cs create mode 100644 NAudio/Dsp/WdlResampler.cs create mode 100644 NAudio/FileFormats/Map/CakewalkDrumMapping.cs create mode 100644 NAudio/FileFormats/Map/CakewalkMapFile.cs create mode 100644 NAudio/FileFormats/Map/MapBlockHeader.cs create mode 100644 NAudio/FileFormats/Mp3/ChannelMode.cs create mode 100644 NAudio/FileFormats/Mp3/DmoMp3FrameDecompressor.cs create mode 100644 NAudio/FileFormats/Mp3/IMp3FrameDecompressor.cs create mode 100644 NAudio/FileFormats/Mp3/Id3v2Tag.cs create mode 100644 NAudio/FileFormats/Mp3/Mp3Frame.cs create mode 100644 NAudio/FileFormats/Mp3/Mp3FrameDecompressor.cs create mode 100644 NAudio/FileFormats/Mp3/MpegLayer.cs create mode 100644 NAudio/FileFormats/Mp3/MpegVersion.cs create mode 100644 NAudio/FileFormats/Mp3/XingHeader.cs create mode 100644 NAudio/FileFormats/Sfz/SfzFileReader.cs create mode 100644 NAudio/FileFormats/SoundFont/Generator.cs create mode 100644 NAudio/FileFormats/SoundFont/GeneratorBuilder.cs create mode 100644 NAudio/FileFormats/SoundFont/GeneratorEnum.cs create mode 100644 NAudio/FileFormats/SoundFont/InfoChunk.cs create mode 100644 NAudio/FileFormats/SoundFont/Instrument.cs create mode 100644 NAudio/FileFormats/SoundFont/InstrumentBuilder.cs create mode 100644 NAudio/FileFormats/SoundFont/Modulator.cs create mode 100644 NAudio/FileFormats/SoundFont/ModulatorBuilder.cs create mode 100644 NAudio/FileFormats/SoundFont/ModulatorType.cs create mode 100644 NAudio/FileFormats/SoundFont/Preset.cs create mode 100644 NAudio/FileFormats/SoundFont/PresetBuilder.cs create mode 100644 NAudio/FileFormats/SoundFont/PresetsChunk.cs create mode 100644 NAudio/FileFormats/SoundFont/RiffChunk.cs create mode 100644 NAudio/FileFormats/SoundFont/SFSampleLink.cs create mode 100644 NAudio/FileFormats/SoundFont/SFVersion.cs create mode 100644 NAudio/FileFormats/SoundFont/SFVersionBuilder.cs create mode 100644 NAudio/FileFormats/SoundFont/SampleDataChunk.cs create mode 100644 NAudio/FileFormats/SoundFont/SampleHeader.cs create mode 100644 NAudio/FileFormats/SoundFont/SampleHeaderBuilder.cs create mode 100644 NAudio/FileFormats/SoundFont/SampleMode.cs create mode 100644 NAudio/FileFormats/SoundFont/SoundFont.cs create mode 100644 NAudio/FileFormats/SoundFont/StructureBuilder.cs create mode 100644 NAudio/FileFormats/SoundFont/Zone.cs create mode 100644 NAudio/FileFormats/SoundFont/ZoneBuilder.cs create mode 100644 NAudio/FileFormats/Wav/WaveFileChunkReader.cs create mode 100644 NAudio/Gui/Fader.cs create mode 100644 NAudio/Gui/Fader.resx create mode 100644 NAudio/Gui/PanSlider.cs create mode 100644 NAudio/Gui/PanSlider.resx create mode 100644 NAudio/Gui/Pot.Designer.cs create mode 100644 NAudio/Gui/Pot.cs create mode 100644 NAudio/Gui/Pot.resx create mode 100644 NAudio/Gui/VolumeMeter.Designer.cs create mode 100644 NAudio/Gui/VolumeMeter.cs create mode 100644 NAudio/Gui/VolumeSlider.cs create mode 100644 NAudio/Gui/VolumeSlider.resx create mode 100644 NAudio/Gui/WaveViewer.cs create mode 100644 NAudio/Gui/WaveViewer.resx create mode 100644 NAudio/Gui/WaveformPainter.Designer.cs create mode 100644 NAudio/Gui/WaveformPainter.cs create mode 100644 NAudio/MediaFoundation/AudioSubtypes.cs create mode 100644 NAudio/MediaFoundation/IMFActivate.cs create mode 100644 NAudio/MediaFoundation/IMFAttributes.cs create mode 100644 NAudio/MediaFoundation/IMFByteStream.cs create mode 100644 NAudio/MediaFoundation/IMFCollection.cs create mode 100644 NAudio/MediaFoundation/IMFMediaBuffer.cs create mode 100644 NAudio/MediaFoundation/IMFMediaEvent.cs create mode 100644 NAudio/MediaFoundation/IMFMediaType.cs create mode 100644 NAudio/MediaFoundation/IMFReadWriteClassFactory.cs create mode 100644 NAudio/MediaFoundation/IMFSample.cs create mode 100644 NAudio/MediaFoundation/IMFSinkWriter.cs create mode 100644 NAudio/MediaFoundation/IMFSourceReader.cs create mode 100644 NAudio/MediaFoundation/IMFTransform.cs create mode 100644 NAudio/MediaFoundation/MFT_INPUT_STREAM_INFO.cs create mode 100644 NAudio/MediaFoundation/MFT_MESSAGE_TYPE.cs create mode 100644 NAudio/MediaFoundation/MFT_OUTPUT_DATA_BUFFER.cs create mode 100644 NAudio/MediaFoundation/MFT_OUTPUT_STREAM_INFO.cs create mode 100644 NAudio/MediaFoundation/MFT_REGISTER_TYPE_INFO.cs create mode 100644 NAudio/MediaFoundation/MF_SINK_WRITER_STATISTICS.cs create mode 100644 NAudio/MediaFoundation/MediaEventType.cs create mode 100644 NAudio/MediaFoundation/MediaFoundationAttributes.cs create mode 100644 NAudio/MediaFoundation/MediaFoundationErrors.cs create mode 100644 NAudio/MediaFoundation/MediaFoundationHelpers.cs create mode 100644 NAudio/MediaFoundation/MediaFoundationInterop.cs create mode 100644 NAudio/MediaFoundation/MediaFoundationTransform.cs create mode 100644 NAudio/MediaFoundation/MediaFoundationTransformCategories.cs create mode 100644 NAudio/MediaFoundation/MediaType.cs create mode 100644 NAudio/MediaFoundation/MediaTypes.cs create mode 100644 NAudio/MediaFoundation/_MFT_ENUM_FLAG.cs create mode 100644 NAudio/MediaFoundation/_MFT_INPUT_STATUS_FLAGS.cs create mode 100644 NAudio/MediaFoundation/_MFT_INPUT_STREAM_INFO_FLAGS.cs create mode 100644 NAudio/MediaFoundation/_MFT_OUTPUT_DATA_BUFFER_FLAGS.cs create mode 100644 NAudio/MediaFoundation/_MFT_OUTPUT_STATUS_FLAGS.cs create mode 100644 NAudio/MediaFoundation/_MFT_OUTPUT_STREAM_INFO_FLAGS.cs create mode 100644 NAudio/MediaFoundation/_MFT_PROCESS_OUTPUT_FLAGS.cs create mode 100644 NAudio/MediaFoundation/_MFT_PROCESS_OUTPUT_STATUS.cs create mode 100644 NAudio/MediaFoundation/_MFT_SET_TYPE_FLAGS.cs create mode 100644 NAudio/Midi/ChannelAfterTouchEvent.cs create mode 100644 NAudio/Midi/ControlChangeEvent.cs create mode 100644 NAudio/Midi/KeySignatureEvent.cs create mode 100644 NAudio/Midi/MetaEvent.cs create mode 100644 NAudio/Midi/MetaEventType.cs create mode 100644 NAudio/Midi/MidiCommandCode.cs create mode 100644 NAudio/Midi/MidiController.cs create mode 100644 NAudio/Midi/MidiEvent.cs create mode 100644 NAudio/Midi/MidiEventCollection.cs create mode 100644 NAudio/Midi/MidiEventComparer.cs create mode 100644 NAudio/Midi/MidiFile.cs create mode 100644 NAudio/Midi/MidiIn.cs create mode 100644 NAudio/Midi/MidiInCapabilities.cs create mode 100644 NAudio/Midi/MidiInMessageEventArgs.cs create mode 100644 NAudio/Midi/MidiInterop.cs create mode 100644 NAudio/Midi/MidiMessage.cs create mode 100644 NAudio/Midi/MidiOut.cs create mode 100644 NAudio/Midi/MidiOutCapabilities.cs create mode 100644 NAudio/Midi/MidiOutTechnology.cs create mode 100644 NAudio/Midi/NoteEvent.cs create mode 100644 NAudio/Midi/NoteOnEvent.cs create mode 100644 NAudio/Midi/PatchChangeEvent.cs create mode 100644 NAudio/Midi/PitchWheelChangeEvent.cs create mode 100644 NAudio/Midi/SequencerSpecificEvent.cs create mode 100644 NAudio/Midi/SmpteOffsetEvent.cs create mode 100644 NAudio/Midi/SysexEvent.cs create mode 100644 NAudio/Midi/TempoEvent.cs create mode 100644 NAudio/Midi/TextEvent.cs create mode 100644 NAudio/Midi/TimeSignatureEvent.cs create mode 100644 NAudio/Midi/TrackSequenceNumberEvent.cs create mode 100644 NAudio/Mixer/BooleanMixerControl.cs create mode 100644 NAudio/Mixer/CustomMixerControl.cs create mode 100644 NAudio/Mixer/ListTextMixerControl.cs create mode 100644 NAudio/Mixer/Mixer.cs create mode 100644 NAudio/Mixer/MixerControl.cs create mode 100644 NAudio/Mixer/MixerControlType.cs create mode 100644 NAudio/Mixer/MixerFlags.cs create mode 100644 NAudio/Mixer/MixerInterop.cs create mode 100644 NAudio/Mixer/MixerLine.cs create mode 100644 NAudio/Mixer/MixerLineComponentType.cs create mode 100644 NAudio/Mixer/MixerSource.cs create mode 100644 NAudio/Mixer/SignedMixerControl.cs create mode 100644 NAudio/Mixer/UnsignedMixerControl.cs create mode 100644 NAudio/NAudio.csproj create mode 100644 NAudio/NAudio.csproj.vspscc create mode 100644 NAudio/NAudio.ruleset create mode 100644 NAudio/Properties/AssemblyInfo.cs create mode 100644 NAudio/Utils/BufferHelpers.cs create mode 100644 NAudio/Utils/ByteArrayExtensions.cs create mode 100644 NAudio/Utils/ByteEncoding.cs create mode 100644 NAudio/Utils/ChunkIdentifier.cs create mode 100644 NAudio/Utils/CircularBuffer.cs create mode 100644 NAudio/Utils/Decibels.cs create mode 100644 NAudio/Utils/FieldDescriptionAttribute.cs create mode 100644 NAudio/Utils/FieldDescriptionHelper.cs create mode 100644 NAudio/Utils/HResult.cs create mode 100644 NAudio/Utils/IEEE.cs create mode 100644 NAudio/Utils/IgnoreDisposeStream.cs create mode 100644 NAudio/Utils/MergeSort.cs create mode 100644 NAudio/Utils/NativeMethods.cs create mode 100644 NAudio/Utils/ProgressLog.Designer.cs create mode 100644 NAudio/Utils/ProgressLog.cs create mode 100644 NAudio/Utils/ProgressLog.resx create mode 100644 NAudio/Utils/WavePositionExtensions.cs create mode 100644 NAudio/Wave/Asio/ASIODriver.cs create mode 100644 NAudio/Wave/Asio/ASIODriverExt.cs create mode 100644 NAudio/Wave/Asio/ASIOSampleConvertor.cs create mode 100644 NAudio/Wave/Asio/ASIOStructures.cs create mode 100644 NAudio/Wave/Asio/AsioDriverCapability.cs create mode 100644 NAudio/Wave/Asio/AsioSampleType.cs create mode 100644 NAudio/Wave/Compression/AcmDriver.cs create mode 100644 NAudio/Wave/Compression/AcmDriverAddFlags.cs create mode 100644 NAudio/Wave/Compression/AcmDriverDetails.cs create mode 100644 NAudio/Wave/Compression/AcmDriverDetailsSupportFlags.cs create mode 100644 NAudio/Wave/Compression/AcmDriverEnumFlags.cs create mode 100644 NAudio/Wave/Compression/AcmFormat.cs create mode 100644 NAudio/Wave/Compression/AcmFormatChoose.cs create mode 100644 NAudio/Wave/Compression/AcmFormatChooseStyleFlags.cs create mode 100644 NAudio/Wave/Compression/AcmFormatDetails.cs create mode 100644 NAudio/Wave/Compression/AcmFormatEnumFlags.cs create mode 100644 NAudio/Wave/Compression/AcmFormatSuggestFlags.cs create mode 100644 NAudio/Wave/Compression/AcmFormatTag.cs create mode 100644 NAudio/Wave/Compression/AcmFormatTagDetails.cs create mode 100644 NAudio/Wave/Compression/AcmInterop.cs create mode 100644 NAudio/Wave/Compression/AcmMetrics.cs create mode 100644 NAudio/Wave/Compression/AcmStream.cs create mode 100644 NAudio/Wave/Compression/AcmStreamConvertFlags.cs create mode 100644 NAudio/Wave/Compression/AcmStreamHeader.cs create mode 100644 NAudio/Wave/Compression/AcmStreamHeaderStatusFlags.cs create mode 100644 NAudio/Wave/Compression/AcmStreamHeaderStruct.cs create mode 100644 NAudio/Wave/Compression/AcmStreamOpenFlags.cs create mode 100644 NAudio/Wave/Compression/AcmStreamSizeFlags.cs create mode 100644 NAudio/Wave/Compression/WaveFilter.cs create mode 100644 NAudio/Wave/MmeInterop/Manufacturers.cs create mode 100644 NAudio/Wave/MmeInterop/MmException.cs create mode 100644 NAudio/Wave/MmeInterop/MmResult.cs create mode 100644 NAudio/Wave/MmeInterop/MmTime.cs create mode 100644 NAudio/Wave/MmeInterop/WaveCallbackInfo.cs create mode 100644 NAudio/Wave/MmeInterop/WaveCallbackStrategy.cs create mode 100644 NAudio/Wave/MmeInterop/WaveHeader.cs create mode 100644 NAudio/Wave/MmeInterop/WaveHeaderFlags.cs create mode 100644 NAudio/Wave/MmeInterop/WaveInCapabilities.cs create mode 100644 NAudio/Wave/MmeInterop/WaveInEventArgs.cs create mode 100644 NAudio/Wave/MmeInterop/WaveInterop.cs create mode 100644 NAudio/Wave/MmeInterop/WaveOutCapabilities.cs create mode 100644 NAudio/Wave/MmeInterop/WaveOutSupport.cs create mode 100644 NAudio/Wave/MmeInterop/WaveWindow.cs create mode 100644 NAudio/Wave/SampleChunkConverters/ISampleChunkConverter.cs create mode 100644 NAudio/Wave/SampleChunkConverters/Mono16SampleChunkConverter.cs create mode 100644 NAudio/Wave/SampleChunkConverters/Mono24SampleChunkConverter.cs create mode 100644 NAudio/Wave/SampleChunkConverters/Mono8SampleChunkConverter.cs create mode 100644 NAudio/Wave/SampleChunkConverters/MonoFloatSampleChunkConverter.cs create mode 100644 NAudio/Wave/SampleChunkConverters/Stereo16SampleChunkConverter.cs create mode 100644 NAudio/Wave/SampleChunkConverters/Stereo24SampleChunkConverter.cs create mode 100644 NAudio/Wave/SampleChunkConverters/Stereo8SampleChunkConverter.cs create mode 100644 NAudio/Wave/SampleChunkConverters/StereoFloatSampleChunkConverter.cs create mode 100644 NAudio/Wave/SampleProviders/AdsrSampleProvider.cs create mode 100644 NAudio/Wave/SampleProviders/FadeInOutSampleProvider.cs create mode 100644 NAudio/Wave/SampleProviders/MeteringSampleProvider.cs create mode 100644 NAudio/Wave/SampleProviders/MixingSampleProvider.cs create mode 100644 NAudio/Wave/SampleProviders/MonoToStereoSampleProvider.cs create mode 100644 NAudio/Wave/SampleProviders/MultiplexingSampleProvider.cs create mode 100644 NAudio/Wave/SampleProviders/NotifyingSampleProvider.cs create mode 100644 NAudio/Wave/SampleProviders/OffsetSampleProvider.cs create mode 100644 NAudio/Wave/SampleProviders/PanningSampleProvider.cs create mode 100644 NAudio/Wave/SampleProviders/Pcm16BitToSampleProvider.cs create mode 100644 NAudio/Wave/SampleProviders/Pcm24BitToSampleProvider.cs create mode 100644 NAudio/Wave/SampleProviders/Pcm32BitToSampleProvider.cs create mode 100644 NAudio/Wave/SampleProviders/Pcm8BitToSampleProvider.cs create mode 100644 NAudio/Wave/SampleProviders/SampleChannel.cs create mode 100644 NAudio/Wave/SampleProviders/SampleProviderConverterBase.cs create mode 100644 NAudio/Wave/SampleProviders/SampleProviderConverters.cs create mode 100644 NAudio/Wave/SampleProviders/SampleToWaveProvider.cs create mode 100644 NAudio/Wave/SampleProviders/SampleToWaveProvider16.cs create mode 100644 NAudio/Wave/SampleProviders/SampleToWaveProvider24.cs create mode 100644 NAudio/Wave/SampleProviders/SignalGenerator.cs create mode 100644 NAudio/Wave/SampleProviders/VolumeSampleProvider.cs create mode 100644 NAudio/Wave/SampleProviders/WaveToSampleProvider.cs create mode 100644 NAudio/Wave/SampleProviders/WaveToSampleProvider64.cs create mode 100644 NAudio/Wave/SampleProviders/WdlResamplingSampleProvider.cs create mode 100644 NAudio/Wave/WaveExtensionMethods.cs create mode 100644 NAudio/Wave/WaveFormats/AdpcmWaveFormat.cs create mode 100644 NAudio/Wave/WaveFormats/Gsm610WaveFormat.cs create mode 100644 NAudio/Wave/WaveFormats/ImaAdpcmWaveFormat.cs create mode 100644 NAudio/Wave/WaveFormats/Mp3WaveFormat.cs create mode 100644 NAudio/Wave/WaveFormats/OggWaveFormat.cs create mode 100644 NAudio/Wave/WaveFormats/TrueSpeechWaveFormat.cs create mode 100644 NAudio/Wave/WaveFormats/WaveFormat.cs create mode 100644 NAudio/Wave/WaveFormats/WaveFormatCustomMarshaler.cs create mode 100644 NAudio/Wave/WaveFormats/WaveFormatEncoding.cs create mode 100644 NAudio/Wave/WaveFormats/WaveFormatExtensible.cs create mode 100644 NAudio/Wave/WaveFormats/WaveFormatExtraData.cs create mode 100644 NAudio/Wave/WaveFormats/WmaWaveFormat.cs create mode 100644 NAudio/Wave/WaveInputs/IWaveIn.cs create mode 100644 NAudio/Wave/WaveInputs/WasapiCapture.cs create mode 100644 NAudio/Wave/WaveInputs/WasapiLoopbackCapture.cs create mode 100644 NAudio/Wave/WaveInputs/WaveIn.cs create mode 100644 NAudio/Wave/WaveInputs/WaveInEvent.cs create mode 100644 NAudio/Wave/WaveOutputs/AiffFileWriter.cs create mode 100644 NAudio/Wave/WaveOutputs/AsioAudioAvailableEventArgs.cs create mode 100644 NAudio/Wave/WaveOutputs/AsioOut.cs create mode 100644 NAudio/Wave/WaveOutputs/CueWaveFileWriter.cs create mode 100644 NAudio/Wave/WaveOutputs/DirectSoundOut.cs create mode 100644 NAudio/Wave/WaveOutputs/IWaveBuffer.cs create mode 100644 NAudio/Wave/WaveOutputs/IWavePlayer.cs create mode 100644 NAudio/Wave/WaveOutputs/IWaveProvider.cs create mode 100644 NAudio/Wave/WaveOutputs/IWaveProviderFloat.cs create mode 100644 NAudio/Wave/WaveOutputs/MediaFoundationEncoder.cs create mode 100644 NAudio/Wave/WaveOutputs/PlaybackState.cs create mode 100644 NAudio/Wave/WaveOutputs/StoppedEventArgs.cs create mode 100644 NAudio/Wave/WaveOutputs/WasapiOut.cs create mode 100644 NAudio/Wave/WaveOutputs/WaveBuffer.cs create mode 100644 NAudio/Wave/WaveOutputs/WaveFileWriter.cs create mode 100644 NAudio/Wave/WaveOutputs/WaveOut.cs create mode 100644 NAudio/Wave/WaveOutputs/WaveOutEvent.cs create mode 100644 NAudio/Wave/WaveProviders/BufferedWaveProvider.cs create mode 100644 NAudio/Wave/WaveProviders/MediaFoundationResampler.cs create mode 100644 NAudio/Wave/WaveProviders/MixingWaveProvider32.cs create mode 100644 NAudio/Wave/WaveProviders/MonoToStereoProvider16.cs create mode 100644 NAudio/Wave/WaveProviders/MultiplexingWaveProvider.cs create mode 100644 NAudio/Wave/WaveProviders/StereoToMonoProvider16.cs create mode 100644 NAudio/Wave/WaveProviders/VolumeWaveProvider16.cs create mode 100644 NAudio/Wave/WaveProviders/Wave16toFloatProvider.cs create mode 100644 NAudio/Wave/WaveProviders/WaveFloatTo16Provider.cs create mode 100644 NAudio/Wave/WaveProviders/WaveInProvider.cs create mode 100644 NAudio/Wave/WaveProviders/WaveProvider16.cs create mode 100644 NAudio/Wave/WaveProviders/WaveProvider32.cs create mode 100644 NAudio/Wave/WaveProviders/WaveRecorder.cs create mode 100644 NAudio/Wave/WaveStreams/AiffFileReader.cs create mode 100644 NAudio/Wave/WaveStreams/AudioFileReader.cs create mode 100644 NAudio/Wave/WaveStreams/BlockAlignReductionStream.cs create mode 100644 NAudio/Wave/WaveStreams/CueList.cs create mode 100644 NAudio/Wave/WaveStreams/CueWaveFileReader.cs create mode 100644 NAudio/Wave/WaveStreams/ISampleNotifier.cs create mode 100644 NAudio/Wave/WaveStreams/MediaFoundationReader.cs create mode 100644 NAudio/Wave/WaveStreams/Mp3FileReader.cs create mode 100644 NAudio/Wave/WaveStreams/RawSourceWaveStream.cs create mode 100644 NAudio/Wave/WaveStreams/ResamplerDmoStream.cs create mode 100644 NAudio/Wave/WaveStreams/RiffChunk.cs create mode 100644 NAudio/Wave/WaveStreams/SimpleCompressorStream.cs create mode 100644 NAudio/Wave/WaveStreams/Wave32To16Stream.cs create mode 100644 NAudio/Wave/WaveStreams/WaveChannel32.cs create mode 100644 NAudio/Wave/WaveStreams/WaveFileReader.cs create mode 100644 NAudio/Wave/WaveStreams/WaveFormatConversionStream.cs create mode 100644 NAudio/Wave/WaveStreams/WaveInBuffer.cs create mode 100644 NAudio/Wave/WaveStreams/WaveMixerStream32.cs create mode 100644 NAudio/Wave/WaveStreams/WaveOffsetStream.cs create mode 100644 NAudio/Wave/WaveStreams/WaveOutBuffer.cs create mode 100644 NAudio/Wave/WaveStreams/WaveStream.cs create mode 100644 NAudioDemo/AcmDemo/AcmPanel.Designer.cs create mode 100644 NAudioDemo/AcmDemo/AcmPanel.cs create mode 100644 NAudioDemo/AcmDemo/AcmPanel.resx create mode 100644 NAudioDemo/AsioDirectDemo/AsioDirectPanel.Designer.cs create mode 100644 NAudioDemo/AsioDirectDemo/AsioDirectPanel.cs create mode 100644 NAudioDemo/AsioDirectDemo/AsioDirectPanel.resx create mode 100644 NAudioDemo/AsioRecordingDemo/AsioRecordingPanel.Designer.cs create mode 100644 NAudioDemo/AsioRecordingDemo/AsioRecordingPanel.cs create mode 100644 NAudioDemo/AsioRecordingDemo/AsioRecordingPanel.resx create mode 100644 NAudioDemo/AudioPlaybackDemo/AsioOutPlugin.cs create mode 100644 NAudioDemo/AudioPlaybackDemo/AsioOutSettingsPanel.Designer.cs create mode 100644 NAudioDemo/AudioPlaybackDemo/AsioOutSettingsPanel.cs create mode 100644 NAudioDemo/AudioPlaybackDemo/AsioOutSettingsPanel.resx create mode 100644 NAudioDemo/AudioPlaybackDemo/AudioPlaybackPanel.Designer.cs create mode 100644 NAudioDemo/AudioPlaybackDemo/AudioPlaybackPanel.cs create mode 100644 NAudioDemo/AudioPlaybackDemo/AudioPlaybackPanel.resx create mode 100644 NAudioDemo/AudioPlaybackDemo/AudioPlaybackPanelPlugin.cs create mode 100644 NAudioDemo/AudioPlaybackDemo/DirectSoundOutPlugin.cs create mode 100644 NAudioDemo/AudioPlaybackDemo/DirectSoundOutSettingsPanel.Designer.cs create mode 100644 NAudioDemo/AudioPlaybackDemo/DirectSoundOutSettingsPanel.cs create mode 100644 NAudioDemo/AudioPlaybackDemo/DirectSoundOutSettingsPanel.resx create mode 100644 NAudioDemo/AudioPlaybackDemo/IOutputDevicePlugin.cs create mode 100644 NAudioDemo/AudioPlaybackDemo/WasapiOutPlugin.cs create mode 100644 NAudioDemo/AudioPlaybackDemo/WasapiOutSettingsPanel.Designer.cs create mode 100644 NAudioDemo/AudioPlaybackDemo/WasapiOutSettingsPanel.cs create mode 100644 NAudioDemo/AudioPlaybackDemo/WasapiOutSettingsPanel.resx create mode 100644 NAudioDemo/AudioPlaybackDemo/WaveOutPlugin.cs create mode 100644 NAudioDemo/AudioPlaybackDemo/WaveOutSettingsPanel.Designer.cs create mode 100644 NAudioDemo/AudioPlaybackDemo/WaveOutSettingsPanel.cs create mode 100644 NAudioDemo/AudioPlaybackDemo/WaveOutSettingsPanel.resx create mode 100644 NAudioDemo/FadeInOutDemo/FadeInOutPanel.Designer.cs create mode 100644 NAudioDemo/FadeInOutDemo/FadeInOutPanel.cs create mode 100644 NAudioDemo/FadeInOutDemo/FadeInOutPanel.resx create mode 100644 NAudioDemo/FadeInOutDemo/FadeInOutPlugin.cs create mode 100644 NAudioDemo/INAudioDemoPlugin.cs create mode 100644 NAudioDemo/Images.Designer.cs create mode 100644 NAudioDemo/Images.resx create mode 100644 NAudioDemo/LoopStream.cs create mode 100644 NAudioDemo/MainForm.Designer.cs create mode 100644 NAudioDemo/MainForm.cs create mode 100644 NAudioDemo/MainForm.resx create mode 100644 NAudioDemo/MediaFoundationDemo/MediaFoundationDemoPanel.Designer.cs create mode 100644 NAudioDemo/MediaFoundationDemo/MediaFoundationDemoPanel.cs create mode 100644 NAudioDemo/MediaFoundationDemo/MediaFoundationDemoPanel.resx create mode 100644 NAudioDemo/MediaFoundationDemo/WasapiOutGuiThread.cs create mode 100644 NAudioDemo/MidiInDemo/MidiInPanel.Designer.cs create mode 100644 NAudioDemo/MidiInDemo/MidiInPanel.cs create mode 100644 NAudioDemo/MidiInDemo/MidiInPanel.resx create mode 100644 NAudioDemo/Mp3StreamingDemo/MP3StreamingPanel.Designer.cs create mode 100644 NAudioDemo/Mp3StreamingDemo/MP3StreamingPanel.cs create mode 100644 NAudioDemo/Mp3StreamingDemo/MP3StreamingPanel.resx create mode 100644 NAudioDemo/Mp3StreamingDemo/ReadFullyStream.cs create mode 100644 NAudioDemo/NAudioDemo.csproj create mode 100644 NAudioDemo/NAudioDemo.csproj.DotSettings create mode 100644 NAudioDemo/NAudioDemo.csproj.user create mode 100644 NAudioDemo/NetworkChatDemo/ALawChatCodec.cs create mode 100644 NAudioDemo/NetworkChatDemo/AcmChatCodec.cs create mode 100644 NAudioDemo/NetworkChatDemo/G722ChatCodec.cs create mode 100644 NAudioDemo/NetworkChatDemo/Gsm610ChatCodec.cs create mode 100644 NAudioDemo/NetworkChatDemo/INetworkChatCodec.cs create mode 100644 NAudioDemo/NetworkChatDemo/MicrosoftAdpcmChatCodec.cs create mode 100644 NAudioDemo/NetworkChatDemo/MuLawChatCodec.cs create mode 100644 NAudioDemo/NetworkChatDemo/NetworkChatPanel.Designer.cs create mode 100644 NAudioDemo/NetworkChatDemo/NetworkChatPanel.cs create mode 100644 NAudioDemo/NetworkChatDemo/NetworkChatPanel.resx create mode 100644 NAudioDemo/NetworkChatDemo/SpeexChatCodec.cs create mode 100644 NAudioDemo/NetworkChatDemo/TrueSpeechChatCodec.cs create mode 100644 NAudioDemo/NetworkChatDemo/UncompressedPcmChatCodec.cs create mode 100644 NAudioDemo/Program.cs create mode 100644 NAudioDemo/Properties/AssemblyInfo.cs create mode 100644 NAudioDemo/Properties/Resources.Designer.cs create mode 100644 NAudioDemo/Properties/Resources.resx create mode 100644 NAudioDemo/Properties/Settings.Designer.cs create mode 100644 NAudioDemo/Properties/Settings.settings create mode 100644 NAudioDemo/RecordingDemo/RecordingPanel.Designer.cs create mode 100644 NAudioDemo/RecordingDemo/RecordingPanel.cs create mode 100644 NAudioDemo/RecordingDemo/RecordingPanel.resx create mode 100644 NAudioDemo/Resources/Back.png create mode 100644 NAudioDemo/Resources/Forward.png create mode 100644 NAudioDemo/Resources/Loop.png create mode 100644 NAudioDemo/Resources/Open.png create mode 100644 NAudioDemo/Resources/Pause.png create mode 100644 NAudioDemo/Resources/Play.png create mode 100644 NAudioDemo/Resources/Rewind.png create mode 100644 NAudioDemo/Resources/Shuffle.png create mode 100644 NAudioDemo/Resources/Stop.png create mode 100644 NAudioDemo/SignalGeneratorDemo/GeneratorPanel.Designer.cs create mode 100644 NAudioDemo/SignalGeneratorDemo/GeneratorPanel.cs create mode 100644 NAudioDemo/SignalGeneratorDemo/GeneratorPanel.resx create mode 100644 NAudioDemo/SignalGeneratorDemo/GeneratorPlugIn.cs create mode 100644 NAudioDemo/SimplePlaybackDemo/SimplePlaybackPanel.Designer.cs create mode 100644 NAudioDemo/SimplePlaybackDemo/SimplePlaybackPanel.cs create mode 100644 NAudioDemo/SimplePlaybackDemo/SimplePlaybackPanel.resx create mode 100644 NAudioDemo/SimplePlaybackDemo/SimplePlaybackPlugin.cs create mode 100644 NAudioDemo/app.config create mode 100644 NAudioTests/Acm/AcmDriverTests.cs create mode 100644 NAudioTests/Acm/GsmEncodeTest.cs create mode 100644 NAudioTests/Acm/WaveFormatConversionStreamTests.cs create mode 100644 NAudioTests/Aiff/AiffReaderTests.cs create mode 100644 NAudioTests/DirectSound/DirectSoundTests.cs create mode 100644 NAudioTests/Dmo/DmoMp3FrameDecompressorTests.cs create mode 100644 NAudioTests/Dmo/DmoTests.cs create mode 100644 NAudioTests/Dmo/ResamplerDmoStreamTests.cs create mode 100644 NAudioTests/Dmo/ResamplerDmoTests.cs create mode 100644 NAudioTests/MediaFoundation/MediaFoundationReaderTests.cs create mode 100644 NAudioTests/Midi/MidiEventCollectionTest.cs create mode 100644 NAudioTests/Midi/PitchWheelChangeEventTests.cs create mode 100644 NAudioTests/Mixer/MixerApiTests.cs create mode 100644 NAudioTests/Mp3/Mp3FileReaderTests.cs create mode 100644 NAudioTests/Mp3/Mp3FrameTests.cs create mode 100644 NAudioTests/NAudioTests.csproj create mode 100644 NAudioTests/NAudioTests.csproj.vspscc create mode 100644 NAudioTests/NAudioTests.nunit create mode 100644 NAudioTests/Properties/AssemblyInfo.cs create mode 100644 NAudioTests/StopwatchExtensions.cs create mode 100644 NAudioTests/Utils/BlockAlignedWaveStream.cs create mode 100644 NAudioTests/Utils/ByteEncodingTests.cs create mode 100644 NAudioTests/Utils/NullWaveStream.cs create mode 100644 NAudioTests/Utils/OSUtils.cs create mode 100644 NAudioTests/Utils/SampleProviderTestHelpers.cs create mode 100644 NAudioTests/Wasapi/AudioClientTests.cs create mode 100644 NAudioTests/Wasapi/MMDeviceEnumeratorTests.cs create mode 100644 NAudioTests/WaveFormats/AdpcmWaveFormatTests.cs create mode 100644 NAudioTests/WaveIn/WaveInDevicesTests.cs create mode 100644 NAudioTests/WaveStreams/BlockAlignmentReductionStreamTests.cs create mode 100644 NAudioTests/WaveStreams/BufferedWaveProviderTests.cs create mode 100644 NAudioTests/WaveStreams/ChunkIdentifierTests.cs create mode 100644 NAudioTests/WaveStreams/CircularBufferTests.cs create mode 100644 NAudioTests/WaveStreams/FadeInOutSampleProviderTests.cs create mode 100644 NAudioTests/WaveStreams/MixingSampleProviderTests.cs create mode 100644 NAudioTests/WaveStreams/MonoToStereoProvider16Tests.cs create mode 100644 NAudioTests/WaveStreams/MultiplexingSampleProviderTests.cs create mode 100644 NAudioTests/WaveStreams/MultiplexingWaveProviderTests.cs create mode 100644 NAudioTests/WaveStreams/OffsetSampleProviderTests.cs create mode 100644 NAudioTests/WaveStreams/SampleToWaveProvider24Tests.cs create mode 100644 NAudioTests/WaveStreams/StereoToMonoProvider16Tests.cs create mode 100644 NAudioTests/WaveStreams/TestSampleProvider.cs create mode 100644 NAudioTests/WaveStreams/TestWaveProvider.cs create mode 100644 NAudioTests/WaveStreams/VolumeWaveProvider16Tests.cs create mode 100644 NAudioTests/WaveStreams/WaveChannel32Tests.cs create mode 100644 NAudioTests/WaveStreams/WaveFileReaderTests.cs create mode 100644 NAudioTests/WaveStreams/WaveFileWriterTests.cs create mode 100644 NAudioTests/WaveStreams/WdlResamplingSampleProviderTests.cs create mode 100644 NAudioTests/WindowsMedia/WindowsMediaTests.cs create mode 100644 NAudioTests/packages.config create mode 100644 NAudioWin8Demo/App.xaml create mode 100644 NAudioWin8Demo/App.xaml.cs create mode 100644 NAudioWin8Demo/Assets/Logo.png create mode 100644 NAudioWin8Demo/Assets/SmallLogo.png create mode 100644 NAudioWin8Demo/Assets/SplashScreen.png create mode 100644 NAudioWin8Demo/Assets/StoreLogo.png create mode 100644 NAudioWin8Demo/Common/StandardStyles.xaml create mode 100644 NAudioWin8Demo/DelegateCommand.cs create mode 100644 NAudioWin8Demo/MainPage.xaml create mode 100644 NAudioWin8Demo/MainPage.xaml.cs create mode 100644 NAudioWin8Demo/MainPageViewModel.cs create mode 100644 NAudioWin8Demo/MediaFoundationReaderRT.cs create mode 100644 NAudioWin8Demo/NAudioWin8Demo.csproj create mode 100644 NAudioWin8Demo/NAudioWin8Demo_TemporaryKey.pfx create mode 100644 NAudioWin8Demo/Package.appxmanifest create mode 100644 NAudioWin8Demo/Properties/AssemblyInfo.cs create mode 100644 NAudioWin8Demo/ViewModelBase.cs create mode 100644 NAudioWpfDemo/App.xaml create mode 100644 NAudioWpfDemo/App.xaml.cs create mode 100644 NAudioWpfDemo/AudioPlaybackDemo/AudioPlayback.cs create mode 100644 NAudioWpfDemo/AudioPlaybackDemo/AudioPlaybackDemoPlugin.cs create mode 100644 NAudioWpfDemo/AudioPlaybackDemo/AudioPlaybackDemoView.xaml create mode 100644 NAudioWpfDemo/AudioPlaybackDemo/AudioPlaybackDemoView.xaml.cs create mode 100644 NAudioWpfDemo/AudioPlaybackDemo/AudioPlaybackViewModel.cs create mode 100644 NAudioWpfDemo/AudioPlaybackDemo/IVisualizationPlugin.cs create mode 100644 NAudioWpfDemo/AudioPlaybackDemo/PolygonWaveFormVisualization.cs create mode 100644 NAudioWpfDemo/AudioPlaybackDemo/PolylineWaveFormVisualization.cs create mode 100644 NAudioWpfDemo/AudioPlaybackDemo/SampleAggregator.cs create mode 100644 NAudioWpfDemo/AudioPlaybackDemo/SpectrumAnalyzerVisualization.cs create mode 100644 NAudioWpfDemo/AudioPlaybackDemo/WaveformVisual.cs create mode 100644 NAudioWpfDemo/DrumMachineDemo/DrumKit.cs create mode 100644 NAudioWpfDemo/DrumMachineDemo/DrumMachineDemoPlugin.cs create mode 100644 NAudioWpfDemo/DrumMachineDemo/DrumMachineDemoView.xaml create mode 100644 NAudioWpfDemo/DrumMachineDemo/DrumMachineDemoView.xaml.cs create mode 100644 NAudioWpfDemo/DrumMachineDemo/DrumMachineDemoViewModel.cs create mode 100644 NAudioWpfDemo/DrumMachineDemo/DrumPattern.cs create mode 100644 NAudioWpfDemo/DrumMachineDemo/DrumPatternEditor.xaml create mode 100644 NAudioWpfDemo/DrumMachineDemo/DrumPatternEditor.xaml.cs create mode 100644 NAudioWpfDemo/DrumMachineDemo/DrumPatternSampleProvider.cs create mode 100644 NAudioWpfDemo/DrumMachineDemo/MusicSampleProvider.cs create mode 100644 NAudioWpfDemo/DrumMachineDemo/PatternSequencer.cs create mode 100644 NAudioWpfDemo/DrumMachineDemo/PatternSequencerTests.cs create mode 100644 NAudioWpfDemo/DrumMachineDemo/SampleSource.cs create mode 100644 NAudioWpfDemo/EnumMediaFoundationTransforms/EnumMftDemo.cs create mode 100644 NAudioWpfDemo/EnumMediaFoundationTransforms/EnumMftView.xaml create mode 100644 NAudioWpfDemo/EnumMediaFoundationTransforms/EnumMftView.xaml.cs create mode 100644 NAudioWpfDemo/EnumMediaFoundationTransforms/EnumMftViewModel.cs create mode 100644 NAudioWpfDemo/EqualizationDemo/EqualizationDemoPlugin.cs create mode 100644 NAudioWpfDemo/EqualizationDemo/EqualizationDemoView.xaml create mode 100644 NAudioWpfDemo/EqualizationDemo/EqualizationDemoView.xaml.cs create mode 100644 NAudioWpfDemo/EqualizationDemo/EqualizationDemoViewModel.cs create mode 100644 NAudioWpfDemo/EqualizationDemo/Equalizer.cs create mode 100644 NAudioWpfDemo/EqualizationDemo/EqualizerBand.cs create mode 100644 NAudioWpfDemo/IModule.cs create mode 100644 NAudioWpfDemo/IWaveFormRenderer.cs create mode 100644 NAudioWpfDemo/MainWindow.xaml create mode 100644 NAudioWpfDemo/MainWindow.xaml.cs create mode 100644 NAudioWpfDemo/MainWindowViewModel.cs create mode 100644 NAudioWpfDemo/MediaFoundationEncode/MediaFoundationEncodePlugin.cs create mode 100644 NAudioWpfDemo/MediaFoundationEncode/MediaFoundationEncodeView.xaml create mode 100644 NAudioWpfDemo/MediaFoundationEncode/MediaFoundationEncodeView.xaml.cs create mode 100644 NAudioWpfDemo/MediaFoundationEncode/MediaFoundationEncodeViewModel.cs create mode 100644 NAudioWpfDemo/MediaFoundationEncode/MediaTypeViewModel.cs create mode 100644 NAudioWpfDemo/MediaFoundationPlayback/MediaFoundationPlaybackPlugin.cs create mode 100644 NAudioWpfDemo/MediaFoundationPlayback/MediaFoundationPlaybackView.xaml create mode 100644 NAudioWpfDemo/MediaFoundationPlayback/MediaFoundationPlaybackView.xaml.cs create mode 100644 NAudioWpfDemo/MediaFoundationPlayback/MediaFoundationPlaybackViewModel.cs create mode 100644 NAudioWpfDemo/MediaFoundationResample/MediaFoundationEncodePlugin.cs create mode 100644 NAudioWpfDemo/MediaFoundationResample/MediaFoundationResampleView.xaml create mode 100644 NAudioWpfDemo/MediaFoundationResample/MediaFoundationResampleView.xaml.cs create mode 100644 NAudioWpfDemo/MediaFoundationResample/MediaFoundationResampleViewModel.cs create mode 100644 NAudioWpfDemo/ModuleBase.cs create mode 100644 NAudioWpfDemo/NAudioWpfDemo.csproj create mode 100644 NAudioWpfDemo/PolygonWaveFormControl.xaml create mode 100644 NAudioWpfDemo/PolygonWaveFormControl.xaml.cs create mode 100644 NAudioWpfDemo/PolylineWaveFormControl.xaml create mode 100644 NAudioWpfDemo/PolylineWaveFormControl.xaml.cs create mode 100644 NAudioWpfDemo/Properties/AssemblyInfo.cs create mode 100644 NAudioWpfDemo/Properties/Resources.Designer.cs create mode 100644 NAudioWpfDemo/Properties/Resources.resx create mode 100644 NAudioWpfDemo/Properties/Settings.Designer.cs create mode 100644 NAudioWpfDemo/Properties/Settings.settings create mode 100644 NAudioWpfDemo/SpectrumAnalyser.xaml create mode 100644 NAudioWpfDemo/SpectrumAnalyser.xaml.cs create mode 100644 NAudioWpfDemo/ViewModel/DelegateCommand.cs create mode 100644 NAudioWpfDemo/ViewModel/RelayCommand.cs create mode 100644 NAudioWpfDemo/ViewModel/ViewModelBase.cs create mode 100644 NAudioWpfDemo/WasapiCaptureDemo/RecordingsView.xaml create mode 100644 NAudioWpfDemo/WasapiCaptureDemo/RecordingsView.xaml.cs create mode 100644 NAudioWpfDemo/WasapiCaptureDemo/RecordingsViewModel.cs create mode 100644 NAudioWpfDemo/WasapiCaptureDemo/WasapiCaptureDemoPlugin.cs create mode 100644 NAudioWpfDemo/WasapiCaptureDemo/WasapiCaptureDemoView.xaml create mode 100644 NAudioWpfDemo/WasapiCaptureDemo/WasapiCaptureDemoView.xaml.cs create mode 100644 NAudioWpfDemo/WasapiCaptureDemo/WasapiCaptureViewModel.cs create mode 100644 NAudioWpfDemo/WaveFormControl.xaml create mode 100644 NAudioWpfDemo/WaveFormControl.xaml.cs create mode 100644 NAudioWpfDemo/app.config create mode 100644 NAudioWpfDemo/packages.config create mode 100644 SampleData/Drums/closed-hat-trimmed.wav create mode 100644 SampleData/Drums/crash-trimmed.wav create mode 100644 SampleData/Drums/kick-trimmed.wav create mode 100644 SampleData/Drums/open-hat-trimmed.wav create mode 100644 SampleData/Drums/snare-trimmed.wav create mode 100644 Tools/NuGet.exe create mode 100644 build.bat create mode 100644 license.txt create mode 100644 readme.txt create mode 100644 zipdemo.py diff --git a/..svnbridge/.svnbridge b/..svnbridge/.svnbridge new file mode 100644 index 00000000..047b5e87 --- /dev/null +++ b/..svnbridge/.svnbridge @@ -0,0 +1,19 @@ +svn:ignore*.docstates +*.suo +Release-1.4 +TestResult.xml +obj +svn:ignore*.docstates +*.suo +Release-1.4 +TestResult.xml +obj +BuildArtefacts +svn:ignore*.docstates +*.suo +BuildArtefacts +Packages +Release-1.4 +TestResult.xml +obj + \ No newline at end of file diff --git a/.build/MSBuild.Community.Tasks.dll b/.build/MSBuild.Community.Tasks.dll new file mode 100644 index 0000000000000000000000000000000000000000..01d1b09c6291e4ff1344dd14ef041d9bb619d8e2 GIT binary patch literal 626176 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 z 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�TE@lh!E9TEk%k}#5qM1XOnaoMdO6Kj% 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 AK>z>% literal 0 HcmV?d00001 diff --git a/.build/MSBuild.Community.Tasks.targets b/.build/MSBuild.Community.Tasks.targets new file mode 100644 index 00000000..15310059 --- /dev/null +++ b/.build/MSBuild.Community.Tasks.targets @@ -0,0 +1,147 @@ + + + + + + $(MSBuildExtensionsPath)\MSBuildCommunityTasks + MSBuild.Community.Tasks.dll + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/.hgignore b/.hgignore new file mode 100644 index 00000000..776fd33a --- /dev/null +++ b/.hgignore @@ -0,0 +1,14 @@ +syntax: glob +bin/ +obj/ +[pP]ackages/ +AppPackages/ +TestResults/ +TestResult.xml +BuildArtefacts/ +_ReSharper.*/ +*.suo +*.ncrunchsolution +*.user +*.ncrunchproject +*.orig \ No newline at end of file diff --git a/AudioFileInspector/AboutForm.Designer.cs b/AudioFileInspector/AboutForm.Designer.cs new file mode 100644 index 00000000..bd8cd680 --- /dev/null +++ b/AudioFileInspector/AboutForm.Designer.cs @@ -0,0 +1,144 @@ +namespace NAudio.Utils +{ + partial class AboutForm + { + /// + /// Required designer variable. + /// + private System.ComponentModel.IContainer components = null; + + /// + /// Clean up any resources being used. + /// + /// true if managed resources should be disposed; otherwise, false. + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Windows Form Designer generated code + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + this.linkLabelWebsite = new System.Windows.Forms.LinkLabel(); + this.buttonOK = new System.Windows.Forms.Button(); + this.labelProductName = new System.Windows.Forms.Label(); + this.labelCopyright = new System.Windows.Forms.Label(); + this.linkLabelFeedback = new System.Windows.Forms.LinkLabel(); + this.label3 = new System.Windows.Forms.Label(); + this.labelVersion = new System.Windows.Forms.Label(); + this.SuspendLayout(); + // + // linkLabelWebsite + // + this.linkLabelWebsite.AutoSize = true; + this.linkLabelWebsite.Location = new System.Drawing.Point(13, 67); + this.linkLabelWebsite.Name = "linkLabelWebsite"; + this.linkLabelWebsite.Size = new System.Drawing.Size(168, 13); + this.linkLabelWebsite.TabIndex = 0; + this.linkLabelWebsite.TabStop = true; + this.linkLabelWebsite.Text = "http://www.codeplex.com/naudio"; + this.linkLabelWebsite.LinkClicked += new System.Windows.Forms.LinkLabelLinkClickedEventHandler(this.linkLabelWebsite_LinkClicked); + // + // buttonOK + // + this.buttonOK.Location = new System.Drawing.Point(111, 124); + this.buttonOK.Name = "buttonOK"; + this.buttonOK.Size = new System.Drawing.Size(75, 23); + this.buttonOK.TabIndex = 1; + this.buttonOK.Text = "OK"; + this.buttonOK.UseVisualStyleBackColor = true; + this.buttonOK.Click += new System.EventHandler(this.buttonOK_Click); + // + // labelProductName + // + this.labelProductName.AutoSize = true; + this.labelProductName.Font = new System.Drawing.Font("Microsoft Sans Serif", 9.75F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0))); + this.labelProductName.Location = new System.Drawing.Point(13, 13); + this.labelProductName.Name = "labelProductName"; + this.labelProductName.Size = new System.Drawing.Size(196, 16); + this.labelProductName.TabIndex = 2; + this.labelProductName.Text = "{Application.ProductName}"; + // + // labelCopyright + // + this.labelCopyright.AutoSize = true; + this.labelCopyright.Location = new System.Drawing.Point(13, 51); + this.labelCopyright.Name = "labelCopyright"; + this.labelCopyright.Size = new System.Drawing.Size(149, 13); + this.labelCopyright.TabIndex = 2; + this.labelCopyright.Text = "Copyright © Mark Heath 2007"; + // + // linkLabelFeedback + // + this.linkLabelFeedback.AutoSize = true; + this.linkLabelFeedback.Location = new System.Drawing.Point(13, 101); + this.linkLabelFeedback.Name = "linkLabelFeedback"; + this.linkLabelFeedback.Size = new System.Drawing.Size(150, 13); + this.linkLabelFeedback.TabIndex = 3; + this.linkLabelFeedback.TabStop = true; + this.linkLabelFeedback.Text = "mark.heath@gmail.com"; + this.linkLabelFeedback.LinkClicked += new System.Windows.Forms.LinkLabelLinkClickedEventHandler(this.linkLabelFeedback_LinkClicked); + // + // label3 + // + this.label3.AutoSize = true; + this.label3.Location = new System.Drawing.Point(13, 85); + this.label3.Name = "label3"; + this.label3.Size = new System.Drawing.Size(243, 13); + this.label3.TabIndex = 2; + this.label3.Text = "Send feedback, feature requests and bug fixes to:"; + // + // labelVersion + // + this.labelVersion.AutoSize = true; + this.labelVersion.Location = new System.Drawing.Point(13, 33); + this.labelVersion.Name = "labelVersion"; + this.labelVersion.Size = new System.Drawing.Size(93, 13); + this.labelVersion.TabIndex = 2; + this.labelVersion.Text = "{Version: X.X.X.X}"; + // + // AboutForm + // + this.AcceptButton = this.buttonOK; + this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.ClientSize = new System.Drawing.Size(292, 159); + this.Controls.Add(this.linkLabelFeedback); + this.Controls.Add(this.label3); + this.Controls.Add(this.labelVersion); + this.Controls.Add(this.labelCopyright); + this.Controls.Add(this.labelProductName); + this.Controls.Add(this.buttonOK); + this.Controls.Add(this.linkLabelWebsite); + this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedSingle; + this.MaximizeBox = false; + this.MinimizeBox = false; + this.Name = "AboutForm"; + this.ShowInTaskbar = false; + this.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent; + this.Text = "About {Application.ProductName}"; + this.ResumeLayout(false); + this.PerformLayout(); + + } + + #endregion + + private System.Windows.Forms.LinkLabel linkLabelWebsite; + private System.Windows.Forms.Button buttonOK; + private System.Windows.Forms.Label labelProductName; + private System.Windows.Forms.Label labelCopyright; + private System.Windows.Forms.LinkLabel linkLabelFeedback; + private System.Windows.Forms.Label label3; + private System.Windows.Forms.Label labelVersion; + } +} \ No newline at end of file diff --git a/AudioFileInspector/AboutForm.cs b/AudioFileInspector/AboutForm.cs new file mode 100644 index 00000000..2d5861e0 --- /dev/null +++ b/AudioFileInspector/AboutForm.cs @@ -0,0 +1,71 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Data; +using System.Drawing; +using System.Text; +using System.Windows.Forms; + +namespace NAudio.Utils +{ + /// + /// A standard about form + /// + public partial class AboutForm : Form + { + /// + /// Creates a new about form + /// + public AboutForm() + { + InitializeComponent(); + labelProductName.Text = Application.ProductName; + labelVersion.Text = String.Format("Version: {0}", Application.ProductVersion); + this.Text = String.Format("About {0}", Application.ProductName); + } + + private void linkLabelWebsite_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e) + { + System.Diagnostics.Process.Start(linkLabelWebsite.Text); + } + + private void linkLabelFeedback_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e) + { + System.Diagnostics.Process.Start("mailto:" + linkLabelFeedback.Text); + } + + private void buttonOK_Click(object sender, EventArgs e) + { + this.Close(); + } + + /// + /// The URL of the website to use for help + /// e.g. http://www.codeplex.com/naudio + /// + public string Url + { + get { return linkLabelWebsite.Text; } + set { linkLabelWebsite.Text = value; } + } + + /// + /// The email address for feedback + /// + public string Email + { + get { return linkLabelFeedback.Text; } + set { linkLabelFeedback.Text = value; } + } + + /// + /// The copyright info + /// e.g. Copyright © 2007 Mark Heath + /// + public string Copyright + { + get { return labelCopyright.Text; } + set { labelCopyright.Text = value; } + } + } +} \ No newline at end of file diff --git a/AudioFileInspector/AboutForm.resx b/AudioFileInspector/AboutForm.resx new file mode 100644 index 00000000..ff31a6db --- /dev/null +++ b/AudioFileInspector/AboutForm.resx @@ -0,0 +1,120 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + \ No newline at end of file diff --git a/AudioFileInspector/AudioFileInspector.csproj b/AudioFileInspector/AudioFileInspector.csproj new file mode 100644 index 00000000..64617ce3 --- /dev/null +++ b/AudioFileInspector/AudioFileInspector.csproj @@ -0,0 +1,186 @@ + + + + Debug + AnyCPU + 9.0.30729 + 2.0 + {D29C1659-635C-497B-847E-FE9A5A69ED03} + WinExe + Properties + AudioFileInspector + AudioFileInspector + + + + + + + + + + + + + 3.5 + v3.5 + publish\ + true + Disk + false + Foreground + 7 + Days + false + false + true + 0 + 1.0.0.%2a + false + false + true + + + true + full + false + bin\Debug\ + DEBUG;TRACE + prompt + 4 + AllRules.ruleset + AnyCPU + + + pdbonly + true + bin\Release\ + TRACE + prompt + 4 + AllRules.ruleset + x86 + + + + + False + ..\Lib\MEF\System.ComponentModel.Composition.dll + + + 3.5 + + + + + + + + + + Form + + + AboutForm.cs + + + Form + + + AudioFileInspectorForm.cs + + + + + + Form + + + FindForm.cs + + + + + Form + + + OptionsForm.cs + + + + + AboutForm.cs + Designer + + + Designer + AudioFileInspectorForm.cs + + + Designer + FindForm.cs + + + Designer + OptionsForm.cs + + + ResXFileCodeGenerator + Resources.Designer.cs + Designer + + + True + Resources.resx + True + + + + SettingsSingleFileGenerator + Settings.Designer.cs + + + True + Settings.settings + True + + + + + + + Always + + + + + False + .NET Framework 3.5 SP1 Client Profile + false + + + False + .NET Framework 3.5 SP1 + true + + + False + Windows Installer 3.1 + true + + + + + {DA4F02E3-0B5E-42CD-B8D9-5583FA51D66E} + NAudio + + + + + \ No newline at end of file diff --git a/AudioFileInspector/AudioFileInspectorForm.Designer.cs b/AudioFileInspector/AudioFileInspectorForm.Designer.cs new file mode 100644 index 00000000..ed3ab328 --- /dev/null +++ b/AudioFileInspector/AudioFileInspectorForm.Designer.cs @@ -0,0 +1,203 @@ +namespace AudioFileInspector +{ + partial class AudioFileInspectorForm + { + /// + /// Required designer variable. + /// + private System.ComponentModel.IContainer components = null; + + /// + /// Clean up any resources being used. + /// + /// true if managed resources should be disposed; otherwise, false. + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Windows Form Designer generated code + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + this.menuStrip1 = new System.Windows.Forms.MenuStrip(); + this.fileToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.openToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.exitToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.editToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.findToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.toolsToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.optionsToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.saveLogToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.clearLogToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.helpToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.aboutToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.contentsToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.textLog = new System.Windows.Forms.RichTextBox(); + this.menuStrip1.SuspendLayout(); + this.SuspendLayout(); + // + // menuStrip1 + // + this.menuStrip1.Items.AddRange(new System.Windows.Forms.ToolStripItem[] { + this.fileToolStripMenuItem, + this.editToolStripMenuItem, + this.toolsToolStripMenuItem, + this.helpToolStripMenuItem}); + this.menuStrip1.Location = new System.Drawing.Point(0, 0); + this.menuStrip1.Name = "menuStrip1"; + this.menuStrip1.Size = new System.Drawing.Size(513, 24); + this.menuStrip1.TabIndex = 0; + this.menuStrip1.Text = "menuStrip1"; + // + // fileToolStripMenuItem + // + this.fileToolStripMenuItem.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] { + this.openToolStripMenuItem, + this.exitToolStripMenuItem}); + this.fileToolStripMenuItem.Name = "fileToolStripMenuItem"; + this.fileToolStripMenuItem.Size = new System.Drawing.Size(35, 20); + this.fileToolStripMenuItem.Text = "&File"; + // + // openToolStripMenuItem + // + this.openToolStripMenuItem.Name = "openToolStripMenuItem"; + this.openToolStripMenuItem.Size = new System.Drawing.Size(152, 22); + this.openToolStripMenuItem.Text = "&Open..."; + this.openToolStripMenuItem.Click += new System.EventHandler(this.openToolStripMenuItem_Click); + // + // exitToolStripMenuItem + // + this.exitToolStripMenuItem.Name = "exitToolStripMenuItem"; + this.exitToolStripMenuItem.Size = new System.Drawing.Size(152, 22); + this.exitToolStripMenuItem.Text = "E&xit"; + this.exitToolStripMenuItem.Click += new System.EventHandler(this.exitToolStripMenuItem_Click); + // + // editToolStripMenuItem + // + this.editToolStripMenuItem.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] { + this.findToolStripMenuItem}); + this.editToolStripMenuItem.Name = "editToolStripMenuItem"; + this.editToolStripMenuItem.Size = new System.Drawing.Size(37, 20); + this.editToolStripMenuItem.Text = "&Edit"; + // + // findToolStripMenuItem + // + this.findToolStripMenuItem.Name = "findToolStripMenuItem"; + this.findToolStripMenuItem.ShortcutKeys = ((System.Windows.Forms.Keys)((System.Windows.Forms.Keys.Control | System.Windows.Forms.Keys.F))); + this.findToolStripMenuItem.Size = new System.Drawing.Size(155, 22); + this.findToolStripMenuItem.Text = "&Find..."; + this.findToolStripMenuItem.Click += new System.EventHandler(this.findToolStripMenuItem_Click); + // + // toolsToolStripMenuItem + // + this.toolsToolStripMenuItem.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] { + this.optionsToolStripMenuItem, + this.saveLogToolStripMenuItem, + this.clearLogToolStripMenuItem}); + this.toolsToolStripMenuItem.Name = "toolsToolStripMenuItem"; + this.toolsToolStripMenuItem.Size = new System.Drawing.Size(44, 20); + this.toolsToolStripMenuItem.Text = "&Tools"; + // + // optionsToolStripMenuItem + // + this.optionsToolStripMenuItem.Name = "optionsToolStripMenuItem"; + this.optionsToolStripMenuItem.Size = new System.Drawing.Size(141, 22); + this.optionsToolStripMenuItem.Text = "&Options..."; + this.optionsToolStripMenuItem.Click += new System.EventHandler(this.optionsToolStripMenuItem_Click); + // + // saveLogToolStripMenuItem + // + this.saveLogToolStripMenuItem.Name = "saveLogToolStripMenuItem"; + this.saveLogToolStripMenuItem.Size = new System.Drawing.Size(141, 22); + this.saveLogToolStripMenuItem.Text = "&Save Log..."; + this.saveLogToolStripMenuItem.Click += new System.EventHandler(this.saveLogToolStripMenuItem_Click); + // + // clearLogToolStripMenuItem + // + this.clearLogToolStripMenuItem.Name = "clearLogToolStripMenuItem"; + this.clearLogToolStripMenuItem.Size = new System.Drawing.Size(141, 22); + this.clearLogToolStripMenuItem.Text = "&Clear Log"; + this.clearLogToolStripMenuItem.Click += new System.EventHandler(this.clearLogToolStripMenuItem_Click); + // + // helpToolStripMenuItem + // + this.helpToolStripMenuItem.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] { + this.aboutToolStripMenuItem, + this.contentsToolStripMenuItem}); + this.helpToolStripMenuItem.Name = "helpToolStripMenuItem"; + this.helpToolStripMenuItem.Size = new System.Drawing.Size(40, 20); + this.helpToolStripMenuItem.Text = "&Help"; + // + // aboutToolStripMenuItem + // + this.aboutToolStripMenuItem.Name = "aboutToolStripMenuItem"; + this.aboutToolStripMenuItem.Size = new System.Drawing.Size(129, 22); + this.aboutToolStripMenuItem.Text = "&About"; + this.aboutToolStripMenuItem.Click += new System.EventHandler(this.aboutToolStripMenuItem_Click); + // + // contentsToolStripMenuItem + // + this.contentsToolStripMenuItem.Name = "contentsToolStripMenuItem"; + this.contentsToolStripMenuItem.Size = new System.Drawing.Size(129, 22); + this.contentsToolStripMenuItem.Text = "&Contents"; + this.contentsToolStripMenuItem.Click += new System.EventHandler(this.contentsToolStripMenuItem_Click); + // + // textLog + // + this.textLog.Dock = System.Windows.Forms.DockStyle.Fill; + this.textLog.HideSelection = false; + this.textLog.Location = new System.Drawing.Point(0, 24); + this.textLog.Name = "textLog"; + this.textLog.Size = new System.Drawing.Size(513, 409); + this.textLog.TabIndex = 1; + this.textLog.Text = ""; + // + // AudioFileInspectorForm + // + this.AllowDrop = true; + this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.ClientSize = new System.Drawing.Size(513, 433); + this.Controls.Add(this.textLog); + this.Controls.Add(this.menuStrip1); + this.MainMenuStrip = this.menuStrip1; + this.Name = "AudioFileInspectorForm"; + this.Text = "Audio File Inspector"; + this.FormClosed += new System.Windows.Forms.FormClosedEventHandler(this.AudioFileInspectorForm_FormClosed); + this.DragDrop += new System.Windows.Forms.DragEventHandler(this.AudioFileInspectorForm_DragDrop); + this.DragOver += new System.Windows.Forms.DragEventHandler(this.AudioFileInspectorForm_DragOver); + this.Load += new System.EventHandler(this.AudioFileInspectorForm_Load); + this.menuStrip1.ResumeLayout(false); + this.menuStrip1.PerformLayout(); + this.ResumeLayout(false); + this.PerformLayout(); + + } + + #endregion + + private System.Windows.Forms.MenuStrip menuStrip1; + private System.Windows.Forms.ToolStripMenuItem fileToolStripMenuItem; + private System.Windows.Forms.ToolStripMenuItem openToolStripMenuItem; + private System.Windows.Forms.ToolStripMenuItem exitToolStripMenuItem; + private System.Windows.Forms.ToolStripMenuItem toolsToolStripMenuItem; + private System.Windows.Forms.ToolStripMenuItem helpToolStripMenuItem; + private System.Windows.Forms.ToolStripMenuItem aboutToolStripMenuItem; + private System.Windows.Forms.ToolStripMenuItem contentsToolStripMenuItem; + private System.Windows.Forms.ToolStripMenuItem optionsToolStripMenuItem; + private System.Windows.Forms.ToolStripMenuItem saveLogToolStripMenuItem; + private System.Windows.Forms.RichTextBox textLog; + private System.Windows.Forms.ToolStripMenuItem clearLogToolStripMenuItem; + private System.Windows.Forms.ToolStripMenuItem editToolStripMenuItem; + private System.Windows.Forms.ToolStripMenuItem findToolStripMenuItem; + } +} \ No newline at end of file diff --git a/AudioFileInspector/AudioFileInspectorForm.cs b/AudioFileInspector/AudioFileInspectorForm.cs new file mode 100644 index 00000000..0ee3d51a --- /dev/null +++ b/AudioFileInspector/AudioFileInspectorForm.cs @@ -0,0 +1,229 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Data; +using System.Drawing; +using System.Text; +using System.Windows.Forms; +using System.IO; +using System.ComponentModel.Composition; + +namespace AudioFileInspector +{ + [Export(typeof(AudioFileInspectorForm))] + public partial class AudioFileInspectorForm : Form + { + + public ICollection Inspectors { get; private set; } + string filterString; + int filterIndex; + string currentFile; + FindForm findForm; + + public string[] CommandLineArguments { get; set; } + + [ImportingConstructor] + public AudioFileInspectorForm([ImportMany(typeof(IAudioFileInspector))] IEnumerable inspectors) + { + InitializeComponent(); + this.Inspectors = new List(inspectors); + } + + private void DescribeFile(string fileName) + { + currentFile = fileName; + textLog.Text = String.Format("Opening {0}\r\n", fileName); + + try + { + string extension = System.IO.Path.GetExtension(fileName).ToLower(); + bool described = false; + foreach (IAudioFileInspector inspector in Inspectors) + { + if (extension == inspector.FileExtension) + { + textLog.AppendText(inspector.Describe(fileName)); + described = true; + break; + } + } + if (!described) + { + textLog.AppendText("Unrecognised file type"); + } + } + catch (Exception ex) + { + textLog.AppendText(ex.ToString()); + } + } + + private void CreateFilterString() + { + StringBuilder stringBuilder = new StringBuilder(); + if (Inspectors.Count > 0) + { + stringBuilder.Append("All Supported Files|"); + foreach (IAudioFileInspector inspector in Inspectors) + { + stringBuilder.AppendFormat("*{0};", inspector.FileExtension); + } + stringBuilder.Length--; + stringBuilder.Append("|"); + foreach (IAudioFileInspector inspector in Inspectors) + { + stringBuilder.AppendFormat("{0}|*{1}|", inspector.FileTypeDescription, inspector.FileExtension); + } + } + stringBuilder.Append("All files (*.*)|*.*"); + filterString = stringBuilder.ToString(); + filterIndex = 1; + } + + private void openToolStripMenuItem_Click(object sender, EventArgs e) + { + OpenFileDialog ofd = new OpenFileDialog(); + + ofd.Filter = filterString; + ofd.FilterIndex = filterIndex; + + if (ofd.ShowDialog() == DialogResult.OK) + { + filterIndex = ofd.FilterIndex; + DescribeFile(ofd.FileName); + textLog.SelectionStart = 0; + textLog.SelectionLength = 0; + } + } + + private void exitToolStripMenuItem_Click(object sender, EventArgs e) + { + this.Close(); + } + + private void aboutToolStripMenuItem_Click(object sender, EventArgs e) + { + NAudio.Utils.AboutForm aboutForm = new NAudio.Utils.AboutForm(); + aboutForm.ShowDialog(); + } + + private void AudioFileInspectorForm_Load(object sender, EventArgs e) + { + CreateFilterString(); + if (CommandLineArguments != null && CommandLineArguments.Length > 0) + { + DescribeFile(CommandLineArguments[0]); + } + } + + private void optionsToolStripMenuItem_Click(object sender, EventArgs e) + { + OptionsForm optionsForm = new OptionsForm(Inspectors); + optionsForm.ShowDialog(); + + } + + private void AudioFileInspectorForm_DragOver(object sender, DragEventArgs e) + { + if (e.Data.GetDataPresent(DataFormats.FileDrop)) + { + e.Effect = DragDropEffects.Copy; + } + } + + private void AudioFileInspectorForm_DragDrop(object sender, DragEventArgs e) + { + if (!e.Data.GetDataPresent(DataFormats.FileDrop)) + { + return; + } + string[] files = (string[])e.Data.GetData(DataFormats.FileDrop); + + if (files.Length > 0) + { + DescribeFile(files[0]); + } + } + + private void saveLogToolStripMenuItem_Click(object sender, EventArgs args) + { + SaveFileDialog saveFileDialog = new SaveFileDialog(); + saveFileDialog.DefaultExt = ".txt"; + if (currentFile != null) + { + saveFileDialog.InitialDirectory = Path.GetDirectoryName(currentFile); + saveFileDialog.FileName = Path.GetFileNameWithoutExtension(currentFile) + ".txt"; + } + saveFileDialog.Filter = "Text Files (*.txt)|*.txt"; + saveFileDialog.FilterIndex = 1; + if (saveFileDialog.ShowDialog() == DialogResult.OK) + { + try + { + + using (StreamWriter writer = new StreamWriter(saveFileDialog.FileName)) + { + string text = textLog.Text; + if (!text.Contains("\r")) + { + text = text.Replace("\n", "\r\n"); + } + writer.Write(text); + } + } + catch (Exception e) + { + MessageBox.Show( + String.Format("Error saving conversion log\r\n{0}", e.Message), + Application.ProductName, + MessageBoxButtons.OK, + MessageBoxIcon.Error); + } + + } + + } + + private void contentsToolStripMenuItem_Click(object sender, EventArgs e) + { + string helpFilePath = Path.Combine(Path.GetDirectoryName(Application.ExecutablePath), "audio_file_inspector.html"); + try + { + System.Diagnostics.Process.Start(helpFilePath); + } + catch (Win32Exception) + { + MessageBox.Show("Could not display the help file", Application.ProductName); + } + } + + private void clearLogToolStripMenuItem_Click(object sender, EventArgs e) + { + textLog.Clear(); + } + + private void findToolStripMenuItem_Click(object sender, EventArgs e) + { + if (findForm == null) + { + findForm = new FindForm(textLog); + findForm.Disposed += new EventHandler(findForm_Disposed); + } + findForm.Show(this); + } + + void findForm_Disposed(object sender, EventArgs e) + { + findForm = null; + } + + private void AudioFileInspectorForm_FormClosed(object sender, FormClosedEventArgs e) + { + if (findForm != null) + { + findForm.Close(); + } + } + + } +} \ No newline at end of file diff --git a/AudioFileInspector/AudioFileInspectorForm.resx b/AudioFileInspector/AudioFileInspectorForm.resx new file mode 100644 index 00000000..69c56499 --- /dev/null +++ b/AudioFileInspector/AudioFileInspectorForm.resx @@ -0,0 +1,123 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + 17, 17 + + \ No newline at end of file diff --git a/AudioFileInspector/FileAssociations.cs b/AudioFileInspector/FileAssociations.cs new file mode 100644 index 00000000..76642e82 --- /dev/null +++ b/AudioFileInspector/FileAssociations.cs @@ -0,0 +1,379 @@ +using System; +using Microsoft.Win32; + +namespace AudioFileInspector +{ + /// + /// Helper class for registering Windows Explorer File associations + /// + public class FileAssociations + { + + [System.Runtime.InteropServices.DllImport("shell32.dll")] + static extern void SHChangeNotify(HChangeNotifyEventID wEventId, + HChangeNotifyFlags uFlags, + IntPtr dwItem1, + IntPtr dwItem2); + + /// + /// Determines if the specified file type is registered + /// + /// The file extension including the leading period (e.g. ".wav") + /// True if it is registered + public static bool IsFileTypeRegistered(string extension) + { + RegistryKey key = Registry.ClassesRoot.OpenSubKey(extension); + if(key == null) + return false; + key.Close(); + return true; + } + + /// + /// Gets the HKCR key name for the extenstion + /// + /// The file extension including the leading period (e.g. ".wav") + /// The HKCR key name or null if not registered + public static string GetFileTypeKey(string extension) + { + RegistryKey key = Registry.ClassesRoot.OpenSubKey(extension); + string fileTypeKey = null; + if (key != null) + { + fileTypeKey = (string) key.GetValue(null); + key.Close(); + } + return fileTypeKey; + } + + /// + /// Registers a file type in Windows + /// + /// Extension include leading '.' + /// The description of this file type + /// Null for no icon or e.g c:\windows\regedit.exe,0 + public static void RegisterFileType(string extension, string description, string iconPath) + { + if (IsFileTypeRegistered(extension)) + throw new ArgumentException(extension + "is already registered"); + + RegistryKey key = Registry.ClassesRoot.CreateSubKey(extension); + string fileKey = extension.Substring(1) + "File"; + key.SetValue(null, fileKey); + key.Close(); + key = Registry.ClassesRoot.CreateSubKey(fileKey); + key.SetValue(null, description); + key.Close(); + if (iconPath != null) + { + key = Registry.ClassesRoot.CreateSubKey(fileKey + "\\DefaultIcon"); + key.SetValue(null, iconPath); + key.Close(); + } + SHChangeNotify(HChangeNotifyEventID.SHCNE_ASSOCCHANGED, HChangeNotifyFlags.SHCNF_IDLIST, IntPtr.Zero, IntPtr.Zero); + } + + /// + /// Adds a new explorer context menu action for this file type + /// Will overwrite any existing action with this key + /// + /// The file extension (include the leading dot) + /// A unique key for this action + /// What will appear on the context menu + /// The command to execute + public static void AddAction(string extension, string actionKey, string actionDescription, string command) + { + // command e.g. notepad.exe "%1" + string fileTypeKey = GetFileTypeKey(extension); + if (fileTypeKey == null) + throw new ArgumentException(extension + "is not a registered file type"); + RegistryKey key = Registry.ClassesRoot.CreateSubKey(fileTypeKey + "\\shell\\" + actionKey); + key.SetValue(null, actionDescription); + key.Close(); + + key = Registry.ClassesRoot.CreateSubKey(fileTypeKey + "\\shell\\" + actionKey + "\\command"); + key.SetValue(null, command); + key.Close(); + SHChangeNotify(HChangeNotifyEventID.SHCNE_ASSOCCHANGED, HChangeNotifyFlags.SHCNF_IDLIST, IntPtr.Zero, IntPtr.Zero); + } + + /// + /// Removes an explorer context menu action from a file extension + /// + /// The file extension (include the leading dot) + /// The unique key used to register this action + public static void RemoveAction(string extension, string actionKey) + { + string fileTypeKey = GetFileTypeKey(extension); + if (fileTypeKey == null) + { + return; + //throw new ArgumentException(extension + "is not a registered file type"); + } + Registry.ClassesRoot.DeleteSubKey(fileTypeKey + "\\shell\\" + actionKey + "\\command"); + Registry.ClassesRoot.DeleteSubKey(fileTypeKey + "\\shell\\" + actionKey); + } + + // TODO: add ourselves as an "Open With" application + // TODO: better error handling + // TODO: unregistering stuff + // TODO: set default action + + } + + #region enum HChangeNotifyEventID + /// + /// Describes the event that has occurred. + /// Typically, only one event is specified at a time. + /// If more than one event is specified, the values contained + /// in the dwItem1 and dwItem2 + /// parameters must be the same, respectively, for all specified events. + /// This parameter can be one or more of the following values. + /// + /// + /// Windows NT/2000/XP: dwItem2 contains the index + /// in the system image list that has changed. + /// dwItem1 is not used and should be . + /// Windows 95/98: dwItem1 contains the index + /// in the system image list that has changed. + /// dwItem2 is not used and should be . + /// + [Flags] + enum HChangeNotifyEventID + { + /// + /// All events have occurred. + /// + SHCNE_ALLEVENTS = 0x7FFFFFFF, + + /// + /// A file type association has changed. + /// must be specified in the uFlags parameter. + /// dwItem1 and dwItem2 are not used and must be . + /// + SHCNE_ASSOCCHANGED = 0x08000000, + + /// + /// The attributes of an item or folder have changed. + /// or + /// must be specified in uFlags. + /// dwItem1 contains the item or folder that has changed. + /// dwItem2 is not used and should be . + /// + SHCNE_ATTRIBUTES = 0x00000800, + + /// + /// A nonfolder item has been created. + /// or + /// must be specified in uFlags. + /// dwItem1 contains the item that was created. + /// dwItem2 is not used and should be . + /// + SHCNE_CREATE = 0x00000002, + + /// + /// A nonfolder item has been deleted. + /// or + /// must be specified in uFlags. + /// dwItem1 contains the item that was deleted. + /// dwItem2 is not used and should be . + /// + SHCNE_DELETE = 0x00000004, + + /// + /// A drive has been added. + /// or + /// must be specified in uFlags. + /// dwItem1 contains the root of the drive that was added. + /// dwItem2 is not used and should be . + /// + SHCNE_DRIVEADD = 0x00000100, + + /// + /// A drive has been added and the Shell should create a new window for the drive. + /// or + /// must be specified in uFlags. + /// dwItem1 contains the root of the drive that was added. + /// dwItem2 is not used and should be . + /// + SHCNE_DRIVEADDGUI = 0x00010000, + + /// + /// A drive has been removed. or + /// must be specified in uFlags. + /// dwItem1 contains the root of the drive that was removed. + /// dwItem2 is not used and should be . + /// + SHCNE_DRIVEREMOVED = 0x00000080, + + /// + /// Not currently used. + /// + SHCNE_EXTENDED_EVENT = 0x04000000, + + /// + /// The amount of free space on a drive has changed. + /// or + /// must be specified in uFlags. + /// dwItem1 contains the root of the drive on which the free space changed. + /// dwItem2 is not used and should be . + /// + SHCNE_FREESPACE = 0x00040000, + + /// + /// Storage media has been inserted into a drive. + /// or + /// must be specified in uFlags. + /// dwItem1 contains the root of the drive that contains the new media. + /// dwItem2 is not used and should be . + /// + SHCNE_MEDIAINSERTED = 0x00000020, + + /// + /// Storage media has been removed from a drive. + /// or + /// must be specified in uFlags. + /// dwItem1 contains the root of the drive from which the media was removed. + /// dwItem2 is not used and should be . + /// + SHCNE_MEDIAREMOVED = 0x00000040, + + /// + /// A folder has been created. + /// or must be specified in uFlags. + /// dwItem1 contains the folder that was created. + /// dwItem2 is not used and should be . + /// + SHCNE_MKDIR = 0x00000008, + + /// + /// A folder on the local computer is being shared via the network. + /// or + /// must be specified in uFlags. + /// dwItem1 contains the folder that is being shared. + /// dwItem2 is not used and should be . + /// + SHCNE_NETSHARE = 0x00000200, + + /// + /// A folder on the local computer is no longer being shared via the network. + /// or + /// must be specified in uFlags. + /// dwItem1 contains the folder that is no longer being shared. + /// dwItem2 is not used and should be . + /// + SHCNE_NETUNSHARE = 0x00000400, + + /// + /// The name of a folder has changed. + /// or + /// must be specified in uFlags. + /// dwItem1 contains the previous pointer to an item identifier list (PIDL) or name of the folder. + /// dwItem2 contains the new PIDL or name of the folder. + /// + SHCNE_RENAMEFOLDER = 0x00020000, + + /// + /// The name of a nonfolder item has changed. + /// or + /// must be specified in uFlags. + /// dwItem1 contains the previous PIDL or name of the item. + /// dwItem2 contains the new PIDL or name of the item. + /// + SHCNE_RENAMEITEM = 0x00000001, + + /// + /// A folder has been removed. + /// or + /// must be specified in uFlags. + /// dwItem1 contains the folder that was removed. + /// dwItem2 is not used and should be . + /// + SHCNE_RMDIR = 0x00000010, + + /// + /// The computer has disconnected from a server. + /// or + /// must be specified in uFlags. + /// dwItem1 contains the server from which the computer was disconnected. + /// dwItem2 is not used and should be . + /// + SHCNE_SERVERDISCONNECT = 0x00004000, + + /// + /// The contents of an existing folder have changed, + /// but the folder still exists and has not been renamed. + /// or + /// must be specified in uFlags. + /// dwItem1 contains the folder that has changed. + /// dwItem2 is not used and should be . + /// If a folder has been created, deleted, or renamed, use SHCNE_MKDIR, SHCNE_RMDIR, or + /// SHCNE_RENAMEFOLDER, respectively, instead. + /// + SHCNE_UPDATEDIR = 0x00001000, + + /// + /// An image in the system image list has changed. + /// must be specified in uFlags. + /// + SHCNE_UPDATEIMAGE = 0x00008000, + + } + #endregion // enum HChangeNotifyEventID + + #region public enum HChangeNotifyFlags + /// + /// Flags that indicate the meaning of the dwItem1 and dwItem2 parameters. + /// The uFlags parameter must be one of the following values. + /// + [Flags] + public enum HChangeNotifyFlags + { + /// + /// The dwItem1 and dwItem2 parameters are DWORD values. + /// + SHCNF_DWORD = 0x0003, + /// + /// dwItem1 and dwItem2 are the addresses of ITEMIDLIST structures that + /// represent the item(s) affected by the change. + /// Each ITEMIDLIST must be relative to the desktop folder. + /// + SHCNF_IDLIST = 0x0000, + /// + /// dwItem1 and dwItem2 are the addresses of null-terminated strings of + /// maximum length MAX_PATH that contain the full path names + /// of the items affected by the change. + /// + SHCNF_PATHA = 0x0001, + /// + /// dwItem1 and dwItem2 are the addresses of null-terminated strings of + /// maximum length MAX_PATH that contain the full path names + /// of the items affected by the change. + /// + SHCNF_PATHW = 0x0005, + /// + /// dwItem1 and dwItem2 are the addresses of null-terminated strings that + /// represent the friendly names of the printer(s) affected by the change. + /// + SHCNF_PRINTERA = 0x0002, + /// + /// dwItem1 and dwItem2 are the addresses of null-terminated strings that + /// represent the friendly names of the printer(s) affected by the change. + /// + SHCNF_PRINTERW = 0x0006, + /// + /// The function should not return until the notification + /// has been delivered to all affected components. + /// As this flag modifies other data-type flags, it cannot by used by itself. + /// + SHCNF_FLUSH = 0x1000, + /// + /// The function should begin delivering notifications to all affected components + /// but should return as soon as the notification process has begun. + /// As this flag modifies other data-type flags, it cannot by used by itself. + /// + SHCNF_FLUSHNOWAIT = 0x2000 + } + #endregion // enum HChangeNotifyFlags + +} diff --git a/AudioFileInspector/FileInspectors/CakewalkMapInspector.cs b/AudioFileInspector/FileInspectors/CakewalkMapInspector.cs new file mode 100644 index 00000000..c2402149 --- /dev/null +++ b/AudioFileInspector/FileInspectors/CakewalkMapInspector.cs @@ -0,0 +1,32 @@ +using System; +using System.Collections.Generic; +using System.Text; +using NAudio.FileFormats.Map; +using System.ComponentModel.Composition; + +namespace AudioFileInspector +{ + [Export(typeof(IAudioFileInspector))] + public class CakewalkMapInspector : IAudioFileInspector + { + #region IAudioFileInspector Members + + public string FileExtension + { + get { return ".map"; } + } + + public string FileTypeDescription + { + get { return "Cakewalk Drum Map"; } + } + + public string Describe(string fileName) + { + CakewalkMapFile mapFile = new CakewalkMapFile(fileName); + return mapFile.ToString(); + } + + #endregion + } +} diff --git a/AudioFileInspector/FileInspectors/MidiFileInspector.cs b/AudioFileInspector/FileInspectors/MidiFileInspector.cs new file mode 100644 index 00000000..d71618d7 --- /dev/null +++ b/AudioFileInspector/FileInspectors/MidiFileInspector.cs @@ -0,0 +1,78 @@ +using System; +using System.Linq; +using System.Collections.Generic; +using System.Text; +using NAudio.Midi; +using System.ComponentModel.Composition; + +namespace AudioFileInspector +{ + [Export(typeof(IAudioFileInspector))] + public class MidiFileInspector : IAudioFileInspector + { + #region IAudioFileInspector Members + + public string FileExtension + { + get { return ".mid"; } + } + + public string FileTypeDescription + { + get { return "Standard MIDI File"; } + } + + public string Describe(string fileName) + { + MidiFile mf = new MidiFile(fileName, false); + + StringBuilder sb = new StringBuilder(); + sb.AppendFormat("Format {0}, Tracks {1}, Delta Ticks Per Quarter Note {2}\r\n", + mf.FileFormat, mf.Tracks, mf.DeltaTicksPerQuarterNote); + var timeSignature = mf.Events[0].OfType().FirstOrDefault(); + for (int n = 0; n < mf.Tracks; n++) + { + foreach (MidiEvent midiEvent in mf.Events[n]) + { + if(!MidiEvent.IsNoteOff(midiEvent)) + { + sb.AppendFormat("{0} {1}\r\n", ToMBT(midiEvent.AbsoluteTime, mf.DeltaTicksPerQuarterNote, timeSignature), midiEvent); + } + } + } + return sb.ToString(); + } + + private string ToMBT(long eventTime, int ticksPerQuarterNote, TimeSignatureEvent timeSignature) + { + int beatsPerBar = timeSignature == null ? 4 : timeSignature.Numerator; + int ticksPerBar = timeSignature == null ? ticksPerQuarterNote * 4 : (timeSignature.Numerator * ticksPerQuarterNote * 4) / (1 << timeSignature.Denominator); + int ticksPerBeat = ticksPerBar / beatsPerBar; + long bar = 1 + (eventTime / ticksPerBar); + long beat = 1 + ((eventTime % ticksPerBar) / ticksPerBeat); + long tick = eventTime % ticksPerBeat; + return String.Format("{0}:{1}:{2}", bar, beat, tick); + } + + /// + /// Find the number of beats per measure + /// (for now assume just one TimeSignature per MIDI track) + /// + private int FindBeatsPerMeasure(IEnumerable midiEvents) + { + int beatsPerMeasure = 4; + foreach (MidiEvent midiEvent in midiEvents) + { + TimeSignatureEvent tse = midiEvent as TimeSignatureEvent; + if (tse != null) + { + beatsPerMeasure = tse.Numerator; + } + } + return beatsPerMeasure; + } + + + #endregion + } +} diff --git a/AudioFileInspector/FileInspectors/Mp3FileInspector.cs b/AudioFileInspector/FileInspectors/Mp3FileInspector.cs new file mode 100644 index 00000000..b96b8711 --- /dev/null +++ b/AudioFileInspector/FileInspectors/Mp3FileInspector.cs @@ -0,0 +1,56 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Text; +using System.ComponentModel.Composition; +using NAudio.Utils; +using NAudio.Wave; + +namespace AudioFileInspector +{ + [Export(typeof(IAudioFileInspector))] + public class Mp3FileInspector : IAudioFileInspector + { + public string FileExtension + { + get { return ".mp3"; } + } + + public string FileTypeDescription + { + get { return "MP3 File"; } + } + + public string Describe(string fileName) + { + var stringBuilder = new StringBuilder(); + using (var reader = new Mp3FileReader(fileName)) + { + Mp3WaveFormat wf = reader.Mp3WaveFormat; + stringBuilder.AppendFormat("MP3 File WaveFormat: {0} {1}Hz {2} channels {3} bits per sample\r\n", + wf.Encoding, wf.SampleRate, + wf.Channels, wf.BitsPerSample); + stringBuilder.AppendFormat("Extra Size: {0} Block Align: {1} Average Bytes Per Second: {2}\r\n", + wf.ExtraSize, wf.BlockAlign, + wf.AverageBytesPerSecond); + stringBuilder.AppendFormat("ID: {0} Flags: {1} Block Size: {2} Frames per Block: {3}\r\n", + wf.id, wf.flags, wf.blockSize, wf.framesPerBlock + ); + + stringBuilder.AppendFormat("Length: {0} bytes: {1} \r\n", reader.Length, reader.TotalTime); + stringBuilder.AppendFormat("ID3v1 Tag: {0}\r\n", reader.Id3v1Tag == null ? "None" : reader.Id3v1Tag.ToString()); + stringBuilder.AppendFormat("ID3v2 Tag: {0}\r\n", reader.Id3v2Tag == null ? "None" : reader.Id3v2Tag.ToString()); + Mp3Frame frame; + while ((frame = reader.ReadNextFrame()) != null) + { + stringBuilder.AppendFormat("{0},{1},{2}Hz,{3},{4}bps, length {5}\r\n", + frame.MpegVersion, frame.MpegLayer, + frame.SampleRate, frame.ChannelMode, + frame.BitRate, frame.FrameLength); + } + } + return stringBuilder.ToString(); + } + } +} diff --git a/AudioFileInspector/FileInspectors/SoundFontInspector.cs b/AudioFileInspector/FileInspectors/SoundFontInspector.cs new file mode 100644 index 00000000..e2876687 --- /dev/null +++ b/AudioFileInspector/FileInspectors/SoundFontInspector.cs @@ -0,0 +1,69 @@ +using System; +using System.Collections.Generic; +using System.Text; +using NAudio.SoundFont; +using System.ComponentModel.Composition; + +namespace AudioFileInspector +{ + [Export(typeof(IAudioFileInspector))] + public class SoundFontInspector : IAudioFileInspector + { + #region IAudioFileInspector Members + + public string FileExtension + { + get { return ".sf2"; } + } + + public string FileTypeDescription + { + get { return "SoundFont File"; } + } + + public string Describe(string fileName) + { + SoundFont sf = new SoundFont(fileName); + StringBuilder stringBuilder = new StringBuilder(); + stringBuilder.AppendFormat("{0}\r\n",sf.FileInfo); + stringBuilder.Append("Presets\r\n"); + foreach(Preset p in sf.Presets) + { + stringBuilder.AppendFormat("{0}\r\n",p); + foreach(Zone z in p.Zones) + { + stringBuilder.AppendFormat(" {0}\r\n",z); + foreach(Generator g in z.Generators) + { + stringBuilder.AppendFormat(" {0}\r\n",g); + } + foreach(Modulator m in z.Modulators) + { + stringBuilder.AppendFormat(" {0}\r\n",m); + } + } + } + + stringBuilder.Append("Instruments\r\n"); + foreach(Instrument i in sf.Instruments) + { + stringBuilder.AppendFormat("{0}\r\n",i); + foreach(Zone z in i.Zones) + { + stringBuilder.AppendFormat(" {0}\r\n",z); + foreach(Generator g in z.Generators) + { + stringBuilder.AppendFormat(" {0}\r\n",g); + } + foreach(Modulator m in z.Modulators) + { + stringBuilder.AppendFormat(" {0}\r\n",m); + } + } + } + return stringBuilder.ToString(); + } + + #endregion + } +} diff --git a/AudioFileInspector/FileInspectors/WaveFileInspector.cs b/AudioFileInspector/FileInspectors/WaveFileInspector.cs new file mode 100644 index 00000000..4f28cced --- /dev/null +++ b/AudioFileInspector/FileInspectors/WaveFileInspector.cs @@ -0,0 +1,149 @@ +using System; +using System.Collections.Generic; +using System.Text; +using NAudio.Wave; +using NAudio.Utils; +using System.Diagnostics; +using System.ComponentModel.Composition; + +namespace AudioFileInspector +{ + [Export(typeof(IAudioFileInspector))] + public class WaveFileInspector : IAudioFileInspector + { + + public string FileExtension + { + get { return ".wav"; } + } + + public string FileTypeDescription + { + get { return "Wave File"; } + } + + public string Describe(string fileName) + { + StringBuilder stringBuilder = new StringBuilder(); + using (WaveFileReader wf = new WaveFileReader(fileName)) + { + stringBuilder.AppendFormat("{0} {1}Hz {2} channels {3} bits per sample\r\n", + wf.WaveFormat.Encoding, wf.WaveFormat.SampleRate, + wf.WaveFormat.Channels, wf.WaveFormat.BitsPerSample); + stringBuilder.AppendFormat("Extra Size: {0} Block Align: {1} Average Bytes Per Second: {2}\r\n", + wf.WaveFormat.ExtraSize, wf.WaveFormat.BlockAlign, + wf.WaveFormat.AverageBytesPerSecond); + stringBuilder.AppendFormat("WaveFormat: {0}\r\n",wf.WaveFormat); + + stringBuilder.AppendFormat("Length: {0} bytes: {1} \r\n", wf.Length, wf.TotalTime); + foreach (RiffChunk chunk in wf.ExtraChunks) + { + stringBuilder.AppendFormat("Chunk: {0}, length {1}\r\n", chunk.IdentifierAsString, chunk.Length); + byte[] data = wf.GetChunkData(chunk); + DescribeChunk(chunk, stringBuilder, data); + } + } + return stringBuilder.ToString(); + } + + private static void DescribeChunk(RiffChunk chunk, StringBuilder stringBuilder, byte[] data) + { + switch(chunk.IdentifierAsString) + { + case "strc": + DescribeStrc(stringBuilder, data); + break; + case "bext": + DescribeBext(stringBuilder, data); + break; + case "iXML": + stringBuilder.Append(UTF8Encoding.UTF8.GetString(data)); + break; + default: + { + if (ByteArrayExtensions.IsEntirelyNull(data)) + { + stringBuilder.AppendFormat("{0} null bytes\r\n", data.Length); + } + else + { + stringBuilder.AppendFormat("{0}\r\n", ByteArrayExtensions.DescribeAsHex(data," ",32)); + } + } + break; + } + } + + private static void DescribeBext(StringBuilder sb, byte[] data) + { + int offset = 0; + sb.AppendFormat("Description: {0}\r\n", ByteArrayExtensions.DecodeAsString(data, 0, 256, ASCIIEncoding.ASCII)); + offset += 256; + sb.AppendFormat("Originator: {0}\r\n", ByteArrayExtensions.DecodeAsString(data, offset, 32, ASCIIEncoding.ASCII)); + offset += 32; + sb.AppendFormat("Originator Reference: {0}\r\n", ByteArrayExtensions.DecodeAsString(data, offset, 32, ASCIIEncoding.ASCII)); + offset += 32; + sb.AppendFormat("Origination Date: {0}\r\n", ByteArrayExtensions.DecodeAsString(data, offset, 10, ASCIIEncoding.ASCII)); + offset += 10; + sb.AppendFormat("Origination Time: {0}\r\n", ByteArrayExtensions.DecodeAsString(data, offset, 8, ASCIIEncoding.ASCII)); + offset += 8; + sb.AppendFormat("Time Reference Low: {0}\r\n", BitConverter.ToUInt32(data, offset)); + offset += 4; + sb.AppendFormat("Time Reference High: {0}\r\n", BitConverter.ToUInt32(data, offset)); + offset += 4; + sb.AppendFormat("Version: {0}\r\n", BitConverter.ToUInt16(data, offset)); + offset += 2; + sb.AppendFormat("SMPTE UMID: {0}\r\n", ByteArrayExtensions.DecodeAsString(data, offset, 64, Encoding.ASCII)); + //byte[] smpteumid = 64 bytes; + offset += 64; + sb.AppendFormat("Loudness Value: {0}\r\n", BitConverter.ToUInt16(data, offset)); + offset += 2; + sb.AppendFormat("Loudness Range: {0}\r\n", BitConverter.ToUInt16(data, offset)); + offset += 2; + sb.AppendFormat("Max True Peak Level: {0}\r\n", BitConverter.ToUInt16(data, offset)); + offset += 2; + sb.AppendFormat("Max Momentary Loudness: {0}\r\n", BitConverter.ToUInt16(data, offset)); + offset += 2; + sb.AppendFormat("Max short term loudness: {0}\r\n", BitConverter.ToUInt16(data, offset)); + offset += 2; + //byte[] reserved = 180 bytes; + offset += 180; + sb.AppendFormat("Coding History: {0}\r\n", ByteArrayExtensions.DecodeAsString(data, offset, data.Length-offset, Encoding.ASCII)); + + } + + + + + private static void DescribeStrc(StringBuilder stringBuilder, byte[] data) + { + // First 28 bytes are header + int header1 = BitConverter.ToInt32(data, 0); // always 0x1C? + int sliceCount = BitConverter.ToInt32(data, 4); + int header2 = BitConverter.ToInt32(data, 8); // 0x19 or 0x41? + int header3 = BitConverter.ToInt32(data, 12); // 0x05 or 0x0A? (linked with header 2 - 0x41 0x05 go together and 0x19 0x0A go together) + int header4 = BitConverter.ToInt32(data, 16); // always 1? + int header5 = BitConverter.ToInt32(data, 20); // 0x00, 0x01 or 0x0A? + int header6 = BitConverter.ToInt32(data, 24); // 0x02, 0x04. 0x05 + + stringBuilder.AppendFormat("{0} slices. unknown: {1},{2},{3},{4},{5},{6}\r\n", + sliceCount,header1,header2,header3,header4,header5,header6); + + int offset = 28; + + for (int slice = 0; slice < sliceCount; slice++) + { + int unknown1 = BitConverter.ToInt32(data, offset); // 0 or 2 + int uniqueId1 = BitConverter.ToInt32(data, offset + 4); // another unique ID - doesn't change? + + long samplePosition = BitConverter.ToInt64(data, offset + 8); + long samplePos2 = BitConverter.ToInt64(data, offset + 16); // is zero the first time through, equal to sample position next time round + int unknown5 = BitConverter.ToInt32(data, offset + 24); // large number first time through, zero second time through, not flags, not a float + int uniqueId2 = BitConverter.ToInt32(data, offset + 28); // always the same + offset += 32; + stringBuilder.AppendFormat("Pos: {2},{3} unknown: {0},{4}\r\n", + unknown1, uniqueId1, samplePosition, samplePos2, unknown5, uniqueId2); + } + } + } +} diff --git a/AudioFileInspector/FindForm.Designer.cs b/AudioFileInspector/FindForm.Designer.cs new file mode 100644 index 00000000..1da68918 --- /dev/null +++ b/AudioFileInspector/FindForm.Designer.cs @@ -0,0 +1,88 @@ +namespace AudioFileInspector +{ + partial class FindForm + { + /// + /// Required designer variable. + /// + private System.ComponentModel.IContainer components = null; + + /// + /// Clean up any resources being used. + /// + /// true if managed resources should be disposed; otherwise, false. + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Windows Form Designer generated code + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + this.label1 = new System.Windows.Forms.Label(); + this.textBoxFind = new System.Windows.Forms.TextBox(); + this.buttonFind = new System.Windows.Forms.Button(); + this.SuspendLayout(); + // + // label1 + // + this.label1.AutoSize = true; + this.label1.Location = new System.Drawing.Point(12, 9); + this.label1.Name = "label1"; + this.label1.Size = new System.Drawing.Size(56, 13); + this.label1.TabIndex = 0; + this.label1.Text = "Find what:"; + // + // textBoxFind + // + this.textBoxFind.Location = new System.Drawing.Point(74, 6); + this.textBoxFind.Name = "textBoxFind"; + this.textBoxFind.Size = new System.Drawing.Size(206, 20); + this.textBoxFind.TabIndex = 1; + // + // buttonFind + // + this.buttonFind.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right))); + this.buttonFind.Location = new System.Drawing.Point(205, 32); + this.buttonFind.Name = "buttonFind"; + this.buttonFind.Size = new System.Drawing.Size(75, 23); + this.buttonFind.TabIndex = 2; + this.buttonFind.Text = "Find Next"; + this.buttonFind.UseVisualStyleBackColor = true; + this.buttonFind.Click += new System.EventHandler(this.buttonFind_Click); + // + // FindForm + // + this.AcceptButton = this.buttonFind; + this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.ClientSize = new System.Drawing.Size(292, 64); + this.Controls.Add(this.buttonFind); + this.Controls.Add(this.textBoxFind); + this.Controls.Add(this.label1); + this.MaximizeBox = false; + this.MinimizeBox = false; + this.Name = "FindForm"; + this.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent; + this.Text = "Find"; + this.ResumeLayout(false); + this.PerformLayout(); + + } + + #endregion + + private System.Windows.Forms.Label label1; + private System.Windows.Forms.TextBox textBoxFind; + private System.Windows.Forms.Button buttonFind; + } +} \ No newline at end of file diff --git a/AudioFileInspector/FindForm.cs b/AudioFileInspector/FindForm.cs new file mode 100644 index 00000000..77bfa692 --- /dev/null +++ b/AudioFileInspector/FindForm.cs @@ -0,0 +1,29 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Data; +using System.Drawing; +using System.Text; +using System.Windows.Forms; + +namespace AudioFileInspector +{ + public partial class FindForm : Form + { + RichTextBox richTextBox; + public FindForm(RichTextBox richTextBox) + { + InitializeComponent(); + this.richTextBox = richTextBox; + } + + private void buttonFind_Click(object sender, EventArgs e) + { + richTextBox.Find(textBoxFind.Text, + richTextBox.SelectionStart + + richTextBox.SelectionLength, + RichTextBoxFinds.None); + richTextBox.ScrollToCaret(); + } + } +} \ No newline at end of file diff --git a/AudioFileInspector/FindForm.resx b/AudioFileInspector/FindForm.resx new file mode 100644 index 00000000..ff31a6db --- /dev/null +++ b/AudioFileInspector/FindForm.resx @@ -0,0 +1,120 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + \ No newline at end of file diff --git a/AudioFileInspector/IAudioFileInspector.cs b/AudioFileInspector/IAudioFileInspector.cs new file mode 100644 index 00000000..70fdaea4 --- /dev/null +++ b/AudioFileInspector/IAudioFileInspector.cs @@ -0,0 +1,13 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace AudioFileInspector +{ + public interface IAudioFileInspector + { + string FileExtension { get; } + string FileTypeDescription { get; } + string Describe(string fileName); + } +} diff --git a/AudioFileInspector/InstallScript.nsi b/AudioFileInspector/InstallScript.nsi new file mode 100644 index 00000000..e1a1bef2 --- /dev/null +++ b/AudioFileInspector/InstallScript.nsi @@ -0,0 +1,154 @@ +; Audio File Inspector install script +; originally based on example2 that comes with nsis +; +; This script is based on example1.nsi, but it remember the directory, +; has uninstall support and (optionally) installs start menu shortcuts. +; +; It will install example2.nsi into a directory that the user selects, + +;-------------------------------- +!include WordFunc.nsh +!insertmacro VersionCompare + +!include LogicLib.nsh + +!define VERSION "0.1" +!define FULLVERSION "0.1.1.0" +!define PRODUCT_NAME "Audio File Inspector" +!define EXECUTABLE_NAME "AudioFileInspector.exe" + +; The name of the installer +Name "Audio File Inspector" + +; The file to write +;OutFile "${PRODUCT_NAME} v${VERSION} Install.exe" +OutFile "audio_file_inspector_0_1_install.exe" + +; The default installation directory +InstallDir "$PROGRAMFILES\Mark Heath\${PRODUCT_NAME}" + +; Registry key to check for directory (so if you install again, it will +; overwrite the old one automatically) +InstallDirRegKey HKLM "Software\${PRODUCT_NAME}" "Install_Dir" + +VIAddVersionKey /LANG=${LANG_ENGLISH} "ProductName" "${PRODUCT_NAME}" +VIAddVersionKey /LANG=${LANG_ENGLISH} "Comments" "" +VIAddVersionKey /LANG=${LANG_ENGLISH} "CompanyName" "Mark Heath" +VIAddVersionKey /LANG=${LANG_ENGLISH} "LegalCopyright" "© 2006-2009 Mark Heath" +VIAddVersionKey /LANG=${LANG_ENGLISH} "FileDescription" "${PRODUCT_NAME} Installer" +VIAddVersionKey /LANG=${LANG_ENGLISH} "FileVersion" "${VERSION}" +VIProductVersion "${FULLVERSION}" + + + +;-------------------------------- + +; Utils + +Function .onInit + Call GetDotNETVersion + Pop $0 + ${If} $0 == "not found" + MessageBox MB_OK|MB_ICONSTOP ".NET runtime library v2.0 or newer is required." + ExecShell "open" "http://msdn.microsoft.com/netframework/downloads/updates/default.aspx" + Abort + ${EndIf} + + StrCpy $0 $0 "" 1 # skip "v" + + ${VersionCompare} $0 "2.0" $1 + ${If} $1 == 2 + MessageBox MB_OK|MB_ICONSTOP ".NET runtime library v2.0 or newer is required. You have $0." + ExecShell "open" "http://msdn.microsoft.com/netframework/downloads/updates/default.aspx" + Abort + ${EndIf} +FunctionEnd + +Function GetDotNETVersion + Push $0 + Push $1 + + System::Call "mscoree::GetCORVersion(w .r0, i ${NSIS_MAX_STRLEN}, *i) i .r1" + StrCmp $1 "error" 0 +2 + StrCpy $0 "not found" + + Pop $1 + Exch $0 +FunctionEnd + +;-------------------------------- + +; Pages + +Page components +Page directory +Page instfiles + +UninstPage uninstConfirm +UninstPage instfiles + +;-------------------------------- + +; The stuff to install +Section "Program Files (required)" + + SectionIn RO + + ; Set output path to the installation directory. + SetOutPath $INSTDIR + + ; Put file there + File "${EXECUTABLE_NAME}" + ; File "${EXECUTABLE_NAME}.config" + File "NAudio.dll" + File "audio_file_inspector.html" + + ; Write the installation path into the registry + WriteRegStr HKLM "SOFTWARE\${PRODUCT_NAME}" "Install_Dir" "$INSTDIR" + + ; Write the uninstall keys for Windows + WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${PRODUCT_NAME}" "DisplayName" "${PRODUCT_NAME}" + WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${PRODUCT_NAME}" "UninstallString" '"$INSTDIR\uninstall.exe"' + WriteRegDWORD HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${PRODUCT_NAME}" "NoModify" 1 + WriteRegDWORD HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${PRODUCT_NAME}" "NoRepair" 1 + WriteUninstaller "uninstall.exe" + + ExecWait '"$INSTDIR\${EXECUTABLE_NAME}" -install' $0 + DetailPrint "Associating File Types returned $0" +SectionEnd + +; Optional section (can be disabled by the user) +Section "Start Menu Shortcuts" + + CreateDirectory "$SMPROGRAMS\${PRODUCT_NAME}" + CreateShortCut "$SMPROGRAMS\${PRODUCT_NAME}\Uninstall.lnk" "$INSTDIR\uninstall.exe" "" "$INSTDIR\uninstall.exe" 0 + CreateShortCut "$SMPROGRAMS\${PRODUCT_NAME}\${PRODUCT_NAME}.lnk" "$INSTDIR\${EXECUTABLE_NAME}" "" "$INSTDIR\${EXECUTABLE_NAME}" 0 + +SectionEnd + +;-------------------------------- + +; Uninstaller + +Section "Uninstall" + ExecWait '"$INSTDIR\${EXECUTABLE_NAME}" -uninstall' $0 + DetailPrint "Removing Explorer Context Action returned $0" + ; Remove registry keys + DeleteRegKey HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${PRODUCT_NAME}" + DeleteRegKey HKLM "SOFTWARE\${PRODUCT_NAME}" + + ; Remove files and uninstaller + Delete "$INSTDIR\uninstall.exe" + Delete "$INSTDIR\${EXECUTABLE_NAME}" + Delete "$INSTDIR\${EXECUTABLE_NAME}.config" + Delete "$INSTDIR\NAudio.dll" + Delete "$INSTDIR\audio_file_inspector.html" + + ; Remove shortcuts, if any + Delete "$SMPROGRAMS\${PRODUCT_NAME}\*.*" + + ; Remove directories used + RMDir "$SMPROGRAMS\${PRODUCT_NAME}" + RMDir "$INSTDIR" + +SectionEnd diff --git a/AudioFileInspector/OptionsForm.Designer.cs b/AudioFileInspector/OptionsForm.Designer.cs new file mode 100644 index 00000000..737a304b --- /dev/null +++ b/AudioFileInspector/OptionsForm.Designer.cs @@ -0,0 +1,94 @@ +namespace AudioFileInspector +{ + partial class OptionsForm + { + /// + /// Required designer variable. + /// + private System.ComponentModel.IContainer components = null; + + /// + /// Clean up any resources being used. + /// + /// true if managed resources should be disposed; otherwise, false. + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Windows Form Designer generated code + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + this.buttonAssociate = new System.Windows.Forms.Button(); + this.buttonDisassociate = new System.Windows.Forms.Button(); + this.label1 = new System.Windows.Forms.Label(); + this.SuspendLayout(); + // + // buttonAssociate + // + this.buttonAssociate.Location = new System.Drawing.Point(73, 64); + this.buttonAssociate.Name = "buttonAssociate"; + this.buttonAssociate.Size = new System.Drawing.Size(164, 23); + this.buttonAssociate.TabIndex = 0; + this.buttonAssociate.Text = "Recreate File Associations"; + this.buttonAssociate.UseVisualStyleBackColor = true; + this.buttonAssociate.Click += new System.EventHandler(this.buttonAssociate_Click); + // + // buttonDisassociate + // + this.buttonDisassociate.Location = new System.Drawing.Point(73, 93); + this.buttonDisassociate.Name = "buttonDisassociate"; + this.buttonDisassociate.Size = new System.Drawing.Size(164, 23); + this.buttonDisassociate.TabIndex = 1; + this.buttonDisassociate.Text = "Remove File Associations"; + this.buttonDisassociate.UseVisualStyleBackColor = true; + this.buttonDisassociate.Click += new System.EventHandler(this.buttonDisassociate_Click); + // + // label1 + // + this.label1.AutoSize = true; + this.label1.Location = new System.Drawing.Point(12, 9); + this.label1.Name = "label1"; + this.label1.Size = new System.Drawing.Size(290, 52); + this.label1.TabIndex = 2; + this.label1.Text = "Audio File Inspector can be set up to appear as a right-click \r\ncontext menu opti" + + "on in Windows explorer. You can recreate\r\nor remove the file associations at any" + + " time using the buttons\r\nbelow."; + // + // OptionsForm + // + this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.ClientSize = new System.Drawing.Size(309, 128); + this.Controls.Add(this.label1); + this.Controls.Add(this.buttonDisassociate); + this.Controls.Add(this.buttonAssociate); + this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedSingle; + this.MaximizeBox = false; + this.MinimizeBox = false; + this.Name = "OptionsForm"; + this.ShowIcon = false; + this.ShowInTaskbar = false; + this.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent; + this.Text = "Options"; + this.ResumeLayout(false); + this.PerformLayout(); + + } + + #endregion + + private System.Windows.Forms.Button buttonAssociate; + private System.Windows.Forms.Button buttonDisassociate; + private System.Windows.Forms.Label label1; + } +} \ No newline at end of file diff --git a/AudioFileInspector/OptionsForm.cs b/AudioFileInspector/OptionsForm.cs new file mode 100644 index 00000000..e61dad40 --- /dev/null +++ b/AudioFileInspector/OptionsForm.cs @@ -0,0 +1,87 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Data; +using System.Drawing; +using System.Text; +using System.Windows.Forms; +using NAudio.Utils; + +namespace AudioFileInspector +{ + partial class OptionsForm : Form + { + IEnumerable inspectors; + + public OptionsForm(IEnumerable inspectors) + { + InitializeComponent(); + this.inspectors = inspectors; + } + + private void buttonAssociate_Click(object sender, EventArgs args) + { + try + { + Associate(inspectors); + } + catch (Exception e) + { + MessageBox.Show( + String.Format("Unable to create file associations\r\n{0}", e), + Application.ProductName, + MessageBoxButtons.OK, + MessageBoxIcon.Error); + } + + } + + private void buttonDisassociate_Click(object sender, EventArgs args) + { + try + { + Disassociate(inspectors); + } + catch (Exception e) + { + MessageBox.Show( + String.Format("Unable to remove file associations\r\n{0}", e), + Application.ProductName, + MessageBoxButtons.OK, + MessageBoxIcon.Error); + } + } + + public static void Disassociate(IEnumerable inspectors) + { + foreach (IAudioFileInspector inspector in inspectors) + { + if (!FileAssociations.IsFileTypeRegistered(inspector.FileExtension)) + { + FileAssociations.RegisterFileType(inspector.FileExtension, inspector.FileTypeDescription, null); + } + string command = "\"" + Application.ExecutablePath + "\" \"%1\""; + FileAssociations.RemoveAction( + inspector.FileExtension, + "AudioFileInspector"); + } + } + + public static void Associate(IEnumerable inspectors) + { + foreach (IAudioFileInspector inspector in inspectors) + { + if (!FileAssociations.IsFileTypeRegistered(inspector.FileExtension)) + { + FileAssociations.RegisterFileType(inspector.FileExtension, inspector.FileTypeDescription, null); + } + string command = "\"" + Application.ExecutablePath + "\" \"%1\""; + FileAssociations.AddAction( + inspector.FileExtension, + "AudioFileInspector", + "Describe", + command); + } + } + } +} \ No newline at end of file diff --git a/AudioFileInspector/OptionsForm.resx b/AudioFileInspector/OptionsForm.resx new file mode 100644 index 00000000..ff31a6db --- /dev/null +++ b/AudioFileInspector/OptionsForm.resx @@ -0,0 +1,120 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + \ No newline at end of file diff --git a/AudioFileInspector/Program.cs b/AudioFileInspector/Program.cs new file mode 100644 index 00000000..79a228c4 --- /dev/null +++ b/AudioFileInspector/Program.cs @@ -0,0 +1,65 @@ +using System; +using System.Linq; +using System.Collections.Generic; +using System.Windows.Forms; +using System.ComponentModel.Composition; +using System.ComponentModel.Composition.Hosting; + +namespace AudioFileInspector +{ + static class Program + { + /// + /// The main entry point for the application. + /// + [STAThread] + static int Main(string[] args) + { + Application.EnableVisualStyles(); + Application.SetCompatibleTextRenderingDefault(false); + + var catalog = new AssemblyCatalog(System.Reflection.Assembly.GetExecutingAssembly()); + var container = new CompositionContainer(catalog); + var inspectors = container.GetExportedValues(); + + if (args.Length > 0) + { + if (args[0] == "-install") + { + try + { + OptionsForm.Associate(inspectors); + Console.WriteLine("Created {0} file associations", inspectors.Count()); + } + catch (Exception e) + { + Console.WriteLine("Unable to create file associations"); + Console.WriteLine(e.ToString()); + return -1; + } + + return 0; + } + else if (args[0] == "-uninstall") + { + try + { + OptionsForm.Disassociate(inspectors); + Console.WriteLine("Removed {0} file associations", inspectors.Count()); + } + catch (Exception e) + { + Console.WriteLine("Unable to remove file associations"); + Console.WriteLine(e.ToString()); + return -1; + } + return 0; + } + } + var mainForm = container.GetExportedValue(); + mainForm.CommandLineArguments = args; + Application.Run(mainForm); + return 0; + } + } +} \ No newline at end of file diff --git a/AudioFileInspector/Properties/AssemblyInfo.cs b/AudioFileInspector/Properties/AssemblyInfo.cs new file mode 100644 index 00000000..fab0c400 --- /dev/null +++ b/AudioFileInspector/Properties/AssemblyInfo.cs @@ -0,0 +1,77 @@ +using System.Reflection; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +// General Information about an assembly is controlled through the following +// set of attributes. Change these attribute values to modify the information +// associated with an assembly. +[assembly: AssemblyTitle("Audio File Inspector")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("Mark Heath")] +[assembly: AssemblyProduct("Audio File Inspector")] +[assembly: AssemblyCopyright("Copyright © Mark Heath 2012")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// Setting ComVisible to false makes the types in this assembly not visible +// to COM components. If you need to access a type in this assembly from +// COM, set the ComVisible attribute to true on that type. +[assembly: ComVisible(false)] + +// The following GUID is for the ID of the typelib if this project is exposed to COM +[assembly: Guid("8bb855c5-ddfc-4596-a5df-aa9059be7705")] + +// Version information for an assembly consists of the following four values: +// +// Major Version +// Minor Version +// Build Number +// Revision +// +[assembly: AssemblyVersion("0.1.7.0")] +[assembly: AssemblyFileVersion("0.1.7.0")] + +// build 1 - 1 Nov 2006 +// initial version - moved out of WavePlayer +// extracted file describing logic into classes +// drag and drop support +// command line support +// explorer context menu support +// save analysis to text file +// installer +// command line register and unregister file associations +// build 2 - 2 Nov 2006 +// fixed some installer problems +// build 3 - 10 Nov 2006 +// MIDI note off events are not displayed +// Initial M:B:T support for MIDI +// build 4 - 26 Apr 2007 +// Updated to work with latest code in CodePlex +// Beginnings of a find feature +// build 5 - 8 Jun 2008 +// Shows length of Wave file as a TimeSpan as well as bytes +// build 6 - 13 Jan 2009 +// can report on strc chunks in ACID wav files +// build 7 - 13 Jan 2012 +// better MBT calculation for MIDI files + +// TODO list +// help file + +// better error handling +// possibly: a plugin format +// options for each inspector +// describe on a separate thread + + +// Enhance existing: +// MIDI: riff, M:B:T +// WAV: ACID format +// Additional formats: +// WAV 64 +// AIFF +// REX +// MP3 +// OGG +// Project 5 pattern diff --git a/AudioFileInspector/Properties/Resources.Designer.cs b/AudioFileInspector/Properties/Resources.Designer.cs new file mode 100644 index 00000000..63e68a94 --- /dev/null +++ b/AudioFileInspector/Properties/Resources.Designer.cs @@ -0,0 +1,63 @@ +//------------------------------------------------------------------------------ +// +// This code was generated by a tool. +// Runtime Version:4.0.30319.1 +// +// Changes to this file may cause incorrect behavior and will be lost if +// the code is regenerated. +// +//------------------------------------------------------------------------------ + +namespace AudioFileInspector.Properties { + using System; + + + /// + /// A strongly-typed resource class, for looking up localized strings, etc. + /// + // This class was auto-generated by the StronglyTypedResourceBuilder + // class via a tool like ResGen or Visual Studio. + // To add or remove a member, edit your .ResX file then rerun ResGen + // with the /str option, or rebuild your VS project. + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")] + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] + internal class Resources { + + private static global::System.Resources.ResourceManager resourceMan; + + private static global::System.Globalization.CultureInfo resourceCulture; + + [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] + internal Resources() { + } + + /// + /// Returns the cached ResourceManager instance used by this class. + /// + [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] + internal static global::System.Resources.ResourceManager ResourceManager { + get { + if (object.ReferenceEquals(resourceMan, null)) { + global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("AudioFileInspector.Properties.Resources", typeof(Resources).Assembly); + resourceMan = temp; + } + return resourceMan; + } + } + + /// + /// Overrides the current thread's CurrentUICulture property for all + /// resource lookups using this strongly typed resource class. + /// + [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] + internal static global::System.Globalization.CultureInfo Culture { + get { + return resourceCulture; + } + set { + resourceCulture = value; + } + } + } +} diff --git a/AudioFileInspector/Properties/Resources.resx b/AudioFileInspector/Properties/Resources.resx new file mode 100644 index 00000000..ffecec85 --- /dev/null +++ b/AudioFileInspector/Properties/Resources.resx @@ -0,0 +1,117 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + \ No newline at end of file diff --git a/AudioFileInspector/Properties/Settings.Designer.cs b/AudioFileInspector/Properties/Settings.Designer.cs new file mode 100644 index 00000000..89cacc5a --- /dev/null +++ b/AudioFileInspector/Properties/Settings.Designer.cs @@ -0,0 +1,26 @@ +//------------------------------------------------------------------------------ +// +// This code was generated by a tool. +// Runtime Version:4.0.30319.1 +// +// Changes to this file may cause incorrect behavior and will be lost if +// the code is regenerated. +// +//------------------------------------------------------------------------------ + +namespace AudioFileInspector.Properties { + + + [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "10.0.0.0")] + internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase { + + private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings()))); + + public static Settings Default { + get { + return defaultInstance; + } + } + } +} diff --git a/AudioFileInspector/Properties/Settings.settings b/AudioFileInspector/Properties/Settings.settings new file mode 100644 index 00000000..abf36c5d --- /dev/null +++ b/AudioFileInspector/Properties/Settings.settings @@ -0,0 +1,7 @@ + + + + + + + diff --git a/AudioFileInspector/audio_file_inspector.html b/AudioFileInspector/audio_file_inspector.html new file mode 100644 index 00000000..65a17b92 --- /dev/null +++ b/AudioFileInspector/audio_file_inspector.html @@ -0,0 +1,84 @@ + + + + Audio File Inspector + + +

+ Audio File Inspector

+

+ Audio File Inspector is a simple utility that describes the contents of various + types of audio file (for example WAV files or MIDI sequences). It started out as + a developer tool to aid in writing code that reads these various formats, but has + been released because some people may find it useful for diagnosing problems playing + back various media files.

+

+ Audio File Formats are notoriously vague and it is likely that you will have some + files on your computer that cause Audio File Inspector to generate an error message. + If you encounter a problem, then feel free to zip the file up and email it to me + and I will consider updating the utility to support your file.

+

+ Supported File Types

+

+ The current version of Audio File Inspector supports the following file types:

+
    +
  • MID - This will enumerate each event in the MIDI file. At the moment it + reports the time of the event in terms of "absolute time". A future update will turn + this into measures, beats and ticks (M:B:T)
  • +
  • SF2 - This examines a SoundFont file, reporting all the instruments, zones + and audio files contained within
  • +
  • WAV - This will report the format of the audio data, as well as providing + binary dumps of any extra chunks of information.
  • +
  • MAP - This can extract some information from a Cakewalk drum map file. +
  • +
+ +

+ Download

+ +

A link to the latest version of Audio File Inspector can be found + here.

+

+ Installation

+ +

Audio File Inspector requires the .NET framework version 3.5 to be installed. + You can download this + here. Once you have done this you can run the installer which will add a right-click "Describe" + action to Windows Explorer for each of the supported file types.

+

+ Usage

+

+ There are a variety of ways in which you can load a file into Audio File Inspector for + analysis.

+
    +
  • Right-click a supported file in Windows explorer and click "Describe"
  • +
  • Use the File|Open menu option to select a file to analyse
  • +
  • Drag a file from Windows explorer onto the title-bar of Audio File Inspector
  • +
  • You can also drag a file over the executable itself or run Audio File Inspector + from the command line with a filename as an argument.
  • +
+

+ Tools Menu

+

+ On the tools menu you can find commands that allow you to clear the log or to save its + contents to disk (you are of course free to edit the contents in any way you like before + saving it). + + There is also an options form, which in this version simply allows you to recreate or remove + the right-click "Describe" option in Windows Explorer.

+

+ Version History

+

+ The latest version of Audio File Inspector can be found at + http://naudio.codeplex.com. +

+
    +
  • v0.1 2 Nov 2006 +
      +
    • First public beta release
    • +
    • Support for WAV, MID, SF2 and MAP
    • +
    +
  • +
+ + diff --git a/Build.proj b/Build.proj new file mode 100644 index 00000000..f2dd1b46 --- /dev/null +++ b/Build.proj @@ -0,0 +1,65 @@ + + + + $(MSBuildProjectDirectory)\.build + + + + + + + 1.0.0.0 + 1.0.0.0 + 1.0.0.0 + + + + + 1.0.0.0 + $(BUILD_NUMBER) + $(BUILD_NUMBER) + + + + Release + + + + + + + + + + + + + + + + + + + + Configuration=$(BuildConfiguration) + + + + + + + + + + + + \ No newline at end of file diff --git a/BuildProcessTemplates/DefaultTemplate.xaml b/BuildProcessTemplates/DefaultTemplate.xaml new file mode 100644 index 00000000..eae035b2 --- /dev/null +++ b/BuildProcessTemplates/DefaultTemplate.xaml @@ -0,0 +1,602 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Assembly references and imported namespaces serialized as XML namespaces + + + True + + + + + + + + + True + + + + + + + True + + + + + + + + + + + True + + + + + + + + + + + + + + + + + + + + True + + + + + + + + + + + + + + + + + + + + + + + + + + + + True + + + + + + + + + + + + + + + + + + + True + + + + + + + + + + + + True + + + + + + + + + + + + + + True + + + + + + + + + + + + + + + + + + + True + + + + + + + + + + + + + + + + True + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + True + + + + + + + + + + + + + + + + + + + + + + True + + + + + + + + + True + + + + + + + + + + + + + + + True + + + + + + True + + + + + + + + + + + + + + + + + + + + + + + + + True + + + + + + + + + + + + + + + + + + False + + + + + + + + + + True + + + + + + + + + + + + + + + + + + + + + + + + + + True + + + + + + + + + + + + + + + + + + + + + True + + + + + + + + + + + + + + + + + + True + + + + + + + + + + + + + + + True + + + + + + + + + + + + + + + + + + + + + False + + + + + + + + + + True + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + False + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + True + + + + + + + + + + + + + + + + + + + + + + + + + False + + + + + + + + + + + + + + + + + + + + + + + + + + False + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/BuildProcessTemplates/UpgradeTemplate.xaml b/BuildProcessTemplates/UpgradeTemplate.xaml new file mode 100644 index 00000000..4877aa35 --- /dev/null +++ b/BuildProcessTemplates/UpgradeTemplate.xaml @@ -0,0 +1,76 @@ + + + + + + + + + + + + + + + + + + + + [New Microsoft.TeamFoundation.Build.Workflow.Activities.AgentSettings() With {.MaxWaitTime = New System.TimeSpan(4, 0, 0), .MaxExecutionTime = New System.TimeSpan(0, 0, 0), .TagComparison = Microsoft.TeamFoundation.Build.Workflow.Activities.TagComparison.MatchExactly }] + + + + [Microsoft.TeamFoundation.Build.Workflow.Activities.ToolPlatform.Auto] + [False] + [False] + + + + + + + + + + [Microsoft.TeamFoundation.VersionControl.Client.RecursionType.OneLevel] + [Microsoft.TeamFoundation.Build.Workflow.BuildVerbosity.Normal] + + + + All + Assembly references and imported namespaces serialized as XML namespaces + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Lib/MEF/Microsoft.ComponentModel.Composition.Initialization.Desktop.dll b/Lib/MEF/Microsoft.ComponentModel.Composition.Initialization.Desktop.dll new file mode 100644 index 0000000000000000000000000000000000000000..60a974d74505458520ea307dc72e0868b705bcc4 GIT binary patch literal 25600 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°X12&-eJ#J^n~7iqG*TAT@{75GY)O39KE5>-G}OOMu5jJvo%h z;$xQt?z2C0qh|i#&;3Tw{d%xZm& zAkUS^pUFX+W!-sAxD|0=aM3)CrENpoaYnMMKz(b@OGUR)oHykb^H+h~&N$H-hwH$sFBO4&n$i{#cOhv=tQYlk}`yuGjsrvi%ev5pwNHvv!;$Eqv~26PA8?cxKpWBMo{bKJD=sksjR$_@bH?>G4EK^Mhl)7HQOt@*t8? zJ<^2Jlt!e?8>L8@@Rb=+U2BMhji?q0N5Y`#k#JR1mx9d#J5;*VAvQ*qMV5PG5D{|Ej7n`Dlqh6XYS0fL2Ecl+ zme!&EN=RY0N=-`7=R^z?PM}$9a2805tnm{-V`N<^>1akLkc!9})Pf_6kuE=K!oj63 zt^t2310dkWCuH}EO`6b(a&83xMf!x+$H^wPQgfuaJPK`B>*Z)X!%)-%!!||wB7Fwx z?u#@nP`0WLZ`I2qeXO99jPwQ23yly`hL5=#xCjcCMVjYT=pOFXg#_~ot^vO=k5^VO zu1x9jK;b@IO)xb60uwZ4(1i0nksV%GqCw2Di=BXtz;u`)ayhOm8M&OnmBMtT2S<3k z0j2?5=?PG|ze3YddpS;jY31c86ZdL_Bh)a94l`)s>3cXGQ0Yf-KrB!Z2n77qk?AkN zm3-`0bs=!%3Fwj24+6G`J8)M_ zf4dxMmBJ9ve14{}3g1H~bU;PL3Ah>XaCCZUCO)*8^17e8G~_$32{M$t9%aS>|!}kMgKq3SY=GR?N*UX zxvqjok*cMr$U?0&ly53}5tiQ$C*kN)!Cl(Hz0w$Ivm6u5|9gQ9L6n;DAqiCxu>4{!&Zv&e1VsiLVU2448l37ckIa;nH#R^(WQ`uV43^Rmt{`8F ztZR&vxdJ2W&`Jo7tTX(2WCtYpJ$htKgD*;r97oVH6@4&3Rg(FG2uLL|?3CI*(h!1z z?D3L^@vN7ZmvQNQRD#6t%>25jA0xep44SToXBsg&$`RP~$V^iRt$^bprNg4(nPrh> z2CFmE(QeF;U(;$e0d3m`PE>I31jO-}Kte{19i5+$^OJr9FJ+0z| zjNxW>>d4HlAlPSiVLBGx9UC-S={yj+FYWF20n5UlQ^1ptg$+!xK~MOSomcHrSfqs5)(aA*A7vsW)aclD~| z@>MJ2tCq)y*POfDTshQv_PO!SbI)Fxz=>Lo{GIAA&=76Xs4Fk(Z5%coF!_-l-<0Ff zHvbm#H{}C*&86A+IG(KYPwD(Xd$sM%t?u6>X3KpG*Q%>=T~4&Kzo&oU3)_xYY*};R zr`mq&|6%i=C$V0j?(_DHnZtYj-L`xiCGZDM_Tbf=i5-qTe~MkklS4#p2cf+4yM)tG z7n^jqa$tK=EzDpZFl>TEungSuAKi|8@xyS zOYLbUvHO-ls|!8!pW|1n#II)SaI$xu>|5tbnJ)Mr?>dZOgr(7QQH<`{UU_mk>74%p Zf4T(_5b!ZN?LGHT7xiBf{{OSU{{iK=ohkqT literal 0 HcmV?d00001 diff --git a/Lib/MEF/System.ComponentModel.Composition.dll b/Lib/MEF/System.ComponentModel.Composition.dll new file mode 100644 index 0000000000000000000000000000000000000000..bbbae1e105d9e2052af557f4bf7d3264aa1cbdb4 GIT binary patch literal 238080 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

  • DI~J=doDLzRKNq?Hj{#Uo(9X4oK6!LhRWFP#+?Y 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 z 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

    ?Z!P=A>=Wkt^ESn;7vSqAtL8jm9-i~0 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 with .NET 3.5 +http://cid-f8b2fd72406fb218.office.live.com/self.aspx/blog/Composition.Initialization.Desktop.zip \ No newline at end of file diff --git a/Lib/NSpeex/NSpeex.dll b/Lib/NSpeex/NSpeex.dll new file mode 100644 index 0000000000000000000000000000000000000000..5de7848ee8a87d574efecc0dc55f61157e841134 GIT binary patch literal 118272 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 + /// Required designer variable. + /// + private System.ComponentModel.IContainer components = null; + + /// + /// Clean up any resources being used. + /// + /// true if managed resources should be disposed; otherwise, false. + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Windows Form Designer generated code + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + this.linkLabelWebsite = new System.Windows.Forms.LinkLabel(); + this.buttonOK = new System.Windows.Forms.Button(); + this.labelProductName = new System.Windows.Forms.Label(); + this.labelCopyright = new System.Windows.Forms.Label(); + this.linkLabelFeedback = new System.Windows.Forms.LinkLabel(); + this.label3 = new System.Windows.Forms.Label(); + this.labelVersion = new System.Windows.Forms.Label(); + this.SuspendLayout(); + // + // linkLabelWebsite + // + this.linkLabelWebsite.AutoSize = true; + this.linkLabelWebsite.Location = new System.Drawing.Point(13, 67); + this.linkLabelWebsite.Name = "linkLabelWebsite"; + this.linkLabelWebsite.Size = new System.Drawing.Size(168, 13); + this.linkLabelWebsite.TabIndex = 0; + this.linkLabelWebsite.TabStop = true; + this.linkLabelWebsite.Text = "http://www.codeplex.com/naudio"; + this.linkLabelWebsite.LinkClicked += new System.Windows.Forms.LinkLabelLinkClickedEventHandler(this.linkLabelWebsite_LinkClicked); + // + // buttonOK + // + this.buttonOK.Location = new System.Drawing.Point(111, 124); + this.buttonOK.Name = "buttonOK"; + this.buttonOK.Size = new System.Drawing.Size(75, 23); + this.buttonOK.TabIndex = 1; + this.buttonOK.Text = "OK"; + this.buttonOK.UseVisualStyleBackColor = true; + this.buttonOK.Click += new System.EventHandler(this.buttonOK_Click); + // + // labelProductName + // + this.labelProductName.AutoSize = true; + this.labelProductName.Font = new System.Drawing.Font("Microsoft Sans Serif", 9.75F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0))); + this.labelProductName.Location = new System.Drawing.Point(13, 13); + this.labelProductName.Name = "labelProductName"; + this.labelProductName.Size = new System.Drawing.Size(196, 16); + this.labelProductName.TabIndex = 2; + this.labelProductName.Text = "{Application.ProductName}"; + // + // labelCopyright + // + this.labelCopyright.AutoSize = true; + this.labelCopyright.Location = new System.Drawing.Point(13, 51); + this.labelCopyright.Name = "labelCopyright"; + this.labelCopyright.Size = new System.Drawing.Size(149, 13); + this.labelCopyright.TabIndex = 2; + this.labelCopyright.Text = "Copyright © Mark Heath 2007"; + // + // linkLabelFeedback + // + this.linkLabelFeedback.AutoSize = true; + this.linkLabelFeedback.Location = new System.Drawing.Point(13, 101); + this.linkLabelFeedback.Name = "linkLabelFeedback"; + this.linkLabelFeedback.Size = new System.Drawing.Size(150, 13); + this.linkLabelFeedback.TabIndex = 3; + this.linkLabelFeedback.TabStop = true; + this.linkLabelFeedback.Text = "mark.heath@gmail.com"; + this.linkLabelFeedback.LinkClicked += new System.Windows.Forms.LinkLabelLinkClickedEventHandler(this.linkLabelFeedback_LinkClicked); + // + // label3 + // + this.label3.AutoSize = true; + this.label3.Location = new System.Drawing.Point(13, 85); + this.label3.Name = "label3"; + this.label3.Size = new System.Drawing.Size(243, 13); + this.label3.TabIndex = 2; + this.label3.Text = "Send feedback, feature requests and bug fixes to:"; + // + // labelVersion + // + this.labelVersion.AutoSize = true; + this.labelVersion.Location = new System.Drawing.Point(13, 33); + this.labelVersion.Name = "labelVersion"; + this.labelVersion.Size = new System.Drawing.Size(93, 13); + this.labelVersion.TabIndex = 2; + this.labelVersion.Text = "{Version: X.X.X.X}"; + // + // AboutForm + // + this.AcceptButton = this.buttonOK; + this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.ClientSize = new System.Drawing.Size(292, 159); + this.Controls.Add(this.linkLabelFeedback); + this.Controls.Add(this.label3); + this.Controls.Add(this.labelVersion); + this.Controls.Add(this.labelCopyright); + this.Controls.Add(this.labelProductName); + this.Controls.Add(this.buttonOK); + this.Controls.Add(this.linkLabelWebsite); + this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedSingle; + this.MaximizeBox = false; + this.MinimizeBox = false; + this.Name = "AboutForm"; + this.ShowInTaskbar = false; + this.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent; + this.Text = "About {Application.ProductName}"; + this.ResumeLayout(false); + this.PerformLayout(); + + } + + #endregion + + private System.Windows.Forms.LinkLabel linkLabelWebsite; + private System.Windows.Forms.Button buttonOK; + private System.Windows.Forms.Label labelProductName; + private System.Windows.Forms.Label labelCopyright; + private System.Windows.Forms.LinkLabel linkLabelFeedback; + private System.Windows.Forms.Label label3; + private System.Windows.Forms.Label labelVersion; + } +} \ No newline at end of file diff --git a/MidiFileConverter/AboutForm.cs b/MidiFileConverter/AboutForm.cs new file mode 100644 index 00000000..2d5861e0 --- /dev/null +++ b/MidiFileConverter/AboutForm.cs @@ -0,0 +1,71 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Data; +using System.Drawing; +using System.Text; +using System.Windows.Forms; + +namespace NAudio.Utils +{ + /// + /// A standard about form + /// + public partial class AboutForm : Form + { + /// + /// Creates a new about form + /// + public AboutForm() + { + InitializeComponent(); + labelProductName.Text = Application.ProductName; + labelVersion.Text = String.Format("Version: {0}", Application.ProductVersion); + this.Text = String.Format("About {0}", Application.ProductName); + } + + private void linkLabelWebsite_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e) + { + System.Diagnostics.Process.Start(linkLabelWebsite.Text); + } + + private void linkLabelFeedback_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e) + { + System.Diagnostics.Process.Start("mailto:" + linkLabelFeedback.Text); + } + + private void buttonOK_Click(object sender, EventArgs e) + { + this.Close(); + } + + /// + /// The URL of the website to use for help + /// e.g. http://www.codeplex.com/naudio + /// + public string Url + { + get { return linkLabelWebsite.Text; } + set { linkLabelWebsite.Text = value; } + } + + /// + /// The email address for feedback + /// + public string Email + { + get { return linkLabelFeedback.Text; } + set { linkLabelFeedback.Text = value; } + } + + /// + /// The copyright info + /// e.g. Copyright © 2007 Mark Heath + /// + public string Copyright + { + get { return labelCopyright.Text; } + set { labelCopyright.Text = value; } + } + } +} \ No newline at end of file diff --git a/MidiFileConverter/AboutForm.resx b/MidiFileConverter/AboutForm.resx new file mode 100644 index 00000000..ff31a6db --- /dev/null +++ b/MidiFileConverter/AboutForm.resx @@ -0,0 +1,120 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + \ No newline at end of file diff --git a/MidiFileConverter/AdvancedOptionsForm.Designer.cs b/MidiFileConverter/AdvancedOptionsForm.Designer.cs new file mode 100644 index 00000000..7874856f --- /dev/null +++ b/MidiFileConverter/AdvancedOptionsForm.Designer.cs @@ -0,0 +1,169 @@ +namespace MarkHeath.MidiUtils +{ + partial class AdvancedOptionsForm + { + /// + /// Required designer variable. + /// + private System.ComponentModel.IContainer components = null; + + /// + /// Clean up any resources being used. + /// + /// true if managed resources should be disposed; otherwise, false. + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Windows Form Designer generated code + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + this.checkBoxRemoveSequencerSpecific = new System.Windows.Forms.CheckBox(); + this.checkBoxRecreateEndTrack = new System.Windows.Forms.CheckBox(); + this.checkBoxAddNameMarker = new System.Windows.Forms.CheckBox(); + this.checkBoxTrimTextEvents = new System.Windows.Forms.CheckBox(); + this.checkBoxRemoveEmptyTracks = new System.Windows.Forms.CheckBox(); + this.buttonOK = new System.Windows.Forms.Button(); + this.buttonCancel = new System.Windows.Forms.Button(); + this.checkBoxRemoveExtraTempoEvents = new System.Windows.Forms.CheckBox(); + this.checkBoxRemoveExtraMarkers = new System.Windows.Forms.CheckBox(); + this.SuspendLayout(); + // + // checkBoxRemoveSequencerSpecific + // + this.checkBoxRemoveSequencerSpecific.AutoSize = true; + this.checkBoxRemoveSequencerSpecific.Location = new System.Drawing.Point(13, 13); + this.checkBoxRemoveSequencerSpecific.Name = "checkBoxRemoveSequencerSpecific"; + this.checkBoxRemoveSequencerSpecific.Size = new System.Drawing.Size(198, 17); + this.checkBoxRemoveSequencerSpecific.TabIndex = 0; + this.checkBoxRemoveSequencerSpecific.Text = "Remove Sequencer Specific Events"; + this.checkBoxRemoveSequencerSpecific.UseVisualStyleBackColor = true; + // + // checkBoxRecreateEndTrack + // + this.checkBoxRecreateEndTrack.AutoSize = true; + this.checkBoxRecreateEndTrack.Location = new System.Drawing.Point(13, 37); + this.checkBoxRecreateEndTrack.Name = "checkBoxRecreateEndTrack"; + this.checkBoxRecreateEndTrack.Size = new System.Drawing.Size(159, 17); + this.checkBoxRecreateEndTrack.TabIndex = 1; + this.checkBoxRecreateEndTrack.Text = "Recreate End Track Events"; + this.checkBoxRecreateEndTrack.UseVisualStyleBackColor = true; + // + // checkBoxAddNameMarker + // + this.checkBoxAddNameMarker.AutoSize = true; + this.checkBoxAddNameMarker.Location = new System.Drawing.Point(13, 61); + this.checkBoxAddNameMarker.Name = "checkBoxAddNameMarker"; + this.checkBoxAddNameMarker.Size = new System.Drawing.Size(112, 17); + this.checkBoxAddNameMarker.TabIndex = 2; + this.checkBoxAddNameMarker.Text = "Add Name Marker"; + this.checkBoxAddNameMarker.UseVisualStyleBackColor = true; + // + // checkBoxTrimTextEvents + // + this.checkBoxTrimTextEvents.AutoSize = true; + this.checkBoxTrimTextEvents.Location = new System.Drawing.Point(13, 85); + this.checkBoxTrimTextEvents.Name = "checkBoxTrimTextEvents"; + this.checkBoxTrimTextEvents.Size = new System.Drawing.Size(106, 17); + this.checkBoxTrimTextEvents.TabIndex = 3; + this.checkBoxTrimTextEvents.Text = "Trim Text Events"; + this.checkBoxTrimTextEvents.UseVisualStyleBackColor = true; + // + // checkBoxRemoveEmptyTracks + // + this.checkBoxRemoveEmptyTracks.AutoSize = true; + this.checkBoxRemoveEmptyTracks.Location = new System.Drawing.Point(13, 109); + this.checkBoxRemoveEmptyTracks.Name = "checkBoxRemoveEmptyTracks"; + this.checkBoxRemoveEmptyTracks.Size = new System.Drawing.Size(134, 17); + this.checkBoxRemoveEmptyTracks.TabIndex = 4; + this.checkBoxRemoveEmptyTracks.Text = "Remove Empty Tracks"; + this.checkBoxRemoveEmptyTracks.UseVisualStyleBackColor = true; + // + // buttonOK + // + this.buttonOK.Location = new System.Drawing.Point(60, 182); + this.buttonOK.Name = "buttonOK"; + this.buttonOK.Size = new System.Drawing.Size(75, 23); + this.buttonOK.TabIndex = 5; + this.buttonOK.Text = "OK"; + this.buttonOK.UseVisualStyleBackColor = true; + this.buttonOK.Click += new System.EventHandler(this.buttonOK_Click); + // + // buttonCancel + // + this.buttonCancel.DialogResult = System.Windows.Forms.DialogResult.Cancel; + this.buttonCancel.Location = new System.Drawing.Point(141, 182); + this.buttonCancel.Name = "buttonCancel"; + this.buttonCancel.Size = new System.Drawing.Size(75, 23); + this.buttonCancel.TabIndex = 6; + this.buttonCancel.Text = "Cancel"; + this.buttonCancel.UseVisualStyleBackColor = true; + // + // checkBoxRemoveExtraTempoEvents + // + this.checkBoxRemoveExtraTempoEvents.AutoSize = true; + this.checkBoxRemoveExtraTempoEvents.Location = new System.Drawing.Point(13, 132); + this.checkBoxRemoveExtraTempoEvents.Name = "checkBoxRemoveExtraTempoEvents"; + this.checkBoxRemoveExtraTempoEvents.Size = new System.Drawing.Size(165, 17); + this.checkBoxRemoveExtraTempoEvents.TabIndex = 4; + this.checkBoxRemoveExtraTempoEvents.Text = "Remove Extra Tempo Events"; + this.checkBoxRemoveExtraTempoEvents.UseVisualStyleBackColor = true; + // + // checkBoxRemoveExtraMarkers + // + this.checkBoxRemoveExtraMarkers.AutoSize = true; + this.checkBoxRemoveExtraMarkers.Location = new System.Drawing.Point(13, 155); + this.checkBoxRemoveExtraMarkers.Name = "checkBoxRemoveExtraMarkers"; + this.checkBoxRemoveExtraMarkers.Size = new System.Drawing.Size(134, 17); + this.checkBoxRemoveExtraMarkers.TabIndex = 4; + this.checkBoxRemoveExtraMarkers.Text = "Remove Extra Markers"; + this.checkBoxRemoveExtraMarkers.UseVisualStyleBackColor = true; + // + // AdvancedOptionsForm + // + this.AcceptButton = this.buttonOK; + this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.CancelButton = this.buttonCancel; + this.ClientSize = new System.Drawing.Size(227, 217); + this.Controls.Add(this.buttonCancel); + this.Controls.Add(this.buttonOK); + this.Controls.Add(this.checkBoxRemoveExtraMarkers); + this.Controls.Add(this.checkBoxRemoveExtraTempoEvents); + this.Controls.Add(this.checkBoxRemoveEmptyTracks); + this.Controls.Add(this.checkBoxTrimTextEvents); + this.Controls.Add(this.checkBoxAddNameMarker); + this.Controls.Add(this.checkBoxRecreateEndTrack); + this.Controls.Add(this.checkBoxRemoveSequencerSpecific); + this.MinimumSize = new System.Drawing.Size(235, 210); + this.Name = "AdvancedOptionsForm"; + this.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent; + this.Text = "Advanced Options"; + this.ResumeLayout(false); + this.PerformLayout(); + + } + + #endregion + + private System.Windows.Forms.CheckBox checkBoxRemoveSequencerSpecific; + private System.Windows.Forms.CheckBox checkBoxRecreateEndTrack; + private System.Windows.Forms.CheckBox checkBoxAddNameMarker; + private System.Windows.Forms.CheckBox checkBoxTrimTextEvents; + private System.Windows.Forms.CheckBox checkBoxRemoveEmptyTracks; + private System.Windows.Forms.Button buttonOK; + private System.Windows.Forms.Button buttonCancel; + private System.Windows.Forms.CheckBox checkBoxRemoveExtraTempoEvents; + private System.Windows.Forms.CheckBox checkBoxRemoveExtraMarkers; + } +} \ No newline at end of file diff --git a/MidiFileConverter/AdvancedOptionsForm.cs b/MidiFileConverter/AdvancedOptionsForm.cs new file mode 100644 index 00000000..cb6db858 --- /dev/null +++ b/MidiFileConverter/AdvancedOptionsForm.cs @@ -0,0 +1,45 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Data; +using System.Drawing; +using System.Text; +using System.Windows.Forms; + +namespace MarkHeath.MidiUtils +{ + public partial class AdvancedOptionsForm : Form + { + private Properties.Settings settings; + public AdvancedOptionsForm() + { + InitializeComponent(); + settings = Properties.Settings.Default; + LoadSettings(); + } + + private void LoadSettings() + { + checkBoxAddNameMarker.Checked = settings.AddNameMarker; + checkBoxRecreateEndTrack.Checked = settings.RecreateEndTrackMarkers; + checkBoxRemoveEmptyTracks.Checked = settings.RemoveEmptyTracks; + checkBoxRemoveSequencerSpecific.Checked = settings.RemoveSequencerSpecific; + checkBoxTrimTextEvents.Checked = settings.TrimTextEvents; + checkBoxRemoveExtraTempoEvents.Checked = settings.RemoveExtraTempoEvents; + checkBoxRemoveExtraMarkers.Checked = settings.RemoveExtraMarkers; + } + + private void buttonOK_Click(object sender, EventArgs e) + { + settings.AddNameMarker = checkBoxAddNameMarker.Checked; + settings.RecreateEndTrackMarkers = checkBoxRecreateEndTrack.Checked; + settings.RemoveEmptyTracks =checkBoxRemoveEmptyTracks.Checked; + settings.RemoveSequencerSpecific = checkBoxRemoveSequencerSpecific.Checked; + settings.TrimTextEvents = checkBoxTrimTextEvents.Checked; + settings.RemoveExtraTempoEvents = checkBoxRemoveExtraTempoEvents.Checked; + settings.RemoveExtraMarkers = checkBoxRemoveExtraMarkers.Checked; + settings.Save(); + this.Close(); + } + } +} \ No newline at end of file diff --git a/MidiFileConverter/AdvancedOptionsForm.resx b/MidiFileConverter/AdvancedOptionsForm.resx new file mode 100644 index 00000000..ff31a6db --- /dev/null +++ b/MidiFileConverter/AdvancedOptionsForm.resx @@ -0,0 +1,120 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + \ No newline at end of file diff --git a/MidiFileConverter/InstallScript.nsi b/MidiFileConverter/InstallScript.nsi new file mode 100644 index 00000000..bd86a437 --- /dev/null +++ b/MidiFileConverter/InstallScript.nsi @@ -0,0 +1,153 @@ +; MIDI File Converter install script +; originally based on example2 that comes with nsis +; +; This script is based on example1.nsi, but it remember the directory, +; has uninstall support and (optionally) installs start menu shortcuts. +; +; It will install example2.nsi into a directory that the user selects, + +;-------------------------------- +!include WordFunc.nsh +!insertmacro VersionCompare + +!include LogicLib.nsh +RequestExecutionLevel highest +!define VERSION "0.3" +!define FULLVERSION "0.3.9.0" +!define PRODUCT_NAME "MIDI File Converter" +!define EXECUTABLE_NAME "MIDI File Converter.exe" + +; The name of the installer +Name "MIDI File Converter" + +; The file to write +; OutFile "${PRODUCT_NAME} v${VERSION} Install.exe" +OutFile "midi_file_converter_0_3_install.exe" + +; The default installation directory +InstallDir "$PROGRAMFILES\Mark Heath\${PRODUCT_NAME}" + +; Registry key to check for directory (so if you install again, it will +; overwrite the old one automatically) +InstallDirRegKey HKLM "Software\${PRODUCT_NAME}" "Install_Dir" + +VIAddVersionKey /LANG=1033-English "ProductName" "${PRODUCT_NAME}" +VIAddVersionKey /LANG=1033-English "Comments" "" +VIAddVersionKey /LANG=1033-English "CompanyName" "Mark Heath" +VIAddVersionKey /LANG=1033-English "LegalCopyright" "© 2007 Mark Heath" +VIAddVersionKey /LANG=1033-English "FileDescription" "${PRODUCT_NAME} Installer" +VIAddVersionKey /LANG=1033-English "FileVersion" "${VERSION}" +VIProductVersion "${FULLVERSION}" + + + +;-------------------------------- + +; Utils + +Function .onInit + Call GetDotNETVersion + Pop $0 + ${If} $0 == "not found" + MessageBox MB_OK|MB_ICONSTOP ".NET runtime library v2.0 or newer is required." + ExecShell "open" "http://msdn.microsoft.com/netframework/downloads/updates/default.aspx" + Abort + ${EndIf} + + StrCpy $0 $0 "" 1 # skip "v" + + ${VersionCompare} $0 "2.0" $1 + ${If} $1 == 2 + MessageBox MB_OK|MB_ICONSTOP ".NET runtime library v2.0 or newer is required. You have $0." + ExecShell "open" "http://msdn.microsoft.com/netframework/downloads/updates/default.aspx" + Abort + ${EndIf} +FunctionEnd + +Function GetDotNETVersion + Push $0 + Push $1 + + System::Call "mscoree::GetCORVersion(w .r0, i ${NSIS_MAX_STRLEN}, *i) i .r1" + StrCmp $1 "error" 0 +2 + StrCpy $0 "not found" + + Pop $1 + Exch $0 +FunctionEnd + +;-------------------------------- + +; Pages + +Page components +Page directory +Page instfiles + +UninstPage uninstConfirm +UninstPage instfiles + +;-------------------------------- + +; The stuff to install +Section "Program Files (required)" + + SectionIn RO + + ; Set output path to the installation directory. + SetOutPath $INSTDIR + + ; Put file there + File "MIDI File Converter.exe" + File "MIDI File Converter.exe.config" + File "NAudio.dll" + File "midi_file_converter.html" + File "NamingRules.xml" + + ; Write the installation path into the registry + WriteRegStr HKLM "SOFTWARE\${PRODUCT_NAME}" "Install_Dir" "$INSTDIR" + + ; Write the uninstall keys for Windows + WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${PRODUCT_NAME}" "DisplayName" "${PRODUCT_NAME}" + WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${PRODUCT_NAME}" "UninstallString" '"$INSTDIR\uninstall.exe"' + WriteRegDWORD HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${PRODUCT_NAME}" "NoModify" 1 + WriteRegDWORD HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${PRODUCT_NAME}" "NoRepair" 1 + WriteUninstaller "uninstall.exe" + +SectionEnd + +; Optional section (can be disabled by the user) +Section "Start Menu Shortcuts" + + CreateDirectory "$SMPROGRAMS\${PRODUCT_NAME}" + CreateShortCut "$SMPROGRAMS\${PRODUCT_NAME}\Uninstall.lnk" "$INSTDIR\uninstall.exe" "" "$INSTDIR\uninstall.exe" 0 + CreateShortCut "$SMPROGRAMS\${PRODUCT_NAME}\${PRODUCT_NAME}.lnk" "$INSTDIR\${EXECUTABLE_NAME}" "" "$INSTDIR\${EXECUTABLE_NAME}" 0 + +SectionEnd + +;-------------------------------- + +; Uninstaller + +Section "Uninstall" + + ; Remove registry keys + DeleteRegKey HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${PRODUCT_NAME}" + DeleteRegKey HKLM "SOFTWARE\${PRODUCT_NAME}" + + ; Remove files and uninstaller + Delete "$INSTDIR\uninstall.exe" + Delete "$INSTDIR\MIDI File Converter.exe" + Delete "$INSTDIR\MIDI File Converter.exe.config" + Delete "$INSTDIR\NAudio.dll" + Delete "$INSTDIR\midi_file_converter.html" + Delete "$INSTDIR\NamingRules.xml" + + ; Remove shortcuts, if any + Delete "$SMPROGRAMS\${PRODUCT_NAME}\*.*" + + ; Remove directories used + RMDir "$SMPROGRAMS\${PRODUCT_NAME}" + RMDir "$INSTDIR" + +SectionEnd diff --git a/MidiFileConverter/MainForm.Designer.cs b/MidiFileConverter/MainForm.Designer.cs new file mode 100644 index 00000000..17bd0aa0 --- /dev/null +++ b/MidiFileConverter/MainForm.Designer.cs @@ -0,0 +1,449 @@ +namespace MarkHeath.MidiUtils +{ + partial class MainForm + { + /// + /// Required designer variable. + /// + private System.ComponentModel.IContainer components = null; + + /// + /// Clean up any resources being used. + /// + /// true if managed resources should be disposed; otherwise, false. + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Windows Form Designer generated code + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + this.label1 = new System.Windows.Forms.Label(); + this.label2 = new System.Windows.Forms.Label(); + this.textBoxInputFolder = new System.Windows.Forms.TextBox(); + this.textBoxOutputFolder = new System.Windows.Forms.TextBox(); + this.buttonBrowseEZDrummer = new System.Windows.Forms.Button(); + this.buttonBrowseOutputFolder = new System.Windows.Forms.Button(); + this.buttonConvert = new System.Windows.Forms.Button(); + this.label3 = new System.Windows.Forms.Label(); + this.checkBoxVerbose = new System.Windows.Forms.CheckBox(); + this.menuStrip1 = new System.Windows.Forms.MenuStrip(); + this.fileToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.exitToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.toolsToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.optionsToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.clearLogToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.saveLogToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.helpToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.contentsToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.aboutToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.groupBox1 = new System.Windows.Forms.GroupBox(); + this.radioButtonType1 = new System.Windows.Forms.RadioButton(); + this.radioButtonTypeUnchanged = new System.Windows.Forms.RadioButton(); + this.radioButtonType0 = new System.Windows.Forms.RadioButton(); + this.groupBox2 = new System.Windows.Forms.GroupBox(); + this.radioButtonChannel10 = new System.Windows.Forms.RadioButton(); + this.radioButtonChannelUnchanged = new System.Windows.Forms.RadioButton(); + this.radioButtonChannel1 = new System.Windows.Forms.RadioButton(); + this.groupBox4 = new System.Windows.Forms.GroupBox(); + this.checkBoxUseFilename = new System.Windows.Forms.CheckBox(); + this.checkBoxApplyNamingRules = new System.Windows.Forms.CheckBox(); + this.progressLog1 = new NAudio.Utils.ProgressLog(); + this.menuStrip1.SuspendLayout(); + this.groupBox1.SuspendLayout(); + this.groupBox2.SuspendLayout(); + this.groupBox4.SuspendLayout(); + this.SuspendLayout(); + // + // label1 + // + this.label1.AutoSize = true; + this.label1.Location = new System.Drawing.Point(12, 34); + this.label1.Name = "label1"; + this.label1.Size = new System.Drawing.Size(66, 13); + this.label1.TabIndex = 0; + this.label1.Text = "Input Folder:"; + // + // label2 + // + this.label2.AutoSize = true; + this.label2.Location = new System.Drawing.Point(12, 64); + this.label2.Name = "label2"; + this.label2.Size = new System.Drawing.Size(74, 13); + this.label2.TabIndex = 3; + this.label2.Text = "Output Folder:"; + // + // textBoxInputFolder + // + this.textBoxInputFolder.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) + | System.Windows.Forms.AnchorStyles.Right))); + this.textBoxInputFolder.Location = new System.Drawing.Point(144, 31); + this.textBoxInputFolder.Name = "textBoxInputFolder"; + this.textBoxInputFolder.ReadOnly = true; + this.textBoxInputFolder.Size = new System.Drawing.Size(310, 20); + this.textBoxInputFolder.TabIndex = 1; + // + // textBoxOutputFolder + // + this.textBoxOutputFolder.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) + | System.Windows.Forms.AnchorStyles.Right))); + this.textBoxOutputFolder.Location = new System.Drawing.Point(144, 61); + this.textBoxOutputFolder.Name = "textBoxOutputFolder"; + this.textBoxOutputFolder.ReadOnly = true; + this.textBoxOutputFolder.Size = new System.Drawing.Size(310, 20); + this.textBoxOutputFolder.TabIndex = 4; + // + // buttonBrowseEZDrummer + // + this.buttonBrowseEZDrummer.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right))); + this.buttonBrowseEZDrummer.Location = new System.Drawing.Point(460, 29); + this.buttonBrowseEZDrummer.Name = "buttonBrowseEZDrummer"; + this.buttonBrowseEZDrummer.Size = new System.Drawing.Size(75, 23); + this.buttonBrowseEZDrummer.TabIndex = 2; + this.buttonBrowseEZDrummer.Text = "Browse..."; + this.buttonBrowseEZDrummer.UseVisualStyleBackColor = true; + this.buttonBrowseEZDrummer.Click += new System.EventHandler(this.buttonBrowseEZDrummer_Click); + // + // buttonBrowseOutputFolder + // + this.buttonBrowseOutputFolder.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right))); + this.buttonBrowseOutputFolder.Location = new System.Drawing.Point(460, 59); + this.buttonBrowseOutputFolder.Name = "buttonBrowseOutputFolder"; + this.buttonBrowseOutputFolder.Size = new System.Drawing.Size(75, 23); + this.buttonBrowseOutputFolder.TabIndex = 5; + this.buttonBrowseOutputFolder.Text = "Browse..."; + this.buttonBrowseOutputFolder.UseVisualStyleBackColor = true; + this.buttonBrowseOutputFolder.Click += new System.EventHandler(this.buttonBrowseOutputFolder_Click); + // + // buttonConvert + // + this.buttonConvert.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right))); + this.buttonConvert.Location = new System.Drawing.Point(460, 204); + this.buttonConvert.Name = "buttonConvert"; + this.buttonConvert.Size = new System.Drawing.Size(75, 23); + this.buttonConvert.TabIndex = 11; + this.buttonConvert.Text = "Convert"; + this.buttonConvert.UseVisualStyleBackColor = true; + this.buttonConvert.Click += new System.EventHandler(this.buttonConvert_Click); + // + // label3 + // + this.label3.AutoSize = true; + this.label3.Location = new System.Drawing.Point(12, 209); + this.label3.Name = "label3"; + this.label3.Size = new System.Drawing.Size(319, 13); + this.label3.TabIndex = 9; + this.label3.Text = "When you have verified the above settings, click Convert to begin"; + // + // checkBoxVerbose + // + this.checkBoxVerbose.AutoSize = true; + this.checkBoxVerbose.Checked = true; + this.checkBoxVerbose.CheckState = System.Windows.Forms.CheckState.Checked; + this.checkBoxVerbose.Location = new System.Drawing.Point(351, 208); + this.checkBoxVerbose.Name = "checkBoxVerbose"; + this.checkBoxVerbose.Size = new System.Drawing.Size(100, 17); + this.checkBoxVerbose.TabIndex = 10; + this.checkBoxVerbose.Text = "Verbose Output"; + this.checkBoxVerbose.UseVisualStyleBackColor = true; + // + // menuStrip1 + // + this.menuStrip1.Items.AddRange(new System.Windows.Forms.ToolStripItem[] { + this.fileToolStripMenuItem, + this.toolsToolStripMenuItem, + this.helpToolStripMenuItem}); + this.menuStrip1.Location = new System.Drawing.Point(0, 0); + this.menuStrip1.Name = "menuStrip1"; + this.menuStrip1.Size = new System.Drawing.Size(551, 24); + this.menuStrip1.TabIndex = 10; + this.menuStrip1.Text = "menuStrip1"; + // + // fileToolStripMenuItem + // + this.fileToolStripMenuItem.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] { + this.exitToolStripMenuItem}); + this.fileToolStripMenuItem.Name = "fileToolStripMenuItem"; + this.fileToolStripMenuItem.Size = new System.Drawing.Size(35, 20); + this.fileToolStripMenuItem.Text = "&File"; + // + // exitToolStripMenuItem + // + this.exitToolStripMenuItem.Name = "exitToolStripMenuItem"; + this.exitToolStripMenuItem.Size = new System.Drawing.Size(103, 22); + this.exitToolStripMenuItem.Text = "E&xit"; + this.exitToolStripMenuItem.Click += new System.EventHandler(this.exitToolStripMenuItem_Click); + // + // toolsToolStripMenuItem + // + this.toolsToolStripMenuItem.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] { + this.optionsToolStripMenuItem, + this.clearLogToolStripMenuItem, + this.saveLogToolStripMenuItem}); + this.toolsToolStripMenuItem.Name = "toolsToolStripMenuItem"; + this.toolsToolStripMenuItem.Size = new System.Drawing.Size(44, 20); + this.toolsToolStripMenuItem.Text = "&Tools"; + // + // optionsToolStripMenuItem + // + this.optionsToolStripMenuItem.Name = "optionsToolStripMenuItem"; + this.optionsToolStripMenuItem.Size = new System.Drawing.Size(185, 22); + this.optionsToolStripMenuItem.Text = "Advanced &Options..."; + this.optionsToolStripMenuItem.Click += new System.EventHandler(this.optionsToolStripMenuItem_Click); + // + // clearLogToolStripMenuItem + // + this.clearLogToolStripMenuItem.Name = "clearLogToolStripMenuItem"; + this.clearLogToolStripMenuItem.Size = new System.Drawing.Size(185, 22); + this.clearLogToolStripMenuItem.Text = "&Clear Log"; + this.clearLogToolStripMenuItem.Click += new System.EventHandler(this.clearLogToolStripMenuItem_Click); + // + // saveLogToolStripMenuItem + // + this.saveLogToolStripMenuItem.Enabled = false; + this.saveLogToolStripMenuItem.Name = "saveLogToolStripMenuItem"; + this.saveLogToolStripMenuItem.Size = new System.Drawing.Size(185, 22); + this.saveLogToolStripMenuItem.Text = "&Save Log..."; + this.saveLogToolStripMenuItem.Click += new System.EventHandler(this.saveLogToolStripMenuItem_Click); + // + // helpToolStripMenuItem + // + this.helpToolStripMenuItem.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] { + this.contentsToolStripMenuItem, + this.aboutToolStripMenuItem}); + this.helpToolStripMenuItem.Name = "helpToolStripMenuItem"; + this.helpToolStripMenuItem.Size = new System.Drawing.Size(40, 20); + this.helpToolStripMenuItem.Text = "&Help"; + // + // contentsToolStripMenuItem + // + this.contentsToolStripMenuItem.Name = "contentsToolStripMenuItem"; + this.contentsToolStripMenuItem.Size = new System.Drawing.Size(152, 22); + this.contentsToolStripMenuItem.Text = "&Contents"; + this.contentsToolStripMenuItem.Click += new System.EventHandler(this.contentsToolStripMenuItem_Click); + // + // aboutToolStripMenuItem + // + this.aboutToolStripMenuItem.Name = "aboutToolStripMenuItem"; + this.aboutToolStripMenuItem.Size = new System.Drawing.Size(152, 22); + this.aboutToolStripMenuItem.Text = "&About"; + this.aboutToolStripMenuItem.Click += new System.EventHandler(this.aboutToolStripMenuItem_Click); + // + // groupBox1 + // + this.groupBox1.Controls.Add(this.radioButtonType1); + this.groupBox1.Controls.Add(this.radioButtonTypeUnchanged); + this.groupBox1.Controls.Add(this.radioButtonType0); + this.groupBox1.Location = new System.Drawing.Point(337, 96); + this.groupBox1.Name = "groupBox1"; + this.groupBox1.Size = new System.Drawing.Size(148, 100); + this.groupBox1.TabIndex = 8; + this.groupBox1.TabStop = false; + this.groupBox1.Text = "Output File Type"; + // + // radioButtonType1 + // + this.radioButtonType1.AutoSize = true; + this.radioButtonType1.Checked = true; + this.radioButtonType1.Location = new System.Drawing.Point(6, 65); + this.radioButtonType1.Name = "radioButtonType1"; + this.radioButtonType1.Size = new System.Drawing.Size(84, 17); + this.radioButtonType1.TabIndex = 2; + this.radioButtonType1.TabStop = true; + this.radioButtonType1.Text = "MIDI Type 1"; + this.radioButtonType1.UseVisualStyleBackColor = true; + // + // radioButtonTypeUnchanged + // + this.radioButtonTypeUnchanged.AutoSize = true; + this.radioButtonTypeUnchanged.Location = new System.Drawing.Point(6, 19); + this.radioButtonTypeUnchanged.Name = "radioButtonTypeUnchanged"; + this.radioButtonTypeUnchanged.Size = new System.Drawing.Size(114, 17); + this.radioButtonTypeUnchanged.TabIndex = 0; + this.radioButtonTypeUnchanged.Text = "Leave Unchanged"; + this.radioButtonTypeUnchanged.UseVisualStyleBackColor = true; + // + // radioButtonType0 + // + this.radioButtonType0.AutoSize = true; + this.radioButtonType0.Location = new System.Drawing.Point(6, 42); + this.radioButtonType0.Name = "radioButtonType0"; + this.radioButtonType0.Size = new System.Drawing.Size(84, 17); + this.radioButtonType0.TabIndex = 1; + this.radioButtonType0.Text = "MIDI Type 0"; + this.radioButtonType0.UseVisualStyleBackColor = true; + // + // groupBox2 + // + this.groupBox2.Controls.Add(this.radioButtonChannel10); + this.groupBox2.Controls.Add(this.radioButtonChannelUnchanged); + this.groupBox2.Controls.Add(this.radioButtonChannel1); + this.groupBox2.Location = new System.Drawing.Point(187, 96); + this.groupBox2.Name = "groupBox2"; + this.groupBox2.Size = new System.Drawing.Size(144, 100); + this.groupBox2.TabIndex = 7; + this.groupBox2.TabStop = false; + this.groupBox2.Text = "MIDI Note Channel"; + // + // radioButtonChannel10 + // + this.radioButtonChannel10.AutoSize = true; + this.radioButtonChannel10.Location = new System.Drawing.Point(6, 65); + this.radioButtonChannel10.Name = "radioButtonChannel10"; + this.radioButtonChannel10.Size = new System.Drawing.Size(134, 17); + this.radioButtonChannel10.TabIndex = 5; + this.radioButtonChannel10.Text = "Force all to Channel 10"; + this.radioButtonChannel10.UseVisualStyleBackColor = true; + // + // radioButtonChannelUnchanged + // + this.radioButtonChannelUnchanged.AutoSize = true; + this.radioButtonChannelUnchanged.Checked = true; + this.radioButtonChannelUnchanged.Location = new System.Drawing.Point(6, 19); + this.radioButtonChannelUnchanged.Name = "radioButtonChannelUnchanged"; + this.radioButtonChannelUnchanged.Size = new System.Drawing.Size(114, 17); + this.radioButtonChannelUnchanged.TabIndex = 3; + this.radioButtonChannelUnchanged.TabStop = true; + this.radioButtonChannelUnchanged.Text = "Leave Unchanged"; + this.radioButtonChannelUnchanged.UseVisualStyleBackColor = true; + // + // radioButtonChannel1 + // + this.radioButtonChannel1.AutoSize = true; + this.radioButtonChannel1.Location = new System.Drawing.Point(6, 42); + this.radioButtonChannel1.Name = "radioButtonChannel1"; + this.radioButtonChannel1.Size = new System.Drawing.Size(128, 17); + this.radioButtonChannel1.TabIndex = 4; + this.radioButtonChannel1.Text = "Force all to Channel 1"; + this.radioButtonChannel1.UseVisualStyleBackColor = true; + // + // groupBox4 + // + this.groupBox4.Controls.Add(this.checkBoxUseFilename); + this.groupBox4.Controls.Add(this.checkBoxApplyNamingRules); + this.groupBox4.Location = new System.Drawing.Point(15, 96); + this.groupBox4.Name = "groupBox4"; + this.groupBox4.Size = new System.Drawing.Size(163, 100); + this.groupBox4.TabIndex = 6; + this.groupBox4.TabStop = false; + this.groupBox4.Text = "Clip Naming"; + // + // checkBoxUseFilename + // + this.checkBoxUseFilename.AutoSize = true; + this.checkBoxUseFilename.Checked = true; + this.checkBoxUseFilename.CheckState = System.Windows.Forms.CheckState.Checked; + this.checkBoxUseFilename.Location = new System.Drawing.Point(6, 55); + this.checkBoxUseFilename.Name = "checkBoxUseFilename"; + this.checkBoxUseFilename.Size = new System.Drawing.Size(117, 30); + this.checkBoxUseFilename.TabIndex = 2; + this.checkBoxUseFilename.Text = "Use filename for\r\nother MIDI patterns"; + this.checkBoxUseFilename.UseVisualStyleBackColor = true; + // + // checkBoxApplyNamingRules + // + this.checkBoxApplyNamingRules.AutoSize = true; + this.checkBoxApplyNamingRules.Checked = true; + this.checkBoxApplyNamingRules.CheckState = System.Windows.Forms.CheckState.Checked; + this.checkBoxApplyNamingRules.Location = new System.Drawing.Point(6, 19); + this.checkBoxApplyNamingRules.Name = "checkBoxApplyNamingRules"; + this.checkBoxApplyNamingRules.Size = new System.Drawing.Size(153, 30); + this.checkBoxApplyNamingRules.TabIndex = 1; + this.checkBoxApplyNamingRules.Text = "Apply XML naming rules\r\nto Toontrack EZD patterns"; + this.checkBoxApplyNamingRules.UseVisualStyleBackColor = true; + // + // progressLog1 + // + this.progressLog1.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) + | System.Windows.Forms.AnchorStyles.Left) + | System.Windows.Forms.AnchorStyles.Right))); + this.progressLog1.BackColor = System.Drawing.SystemColors.InactiveCaption; + this.progressLog1.Location = new System.Drawing.Point(15, 234); + this.progressLog1.Name = "progressLog1"; + this.progressLog1.Padding = new System.Windows.Forms.Padding(1); + this.progressLog1.Size = new System.Drawing.Size(520, 161); + this.progressLog1.TabIndex = 12; + // + // MainForm + // + this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.ClientSize = new System.Drawing.Size(551, 407); + this.Controls.Add(this.progressLog1); + this.Controls.Add(this.groupBox4); + this.Controls.Add(this.groupBox2); + this.Controls.Add(this.groupBox1); + this.Controls.Add(this.checkBoxVerbose); + this.Controls.Add(this.label3); + this.Controls.Add(this.buttonConvert); + this.Controls.Add(this.buttonBrowseOutputFolder); + this.Controls.Add(this.buttonBrowseEZDrummer); + this.Controls.Add(this.textBoxOutputFolder); + this.Controls.Add(this.textBoxInputFolder); + this.Controls.Add(this.label2); + this.Controls.Add(this.label1); + this.Controls.Add(this.menuStrip1); + this.MainMenuStrip = this.menuStrip1; + this.MinimumSize = new System.Drawing.Size(559, 441); + this.Name = "MainForm"; + this.Text = "MIDI File Converter"; + this.Load += new System.EventHandler(this.MainForm_Load); + this.menuStrip1.ResumeLayout(false); + this.menuStrip1.PerformLayout(); + this.groupBox1.ResumeLayout(false); + this.groupBox1.PerformLayout(); + this.groupBox2.ResumeLayout(false); + this.groupBox2.PerformLayout(); + this.groupBox4.ResumeLayout(false); + this.groupBox4.PerformLayout(); + this.ResumeLayout(false); + this.PerformLayout(); + + } + + #endregion + + private System.Windows.Forms.Label label1; + private System.Windows.Forms.Label label2; + private System.Windows.Forms.TextBox textBoxInputFolder; + private System.Windows.Forms.TextBox textBoxOutputFolder; + private System.Windows.Forms.Button buttonBrowseEZDrummer; + private System.Windows.Forms.Button buttonBrowseOutputFolder; + private System.Windows.Forms.Button buttonConvert; + private System.Windows.Forms.Label label3; + private System.Windows.Forms.CheckBox checkBoxVerbose; + private System.Windows.Forms.MenuStrip menuStrip1; + private System.Windows.Forms.ToolStripMenuItem fileToolStripMenuItem; + private System.Windows.Forms.ToolStripMenuItem exitToolStripMenuItem; + private System.Windows.Forms.ToolStripMenuItem helpToolStripMenuItem; + private System.Windows.Forms.ToolStripMenuItem contentsToolStripMenuItem; + private System.Windows.Forms.ToolStripMenuItem aboutToolStripMenuItem; + private System.Windows.Forms.GroupBox groupBox1; + private System.Windows.Forms.RadioButton radioButtonType1; + private System.Windows.Forms.RadioButton radioButtonTypeUnchanged; + private System.Windows.Forms.RadioButton radioButtonType0; + private System.Windows.Forms.GroupBox groupBox2; + private System.Windows.Forms.RadioButton radioButtonChannel10; + private System.Windows.Forms.RadioButton radioButtonChannelUnchanged; + private System.Windows.Forms.RadioButton radioButtonChannel1; + private System.Windows.Forms.GroupBox groupBox4; + private System.Windows.Forms.CheckBox checkBoxUseFilename; + private System.Windows.Forms.CheckBox checkBoxApplyNamingRules; + private NAudio.Utils.ProgressLog progressLog1; + private System.Windows.Forms.ToolStripMenuItem toolsToolStripMenuItem; + private System.Windows.Forms.ToolStripMenuItem optionsToolStripMenuItem; + private System.Windows.Forms.ToolStripMenuItem clearLogToolStripMenuItem; + private System.Windows.Forms.ToolStripMenuItem saveLogToolStripMenuItem; + } +} + diff --git a/MidiFileConverter/MainForm.cs b/MidiFileConverter/MainForm.cs new file mode 100644 index 00000000..089af592 --- /dev/null +++ b/MidiFileConverter/MainForm.cs @@ -0,0 +1,376 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Data; +using System.Drawing; +using System.Text; +using System.Windows.Forms; +using System.IO; +using System.Threading; +using System.Xml; +using System.Configuration; +using MarkHeath.MidiUtils.Properties; +using NAudio.Utils; + +namespace MarkHeath.MidiUtils +{ + public partial class MainForm : Form + { + bool workQueued; + NamingRules namingRules; + MidiConverter midiConverter; + + Properties.Settings settings; + + public MainForm() + { + InitializeComponent(); + + settings = Properties.Settings.Default; + + if (Settings.Default.FirstTime) + { + UpgradeSettings(); + } + + // could look in HKLM \ Software \ Toontrack \ Superior \ EZDrummer \ HomePath + LoadSettings(); + } + + private void UpgradeSettings() + { + string productVersion = (string)settings.GetPreviousVersion("ProductVersion"); + if ((productVersion != null) && (productVersion.Length > 0)) + { + settings.InputFolder = (string)settings.GetPreviousVersion("InputFolder"); + settings.OutputFolder = (string)settings.GetPreviousVersion("OutputFolder"); + settings.OutputChannelNumber = (int)settings.GetPreviousVersion("OutputChannelNumber"); + settings.OutputMidiType = (OutputMidiType)settings.GetPreviousVersion("OutputMidiType"); + settings.VerboseOutput = (bool)settings.GetPreviousVersion("VerboseOutput"); + settings.UseFileName = (bool)settings.GetPreviousVersion("UseFileName"); + try + { + settings.AddNameMarker = (bool)settings.GetPreviousVersion("AddNameMarker"); + settings.TrimTextEvents = (bool)settings.GetPreviousVersion("TrimTextEvents"); + settings.RemoveEmptyTracks = (bool)settings.GetPreviousVersion("RemoveEmptyTracks"); + settings.RemoveSequencerSpecific = (bool)settings.GetPreviousVersion("RemoveSequencerSpecific"); + settings.RecreateEndTrackMarkers = (bool)settings.GetPreviousVersion("RecreateEndTrackMarkers"); + settings.RemoveExtraTempoEvents = (bool)settings.GetPreviousVersion("RemoveExtraTempoEvents"); + settings.RemoveExtraMarkers = (bool)settings.GetPreviousVersion("RemoveExtraMarkers"); + // add new settings at the bottom + } + catch (SettingsPropertyNotFoundException) + { + } + } + } + + + private void LoadSettings() + { + string programFiles = Environment.GetFolderPath(Environment.SpecialFolder.ProgramFiles); + + if (settings.InputFolder.Length == 0) + textBoxInputFolder.Text = Path.Combine(programFiles, "Toontrack\\EZDrummer\\Midi"); + else + textBoxInputFolder.Text = settings.InputFolder; + + if(settings.OutputFolder.Length == 0) + textBoxOutputFolder.Text = Environment.GetFolderPath(Environment.SpecialFolder.Desktop); + else + textBoxOutputFolder.Text = settings.OutputFolder; + + checkBoxApplyNamingRules.Checked = settings.ApplyNamingRules; + checkBoxUseFilename.Checked = settings.UseFileName; + checkBoxVerbose.Checked = settings.VerboseOutput; + if (settings.OutputMidiType == OutputMidiType.Type0) + radioButtonType0.Checked = true; + else if (settings.OutputMidiType == OutputMidiType.Type1) + radioButtonType1.Checked = true; + else + radioButtonTypeUnchanged.Checked = true; + + if (settings.OutputChannelNumber == 1) + radioButtonChannel1.Checked = true; + else if (settings.OutputChannelNumber == 10) + radioButtonChannel10.Checked = true; + else + radioButtonChannelUnchanged.Checked = true; + } + + private void UpdateSettings() + { + settings.InputFolder = textBoxInputFolder.Text; + settings.OutputFolder = textBoxOutputFolder.Text; + settings.ApplyNamingRules = checkBoxApplyNamingRules.Checked; + settings.VerboseOutput = checkBoxVerbose.Checked; + settings.UseFileName = checkBoxUseFilename.Checked; + if(radioButtonType0.Checked) + settings.OutputMidiType = OutputMidiType.Type0; + else if(radioButtonType1.Checked) + settings.OutputMidiType = OutputMidiType.Type1; + else + settings.OutputMidiType = OutputMidiType.LeaveUnchanged; + + if (radioButtonChannel1.Checked) + settings.OutputChannelNumber = 1; + else if (radioButtonChannel10.Checked) + settings.OutputChannelNumber = 10; + else + settings.OutputChannelNumber = -1; + } + + + private void MainForm_Load(object sender, EventArgs args) + { + string executableFolder = Path.GetDirectoryName(Application.ExecutablePath); + try + { + namingRules = NamingRules.LoadRules(Path.Combine(executableFolder, "NamingRules.xml")); + } + catch (Exception e) + { + MessageBox.Show(String.Format("Error reading NamingRules.xml\r\n{0}", e.ToString()), Application.ProductName); + Close(); + } + } + private void buttonConvert_Click(object sender, EventArgs e) + { + if (workQueued) + { + MessageBox.Show("Please wait until the current operation has finished", Application.ProductName); + } + else + { + UpdateSettings(); + if (!CheckInputFolderExists()) + return; + if (!CheckOutputFolderExists()) + return; + if (!CheckOutputFolderIsEmpty()) + return; + this.Cursor = Cursors.WaitCursor; + UpdateSettings(); + workQueued = ThreadPool.QueueUserWorkItem(new WaitCallback(ConvertThreadProc)); + if (workQueued) + { + this.Cursor = Cursors.WaitCursor; + } + } + } + + protected override void OnClosing(CancelEventArgs e) + { + if (workQueued) + { + MessageBox.Show("Please wait until the current operation has finished", Application.ProductName); + e.Cancel = true; + } + else + { + UpdateSettings(); + + settings.FirstTime = false; + settings.ProductVersion = Application.ProductVersion; + settings.Save(); + } + base.OnClosing(e); + } + + private void ConvertThreadProc(object state) + { + try + { + progressLog1.ClearLog(); + midiConverter = new MidiConverter(namingRules); + midiConverter.Progress += new EventHandler(midiConverter_Progress); + midiConverter.Start(); + } + finally + { + workQueued = false; + this.Invoke(new FinishedDelegate(ShowFinishedMessage)); + } + } + + void midiConverter_Progress(object sender, ProgressEventArgs e) + { + var color = Color.Black; + if (e.MessageType == ProgressMessageType.Warning) + { + color = Color.Blue; + } + else if (e.MessageType == ProgressMessageType.Error) + { + color = Color.Red; + } + else if (e.MessageType == ProgressMessageType.Trace) + { + color = Color.Purple; + } + + progressLog1.LogMessage(color, e.Message); + } + + delegate void FinishedDelegate(); + + void ShowFinishedMessage() + { + this.Cursor = Cursors.Default; + saveLogToolStripMenuItem.Enabled = true; + MessageBox.Show(String.Format("Finished:\r\n{0}", midiConverter.Summary), Application.ProductName); + } + + private bool CheckInputFolderExists() + { + if (!Directory.Exists(textBoxInputFolder.Text)) + { + DialogResult result = MessageBox.Show("Your selected input folder does not exist.", Application.ProductName, MessageBoxButtons.OK, MessageBoxIcon.Warning); + return false; + } + return true; + } + + private bool CheckOutputFolderExists() + { + if (!Directory.Exists(textBoxOutputFolder.Text)) + { + DialogResult result = MessageBox.Show("Your selected output folder does not exist.\r\nWould you like to create it now?", Application.ProductName, MessageBoxButtons.YesNo, MessageBoxIcon.Question); + if (result == DialogResult.Yes) + { + Directory.CreateDirectory(textBoxOutputFolder.Text); + } + else + { + return false; + } + } + return true; + } + + private bool CheckOutputFolderIsEmpty() + { + if ((Directory.GetFiles(textBoxOutputFolder.Text).Length > 0) || + (Directory.GetDirectories(textBoxOutputFolder.Text).Length > 0)) + { + MessageBox.Show("Your output folder is not empty.\r\n" + + "You must select an empty folder to store the converted MIDI files.", + Application.ProductName, MessageBoxButtons.OK, MessageBoxIcon.Warning); + return false; + } + return true; + } + + private void buttonBrowseEZDrummer_Click(object sender, EventArgs e) + { + FolderBrowserDialog folderBrowser = new FolderBrowserDialog(); + folderBrowser.Description = "Select Input Folder"; + folderBrowser.SelectedPath = textBoxInputFolder.Text; + if (folderBrowser.ShowDialog() == DialogResult.OK) + { + textBoxInputFolder.Text = folderBrowser.SelectedPath; + } + } + + private void buttonBrowseOutputFolder_Click(object sender, EventArgs e) + { + FolderBrowserDialog folderBrowser = new FolderBrowserDialog(); + folderBrowser.Description = "Select Output Folder"; + folderBrowser.SelectedPath = textBoxOutputFolder.Text; + if (folderBrowser.ShowDialog() == DialogResult.OK) + { + textBoxOutputFolder.Text = folderBrowser.SelectedPath; + if (CheckOutputFolderExists()) + { + CheckOutputFolderIsEmpty(); + } + } + } + + private void exitToolStripMenuItem_Click(object sender, EventArgs e) + { + this.Close(); + } + + private void contentsToolStripMenuItem_Click(object sender, EventArgs e) + { + string helpFilePath = Path.Combine(Path.GetDirectoryName(Application.ExecutablePath), "midi_file_converter.html"); + try + { + System.Diagnostics.Process.Start(helpFilePath); + } + catch (Win32Exception) + { + MessageBox.Show("Could not display the help file", Application.ProductName); + } + } + + private void aboutToolStripMenuItem_Click(object sender, EventArgs e) + { + NAudio.Utils.AboutForm aboutForm = new NAudio.Utils.AboutForm(); + aboutForm.ShowDialog(); + } + + private void clearLogToolStripMenuItem_Click(object sender, EventArgs e) + { + progressLog1.ClearLog(); + saveLogToolStripMenuItem.Enabled = false; + } + + private void optionsToolStripMenuItem_Click(object sender, EventArgs e) + { + if (workQueued) + { + MessageBox.Show("Please wait until the current operation has finished", Application.ProductName); + } + else + { + AdvancedOptionsForm optionsForm = new AdvancedOptionsForm(); + optionsForm.ShowDialog(); + } + } + + private void saveLogToolStripMenuItem_Click(object sender, EventArgs args) + { + if (workQueued) + { + MessageBox.Show("Please wait until the current operation has finished", Application.ProductName); + } + else + { + SaveFileDialog saveFileDialog = new SaveFileDialog(); + saveFileDialog.InitialDirectory = textBoxOutputFolder.Text; + saveFileDialog.DefaultExt = ".txt"; + saveFileDialog.FileName = "Conversion Log.txt"; + saveFileDialog.Filter = "Text Files (*.txt)|*.txt"; + saveFileDialog.FilterIndex = 1; + if (saveFileDialog.ShowDialog() == DialogResult.OK) + { + try + { + + using (StreamWriter writer = new StreamWriter(saveFileDialog.FileName)) + { + string text = progressLog1.Text; + if (!text.Contains("\r")) + { + text = text.Replace("\n", "\r\n"); + } + writer.Write(text); + } + } + catch (Exception e) + { + MessageBox.Show( + String.Format("Error saving conversion log\r\n{0}", e.Message), + Application.ProductName, + MessageBoxButtons.OK, + MessageBoxIcon.Error); + } + + } + } + + } + } +} \ No newline at end of file diff --git a/MidiFileConverter/MainForm.resx b/MidiFileConverter/MainForm.resx new file mode 100644 index 00000000..69c56499 --- /dev/null +++ b/MidiFileConverter/MainForm.resx @@ -0,0 +1,123 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + 17, 17 + + \ No newline at end of file diff --git a/MidiFileConverter/MidiConverter.cs b/MidiFileConverter/MidiConverter.cs new file mode 100644 index 00000000..686cbb53 --- /dev/null +++ b/MidiFileConverter/MidiConverter.cs @@ -0,0 +1,483 @@ +using System; +using System.Collections.Generic; +using System.Text; +using System.IO; +using System.Text.RegularExpressions; +using NAudio.Utils; +using NAudio.Midi; + +namespace MarkHeath.MidiUtils +{ + class MidiConverter + { + public event EventHandler Progress; + int filesConverted; + int filesCopied; + int directoriesCreated; + int errors; + DateTime startTime; + Properties.Settings settings; + Regex ezdFileName; + NamingRules namingRules; + + public MidiConverter(NamingRules namingRules) + { + settings = Properties.Settings.Default; + this.namingRules = namingRules; + ezdFileName = new Regex(namingRules.FilenameRegex); + } + + public void Start() + { + filesConverted = 0; + filesCopied = 0; + directoriesCreated = 0; + errors = 0; + startTime = DateTime.Now; + LogInformation("{0} Beginning to Convert MIDI Files...", startTime); + LogInformation("Processing using EZdrummer MIDI Converter v{0}", System.Windows.Forms.Application.ProductVersion); + LogInformation("Output MIDI type {0}", settings.OutputMidiType); + LogInformation("Output Channel Number {0}", settings.OutputChannelNumber == -1 ? "Unchanged" : settings.OutputChannelNumber.ToString()); + + // warn user if they are using hidden settings + if (settings.RemoveSequencerSpecific) + { + LogWarning("Sequencer Specific Messages will be turned off"); + } + if (settings.RemoveEmptyTracks) + { + LogWarning("Empty type 1 tracks will be removed"); + } + if (!settings.RecreateEndTrackMarkers) + { + LogWarning("End track markers will be left where they are"); + } + if (settings.TrimTextEvents) + { + LogWarning("Text events will have whitespace trimmed"); + } + if (settings.AddNameMarker) + { + LogWarning("Name markers will be added"); + } + if (settings.RemoveExtraTempoEvents) + { + LogWarning("Extra tempo events will be removed"); + } + if (settings.RemoveExtraMarkers) + { + LogWarning("Extra markers will be removed"); + } + + ProcessFolder(settings.InputFolder, settings.OutputFolder, new string[0]); + TimeSpan timeTaken = DateTime.Now - startTime; + LogInformation("Finished in {0}", timeTaken); + LogInformation(Summary); + + } + + private string[] CreateNewContext(string[] oldContext, string newContextItem) + { + string[] newContext = new string[oldContext.Length + 1]; + for (int n = 0; n < oldContext.Length; n++) + { + newContext[n] = oldContext[n]; + } + newContext[oldContext.Length] = newContextItem; + return newContext; + } + + private void ProcessFolder(string folder, string outputFolder, string[] context) + { + string[] midiFiles = Directory.GetFiles(folder); + foreach (string midiFile in midiFiles) + { + try + { + ProcessFile(midiFile, outputFolder, context); + } + catch (Exception e) + { + LogError("Unexpected error processing file {0}", midiFile); + LogError(e.ToString()); + errors++; + } + } + + string[] subfolders = Directory.GetDirectories(folder); + foreach (string subfolder in subfolders) + { + string folderName = Path.GetFileName(subfolder); + string newOutputFolder = Path.Combine(outputFolder, folderName); + string[] newContext = CreateNewContext(context, folderName); + + if (!Directory.Exists(newOutputFolder)) + { + if (settings.VerboseOutput) + { + LogTrace("Creating folder {0}", newOutputFolder); + } + Directory.CreateDirectory(newOutputFolder); + directoriesCreated++; + } + + ProcessFolder(subfolder, newOutputFolder, newContext); + } + } + + private void ProcessFile(string file, string outputFolder, string[] context) + { + bool copy = false; + string fileName = Path.GetFileName(file); + string target = Path.Combine(outputFolder, fileName); + + if (Path.GetExtension(file).ToLower() == ".mid") + { + MidiFile midiFile = new MidiFile(file); + ConvertMidi(midiFile, target, CreateNewContext(context, Path.GetFileNameWithoutExtension(file))); + filesConverted++; + } + else + { + copy = true; + } + + if (copy) + { + if (settings.VerboseOutput) + { + LogTrace("Copying File {0} to {1}", fileName, target); + } + File.Copy(file, target); + filesCopied++; + } + } + + + private void ConvertMidi(MidiFile midiFile, string target, string[] context) + { + string fileNameWithoutExtension = context[context.Length - 1]; + string name = null; + long endTrackTime = -1; + if (settings.UseFileName) + { + name = fileNameWithoutExtension; + } + if (settings.ApplyNamingRules) + { + if (ezdFileName.Match(fileNameWithoutExtension).Success) + { + name = CreateEzdName(context); + } + } + + int outputFileType = midiFile.FileFormat; + int outputTrackCount; + if (settings.OutputMidiType == OutputMidiType.Type0) + { + outputFileType = 0; + } + else if (settings.OutputMidiType == OutputMidiType.Type1) + { + outputFileType = 1; + } + + if (outputFileType == 0) + { + outputTrackCount = 1; + } + else + { + if (midiFile.FileFormat == 0) + outputTrackCount = 2; + else + outputTrackCount = midiFile.Tracks; + } + + + MidiEventCollection events = new MidiEventCollection(outputFileType, midiFile.DeltaTicksPerQuarterNote); + for (int track = 0; track < outputTrackCount; track++) + { + events.AddTrack(); + } + if (name != null) + { + for (int track = 0; track < outputTrackCount; track++) + { + events[track].Add(new TextEvent(name, MetaEventType.SequenceTrackName, 0)); + } + if (settings.AddNameMarker) + { + events[0].Add(new TextEvent(name, MetaEventType.Marker, 0)); + } + } + + foreach (MidiEvent midiEvent in midiFile.Events[0]) + { + if (settings.OutputChannelNumber != -1) + midiEvent.Channel = settings.OutputChannelNumber; + MetaEvent metaEvent = midiEvent as MetaEvent; + if (metaEvent != null) + { + bool exclude = false; + switch (metaEvent.MetaEventType) + { + case MetaEventType.SequenceTrackName: + if (name != null) + { + exclude = true; + } + break; + case MetaEventType.SequencerSpecific: + exclude = settings.RemoveSequencerSpecific; + break; + case MetaEventType.EndTrack: + exclude = settings.RecreateEndTrackMarkers; + endTrackTime = metaEvent.AbsoluteTime; + break; + case MetaEventType.SetTempo: + if (metaEvent.AbsoluteTime != 0 && settings.RemoveExtraTempoEvents) + { + LogWarning("Removing a tempo event ({0}bpm) at {1} from {2}", ((TempoEvent)metaEvent).Tempo, metaEvent.AbsoluteTime, target); + exclude = true; + } + break; + case MetaEventType.TextEvent: + if (settings.TrimTextEvents) + { + TextEvent textEvent = (TextEvent)midiEvent; + textEvent.Text = textEvent.Text.Trim(); + if (textEvent.Text.Length == 0) + { + exclude = true; + } + } + break; + case MetaEventType.Marker: + if (settings.AddNameMarker && midiEvent.AbsoluteTime == 0) + { + exclude = true; + } + if (settings.RemoveExtraMarkers && midiEvent.AbsoluteTime > 0) + { + LogWarning("Removing a marker ({0}) at {1} from {2}", ((TextEvent)metaEvent).Text, metaEvent.AbsoluteTime, target); + exclude = true; + } + break; + } + if (!exclude) + { + events[0].Add(midiEvent); + } + } + else + { + if (outputFileType == 1) + events[1].Add(midiEvent); + else + events[0].Add(midiEvent); + } + } + + // now do track 1 (Groove Monkee) + for (int inputTrack = 1; inputTrack < midiFile.Tracks; inputTrack++) + { + int outputTrack; + if(outputFileType == 1) + outputTrack = inputTrack; + else + outputTrack = 0; + + foreach (MidiEvent midiEvent in midiFile.Events[inputTrack]) + { + if (settings.OutputChannelNumber != -1) + midiEvent.Channel = settings.OutputChannelNumber; + bool exclude = false; + MetaEvent metaEvent = midiEvent as MetaEvent; + if (metaEvent != null) + { + switch (metaEvent.MetaEventType) + { + case MetaEventType.SequenceTrackName: + if (name != null) + { + exclude = true; + } + break; + case MetaEventType.SequencerSpecific: + exclude = settings.RemoveSequencerSpecific; + break; + case MetaEventType.EndTrack: + exclude = settings.RecreateEndTrackMarkers; + break; + } + } + if (!exclude) + { + events[outputTrack].Add(midiEvent); + } + } + if(outputFileType == 1 && settings.RecreateEndTrackMarkers) + { + AppendEndMarker(events[outputTrack]); + } + } + + if (settings.RecreateEndTrackMarkers) + { + if (outputFileType == 1) + { + // if we are converting type 0 to type 1 and recreating end markers, + if (midiFile.FileFormat == 0) + { + AppendEndMarker(events[1]); + } + } + // make sure that track zero has an end track marker + AppendEndMarker(events[0]); + } + else + { + // if we are converting type 0 to type 1 without recreating end markers, + // then we still need to add an end marker to track 1 + if (midiFile.FileFormat == 0) + { + // use the time we got from track 0 as the end track time for track 1 + if (endTrackTime == -1) + { + LogError("Error adding track 1 end marker"); + // make it a valid MIDI file anyway + AppendEndMarker(events[1]); + } + else + { + events[1].Add(new MetaEvent(MetaEventType.EndTrack, 0, endTrackTime)); + } + } + } + + if (settings.VerboseOutput) + { + LogTrace("Processing {0}: {1}", name, target); + } + + if (settings.RemoveEmptyTracks) + { + MidiEventCollection newList = new MidiEventCollection(events.MidiFileType, events.DeltaTicksPerQuarterNote); + + int removed = 0; + for (int track = 0; track < events.Tracks; track++) + { + IList trackEvents = events[track]; + if (track < 2) + { + newList.AddTrack(events[track]); + } + else + { + if(HasNotes(trackEvents)) + { + newList.AddTrack(trackEvents); + } + else + { + removed++; + } + } + + } + if (removed > 0) + { + events = newList; + LogWarning("Removed {0} empty tracks from {1} ({2} remain)", removed, target, events.Tracks); + } + } + MidiFile.Export(target, events); + } + + private bool HasNotes(IList midiEvents) + { + foreach (MidiEvent midiEvent in midiEvents) + { + if (midiEvent.CommandCode == MidiCommandCode.NoteOn) + return true; + } + return false; + } + + private void AppendEndMarker(IList eventList) + { + long absoluteTime = 0; + if (eventList.Count > 0) + absoluteTime = eventList[eventList.Count - 1].AbsoluteTime; + eventList.Add(new MetaEvent(MetaEventType.EndTrack, 0, absoluteTime)); + } + + private string CreateEzdName(string[] context) + { + StringBuilder name = new StringBuilder(); + int contextLevels = Math.Min(namingRules.ContextDepth, context.Length); + for (int n = 0; n < contextLevels; n++) + { + string filtered = ApplyNameFilters(context[context.Length - contextLevels + n]); + if (filtered.Length > 0) + { + name.Append(filtered); + + if (n != contextLevels - 1) + name.Append(namingRules.ContextSeparator); + } + } + return name.ToString(); + } + + private string ApplyNameFilters(string name) + { + foreach (NamingRule rule in namingRules.Rules) + { + name = Regex.Replace(name, rule.Regex, rule.Replacement); + } + return name; + } + + private void LogTrace(string message, params object[] args) + { + OnProgress(this, new ProgressEventArgs(ProgressMessageType.Trace, + message, args)); + } + + private void LogInformation(string message, params object[] args) + { + OnProgress(this, new ProgressEventArgs(ProgressMessageType.Information, + message, args)); + } + + private void LogWarning(string message, params object[] args) + { + OnProgress(this, new ProgressEventArgs(ProgressMessageType.Warning, + message, args)); + } + + private void LogError(string message, params object[] args) + { + OnProgress(this, new ProgressEventArgs(ProgressMessageType.Error, + message, args)); + } + + protected void OnProgress(object sender, ProgressEventArgs args) + { + if (Progress != null) + { + Progress(sender, args); + } + } + + public string Summary + { + get + { + return String.Format("Files Converted {0}\r\nFiles Copied {1}\r\nFolders Created {2}\r\nErrors {3}", filesConverted, filesCopied, directoriesCreated, errors); + } + } + } +} diff --git a/MidiFileConverter/MidiFileConverter.csproj b/MidiFileConverter/MidiFileConverter.csproj new file mode 100644 index 00000000..6f2e6581 --- /dev/null +++ b/MidiFileConverter/MidiFileConverter.csproj @@ -0,0 +1,169 @@ + + + + Debug + AnyCPU + 8.0.50727 + 2.0 + {5B5897BD-A423-4AF8-8A59-1C1372ED77DB} + WinExe + Properties + MarkHeath.MidiUtils + MIDI File Converter + + + + + + + + + + + + + 3.5 + v3.5 + publish\ + true + Disk + false + Foreground + 7 + Days + false + false + true + 0 + 1.0.0.%2a + false + false + true + Client + + + true + full + false + bin\Debug\ + DEBUG;TRACE + prompt + 4 + AllRules.ruleset + + + pdbonly + true + bin\Release\ + TRACE + prompt + 4 + AllRules.ruleset + + + + + + + + + + + + Form + + + AboutForm.cs + + + Form + + + AdvancedOptionsForm.cs + + + Form + + + MainForm.cs + + + + + + + + + AboutForm.cs + Designer + + + Designer + AdvancedOptionsForm.cs + + + Designer + MainForm.cs + + + ResXFileCodeGenerator + Resources.Designer.cs + Designer + + + True + Resources.resx + True + + + + + SettingsSingleFileGenerator + Settings.Designer.cs + + + True + Settings.settings + True + + + + + {DA4F02E3-0B5E-42CD-B8D9-5583FA51D66E} + NAudio + + + + + Always + + + Always + + + + + False + .NET Framework 3.5 SP1 Client Profile + false + + + False + .NET Framework 3.5 SP1 + true + + + False + Windows Installer 3.1 + true + + + + + \ No newline at end of file diff --git a/MidiFileConverter/MidiFileConverter.csproj.vspscc b/MidiFileConverter/MidiFileConverter.csproj.vspscc new file mode 100644 index 00000000..feffdeca --- /dev/null +++ b/MidiFileConverter/MidiFileConverter.csproj.vspscc @@ -0,0 +1,10 @@ +"" +{ +"FILE_VERSION" = "9237" +"ENLISTMENT_CHOICE" = "NEVER" +"PROJECT_FILE_RELATIVE_PATH" = "" +"NUMBER_OF_EXCLUDED_FILES" = "0" +"ORIGINAL_PROJECT_FILE_PATH" = "" +"NUMBER_OF_NESTED_PROJECTS" = "0" +"SOURCE_CONTROL_SETTINGS_PROVIDER" = "PROVIDER" +} diff --git a/MidiFileConverter/NamingRule.cs b/MidiFileConverter/NamingRule.cs new file mode 100644 index 00000000..57338a4f --- /dev/null +++ b/MidiFileConverter/NamingRule.cs @@ -0,0 +1,110 @@ +using System; +using System.Collections.Generic; +using System.Text; +using System.Xml; + +namespace MarkHeath.MidiUtils +{ + class NamingRules + { + string filenameRegex; + int contextDepth; + string contextSeparator; + List rules; + + public static NamingRules LoadRules(string xmlPath) + { + NamingRules namingRules = new NamingRules(); + namingRules.rules = new List(); + + using (XmlReader reader = new XmlTextReader(xmlPath)) + { + reader.ReadStartElement("Rules"); + reader.ReadStartElement("GeneralSettings"); + + reader.ReadStartElement("FilenameRegex"); + namingRules.filenameRegex = reader.ReadString(); + reader.ReadEndElement(); + + reader.ReadStartElement("ContextDepth"); + namingRules.contextDepth = reader.ReadContentAsInt(); + if (namingRules.ContextDepth < 1 || namingRules.ContextDepth > 4) + throw new FormatException("Context Depth must be between 1 and 4"); + reader.ReadEndElement(); + + reader.ReadStartElement("ContextSeparator"); + namingRules.contextSeparator = reader.ReadString(); + reader.ReadEndElement(); + + reader.ReadEndElement(); + while (reader.Read()) + { + if (reader.NodeType == XmlNodeType.EndElement) + { + System.Diagnostics.Debug.Assert(reader.Name == "Rules"); + break; + } + //if (reader.IsStartElement()) + // System.Diagnostics.Debug.Assert(reader.Name == "Rule"); + reader.ReadStartElement("Rule"); + //reader.Read(); + + reader.ReadStartElement("SearchString"); + string regex = reader.ReadString(); + reader.ReadEndElement(); + reader.ReadStartElement("Replacement"); + string replacement = reader.ReadString(); + reader.ReadEndElement(); + reader.ReadEndElement(); + namingRules.rules.Add(new NamingRule(regex, replacement)); + } + reader.ReadEndElement(); + } + return namingRules; + } + + public string ContextSeparator + { + get { return contextSeparator; } + } + + public int ContextDepth + { + get { return contextDepth; } + } + + public string FilenameRegex + { + get { return filenameRegex; } + } + + public List Rules + { + get { return rules; } + } + } + + class NamingRule + { + string regex; + string replacement; + + public NamingRule(string regex, string replacement) + { + this.regex = regex; + this.replacement = replacement; + } + + public string Regex + { + get { return regex; } + } + + public string Replacement + { + get { return replacement; } + } + + + } +} diff --git a/MidiFileConverter/NamingRules.xml b/MidiFileConverter/NamingRules.xml new file mode 100644 index 00000000..306ba3ac --- /dev/null +++ b/MidiFileConverter/NamingRules.xml @@ -0,0 +1,76 @@ + + + + ^[A-Z]\@ + 3 + - + + + ^[0-9A-Z]+\@[0-9][0-9]\. + + + + ^[0-9A-Z]+\@ + + + + _ + + + + # + / + + + GROOVE + G + + + FILL + F + + + Fill + F + + + POP/ROCK + P/R + + + FUNK/ROCK + F/R + + + BALLAD + BLD + + + ^FILLS + + + + FILLS + F + + + MOTOWN + MTN + + + SIDESTICK + STK + + + EZX COCKTAIL + Cocktail + + + SAMBA + + + + BAIAO + + + \ No newline at end of file diff --git a/MidiFileConverter/OutputMidiType.cs b/MidiFileConverter/OutputMidiType.cs new file mode 100644 index 00000000..bd5d180b --- /dev/null +++ b/MidiFileConverter/OutputMidiType.cs @@ -0,0 +1,13 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace MarkHeath.MidiUtils +{ + enum OutputMidiType + { + LeaveUnchanged, + Type0, + Type1 + } +} diff --git a/MidiFileConverter/Program.cs b/MidiFileConverter/Program.cs new file mode 100644 index 00000000..bdc95af7 --- /dev/null +++ b/MidiFileConverter/Program.cs @@ -0,0 +1,20 @@ +using System; +using System.Collections.Generic; +using System.Windows.Forms; + +namespace MarkHeath.MidiUtils +{ + static class Program + { + /// + /// The main entry point for the application. + /// + [STAThread] + static void Main() + { + Application.EnableVisualStyles(); + Application.SetCompatibleTextRenderingDefault(false); + Application.Run(new MainForm()); + } + } +} \ No newline at end of file diff --git a/MidiFileConverter/ProgressEventArgs.cs b/MidiFileConverter/ProgressEventArgs.cs new file mode 100644 index 00000000..74beb53e --- /dev/null +++ b/MidiFileConverter/ProgressEventArgs.cs @@ -0,0 +1,81 @@ +using System; + +namespace MarkHeath.MidiUtils +{ + /// + /// Progress Event Arguments + /// + public class ProgressEventArgs : EventArgs + { + private string message; + private ProgressMessageType messageType; + + /// + /// New progress event arguments + /// + /// The message type + /// The message + public ProgressEventArgs(ProgressMessageType messageType, string message) + { + this.message = message; + this.messageType = messageType; + } + + /// + /// New progress event arguments + /// + /// The message type + /// the message format string + /// format arguments + public ProgressEventArgs(ProgressMessageType messageType, string message, params object[] args) + { + this.messageType = messageType; + this.message = String.Format(message, args); + } + + /// + /// The message + /// + public string Message + { + get + { + return message; + } + } + + /// + /// The message type + /// + public ProgressMessageType MessageType + { + get + { + return messageType; + } + } + } + + /// + /// Progress Message Type + /// + public enum ProgressMessageType + { + /// + /// Trace + /// + Trace, + /// + /// Information + /// + Information, + /// + /// Warning + /// + Warning, + /// + /// Error + /// + Error, + } +} diff --git a/MidiFileConverter/Properties/AssemblyInfo.cs b/MidiFileConverter/Properties/AssemblyInfo.cs new file mode 100644 index 00000000..1452e8bb --- /dev/null +++ b/MidiFileConverter/Properties/AssemblyInfo.cs @@ -0,0 +1,89 @@ +using System.Reflection; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +// General Information about an assembly is controlled through the following +// set of attributes. Change these attribute values to modify the information +// associated with an assembly. +[assembly: AssemblyTitle("MIDI File Converter")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("Mark Heath")] +[assembly: AssemblyProduct("MIDI File Converter")] +[assembly: AssemblyCopyright("Copyright © Mark Heath 2007")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// Setting ComVisible to false makes the types in this assembly not visible +// to COM components. If you need to access a type in this assembly from +// COM, set the ComVisible attribute to true on that type. +[assembly: ComVisible(false)] + +// The following GUID is for the ID of the typelib if this project is exposed to COM +[assembly: Guid("c25a6f6b-abf0-4460-a49e-d73c069f80e3")] + +// Version information for an assembly consists of the following four values: +// +// Major Version +// Minor Version +// Build Number +// Revision +// +[assembly: AssemblyVersion("0.3.10.0")] +[assembly: AssemblyFileVersion("0.3.10.0")] + +// build 1 29 Oct 2006 +// build 1 is experimental +// updated for Groove Monkee loops so it works on all incoming files +// build 2 30 Oct 2006 +// setting to leave MIDI file type unchanged +// settings to force notes to a specific channel +// added clip naming option +// uses new generic about box +// uses new generic progress log +// decoupled logic from Main Form UI +// option not to rename files at all +// Hidden option to trim text markers and remove blank +// Hidden option to insert a name marker and delete all others +// Hidden option to recreate end track markers +// basic install script +// should now be able to cope with multi-track type 1s as input as well +// show hourglass +// remove empty tracks option added +// settings upgrade option +// Update help file +// build 3 +// fixed a bug removing blank tracks +// build 4 +// advanced options dialog +// clear log on start +// build 5 31 Oct 2006 +// Remove extra tempo events option +// Remove extra markers option +// build 6 31 Oct 2006 +// option to save conversion log +// build 7 2 Nov 2006 +// final build for release +// build 8 3 Nov 2006 +// minor changes +// build 9 6 Mar 2007 +// renamed to MIDI file converter +// now hosted on CodePlex +// fixed a bug where track 1 didn't have an end track marker if Recreate Track End Markers wasn't set, +// and converting from type 0 to type 1 +// build 10 5 Apr 2007 +// updated to use new MidiEventCollection + +// revamp help for advanced options + +// Next version +// support changing note length +// perhaps allow markers less than final note event +// work out times in measures and beats +// review error handling +// Consider a command line interface +// Selecting what to copy & what to process (somehow) +// Protect against output folder being a subfolder of input folder + +// Testing +// Public release \ No newline at end of file diff --git a/MidiFileConverter/Properties/Resources.Designer.cs b/MidiFileConverter/Properties/Resources.Designer.cs new file mode 100644 index 00000000..455e7cd2 --- /dev/null +++ b/MidiFileConverter/Properties/Resources.Designer.cs @@ -0,0 +1,63 @@ +//------------------------------------------------------------------------------ +// +// This code was generated by a tool. +// Runtime Version:4.0.30319.17929 +// +// Changes to this file may cause incorrect behavior and will be lost if +// the code is regenerated. +// +//------------------------------------------------------------------------------ + +namespace MarkHeath.MidiUtils.Properties { + using System; + + + /// + /// A strongly-typed resource class, for looking up localized strings, etc. + /// + // This class was auto-generated by the StronglyTypedResourceBuilder + // class via a tool like ResGen or Visual Studio. + // To add or remove a member, edit your .ResX file then rerun ResGen + // with the /str option, or rebuild your VS project. + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")] + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] + internal class Resources { + + private static global::System.Resources.ResourceManager resourceMan; + + private static global::System.Globalization.CultureInfo resourceCulture; + + [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] + internal Resources() { + } + + /// + /// Returns the cached ResourceManager instance used by this class. + /// + [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] + internal static global::System.Resources.ResourceManager ResourceManager { + get { + if (object.ReferenceEquals(resourceMan, null)) { + global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("MarkHeath.MidiUtils.Properties.Resources", typeof(Resources).Assembly); + resourceMan = temp; + } + return resourceMan; + } + } + + /// + /// Overrides the current thread's CurrentUICulture property for all + /// resource lookups using this strongly typed resource class. + /// + [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] + internal static global::System.Globalization.CultureInfo Culture { + get { + return resourceCulture; + } + set { + resourceCulture = value; + } + } + } +} diff --git a/MidiFileConverter/Properties/Resources.resx b/MidiFileConverter/Properties/Resources.resx new file mode 100644 index 00000000..ffecec85 --- /dev/null +++ b/MidiFileConverter/Properties/Resources.resx @@ -0,0 +1,117 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + \ No newline at end of file diff --git a/MidiFileConverter/Properties/Settings.Designer.cs b/MidiFileConverter/Properties/Settings.Designer.cs new file mode 100644 index 00000000..c6ae9b8e --- /dev/null +++ b/MidiFileConverter/Properties/Settings.Designer.cs @@ -0,0 +1,218 @@ +//------------------------------------------------------------------------------ +// +// This code was generated by a tool. +// Runtime Version:4.0.30319.17929 +// +// Changes to this file may cause incorrect behavior and will be lost if +// the code is regenerated. +// +//------------------------------------------------------------------------------ + +namespace MarkHeath.MidiUtils.Properties { + + + [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "11.0.0.0")] + internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase { + + private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings()))); + + public static Settings Default { + get { + return defaultInstance; + } + } + + [global::System.Configuration.UserScopedSettingAttribute()] + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.Configuration.DefaultSettingValueAttribute("")] + public string InputFolder { + get { + return ((string)(this["InputFolder"])); + } + set { + this["InputFolder"] = value; + } + } + + [global::System.Configuration.UserScopedSettingAttribute()] + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.Configuration.DefaultSettingValueAttribute("")] + public string OutputFolder { + get { + return ((string)(this["OutputFolder"])); + } + set { + this["OutputFolder"] = value; + } + } + + [global::System.Configuration.UserScopedSettingAttribute()] + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.Configuration.DefaultSettingValueAttribute("True")] + public bool ApplyNamingRules { + get { + return ((bool)(this["ApplyNamingRules"])); + } + set { + this["ApplyNamingRules"] = value; + } + } + + [global::System.Configuration.UserScopedSettingAttribute()] + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.Configuration.DefaultSettingValueAttribute("True")] + public bool VerboseOutput { + get { + return ((bool)(this["VerboseOutput"])); + } + set { + this["VerboseOutput"] = value; + } + } + + [global::System.Configuration.UserScopedSettingAttribute()] + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.Configuration.DefaultSettingValueAttribute("False")] + public bool RemoveSequencerSpecific { + get { + return ((bool)(this["RemoveSequencerSpecific"])); + } + set { + this["RemoveSequencerSpecific"] = value; + } + } + + [global::System.Configuration.UserScopedSettingAttribute()] + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.Configuration.DefaultSettingValueAttribute("Type1")] + public global::MarkHeath.MidiUtils.OutputMidiType OutputMidiType { + get { + return ((global::MarkHeath.MidiUtils.OutputMidiType)(this["OutputMidiType"])); + } + set { + this["OutputMidiType"] = value; + } + } + + [global::System.Configuration.UserScopedSettingAttribute()] + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.Configuration.DefaultSettingValueAttribute("-1")] + public int OutputChannelNumber { + get { + return ((int)(this["OutputChannelNumber"])); + } + set { + this["OutputChannelNumber"] = value; + } + } + + [global::System.Configuration.UserScopedSettingAttribute()] + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.Configuration.DefaultSettingValueAttribute("True")] + public bool UseFileName { + get { + return ((bool)(this["UseFileName"])); + } + set { + this["UseFileName"] = value; + } + } + + [global::System.Configuration.UserScopedSettingAttribute()] + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.Configuration.DefaultSettingValueAttribute("False")] + public bool TrimTextEvents { + get { + return ((bool)(this["TrimTextEvents"])); + } + set { + this["TrimTextEvents"] = value; + } + } + + [global::System.Configuration.UserScopedSettingAttribute()] + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.Configuration.DefaultSettingValueAttribute("False")] + public bool AddNameMarker { + get { + return ((bool)(this["AddNameMarker"])); + } + set { + this["AddNameMarker"] = value; + } + } + + [global::System.Configuration.UserScopedSettingAttribute()] + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.Configuration.DefaultSettingValueAttribute("True")] + public bool RecreateEndTrackMarkers { + get { + return ((bool)(this["RecreateEndTrackMarkers"])); + } + set { + this["RecreateEndTrackMarkers"] = value; + } + } + + [global::System.Configuration.UserScopedSettingAttribute()] + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.Configuration.DefaultSettingValueAttribute("False")] + public bool RemoveEmptyTracks { + get { + return ((bool)(this["RemoveEmptyTracks"])); + } + set { + this["RemoveEmptyTracks"] = value; + } + } + + [global::System.Configuration.UserScopedSettingAttribute()] + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.Configuration.DefaultSettingValueAttribute("True")] + public bool FirstTime { + get { + return ((bool)(this["FirstTime"])); + } + set { + this["FirstTime"] = value; + } + } + + [global::System.Configuration.UserScopedSettingAttribute()] + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.Configuration.DefaultSettingValueAttribute("")] + public string ProductVersion { + get { + return ((string)(this["ProductVersion"])); + } + set { + this["ProductVersion"] = value; + } + } + + [global::System.Configuration.UserScopedSettingAttribute()] + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.Configuration.DefaultSettingValueAttribute("False")] + public bool RemoveExtraTempoEvents { + get { + return ((bool)(this["RemoveExtraTempoEvents"])); + } + set { + this["RemoveExtraTempoEvents"] = value; + } + } + + [global::System.Configuration.UserScopedSettingAttribute()] + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.Configuration.DefaultSettingValueAttribute("False")] + public bool RemoveExtraMarkers { + get { + return ((bool)(this["RemoveExtraMarkers"])); + } + set { + this["RemoveExtraMarkers"] = value; + } + } + } +} diff --git a/MidiFileConverter/Properties/Settings.settings b/MidiFileConverter/Properties/Settings.settings new file mode 100644 index 00000000..4f321f15 --- /dev/null +++ b/MidiFileConverter/Properties/Settings.settings @@ -0,0 +1,54 @@ + + + + + + + + + + + + True + + + True + + + False + + + Type1 + + + -1 + + + True + + + False + + + False + + + True + + + False + + + True + + + + + + False + + + False + + + \ No newline at end of file diff --git a/MidiFileConverter/app.config b/MidiFileConverter/app.config new file mode 100644 index 00000000..802eb0a3 --- /dev/null +++ b/MidiFileConverter/app.config @@ -0,0 +1,60 @@ + + + + +
    + + + + + + + + + + + + True + + + True + + + False + + + Type1 + + + -1 + + + True + + + False + + + False + + + True + + + False + + + True + + + + + + False + + + False + + + + diff --git a/MidiFileConverter/midi_file_converter.html b/MidiFileConverter/midi_file_converter.html new file mode 100644 index 00000000..37c32036 --- /dev/null +++ b/MidiFileConverter/midi_file_converter.html @@ -0,0 +1,307 @@ + + + MIDI File Converter + + +

    MIDI File Converter

    +

    + MIDI File Converter is a utility designed to convert the MIDI file library + included with Toontrack's EZdrummer virtual + instrument from MIDI type 0 to MIDI type 1, with a customisable name as the track + 1 name. This has the advantage that users of Cakewalk's + SONAR + will find that the MIDI clips created when they drag and drop into + the track pane are given a meaningful default name. It also supports the option + to leave the files as type 0 and simply change the track name, which is supported + by SONAR 6 and above. +

    + +

    This utility has now been expanded to alter other MIDI files + that you might be using with EZD to adjust their end time markers so that they loop + correctly with EZdrummer's built in loop browser. (EZD version 1.0.3 introduced + some problems in this area).

    +

    + Download

    +

    + A link to the latest version of MIDI File converter can be found + here.

    +

    + Installation and Requirements

    +

    + MIDI File Converter requires the .NET framework version 2.0 to be installed. + You can download this + here. Once you have done this you can run the installer (or download the zip archive, + decompress it and run MIDI File Converter.exe).

    + +

    Settings

    + + MIDI File Converter Screenshot + +

    Input Folder

    +

    + Normally you would choose the EZdrummer MIDI folder as the input folder. This is + typically located at C:\Program Files\Toontrack\EZDrummer\Midi. However, if you + want to specifically choose which MIDI files will be processed, you can select a + subfolder or a new folder into which you have copied in the exact files you want to be processed.

    +

    + Output Folder

    +

    + MIDI File Converter will not modify any existing files or folders on your PC. + What it does is recreates all the contents of the input folder into an empty output + folder you have specified. This folder must be initially blank, and its contents + can be copied into the Toontrack MIDI folder when you have finished the conversion + (you must do this part yourself).

    +

    + Clip Naming

    +

    + These settings govern the clip name you will see when dragging into your host sequencer. + Please note that in certain circumstances, EZD will generate its own clip name instead + of the one in the file. You will need to experiment with your own host sequencer + to see how it behaves.

    +

    + If the Apply XML Naming Rules to Toontrack EZD Patterns option is selected, then + whenever a MIDI file that was supplied with EZdrummer is processed, it will be given + a MIDI clip name that is calculated according to the rules in the NamingRules.xml + file (see "Advanced Customisation" below for more details). This setting is turned + on by default.

    +

    + If the Use filename for other MIDI patterns option is selected, then all other + MIDI files in the input folder will have their clip name set to the name of the + file (minus the .mid extension). This setting is on by default. If you turn it off, + MIDI files will retain whatever clip names they already had (which may be blank).

    +

    + MIDI Note Channel

    +

    + You will normally want to leave MIDI notes on whatever channel they were already + on. However, you can move them all to track 1 to be just like the ones in the included + EZD libraries. Or you can move them all to track 10, so that when you play them + in Windows Media Player, or through a GM module, it will play drum sounds instead + of piano sounds.

    +

    + Output File Type

    +

    + MIDI File Converter was written to convert Toontrack's type 0 files into type + 1, so that their clip names would display correctly in SONAR 5. However, users of + different hosts may find that they can use type 0 without problems. Choose type + 1 to force all MIDI files to type 1, type 0 to force them all to type 0, and leave + unchanged if you want them to stay as they are.

    +

    + Verbose Output

    +

    + Select this option if you want a detailed run-down of everything that EZdrummer + MIDI Converter is doing. If it is turned off, you will still be informed of any + errors encountered.

    +

    + How to make MIDI clip names appear in SONAR

    +

    Note: these are for users of SONAR 5 or previous versions. SONAR 6 can display + EZdrummers own clip names. You may still be able to use this utility with SONAR 6 though + if you want to customise what those clip names will be.

    +
      +
    • First, make sure you have no running instances of EZdrummer.
    • +
    • MIDI File Converter will not modify, delete or rename any files on your computer. + It will only create new ones. So now, create an empty folder somewhere to contain + the created library. A good example would be on your desktop, in a subfolder called + Midi.
    • +
    • Make sure that the EZdrummer MIDI folder is pointing at EZdrummer's own MIDI folder.
    • +
    • Point the output folder at your desired output path. MIDI File Converter will + insist that this is a blank folder, to avoid confusion.
    • +
    • You want to select type 1 as the ouput file type.
    • +
    • If you have user MIDI files you would like to be given clip names as well then select + the Use filename for other MIDI patterns option.
    • +
    • By default Apply XML Naming Rules is enabled. If you turn this off, the track name + for converted EZdrummer MIDI files will simply be the filename minus the .mid extension. + It is possible to extensively customise the naming rules, but this is for advanced + users only. See the next section for more details. If you just have the EZdrummer + included MIDI files, and no expansion packs, the default naming rules will probably + be just fine for you.
    • +
    • When you are ready, click Convert. The process will take a few minutes, depending + on the speed of your computer.
    • +
    • When it has finished, you will be informed of how many files were processed, as + well as the number of errors encountered. If you have any errors at all, it is recommended + that you report them to mark.heath@gmail.com. +
    • +
    • If you are happy that the output folder contains the MIDI files you want, you are + ready to replace EZdrummer's MIDI files with the converted ones. Please make a backup + first. One way would simply be to rename the existing MIDI folder to something + else (e.g. Original MIDI).
    • +
    • Now copy the entire contents of the output directory into the Toontrack MIDI folder + (by default this will be C:\Program Files\Toontrack\EZDrummer\Midi.
    • +
    +

    + How to make user MIDI files loop correctly in EZD 1.0.3

    +
      +
    • First, copy all the folders of MIDI files that have the looping problem into an + empty folder. This will be your input folder.
    • +
    • Create another blank folder to use as your output folder.
    • +
    • If you would like them to be given MIDI clip names based on their filename at the + same time, ensure that "Use filename for other MIDI patterns" is selected.
    • +
    • You can also take the opportunity to modify the MIDI file type or the channel number + for the notes. This may be helpful depending on your host.
    • +
    • You may also wish to turn on some options in the advanced options screen, available + on the Tools menu.
    • +
    • When you are ready click Convert. If the process completes without errors, you can + replace your user MIDI files with those in the output folder.
    • +
    +

    + Advanced Customisation

    +

    + MIDI File Converter allows extensive customisation of the filenames it creates. + If you are comfortable with editing XML files and using regular expressions, you + will be able to customise these settings. This allows the flexibility to support + any EZX expansion pack MIDI files you may purchase. The settings are all stored + in NamingRules.xml, which should be in the same folder as the EZdrummer MIDI + Converter application. Please be careful modifying these settings and always check + that the output is what you wanted before replacing your EZdrummer MIDI files.

    +
      +
    • General Settings - This section contains some global settings. Do not change + the order of the keys in this section.
    • +
    • FilenameRegex - This pattern is matched against all the filenames. If a match + is found, then MIDI File Converter considers this to be an EZdrummer MIDI file, + and will attempt to apply naming rules. The default setting looks for a filename + that starts with one uppercase letter followed by an @ symbol. You only need to + change this setting if files you wanted naming rules applied on are being missed + out, or files you didn't want the naming rules applied on were being included.
    • +
    • ContextDepth - This is the number of components (folders and filename) that + will be used to formulate the track 1 name. This is normally set to 3 (4 is the + maximum), but can be set lower if desired.
    • +
    • ContextSeparator - This string will be inserted between the converted name + of each item in the context hierarchy. If the naming rules have caused the length + of a section to be set to zero, then the context separator is not added. The default + will be just fine for most people.
    • +
    • Rules - The rules section allows you to specify a number of string substitutions + to be applied to each part of the name. This consists of two parts - the SearchString + and the Replacement (see below). Each rule is applied in turn on each folder + name or filename used to form the track name. The order is very important in this + section - the rules will be applied in the order they appear in the NamingRules.xml + file.
    • +
    • SearchString - this is a regular expression that defines a string to look + for within the file or folder name.
    • +
    • Replacement - this is a literal string that will replace all occurences of + the search string in the file or folder name being processed.
    • +
    +

    + Some example rules from the default NamingRules.xml file:

    + <Rule>
    +    <SearchString>^[0-9A-Z]+\@[0-9][0-9]\.</SearchString>
    +    <Replacement></Replacement>
    + </Rule>
    +

    + This rule looks for all file or folder names that start with one or more digits + or upper case letters followed by an @ sign, followed by exactly two digits and + then a full stop. It replaces it with a blank string. This effectively strips off + the start of EZdrummer folder and filenames.

    + <Rule>
    +    <SearchString>POP/ROCK</SearchString>
    +    <Replacement>P/R</Replacement>
    + </Rule>
    +

    + This rule abbreviates any instances of the upper case string "POP/ROCK" to "P/R". + Note that this will only operate if it follows the rule that converts the '#' character + to a '/' character.

    + <Rule>
    +    <SearchString>GROOVE </SearchString>
    +    <Replacement>G</Replacement>
    + </Rule>
    +

    + This rule abbreviates any instances of the upper case string "GROOVE" followed by + a trailing space to simply "G". Note that this only works because we have already + converted all underscore characters to spaces with a previous rule.

    + <Rule>
    +    <SearchString>SAMBA</SearchString>
    +    <Replacement></Replacement>
    + </Rule>
    +

    + The Samba MIDI files included with the Cocktail kit EZX will have the word Samba + in their name twice by default. This rule strips out the fully capitalised folder + name, so the mixed case "Samba" in the filename can be used on its own.

    +

    + Advanced Options

    +

    + There are some extra settings available that may be useful for some third party + add-on MIDI libraries. These are accessed from the Tools menu. They are recommended + for advanced users only. Messages will appear in the output window to inform you + of these settings being modified from their default values.

    +
      +
    • Remove Sequencer Specific Events - The Toontrack EZD files each have a sequencer + specific event in them. I don't know what it is for, but you can remove it if you + want (maybe to trick EZD into thinking this is a user file instead). Default is + False.
    • +
    • Recreate End Track Events - This is what will fix most looping issues in + EZD v1.03. It deletes the existing end track markers and puts new ones in that fall + exactly after the last note event. Default is True. If this is set to False, + then end track markers are left exactly where they were.
    • +
    • Add Name Marker - In addition to naming the tracks, this will add a marker + to track zero with the name of the clip. Any existing markers at position 0 on track + 0 will be removed. Default is False
    • +
    • Trim Text Events - Trims the whitespace of Text events and removes them if + they are zero length. Default is False
    • +
    • Remove Empty Tracks - If the input file is type 1 and has tracks containing + no note events, these tracks can be removed. The control track and the first track + are never removed. Default is False.
    • +
    • Remove Extra Tempo Events - Most MIDI files have just one tempo event on + the first tick. This option removes any subsequent ones (this is sometimes needed + to fix the looping issue in EZD v1.0.3). Default is False.
    • +
    • Remove Extra Markers - This will remove any markers that are not at the first + tick. This is sometimes needed to fix the looping issue in EZD v1.0.3. Default is + False.
    • +
    +

    + Notes

    +
      +
    • This software is not affiliated in any way with Toontrack. It is not guaranteed + to work on future versions of EZdrummer, or with EZX expansion packs (although I + expect it will work just fine).
    • +
    • I recommend that if you are installing any patches or updates to EZdrummer, that + you restore the original Midi directory before doing so, and then re-run the EZdrummer + MIDI Converter afterwards.
    • +
    • If you have some user MIDI patterns that you do not want MIDI File Converter + to attempt to convert, simply remove them from the input directory before running + the conversion process. You do not have to point it to the real EZdrummer MIDI directory + if you don't want to. You could create your own folder with only the files you want + converted in.
    • +
    • For the technically inclined, here is an explanation of what happens to your MIDI + events when converting to type 1. All meta-events are placed on track 0. All note + events are placed on track 1. In addition a track name (the one worked out by the + naming rules) and a track end marker are added to track 1.
    • +
    +

    + Version History

    +

    + The latest version of MIDI File Converter can be found at + http://www.codeplex.com/naudio. +

    +
      +
    • v0.1 9 Oct 2006 +
        +
      • First public beta release
      • +
      +
    • +
    • v0.2 2 Nov 2006 +
        +
      • Now processes all MIDI files in the input folder, rather than just copying type + 1
      • +
      • Allow processing of non-EZD files (to move end track markers to work with EZD v1.03)
      • +
      • Ability to select output file type
      • +
      • Both tracks in a type 1 file will be given the same track name
      • +
      • An advanced options dialog added with extra options
      • +
      • Can optionally force all MIDI note events onto channel 1 or 10
      • +
      • Properly handles non-ASCII characters (such as copyright symbol)
      • +
      • Has an installer
      • +
      • Can save the conversion log
      • +
      +
    • +
    • v0.3 16 Mar 2007 +
        +
      • Name changed to MIDI File Converter to reflect its use for more general-purpose tasks
      • +
      • Fixed a bug where track 1 didn't have an end track marker when converting from type 0 to type 1
      • +
      +
    • +
    • v0.4 - t.b.a. +
        +
      • Fixed a sysex writing bug
      • +
      • Better preserving of event ordering
      • +
      +
    • +
    + + diff --git a/MixDiff/AboutForm.Designer.cs b/MixDiff/AboutForm.Designer.cs new file mode 100644 index 00000000..bd8cd680 --- /dev/null +++ b/MixDiff/AboutForm.Designer.cs @@ -0,0 +1,144 @@ +namespace NAudio.Utils +{ + partial class AboutForm + { + /// + /// Required designer variable. + /// + private System.ComponentModel.IContainer components = null; + + /// + /// Clean up any resources being used. + /// + /// true if managed resources should be disposed; otherwise, false. + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Windows Form Designer generated code + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + this.linkLabelWebsite = new System.Windows.Forms.LinkLabel(); + this.buttonOK = new System.Windows.Forms.Button(); + this.labelProductName = new System.Windows.Forms.Label(); + this.labelCopyright = new System.Windows.Forms.Label(); + this.linkLabelFeedback = new System.Windows.Forms.LinkLabel(); + this.label3 = new System.Windows.Forms.Label(); + this.labelVersion = new System.Windows.Forms.Label(); + this.SuspendLayout(); + // + // linkLabelWebsite + // + this.linkLabelWebsite.AutoSize = true; + this.linkLabelWebsite.Location = new System.Drawing.Point(13, 67); + this.linkLabelWebsite.Name = "linkLabelWebsite"; + this.linkLabelWebsite.Size = new System.Drawing.Size(168, 13); + this.linkLabelWebsite.TabIndex = 0; + this.linkLabelWebsite.TabStop = true; + this.linkLabelWebsite.Text = "http://www.codeplex.com/naudio"; + this.linkLabelWebsite.LinkClicked += new System.Windows.Forms.LinkLabelLinkClickedEventHandler(this.linkLabelWebsite_LinkClicked); + // + // buttonOK + // + this.buttonOK.Location = new System.Drawing.Point(111, 124); + this.buttonOK.Name = "buttonOK"; + this.buttonOK.Size = new System.Drawing.Size(75, 23); + this.buttonOK.TabIndex = 1; + this.buttonOK.Text = "OK"; + this.buttonOK.UseVisualStyleBackColor = true; + this.buttonOK.Click += new System.EventHandler(this.buttonOK_Click); + // + // labelProductName + // + this.labelProductName.AutoSize = true; + this.labelProductName.Font = new System.Drawing.Font("Microsoft Sans Serif", 9.75F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0))); + this.labelProductName.Location = new System.Drawing.Point(13, 13); + this.labelProductName.Name = "labelProductName"; + this.labelProductName.Size = new System.Drawing.Size(196, 16); + this.labelProductName.TabIndex = 2; + this.labelProductName.Text = "{Application.ProductName}"; + // + // labelCopyright + // + this.labelCopyright.AutoSize = true; + this.labelCopyright.Location = new System.Drawing.Point(13, 51); + this.labelCopyright.Name = "labelCopyright"; + this.labelCopyright.Size = new System.Drawing.Size(149, 13); + this.labelCopyright.TabIndex = 2; + this.labelCopyright.Text = "Copyright © Mark Heath 2007"; + // + // linkLabelFeedback + // + this.linkLabelFeedback.AutoSize = true; + this.linkLabelFeedback.Location = new System.Drawing.Point(13, 101); + this.linkLabelFeedback.Name = "linkLabelFeedback"; + this.linkLabelFeedback.Size = new System.Drawing.Size(150, 13); + this.linkLabelFeedback.TabIndex = 3; + this.linkLabelFeedback.TabStop = true; + this.linkLabelFeedback.Text = "mark.heath@gmail.com"; + this.linkLabelFeedback.LinkClicked += new System.Windows.Forms.LinkLabelLinkClickedEventHandler(this.linkLabelFeedback_LinkClicked); + // + // label3 + // + this.label3.AutoSize = true; + this.label3.Location = new System.Drawing.Point(13, 85); + this.label3.Name = "label3"; + this.label3.Size = new System.Drawing.Size(243, 13); + this.label3.TabIndex = 2; + this.label3.Text = "Send feedback, feature requests and bug fixes to:"; + // + // labelVersion + // + this.labelVersion.AutoSize = true; + this.labelVersion.Location = new System.Drawing.Point(13, 33); + this.labelVersion.Name = "labelVersion"; + this.labelVersion.Size = new System.Drawing.Size(93, 13); + this.labelVersion.TabIndex = 2; + this.labelVersion.Text = "{Version: X.X.X.X}"; + // + // AboutForm + // + this.AcceptButton = this.buttonOK; + this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.ClientSize = new System.Drawing.Size(292, 159); + this.Controls.Add(this.linkLabelFeedback); + this.Controls.Add(this.label3); + this.Controls.Add(this.labelVersion); + this.Controls.Add(this.labelCopyright); + this.Controls.Add(this.labelProductName); + this.Controls.Add(this.buttonOK); + this.Controls.Add(this.linkLabelWebsite); + this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedSingle; + this.MaximizeBox = false; + this.MinimizeBox = false; + this.Name = "AboutForm"; + this.ShowInTaskbar = false; + this.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent; + this.Text = "About {Application.ProductName}"; + this.ResumeLayout(false); + this.PerformLayout(); + + } + + #endregion + + private System.Windows.Forms.LinkLabel linkLabelWebsite; + private System.Windows.Forms.Button buttonOK; + private System.Windows.Forms.Label labelProductName; + private System.Windows.Forms.Label labelCopyright; + private System.Windows.Forms.LinkLabel linkLabelFeedback; + private System.Windows.Forms.Label label3; + private System.Windows.Forms.Label labelVersion; + } +} \ No newline at end of file diff --git a/MixDiff/AboutForm.cs b/MixDiff/AboutForm.cs new file mode 100644 index 00000000..2d5861e0 --- /dev/null +++ b/MixDiff/AboutForm.cs @@ -0,0 +1,71 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Data; +using System.Drawing; +using System.Text; +using System.Windows.Forms; + +namespace NAudio.Utils +{ + /// + /// A standard about form + /// + public partial class AboutForm : Form + { + /// + /// Creates a new about form + /// + public AboutForm() + { + InitializeComponent(); + labelProductName.Text = Application.ProductName; + labelVersion.Text = String.Format("Version: {0}", Application.ProductVersion); + this.Text = String.Format("About {0}", Application.ProductName); + } + + private void linkLabelWebsite_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e) + { + System.Diagnostics.Process.Start(linkLabelWebsite.Text); + } + + private void linkLabelFeedback_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e) + { + System.Diagnostics.Process.Start("mailto:" + linkLabelFeedback.Text); + } + + private void buttonOK_Click(object sender, EventArgs e) + { + this.Close(); + } + + /// + /// The URL of the website to use for help + /// e.g. http://www.codeplex.com/naudio + /// + public string Url + { + get { return linkLabelWebsite.Text; } + set { linkLabelWebsite.Text = value; } + } + + /// + /// The email address for feedback + /// + public string Email + { + get { return linkLabelFeedback.Text; } + set { linkLabelFeedback.Text = value; } + } + + /// + /// The copyright info + /// e.g. Copyright © 2007 Mark Heath + /// + public string Copyright + { + get { return labelCopyright.Text; } + set { labelCopyright.Text = value; } + } + } +} \ No newline at end of file diff --git a/MixDiff/AboutForm.resx b/MixDiff/AboutForm.resx new file mode 100644 index 00000000..ff31a6db --- /dev/null +++ b/MixDiff/AboutForm.resx @@ -0,0 +1,120 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + \ No newline at end of file diff --git a/MixDiff/Images.Designer.cs b/MixDiff/Images.Designer.cs new file mode 100644 index 00000000..8be93219 --- /dev/null +++ b/MixDiff/Images.Designer.cs @@ -0,0 +1,143 @@ +//------------------------------------------------------------------------------ +// +// This code was generated by a tool. +// Runtime Version:4.0.30319.17929 +// +// Changes to this file may cause incorrect behavior and will be lost if +// the code is regenerated. +// +//------------------------------------------------------------------------------ + +namespace MarkHeath.AudioUtils { + using System; + + + /// + /// A strongly-typed resource class, for looking up localized strings, etc. + /// + // This class was auto-generated by the StronglyTypedResourceBuilder + // class via a tool like ResGen or Visual Studio. + // To add or remove a member, edit your .ResX file then rerun ResGen + // with the /str option, or rebuild your VS project. + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")] + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] + internal class Images { + + private static global::System.Resources.ResourceManager resourceMan; + + private static global::System.Globalization.CultureInfo resourceCulture; + + [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] + internal Images() { + } + + /// + /// Returns the cached ResourceManager instance used by this class. + /// + [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] + internal static global::System.Resources.ResourceManager ResourceManager { + get { + if (object.ReferenceEquals(resourceMan, null)) { + global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("MarkHeath.AudioUtils.Images", typeof(Images).Assembly); + resourceMan = temp; + } + return resourceMan; + } + } + + /// + /// Overrides the current thread's CurrentUICulture property for all + /// resource lookups using this strongly typed resource class. + /// + [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] + internal static global::System.Globalization.CultureInfo Culture { + get { + return resourceCulture; + } + set { + resourceCulture = value; + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap Back { + get { + object obj = ResourceManager.GetObject("Back", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap Forward { + get { + object obj = ResourceManager.GetObject("Forward", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap Loop { + get { + object obj = ResourceManager.GetObject("Loop", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap Pause { + get { + object obj = ResourceManager.GetObject("Pause", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap Play { + get { + object obj = ResourceManager.GetObject("Play", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap Rewind { + get { + object obj = ResourceManager.GetObject("Rewind", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap Shuffle { + get { + object obj = ResourceManager.GetObject("Shuffle", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap Stop { + get { + object obj = ResourceManager.GetObject("Stop", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + } +} diff --git a/MixDiff/Images.resx b/MixDiff/Images.resx new file mode 100644 index 00000000..7e225022 --- /dev/null +++ b/MixDiff/Images.resx @@ -0,0 +1,145 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + + Resources\Back.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + + + Resources\Forward.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + + + Resources\Loop.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + + + Resources\Pause.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + + + Resources\Play.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + + + Resources\Rewind.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + + + Resources\Shuffle.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + + + Resources\Stop.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + + \ No newline at end of file diff --git a/MixDiff/MixDiff.csproj b/MixDiff/MixDiff.csproj new file mode 100644 index 00000000..71a099b0 --- /dev/null +++ b/MixDiff/MixDiff.csproj @@ -0,0 +1,202 @@ + + + + Debug + AnyCPU + 8.0.50727 + 2.0 + {1293DD10-378A-4370-AEE2-AA1E9E87039B} + WinExe + Properties + MarkHeath.AudioUtils + MixDiff + + + + + + + + + + + + + 3.5 + v3.5 + publish\ + true + Disk + false + Foreground + 7 + Days + false + false + true + 0 + 1.0.0.%2a + false + false + true + Client + + + true + full + false + bin\Debug\ + DEBUG;TRACE + prompt + 4 + AllRules.ruleset + + + pdbonly + true + bin\Release\ + TRACE + prompt + 4 + AllRules.ruleset + + + + + + + + + + + + Form + + + AboutForm.cs + + + + True + True + Images.resx + + + Form + + + MixDiffForm.cs + + + + + Form + + + PropertiesForm.cs + + + + AboutForm.cs + Designer + + + Designer + ResXFileCodeGenerator + Images.Designer.cs + + + Designer + MixDiffForm.cs + + + Designer + PropertiesForm.cs + + + ResXFileCodeGenerator + Resources.Designer.cs + Designer + + + Designer + SettingsForm.cs + + + True + Resources.resx + True + + + SettingsSingleFileGenerator + Settings.Designer.cs + + + True + Settings.settings + True + + + Form + + + SettingsForm.cs + + + + + + + + + + + + + + + + + + + + + + + + + + {DA4F02E3-0B5E-42CD-B8D9-5583FA51D66E} + NAudio + + + + + + + + + False + .NET Framework 3.5 SP1 Client Profile + false + + + False + .NET Framework 3.5 SP1 + true + + + False + Windows Installer 3.1 + true + + + + + \ No newline at end of file diff --git a/MixDiff/MixDiff.csproj.vspscc b/MixDiff/MixDiff.csproj.vspscc new file mode 100644 index 00000000..979cc996 --- /dev/null +++ b/MixDiff/MixDiff.csproj.vspscc @@ -0,0 +1,10 @@ +"" +{ +"FILE_VERSION" = "9237" +"ENLISTMENT_CHOICE" = "NEVER" +"PROJECT_FILE_RELATIVE_PATH" = "relative:MixDiff" +"NUMBER_OF_EXCLUDED_FILES" = "0" +"ORIGINAL_PROJECT_FILE_PATH" = "" +"NUMBER_OF_NESTED_PROJECTS" = "0" +"SOURCE_CONTROL_SETTINGS_PROVIDER" = "PROVIDER" +} diff --git a/MixDiff/MixDiffForm.Designer.cs b/MixDiff/MixDiffForm.Designer.cs new file mode 100644 index 00000000..266d8373 --- /dev/null +++ b/MixDiff/MixDiffForm.Designer.cs @@ -0,0 +1,491 @@ +namespace MarkHeath.AudioUtils +{ + partial class MixDiffForm + { + /// + /// Required designer variable. + /// + private System.ComponentModel.IContainer components = null; + + /// + /// Clean up any resources being used. + /// + /// true if managed resources should be disposed; otherwise, false. + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Windows Form Designer generated code + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + this.components = new System.ComponentModel.Container(); + this.toolStrip1 = new System.Windows.Forms.ToolStrip(); + this.toolStripButtonPlay = new System.Windows.Forms.ToolStripButton(); + this.toolStripButtonPause = new System.Windows.Forms.ToolStripButton(); + this.toolStripButtonStop = new System.Windows.Forms.ToolStripButton(); + this.toolStripButtonBack = new System.Windows.Forms.ToolStripButton(); + this.toolStripButtonForward = new System.Windows.Forms.ToolStripButton(); + this.toolStripButtonRewind = new System.Windows.Forms.ToolStripButton(); + this.toolStripButtonLoop = new System.Windows.Forms.ToolStripButton(); + this.toolStripButtonShuffle = new System.Windows.Forms.ToolStripButton(); + this.toolStripSeparator1 = new System.Windows.Forms.ToolStripSeparator(); + this.toolStripLabel1 = new System.Windows.Forms.ToolStripLabel(); + this.toolStripLabelPosition = new System.Windows.Forms.ToolStripLabel(); + this.toolStripSeparator2 = new System.Windows.Forms.ToolStripSeparator(); + this.toolStripLabel2 = new System.Windows.Forms.ToolStripLabel(); + this.toolStripLabelLength = new System.Windows.Forms.ToolStripLabel(); + this.toolStripSeparator3 = new System.Windows.Forms.ToolStripSeparator(); + this.buttonA = new System.Windows.Forms.Button(); + this.contextMenuStrip1 = new System.Windows.Forms.ContextMenuStrip(this.components); + this.selectFileToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.clearToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.propertiesToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.buttonB = new System.Windows.Forms.Button(); + this.buttonC = new System.Windows.Forms.Button(); + this.buttonD = new System.Windows.Forms.Button(); + this.toolTip1 = new System.Windows.Forms.ToolTip(this.components); + this.timer1 = new System.Windows.Forms.Timer(this.components); + this.menuStrip1 = new System.Windows.Forms.MenuStrip(); + this.fileToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.openSavedComparisonToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.saveComparisonToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.exitToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.optionsToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.compareModeToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.currentPositionToolStripMenuItem1 = new System.Windows.Forms.ToolStripMenuItem(); + this.skipBackToolStripMenuItem1 = new System.Windows.Forms.ToolStripMenuItem(); + this.restartToolStripMenuItem1 = new System.Windows.Forms.ToolStripMenuItem(); + this.settingsToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.helpToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.contentsToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.aboutToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.toolStrip1.SuspendLayout(); + this.contextMenuStrip1.SuspendLayout(); + this.menuStrip1.SuspendLayout(); + this.SuspendLayout(); + // + // toolStrip1 + // + this.toolStrip1.Items.AddRange(new System.Windows.Forms.ToolStripItem[] { + this.toolStripButtonPlay, + this.toolStripButtonPause, + this.toolStripButtonStop, + this.toolStripButtonBack, + this.toolStripButtonForward, + this.toolStripButtonRewind, + this.toolStripButtonLoop, + this.toolStripButtonShuffle, + this.toolStripSeparator1, + this.toolStripLabel1, + this.toolStripLabelPosition, + this.toolStripSeparator2, + this.toolStripLabel2, + this.toolStripLabelLength, + this.toolStripSeparator3}); + this.toolStrip1.Location = new System.Drawing.Point(0, 24); + this.toolStrip1.Name = "toolStrip1"; + this.toolStrip1.Size = new System.Drawing.Size(642, 25); + this.toolStrip1.TabIndex = 7; + this.toolStrip1.Text = "toolStrip1"; + // + // toolStripButtonPlay + // + this.toolStripButtonPlay.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Image; + this.toolStripButtonPlay.Image = global::MarkHeath.AudioUtils.Images.Play; + this.toolStripButtonPlay.ImageTransparentColor = System.Drawing.Color.Magenta; + this.toolStripButtonPlay.Name = "toolStripButtonPlay"; + this.toolStripButtonPlay.Size = new System.Drawing.Size(23, 22); + this.toolStripButtonPlay.Text = "Play"; + this.toolStripButtonPlay.Click += new System.EventHandler(this.toolStripButtonPlay_Click); + // + // toolStripButtonPause + // + this.toolStripButtonPause.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Image; + this.toolStripButtonPause.Image = global::MarkHeath.AudioUtils.Images.Pause; + this.toolStripButtonPause.ImageTransparentColor = System.Drawing.Color.Magenta; + this.toolStripButtonPause.Name = "toolStripButtonPause"; + this.toolStripButtonPause.Size = new System.Drawing.Size(23, 22); + this.toolStripButtonPause.Text = "Pause"; + this.toolStripButtonPause.Click += new System.EventHandler(this.toolStripButtonPause_Click); + // + // toolStripButtonStop + // + this.toolStripButtonStop.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Image; + this.toolStripButtonStop.Image = global::MarkHeath.AudioUtils.Images.Stop; + this.toolStripButtonStop.ImageTransparentColor = System.Drawing.Color.Magenta; + this.toolStripButtonStop.Name = "toolStripButtonStop"; + this.toolStripButtonStop.Size = new System.Drawing.Size(23, 22); + this.toolStripButtonStop.Text = "Stop"; + this.toolStripButtonStop.Click += new System.EventHandler(this.toolStripButtonStop_Click); + // + // toolStripButtonBack + // + this.toolStripButtonBack.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Image; + this.toolStripButtonBack.Image = global::MarkHeath.AudioUtils.Images.Back; + this.toolStripButtonBack.ImageTransparentColor = System.Drawing.Color.Magenta; + this.toolStripButtonBack.Name = "toolStripButtonBack"; + this.toolStripButtonBack.Size = new System.Drawing.Size(23, 22); + this.toolStripButtonBack.Text = "Skip Back"; + this.toolStripButtonBack.Click += new System.EventHandler(this.toolStripButtonBack_Click); + // + // toolStripButtonForward + // + this.toolStripButtonForward.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Image; + this.toolStripButtonForward.Image = global::MarkHeath.AudioUtils.Images.Forward; + this.toolStripButtonForward.ImageTransparentColor = System.Drawing.Color.Magenta; + this.toolStripButtonForward.Name = "toolStripButtonForward"; + this.toolStripButtonForward.Size = new System.Drawing.Size(23, 22); + this.toolStripButtonForward.Text = "Skip Forward"; + this.toolStripButtonForward.Click += new System.EventHandler(this.toolStripButtonForward_Click); + // + // toolStripButtonRewind + // + this.toolStripButtonRewind.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Image; + this.toolStripButtonRewind.Image = global::MarkHeath.AudioUtils.Images.Rewind; + this.toolStripButtonRewind.ImageTransparentColor = System.Drawing.Color.Magenta; + this.toolStripButtonRewind.Name = "toolStripButtonRewind"; + this.toolStripButtonRewind.Size = new System.Drawing.Size(23, 22); + this.toolStripButtonRewind.Text = "Rewind"; + this.toolStripButtonRewind.Click += new System.EventHandler(this.toolStripButtonRewind_Click); + // + // toolStripButtonLoop + // + this.toolStripButtonLoop.CheckOnClick = true; + this.toolStripButtonLoop.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Image; + this.toolStripButtonLoop.Image = global::MarkHeath.AudioUtils.Images.Loop; + this.toolStripButtonLoop.ImageTransparentColor = System.Drawing.Color.Magenta; + this.toolStripButtonLoop.Name = "toolStripButtonLoop"; + this.toolStripButtonLoop.Size = new System.Drawing.Size(23, 22); + this.toolStripButtonLoop.Text = "Loop"; + // + // toolStripButtonShuffle + // + this.toolStripButtonShuffle.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Image; + this.toolStripButtonShuffle.Image = global::MarkHeath.AudioUtils.Images.Shuffle; + this.toolStripButtonShuffle.ImageTransparentColor = System.Drawing.Color.Magenta; + this.toolStripButtonShuffle.Name = "toolStripButtonShuffle"; + this.toolStripButtonShuffle.Size = new System.Drawing.Size(23, 22); + this.toolStripButtonShuffle.Text = "Shuffle"; + this.toolStripButtonShuffle.Click += new System.EventHandler(this.toolStripButtonShuffle_Click); + // + // toolStripSeparator1 + // + this.toolStripSeparator1.Name = "toolStripSeparator1"; + this.toolStripSeparator1.Size = new System.Drawing.Size(6, 25); + // + // toolStripLabel1 + // + this.toolStripLabel1.Name = "toolStripLabel1"; + this.toolStripLabel1.Size = new System.Drawing.Size(53, 22); + this.toolStripLabel1.Text = "Position:"; + // + // toolStripLabelPosition + // + this.toolStripLabelPosition.Name = "toolStripLabelPosition"; + this.toolStripLabelPosition.Size = new System.Drawing.Size(70, 22); + this.toolStripLabelPosition.Text = "00:00:00.000"; + this.toolStripLabelPosition.ToolTipText = "Position"; + // + // toolStripSeparator2 + // + this.toolStripSeparator2.Name = "toolStripSeparator2"; + this.toolStripSeparator2.Size = new System.Drawing.Size(6, 25); + // + // toolStripLabel2 + // + this.toolStripLabel2.Name = "toolStripLabel2"; + this.toolStripLabel2.Size = new System.Drawing.Size(47, 22); + this.toolStripLabel2.Text = "Length:"; + // + // toolStripLabelLength + // + this.toolStripLabelLength.Name = "toolStripLabelLength"; + this.toolStripLabelLength.Size = new System.Drawing.Size(49, 22); + this.toolStripLabelLength.Text = "00:00:00"; + // + // toolStripSeparator3 + // + this.toolStripSeparator3.Name = "toolStripSeparator3"; + this.toolStripSeparator3.Size = new System.Drawing.Size(6, 25); + // + // buttonA + // + this.buttonA.ContextMenuStrip = this.contextMenuStrip1; + this.buttonA.Font = new System.Drawing.Font("Verdana", 15.75F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0))); + this.buttonA.Location = new System.Drawing.Point(12, 62); + this.buttonA.Name = "buttonA"; + this.buttonA.Size = new System.Drawing.Size(150, 150); + this.buttonA.TabIndex = 8; + this.buttonA.Text = ""; + this.buttonA.UseVisualStyleBackColor = true; + this.buttonA.Click += new System.EventHandler(this.OnMixButtonClick); + // + // contextMenuStrip1 + // + this.contextMenuStrip1.Items.AddRange(new System.Windows.Forms.ToolStripItem[] { + this.selectFileToolStripMenuItem, + this.clearToolStripMenuItem, + this.propertiesToolStripMenuItem}); + this.contextMenuStrip1.Name = "contextMenuStrip1"; + this.contextMenuStrip1.Size = new System.Drawing.Size(137, 70); + // + // selectFileToolStripMenuItem + // + this.selectFileToolStripMenuItem.Name = "selectFileToolStripMenuItem"; + this.selectFileToolStripMenuItem.Size = new System.Drawing.Size(136, 22); + this.selectFileToolStripMenuItem.Text = "&Select File..."; + this.selectFileToolStripMenuItem.Click += new System.EventHandler(this.selectFileToolStripMenuItem_Click); + // + // clearToolStripMenuItem + // + this.clearToolStripMenuItem.Name = "clearToolStripMenuItem"; + this.clearToolStripMenuItem.Size = new System.Drawing.Size(136, 22); + this.clearToolStripMenuItem.Text = "&Clear"; + this.clearToolStripMenuItem.Click += new System.EventHandler(this.clearToolStripMenuItem_Click); + // + // propertiesToolStripMenuItem + // + this.propertiesToolStripMenuItem.Name = "propertiesToolStripMenuItem"; + this.propertiesToolStripMenuItem.Size = new System.Drawing.Size(136, 22); + this.propertiesToolStripMenuItem.Text = "&Properties..."; + this.propertiesToolStripMenuItem.Click += new System.EventHandler(this.propertiesToolStripMenuItem_Click); + // + // buttonB + // + this.buttonB.ContextMenuStrip = this.contextMenuStrip1; + this.buttonB.Font = new System.Drawing.Font("Verdana", 15.75F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0))); + this.buttonB.Location = new System.Drawing.Point(168, 62); + this.buttonB.Name = "buttonB"; + this.buttonB.Size = new System.Drawing.Size(150, 150); + this.buttonB.TabIndex = 9; + this.buttonB.Text = ""; + this.buttonB.UseVisualStyleBackColor = true; + this.buttonB.Click += new System.EventHandler(this.OnMixButtonClick); + // + // buttonC + // + this.buttonC.ContextMenuStrip = this.contextMenuStrip1; + this.buttonC.Font = new System.Drawing.Font("Verdana", 15.75F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0))); + this.buttonC.Location = new System.Drawing.Point(324, 62); + this.buttonC.Name = "buttonC"; + this.buttonC.Size = new System.Drawing.Size(150, 150); + this.buttonC.TabIndex = 10; + this.buttonC.Text = ""; + this.buttonC.UseVisualStyleBackColor = true; + this.buttonC.Click += new System.EventHandler(this.OnMixButtonClick); + // + // buttonD + // + this.buttonD.ContextMenuStrip = this.contextMenuStrip1; + this.buttonD.Font = new System.Drawing.Font("Verdana", 15.75F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0))); + this.buttonD.Location = new System.Drawing.Point(480, 62); + this.buttonD.Name = "buttonD"; + this.buttonD.Size = new System.Drawing.Size(150, 150); + this.buttonD.TabIndex = 11; + this.buttonD.Text = ""; + this.buttonD.UseVisualStyleBackColor = true; + this.buttonD.Click += new System.EventHandler(this.OnMixButtonClick); + // + // timer1 + // + this.timer1.Interval = 200; + this.timer1.Tick += new System.EventHandler(this.timer1_Tick); + // + // menuStrip1 + // + this.menuStrip1.Items.AddRange(new System.Windows.Forms.ToolStripItem[] { + this.fileToolStripMenuItem, + this.optionsToolStripMenuItem, + this.helpToolStripMenuItem}); + this.menuStrip1.Location = new System.Drawing.Point(0, 0); + this.menuStrip1.Name = "menuStrip1"; + this.menuStrip1.Size = new System.Drawing.Size(642, 24); + this.menuStrip1.TabIndex = 11; + this.menuStrip1.Text = "menuStrip1"; + // + // fileToolStripMenuItem + // + this.fileToolStripMenuItem.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] { + this.openSavedComparisonToolStripMenuItem, + this.saveComparisonToolStripMenuItem, + this.exitToolStripMenuItem}); + this.fileToolStripMenuItem.Name = "fileToolStripMenuItem"; + this.fileToolStripMenuItem.Size = new System.Drawing.Size(37, 20); + this.fileToolStripMenuItem.Text = "&File"; + // + // openSavedComparisonToolStripMenuItem + // + this.openSavedComparisonToolStripMenuItem.Name = "openSavedComparisonToolStripMenuItem"; + this.openSavedComparisonToolStripMenuItem.Size = new System.Drawing.Size(180, 22); + this.openSavedComparisonToolStripMenuItem.Text = "Open Comparison..."; + this.openSavedComparisonToolStripMenuItem.Click += new System.EventHandler(this.openSavedComparisonToolStripMenuItem_Click); + // + // saveComparisonToolStripMenuItem + // + this.saveComparisonToolStripMenuItem.Name = "saveComparisonToolStripMenuItem"; + this.saveComparisonToolStripMenuItem.Size = new System.Drawing.Size(180, 22); + this.saveComparisonToolStripMenuItem.Text = "Save Comparison..."; + this.saveComparisonToolStripMenuItem.Click += new System.EventHandler(this.saveComparisonToolStripMenuItem_Click); + // + // exitToolStripMenuItem + // + this.exitToolStripMenuItem.Name = "exitToolStripMenuItem"; + this.exitToolStripMenuItem.Size = new System.Drawing.Size(180, 22); + this.exitToolStripMenuItem.Text = "E&xit"; + this.exitToolStripMenuItem.Click += new System.EventHandler(this.exitToolStripMenuItem_Click); + // + // optionsToolStripMenuItem + // + this.optionsToolStripMenuItem.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] { + this.compareModeToolStripMenuItem, + this.settingsToolStripMenuItem}); + this.optionsToolStripMenuItem.Name = "optionsToolStripMenuItem"; + this.optionsToolStripMenuItem.Size = new System.Drawing.Size(61, 20); + this.optionsToolStripMenuItem.Text = "&Options"; + // + // compareModeToolStripMenuItem + // + this.compareModeToolStripMenuItem.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] { + this.currentPositionToolStripMenuItem1, + this.skipBackToolStripMenuItem1, + this.restartToolStripMenuItem1}); + this.compareModeToolStripMenuItem.Name = "compareModeToolStripMenuItem"; + this.compareModeToolStripMenuItem.Size = new System.Drawing.Size(157, 22); + this.compareModeToolStripMenuItem.Text = "&Compare Mode"; + // + // currentPositionToolStripMenuItem1 + // + this.currentPositionToolStripMenuItem1.Checked = true; + this.currentPositionToolStripMenuItem1.CheckState = System.Windows.Forms.CheckState.Checked; + this.currentPositionToolStripMenuItem1.Name = "currentPositionToolStripMenuItem1"; + this.currentPositionToolStripMenuItem1.Size = new System.Drawing.Size(160, 22); + this.currentPositionToolStripMenuItem1.Text = "&Current Position"; + this.currentPositionToolStripMenuItem1.Click += new System.EventHandler(this.currentPositionToolStripMenuItem1_Click); + // + // skipBackToolStripMenuItem1 + // + this.skipBackToolStripMenuItem1.Name = "skipBackToolStripMenuItem1"; + this.skipBackToolStripMenuItem1.Size = new System.Drawing.Size(160, 22); + this.skipBackToolStripMenuItem1.Text = "&Skip Back"; + this.skipBackToolStripMenuItem1.Click += new System.EventHandler(this.skipBackToolStripMenuItem1_Click); + // + // restartToolStripMenuItem1 + // + this.restartToolStripMenuItem1.Name = "restartToolStripMenuItem1"; + this.restartToolStripMenuItem1.Size = new System.Drawing.Size(160, 22); + this.restartToolStripMenuItem1.Text = "&Restart"; + this.restartToolStripMenuItem1.Click += new System.EventHandler(this.restartToolStripMenuItem1_Click); + // + // settingsToolStripMenuItem + // + this.settingsToolStripMenuItem.Name = "settingsToolStripMenuItem"; + this.settingsToolStripMenuItem.Size = new System.Drawing.Size(157, 22); + this.settingsToolStripMenuItem.Text = "&Settings..."; + this.settingsToolStripMenuItem.Click += new System.EventHandler(this.settingsToolStripMenuItem_Click); + // + // helpToolStripMenuItem + // + this.helpToolStripMenuItem.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] { + this.contentsToolStripMenuItem, + this.aboutToolStripMenuItem}); + this.helpToolStripMenuItem.Name = "helpToolStripMenuItem"; + this.helpToolStripMenuItem.Size = new System.Drawing.Size(44, 20); + this.helpToolStripMenuItem.Text = "&Help"; + // + // contentsToolStripMenuItem + // + this.contentsToolStripMenuItem.Name = "contentsToolStripMenuItem"; + this.contentsToolStripMenuItem.Size = new System.Drawing.Size(122, 22); + this.contentsToolStripMenuItem.Text = "&Contents"; + this.contentsToolStripMenuItem.Click += new System.EventHandler(this.contentsToolStripMenuItem_Click); + // + // aboutToolStripMenuItem + // + this.aboutToolStripMenuItem.Name = "aboutToolStripMenuItem"; + this.aboutToolStripMenuItem.Size = new System.Drawing.Size(122, 22); + this.aboutToolStripMenuItem.Text = "&About"; + this.aboutToolStripMenuItem.Click += new System.EventHandler(this.aboutToolStripMenuItem_Click); + // + // MixDiffForm + // + this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.ClientSize = new System.Drawing.Size(642, 296); + this.Controls.Add(this.buttonD); + this.Controls.Add(this.toolStrip1); + this.Controls.Add(this.buttonC); + this.Controls.Add(this.buttonB); + this.Controls.Add(this.buttonA); + this.Controls.Add(this.menuStrip1); + this.KeyPreview = true; + this.MainMenuStrip = this.menuStrip1; + this.Name = "MixDiffForm"; + this.Text = "MixDiff"; + this.FormClosing += new System.Windows.Forms.FormClosingEventHandler(this.MixDiffForm_FormClosing); + this.KeyDown += new System.Windows.Forms.KeyEventHandler(this.MixDiffForm_KeyDown); + this.toolStrip1.ResumeLayout(false); + this.toolStrip1.PerformLayout(); + this.contextMenuStrip1.ResumeLayout(false); + this.menuStrip1.ResumeLayout(false); + this.menuStrip1.PerformLayout(); + this.ResumeLayout(false); + this.PerformLayout(); + + } + + #endregion + + private System.Windows.Forms.ToolStrip toolStrip1; + private System.Windows.Forms.ToolStripButton toolStripButtonPlay; + private System.Windows.Forms.ToolStripButton toolStripButtonPause; + private System.Windows.Forms.ToolStripButton toolStripButtonStop; + private System.Windows.Forms.ToolStripButton toolStripButtonBack; + private System.Windows.Forms.ToolStripButton toolStripButtonForward; + private System.Windows.Forms.ToolStripButton toolStripButtonRewind; + private System.Windows.Forms.ToolStripButton toolStripButtonLoop; + private System.Windows.Forms.Button buttonA; + private System.Windows.Forms.ToolStripSeparator toolStripSeparator1; + private System.Windows.Forms.ToolStripLabel toolStripLabelPosition; + private System.Windows.Forms.Button buttonB; + private System.Windows.Forms.Button buttonC; + private System.Windows.Forms.Button buttonD; + private System.Windows.Forms.ToolTip toolTip1; + private System.Windows.Forms.ContextMenuStrip contextMenuStrip1; + private System.Windows.Forms.ToolStripMenuItem clearToolStripMenuItem; + private System.Windows.Forms.Timer timer1; + private System.Windows.Forms.ToolStripLabel toolStripLabel1; + private System.Windows.Forms.ToolStripSeparator toolStripSeparator2; + private System.Windows.Forms.MenuStrip menuStrip1; + private System.Windows.Forms.ToolStripMenuItem fileToolStripMenuItem; + private System.Windows.Forms.ToolStripMenuItem openSavedComparisonToolStripMenuItem; + private System.Windows.Forms.ToolStripMenuItem saveComparisonToolStripMenuItem; + private System.Windows.Forms.ToolStripMenuItem exitToolStripMenuItem; + private System.Windows.Forms.ToolStripMenuItem helpToolStripMenuItem; + private System.Windows.Forms.ToolStripMenuItem contentsToolStripMenuItem; + private System.Windows.Forms.ToolStripMenuItem aboutToolStripMenuItem; + private System.Windows.Forms.ToolStripMenuItem optionsToolStripMenuItem; + private System.Windows.Forms.ToolStripMenuItem compareModeToolStripMenuItem; + private System.Windows.Forms.ToolStripMenuItem currentPositionToolStripMenuItem1; + private System.Windows.Forms.ToolStripMenuItem skipBackToolStripMenuItem1; + private System.Windows.Forms.ToolStripMenuItem restartToolStripMenuItem1; + private System.Windows.Forms.ToolStripLabel toolStripLabel2; + private System.Windows.Forms.ToolStripLabel toolStripLabelLength; + private System.Windows.Forms.ToolStripMenuItem settingsToolStripMenuItem; + private System.Windows.Forms.ToolStripMenuItem selectFileToolStripMenuItem; + private System.Windows.Forms.ToolStripMenuItem propertiesToolStripMenuItem; + private System.Windows.Forms.ToolStripButton toolStripButtonShuffle; + private System.Windows.Forms.ToolStripSeparator toolStripSeparator3; + + } +} + diff --git a/MixDiff/MixDiffForm.cs b/MixDiff/MixDiffForm.cs new file mode 100644 index 00000000..b4847bf7 --- /dev/null +++ b/MixDiff/MixDiffForm.cs @@ -0,0 +1,612 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Data; +using System.Drawing; +using System.Text; +using System.Windows.Forms; +using System.Xml; +using NAudio.Wave; +using MarkHeath.AudioUtils.Properties; + +namespace MarkHeath.AudioUtils +{ + public partial class MixDiffForm : Form + { + private PlaybackStatus playbackStatus; + private IWavePlayer wavePlayer; + readonly Font BigFont = new Font("Verdana", 36, FontStyle.Bold); + readonly Font EmptyFont = new Font("Verdana", 16, FontStyle.Bold); + private WaveMixerStream32 mixer; + private int skipSeconds; + private Button selectedButton; + private CompareMode compareMode; + private List + + + + + + diff --git a/NAudioWpfDemo/AudioPlaybackDemo/AudioPlaybackDemoView.xaml.cs b/NAudioWpfDemo/AudioPlaybackDemo/AudioPlaybackDemoView.xaml.cs new file mode 100644 index 00000000..9cda2c3b --- /dev/null +++ b/NAudioWpfDemo/AudioPlaybackDemo/AudioPlaybackDemoView.xaml.cs @@ -0,0 +1,27 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Windows; +using System.Windows.Controls; +using System.Windows.Data; +using System.Windows.Documents; +using System.Windows.Input; +using System.Windows.Media; +using System.Windows.Media.Imaging; +using System.Windows.Navigation; +using System.Windows.Shapes; + +namespace NAudioWpfDemo +{ + /// + /// Interaction logic for AudioPlaybackDemo.xaml + /// + public partial class AudioPlaybackDemoView : UserControl + { + public AudioPlaybackDemoView() + { + InitializeComponent(); + } + } +} diff --git a/NAudioWpfDemo/AudioPlaybackDemo/AudioPlaybackViewModel.cs b/NAudioWpfDemo/AudioPlaybackDemo/AudioPlaybackViewModel.cs new file mode 100644 index 00000000..1a8566f7 --- /dev/null +++ b/NAudioWpfDemo/AudioPlaybackDemo/AudioPlaybackViewModel.cs @@ -0,0 +1,124 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.ComponentModel; +using System.Windows.Input; +using Microsoft.Win32; +using System.Windows; +using NAudio.Wave; +using NAudioWpfDemo.AudioPlaybackDemo; +using NAudioWpfDemo.ViewModel; + +namespace NAudioWpfDemo +{ + class AudioPlaybackViewModel : ViewModelBase, IDisposable + { + private AudioPlayback audioPlayback; + private List visualizations; + private IVisualizationPlugin selectedVisualization; + private string selectedFile; + + public ICommand OpenFileCommand { get; private set; } + public ICommand PlayCommand { get; private set; } + public ICommand PauseCommand { get; private set; } + public ICommand StopCommand { get; private set; } + + public AudioPlaybackViewModel(IEnumerable visualizations) + { + this.visualizations = new List(visualizations); + this.selectedVisualization = this.visualizations.FirstOrDefault(); + + this.audioPlayback = new AudioPlayback(); + audioPlayback.MaximumCalculated += audioGraph_MaximumCalculated; + audioPlayback.FftCalculated += audioGraph_FftCalculated; + + PlayCommand = new DelegateCommand(Play); + OpenFileCommand = new DelegateCommand(OpenFile); + StopCommand = new DelegateCommand(Stop); + PauseCommand = new DelegateCommand(Pause); + } + + private void Pause() + { + audioPlayback.Pause(); + } + + public IList Visualizations { get { return this.visualizations; } } + + public IVisualizationPlugin SelectedVisualization + { + get + { + return this.selectedVisualization; + } + set + { + if (this.selectedVisualization != value) + { + this.selectedVisualization = value; + OnPropertyChanged("SelectedVisualization"); + OnPropertyChanged("Visualization"); + } + } + } + + public object Visualization + { + get + { + return this.selectedVisualization.Content; + } + } + + void audioGraph_FftCalculated(object sender, FftEventArgs e) + { + if (this.SelectedVisualization != null) + { + this.SelectedVisualization.OnFftCalculated(e.Result); + } + } + + void audioGraph_MaximumCalculated(object sender, MaxSampleEventArgs e) + { + if (this.SelectedVisualization != null) + { + this.SelectedVisualization.OnMaxCalculated(e.MinSample, e.MaxSample); + } + } + + private void OpenFile() + { + OpenFileDialog openFileDialog = new OpenFileDialog(); + openFileDialog.Filter = "All Supported Files (*.wav;*.mp3)|*.wav;*.mp3|All Files (*.*)|*.*"; + bool? result = openFileDialog.ShowDialog(); + if (result.HasValue && result.Value) + { + this.selectedFile = openFileDialog.FileName; + audioPlayback.Load(this.selectedFile); + } + } + + private void Play() + { + if (this.selectedFile == null) + { + OpenFile(); + } + if (this.selectedFile != null) + { + audioPlayback.Play(); + } + } + + private void Stop() + { + audioPlayback.Stop(); + } + + public void Dispose() + { + audioPlayback.Dispose(); + } + } +} diff --git a/NAudioWpfDemo/AudioPlaybackDemo/IVisualizationPlugin.cs b/NAudioWpfDemo/AudioPlaybackDemo/IVisualizationPlugin.cs new file mode 100644 index 00000000..0f0139b5 --- /dev/null +++ b/NAudioWpfDemo/AudioPlaybackDemo/IVisualizationPlugin.cs @@ -0,0 +1,18 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using NAudio.Dsp; + +namespace NAudioWpfDemo.AudioPlaybackDemo +{ + interface IVisualizationPlugin + { + string Name { get; } + object Content { get; } + + // n.b. not great design, need to refactor so visualizations can attach to the playback graph and measure just what they need + void OnMaxCalculated(float min, float max); + void OnFftCalculated(Complex[] result); + } +} diff --git a/NAudioWpfDemo/AudioPlaybackDemo/PolygonWaveFormVisualization.cs b/NAudioWpfDemo/AudioPlaybackDemo/PolygonWaveFormVisualization.cs new file mode 100644 index 00000000..1fcf962c --- /dev/null +++ b/NAudioWpfDemo/AudioPlaybackDemo/PolygonWaveFormVisualization.cs @@ -0,0 +1,35 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.ComponentModel.Composition; + +namespace NAudioWpfDemo.AudioPlaybackDemo +{ + [Export(typeof(IVisualizationPlugin))] + class PolygonWaveFormVisualization : IVisualizationPlugin + { + private PolygonWaveFormControl polygonWaveFormControl = new PolygonWaveFormControl(); + + public string Name + { + get { return "Polygon WaveForm Visualization"; } + } + + public object Content + { + get { return polygonWaveFormControl; } + } + + + public void OnMaxCalculated(float min, float max) + { + polygonWaveFormControl.AddValue(max, min); + } + + public void OnFftCalculated(NAudio.Dsp.Complex[] result) + { + // nothing to do + } + } +} diff --git a/NAudioWpfDemo/AudioPlaybackDemo/PolylineWaveFormVisualization.cs b/NAudioWpfDemo/AudioPlaybackDemo/PolylineWaveFormVisualization.cs new file mode 100644 index 00000000..87946fc9 --- /dev/null +++ b/NAudioWpfDemo/AudioPlaybackDemo/PolylineWaveFormVisualization.cs @@ -0,0 +1,34 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.ComponentModel.Composition; + +namespace NAudioWpfDemo.AudioPlaybackDemo +{ + [Export(typeof(IVisualizationPlugin))] + class PolylineWaveFormVisualization : IVisualizationPlugin + { + private PolylineWaveFormControl polylineWaveFormControl = new PolylineWaveFormControl(); + + public string Name + { + get { return "Polyline WaveForm Visualization"; } + } + + public object Content + { + get { return polylineWaveFormControl; } + } + + public void OnMaxCalculated(float min, float max) + { + polylineWaveFormControl.AddValue(max, min); + } + + public void OnFftCalculated(NAudio.Dsp.Complex[] result) + { + // nothing to do + } + } +} diff --git a/NAudioWpfDemo/AudioPlaybackDemo/SampleAggregator.cs b/NAudioWpfDemo/AudioPlaybackDemo/SampleAggregator.cs new file mode 100644 index 00000000..e943fb69 --- /dev/null +++ b/NAudioWpfDemo/AudioPlaybackDemo/SampleAggregator.cs @@ -0,0 +1,121 @@ +using System; +using System.Collections.Generic; +using System.Text; +using System.Diagnostics; +using NAudio.Dsp; +using NAudio.Wave; + +namespace NAudioWpfDemo +{ + public class SampleAggregator : ISampleProvider + { + // volume + public event EventHandler MaximumCalculated; + private float maxValue; + private float minValue; + public int NotificationCount { get; set; } + int count; + + // FFT + public event EventHandler FftCalculated; + public bool PerformFFT { get; set; } + private readonly Complex[] fftBuffer; + private readonly FftEventArgs fftArgs; + private int fftPos; + private readonly int fftLength; + private int m; + private readonly ISampleProvider source; + + private readonly int channels; + + public SampleAggregator(ISampleProvider source, int fftLength = 1024) + { + channels = source.WaveFormat.Channels; + if (!IsPowerOfTwo(fftLength)) + { + throw new ArgumentException("FFT Length must be a power of two"); + } + this.m = (int)Math.Log(fftLength, 2.0); + this.fftLength = fftLength; + this.fftBuffer = new Complex[fftLength]; + this.fftArgs = new FftEventArgs(fftBuffer); + this.source = source; + } + + bool IsPowerOfTwo(int x) + { + return (x & (x - 1)) == 0; + } + + + public void Reset() + { + count = 0; + maxValue = minValue = 0; + } + + private void Add(float value) + { + if (PerformFFT && FftCalculated != null) + { + fftBuffer[fftPos].X = (float)(value * FastFourierTransform.HammingWindow(fftPos, fftLength)); + fftBuffer[fftPos].Y = 0; + fftPos++; + if (fftPos >= fftBuffer.Length) + { + fftPos = 0; + // 1024 = 2^10 + FastFourierTransform.FFT(true, m, fftBuffer); + FftCalculated(this, fftArgs); + } + } + + maxValue = Math.Max(maxValue, value); + minValue = Math.Min(minValue, value); + count++; + if (count >= NotificationCount && NotificationCount > 0) + { + if (MaximumCalculated != null) + { + MaximumCalculated(this, new MaxSampleEventArgs(minValue, maxValue)); + } + Reset(); + } + } + + public WaveFormat WaveFormat { get { return source.WaveFormat; } } + + public int Read(float[] buffer, int offset, int count) + { + var samplesRead = source.Read(buffer, offset, count); + + for (int n = 0; n < samplesRead; n+=channels) + { + Add(buffer[n+offset]); + } + return samplesRead; + } + } + + public class MaxSampleEventArgs : EventArgs + { + [DebuggerStepThrough] + public MaxSampleEventArgs(float minValue, float maxValue) + { + this.MaxSample = maxValue; + this.MinSample = minValue; + } + public float MaxSample { get; private set; } + public float MinSample { get; private set; } + } + + public class FftEventArgs : EventArgs + { + [DebuggerStepThrough] + public FftEventArgs(Complex[] result) + { + this.Result = result; + } + public Complex[] Result { get; private set; } + } +} diff --git a/NAudioWpfDemo/AudioPlaybackDemo/SpectrumAnalyzerVisualization.cs b/NAudioWpfDemo/AudioPlaybackDemo/SpectrumAnalyzerVisualization.cs new file mode 100644 index 00000000..6fdc7a88 --- /dev/null +++ b/NAudioWpfDemo/AudioPlaybackDemo/SpectrumAnalyzerVisualization.cs @@ -0,0 +1,35 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.ComponentModel.Composition; + +namespace NAudioWpfDemo.AudioPlaybackDemo +{ + [Export(typeof(IVisualizationPlugin))] + class SpectrumAnalyzerVisualization : IVisualizationPlugin + { + private SpectrumAnalyser spectrumAnalyser = new SpectrumAnalyser(); + + public string Name + { + get { return "Spectrum Analyser"; } + } + + public object Content + { + get { return spectrumAnalyser; } + } + + + public void OnMaxCalculated(float min, float max) + { + // nothing to do + } + + public void OnFftCalculated(NAudio.Dsp.Complex[] result) + { + spectrumAnalyser.Update(result); + } + } +} diff --git a/NAudioWpfDemo/AudioPlaybackDemo/WaveformVisual.cs b/NAudioWpfDemo/AudioPlaybackDemo/WaveformVisual.cs new file mode 100644 index 00000000..b07ccd23 --- /dev/null +++ b/NAudioWpfDemo/AudioPlaybackDemo/WaveformVisual.cs @@ -0,0 +1,114 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Windows.Media; +using System.Windows; + +namespace NAudioWpfDemo +{ + class WaveFormVisual : FrameworkElement, IWaveFormRenderer + { + // Create a collection of child visual objects. + private VisualCollection _children; + private List maxPoints; + private List minPoints; + double yTranslate = 40; + double yScale = 40; + + public WaveFormVisual() + { + maxPoints = new List(); + minPoints = new List(); + _children = new VisualCollection(this); + _children.Add(CreateWaveFormVisual()); + } + + private DrawingVisual CreateWaveFormVisual() + { + DrawingVisual drawingVisual = new DrawingVisual(); + + // Retrieve the DrawingContext in order to create new drawing content. + DrawingContext drawingContext = drawingVisual.RenderOpen(); + if (maxPoints.Count > 0) + { + RenderPolygon(drawingContext); + } + + //drawingContext.DrawGeometry + // Create a rectangle and draw it in the DrawingContext. + //Rect rect = new Rect(new System.Windows.Point(160, 100), new System.Windows.Size(320, 80)); + //drawingContext.DrawRectangle(System.Windows.Media.Brushes.LightBlue, (System.Windows.Media.Pen)null, rect); + + // Persist the drawing content. + drawingContext.Close(); + + return drawingVisual; + } + + private void RenderPolygon(DrawingContext drawingContext) + { + var fillBrush = Brushes.LawnGreen; + var borderPen = new Pen(Brushes.Black,1.0); + + PathFigure myPathFigure = new PathFigure(); + myPathFigure.StartPoint = maxPoints[0]; + + //PolyLineSegment seg = new PolyLineSegment( + + PathSegmentCollection myPathSegmentCollection = new PathSegmentCollection(); + + for (int i = 1; i < maxPoints.Count; i++) + { + myPathSegmentCollection.Add(new LineSegment(maxPoints[i], true)); + } + for (int i = minPoints.Count - 1; i >= 0; i--) + { + myPathSegmentCollection.Add(new LineSegment(minPoints[i], true)); + } + + myPathFigure.Segments = myPathSegmentCollection; + PathGeometry myPathGeometry = new PathGeometry(); + + myPathGeometry.Figures.Add(myPathFigure); + + drawingContext.DrawGeometry(fillBrush, borderPen, myPathGeometry); + } + + // Provide a required override for the VisualChildrenCount property. + protected override int VisualChildrenCount + { + get { return _children.Count; } + } + + // Provide a required override for the GetVisualChild method. + protected override Visual GetVisualChild(int index) + { + if (index < 0 || index >= _children.Count) + { + throw new ArgumentOutOfRangeException(); + } + + return _children[index]; + } + + + #region IWaveFormRenderer Members + + public void AddValue(float maxValue, float minValue) + { + int xpos = maxPoints.Count; + maxPoints.Add(new Point(xpos, SampleToYPosition(minValue))); + minPoints.Add(new Point(xpos, SampleToYPosition(maxValue))); + _children.Clear(); + + _children.Add(CreateWaveFormVisual()); + this.InvalidateVisual(); + } + private double SampleToYPosition(float value) + { + return yTranslate + value * yScale; + } + #endregion + } +} diff --git a/NAudioWpfDemo/DrumMachineDemo/DrumKit.cs b/NAudioWpfDemo/DrumMachineDemo/DrumKit.cs new file mode 100644 index 00000000..d417d5dc --- /dev/null +++ b/NAudioWpfDemo/DrumMachineDemo/DrumKit.cs @@ -0,0 +1,40 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using NAudio.Wave; +using NAudio.Wave.SampleProviders; + +namespace NAudioWpfDemo.DrumMachineDemo +{ + class DrumKit + { + private List sampleSources; + private WaveFormat waveFormat; + + public DrumKit() + { + SampleSource kickSample = SampleSource.CreateFromWaveFile("Samples\\kick-trimmed.wav"); + SampleSource snareSample = SampleSource.CreateFromWaveFile("Samples\\snare-trimmed.wav"); + SampleSource closedHatsSample = SampleSource.CreateFromWaveFile("Samples\\closed-hat-trimmed.wav"); + SampleSource openHatsSample = SampleSource.CreateFromWaveFile("Samples\\open-hat-trimmed.wav"); + sampleSources = new List(); + + sampleSources.Add(kickSample); + sampleSources.Add(snareSample); + sampleSources.Add(closedHatsSample); + sampleSources.Add(openHatsSample); + this.waveFormat = WaveFormat.CreateIeeeFloatWaveFormat(openHatsSample.SampleWaveFormat.SampleRate, openHatsSample.SampleWaveFormat.Channels); + } + + public virtual WaveFormat WaveFormat + { + get { return waveFormat; } + } + + public MusicSampleProvider GetSampleProvider(int note) + { + return new MusicSampleProvider(this.sampleSources[note]); + } + } +} diff --git a/NAudioWpfDemo/DrumMachineDemo/DrumMachineDemoPlugin.cs b/NAudioWpfDemo/DrumMachineDemo/DrumMachineDemoPlugin.cs new file mode 100644 index 00000000..754ed621 --- /dev/null +++ b/NAudioWpfDemo/DrumMachineDemo/DrumMachineDemoPlugin.cs @@ -0,0 +1,43 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.ComponentModel.Composition; + +namespace NAudioWpfDemo.DrumMachineDemo +{ + [Export(typeof(IModule))] + class DrumMachineDemoPlugin : IModule + { + private DrumMachineDemoView view; + private DrumMachineDemoViewModel viewModel; + public string Name + { + get { return "Drum Machine"; } + } + + public System.Windows.Controls.UserControl UserInterface + { + get + { + if (view == null) + { + view = new DrumMachineDemoView(); + viewModel = new DrumMachineDemoViewModel(view.drumPatternEditor1.DrumPattern); + view.DataContext = viewModel; + } + return view; + } + } + + public void Deactivate() + { + if (view != null) + { + viewModel.Dispose(); + view = null; + viewModel = null; + } + } + } +} diff --git a/NAudioWpfDemo/DrumMachineDemo/DrumMachineDemoView.xaml b/NAudioWpfDemo/DrumMachineDemo/DrumMachineDemoView.xaml new file mode 100644 index 00000000..77169ad1 --- /dev/null +++ b/NAudioWpfDemo/DrumMachineDemo/DrumMachineDemoView.xaml @@ -0,0 +1,22 @@ + + + + + + + + + + + + + + + diff --git a/NAudioWpfDemo/EqualizationDemo/EqualizationDemoView.xaml.cs b/NAudioWpfDemo/EqualizationDemo/EqualizationDemoView.xaml.cs new file mode 100644 index 00000000..32405ada --- /dev/null +++ b/NAudioWpfDemo/EqualizationDemo/EqualizationDemoView.xaml.cs @@ -0,0 +1,17 @@ +using System; +using System.Linq; +using System.Windows.Controls; + +namespace NAudioWpfDemo.EqualizationDemo +{ + /// + /// Interaction logic for AudioPlaybackDemo.xaml + /// + public partial class EqualizationDemoView : UserControl + { + public EqualizationDemoView() + { + InitializeComponent(); + } + } +} diff --git a/NAudioWpfDemo/EqualizationDemo/EqualizationDemoViewModel.cs b/NAudioWpfDemo/EqualizationDemo/EqualizationDemoViewModel.cs new file mode 100644 index 00000000..0f558a6b --- /dev/null +++ b/NAudioWpfDemo/EqualizationDemo/EqualizationDemoViewModel.cs @@ -0,0 +1,220 @@ +using System; +using System.ComponentModel; +using System.Linq; +using System.Windows.Input; +using Microsoft.Win32; +using NAudio.Wave; +using NAudioWpfDemo.ViewModel; + +namespace NAudioWpfDemo.EqualizationDemo +{ + class EqualizationDemoViewModel : ViewModelBase, IDisposable + { + private AudioFileReader reader; + private IWavePlayer player; + private Equalizer equalizer; + private string selectedFile; + private readonly EqualizerBand[] bands; + + public ICommand OpenFileCommand { get; private set; } + public ICommand PlayCommand { get; private set; } + public ICommand PauseCommand { get; private set; } + public ICommand StopCommand { get; private set; } + + public EqualizationDemoViewModel() + { + PlayCommand = new DelegateCommand(Play); + OpenFileCommand = new DelegateCommand(OpenFile); + StopCommand = new DelegateCommand(Stop); + PauseCommand = new DelegateCommand(Pause); + bands = new EqualizerBand[] + { + new EqualizerBand {Bandwidth = 0.8f, Frequency = 100, Gain = 0}, + new EqualizerBand {Bandwidth = 0.8f, Frequency = 200, Gain = 0}, + new EqualizerBand {Bandwidth = 0.8f, Frequency = 400, Gain = 0}, + new EqualizerBand {Bandwidth = 0.8f, Frequency = 800, Gain = 0}, + new EqualizerBand {Bandwidth = 0.8f, Frequency = 1200, Gain = 0}, + new EqualizerBand {Bandwidth = 0.8f, Frequency = 2400, Gain = 0}, + new EqualizerBand {Bandwidth = 0.8f, Frequency = 4800, Gain = 0}, + new EqualizerBand {Bandwidth = 0.8f, Frequency = 9600, Gain = 0}, + }; + this.PropertyChanged += OnPropertyChanged; + } + + private void OnPropertyChanged(object sender, PropertyChangedEventArgs propertyChangedEventArgs) + { + if (equalizer!=null) equalizer.Update(); + } + + public float MinimumGain + { + get { return -30; } + } + + public float MaximumGain + { + get { return 30; } + } + + public float Band1 + { + get { return bands[0].Gain; } + set + { + if (bands[0].Gain != value) + { + bands[0].Gain = value; + OnPropertyChanged("Band1"); + } + } + } + + public float Band2 + { + get { return bands[1].Gain; } + set + { + if (bands[1].Gain != value) + { + bands[1].Gain = value; + OnPropertyChanged("Band2"); + } + } + } + + public float Band3 + { + get { return bands[2].Gain; } + set + { + if (bands[2].Gain != value) + { + bands[2].Gain = value; + OnPropertyChanged("Band3"); + } + } + } + + public float Band4 + { + get { return bands[3].Gain; } + set + { + if (bands[3].Gain != value) + { + bands[3].Gain = value; + OnPropertyChanged("Band4"); + } + } + } + + public float Band5 + { + get { return bands[4].Gain; } + set + { + if (bands[4].Gain != value) + { + bands[4].Gain = value; + OnPropertyChanged("Band5"); + } + } + } + + public float Band6 + { + get { return bands[5].Gain; } + set + { + if (bands[5].Gain != value) + { + bands[5].Gain = value; + OnPropertyChanged("Band6"); + } + } + } + + + public float Band7 + { + get { return bands[6].Gain; } + set + { + if (bands[6].Gain != value) + { + bands[6].Gain = value; + OnPropertyChanged("Band7"); + } + } + } + + public float Band8 + { + get { return bands[7].Gain; } + set + { + if (bands[7].Gain != value) + { + bands[7].Gain = value; + OnPropertyChanged("Band7"); + } + } + } + + private void Pause() + { + if (player != null) + { + player.Pause(); + } + } + + private void OpenFile() + { + var openFileDialog = new OpenFileDialog(); + openFileDialog.Filter = "All Supported Files (*.wav;*.mp3)|*.wav;*.mp3|All Files (*.*)|*.*"; + bool? result = openFileDialog.ShowDialog(); + if (result.HasValue && result.Value) + { + selectedFile = openFileDialog.FileName; + reader = new AudioFileReader(selectedFile); + equalizer = new Equalizer(reader, bands); + player = new WaveOutEvent(); + player.Init(equalizer); + } + } + + private void Play() + { + if (selectedFile == null) + { + OpenFile(); + } + if (selectedFile != null) + { + player.Play(); + } + } + + private void Stop() + { + if (player != null) + { + player.Stop(); + } + } + + public void Dispose() + { + if (player != null) + { + player.Dispose(); + } + if (reader != null) + { + reader.Dispose(); + } + + } + } +} diff --git a/NAudioWpfDemo/EqualizationDemo/Equalizer.cs b/NAudioWpfDemo/EqualizationDemo/Equalizer.cs new file mode 100644 index 00000000..8b9c185e --- /dev/null +++ b/NAudioWpfDemo/EqualizationDemo/Equalizer.cs @@ -0,0 +1,76 @@ +using NAudio.Dsp; +using NAudio.Wave; + +namespace NAudioWpfDemo.EqualizationDemo +{ + /// + /// Basic example of a multi-band eq + /// uses the same settings for both channels in stereo audio + /// Call Update after you've updated the bands + /// Potentially to be added to NAudio in a future version + /// + class Equalizer : ISampleProvider + { + private readonly ISampleProvider sourceProvider; + private readonly EqualizerBand[] bands; + private readonly BiQuadFilter[,] filters; + private readonly int channels; + private readonly int bandCount; + private bool updated; + + public Equalizer(ISampleProvider sourceProvider, EqualizerBand[] bands) + { + this.sourceProvider = sourceProvider; + this.bands = bands; + channels = sourceProvider.WaveFormat.Channels; + bandCount = bands.Length; + filters = new BiQuadFilter[channels,bands.Length]; + CreateFilters(); + } + + private void CreateFilters() + { + for (int bandIndex = 0; bandIndex < bandCount; bandIndex++) + { + var band = bands[bandIndex]; + for (int n = 0; n < channels; n++) + { + if (filters[n, bandIndex] == null) + filters[n, bandIndex] = BiQuadFilter.PeakingEQ(sourceProvider.WaveFormat.SampleRate, band.Frequency, band.Bandwidth, band.Gain); + else + filters[n, bandIndex].SetPeakingEq(sourceProvider.WaveFormat.SampleRate, band.Frequency, band.Bandwidth, band.Gain); + } + } + } + + public void Update() + { + updated = true; + CreateFilters(); + } + + public WaveFormat WaveFormat { get { return sourceProvider.WaveFormat; } } + + public int Read(float[] buffer, int offset, int count) + { + int samplesRead = sourceProvider.Read(buffer, offset, count); + + if (updated) + { + CreateFilters(); + updated = false; + } + + for (int n = 0; n < samplesRead; n++) + { + int ch = n % channels; + + for (int band = 0; band < bandCount; band++) + { + buffer[offset + n] = filters[ch, band].Transform(buffer[offset + n]); + } + } + return samplesRead; + } + } +} \ No newline at end of file diff --git a/NAudioWpfDemo/EqualizationDemo/EqualizerBand.cs b/NAudioWpfDemo/EqualizationDemo/EqualizerBand.cs new file mode 100644 index 00000000..3c3584f6 --- /dev/null +++ b/NAudioWpfDemo/EqualizationDemo/EqualizerBand.cs @@ -0,0 +1,9 @@ +namespace NAudioWpfDemo.EqualizationDemo +{ + class EqualizerBand + { + public float Frequency { get; set; } + public float Gain { get; set; } + public float Bandwidth { get; set; } + } +} \ No newline at end of file diff --git a/NAudioWpfDemo/IModule.cs b/NAudioWpfDemo/IModule.cs new file mode 100644 index 00000000..4a0adc47 --- /dev/null +++ b/NAudioWpfDemo/IModule.cs @@ -0,0 +1,15 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Windows.Controls; + +namespace NAudioWpfDemo +{ + public interface IModule + { + string Name { get; } + UserControl UserInterface { get; } + void Deactivate(); + } +} diff --git a/NAudioWpfDemo/IWaveFormRenderer.cs b/NAudioWpfDemo/IWaveFormRenderer.cs new file mode 100644 index 00000000..9c5426c7 --- /dev/null +++ b/NAudioWpfDemo/IWaveFormRenderer.cs @@ -0,0 +1,12 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +namespace NAudioWpfDemo +{ + public interface IWaveFormRenderer + { + void AddValue(float maxValue, float minValue); + } +} diff --git a/NAudioWpfDemo/MainWindow.xaml b/NAudioWpfDemo/MainWindow.xaml new file mode 100644 index 00000000..b59e70b4 --- /dev/null +++ b/NAudioWpfDemo/MainWindow.xaml @@ -0,0 +1,23 @@ + + + + + + + + + + + + + + + + + diff --git a/NAudioWpfDemo/MainWindow.xaml.cs b/NAudioWpfDemo/MainWindow.xaml.cs new file mode 100644 index 00000000..4e58ed88 --- /dev/null +++ b/NAudioWpfDemo/MainWindow.xaml.cs @@ -0,0 +1,17 @@ +using System; +using System.Windows; + +namespace NAudioWpfDemo +{ + /// + /// Interaction logic for Window1.xaml + /// + public partial class MainWindow : Window + { + public MainWindow() + { + InitializeComponent(); + this.Title = this.Title + ((System.Runtime.InteropServices.Marshal.SizeOf(IntPtr.Zero) == 8) ? " (x64)" : " (x86)"); + } + } +} diff --git a/NAudioWpfDemo/MainWindowViewModel.cs b/NAudioWpfDemo/MainWindowViewModel.cs new file mode 100644 index 00000000..195e8912 --- /dev/null +++ b/NAudioWpfDemo/MainWindowViewModel.cs @@ -0,0 +1,56 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.ComponentModel; +using System.Windows.Controls; +using NAudioWpfDemo.ViewModel; + +namespace NAudioWpfDemo +{ + class MainWindowViewModel : ViewModelBase + { + private IModule selectedModule; + + public MainWindowViewModel(IEnumerable modules) + { + this.Modules = modules.OrderBy(m => m.Name).ToList(); + if (this.Modules.Count > 0) + { + this.SelectedModule = this.Modules[0]; + } + } + + public List Modules { get; private set; } + + public IModule SelectedModule + { + get + { + return selectedModule; + } + set + { + if (value != selectedModule) + { + if (selectedModule != null) + { + selectedModule.Deactivate(); + } + selectedModule = value; + OnPropertyChanged("SelectedModule"); + OnPropertyChanged("UserInterface"); + } + } + } + + public UserControl UserInterface + { + get + { + if (SelectedModule == null) return null; + return SelectedModule.UserInterface; + } + } + } +} diff --git a/NAudioWpfDemo/MediaFoundationEncode/MediaFoundationEncodePlugin.cs b/NAudioWpfDemo/MediaFoundationEncode/MediaFoundationEncodePlugin.cs new file mode 100644 index 00000000..328f55d6 --- /dev/null +++ b/NAudioWpfDemo/MediaFoundationEncode/MediaFoundationEncodePlugin.cs @@ -0,0 +1,23 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel.Composition; +using System.Linq; +using System.Text; +using System.Windows.Controls; + +namespace NAudioWpfDemo.MediaFoundationEncode +{ + [Export(typeof(IModule))] + class MediaFoundationEncodePlugin : ModuleBase + { + protected override UserControl CreateViewAndViewModel() + { + return new MediaFoundationEncodeView() {DataContext = new MediaFoundationEncodeViewModel()}; + } + + public override string Name + { + get { return "Media Foundation Encode"; } + } + } +} diff --git a/NAudioWpfDemo/MediaFoundationEncode/MediaFoundationEncodeView.xaml b/NAudioWpfDemo/MediaFoundationEncode/MediaFoundationEncodeView.xaml new file mode 100644 index 00000000..ec441452 --- /dev/null +++ b/NAudioWpfDemo/MediaFoundationEncode/MediaFoundationEncodeView.xaml @@ -0,0 +1,39 @@ + + +