├── .gitignore ├── resource ├── bankA.png ├── bankB.png ├── bankC.png ├── bankD.png ├── button.png ├── edit.png ├── play.png ├── vu_on.png ├── arrow_up.png ├── bankA_2x.png ├── bankB_2x.png ├── bankC_2x.png ├── bankD_2x.png ├── edit_2x.png ├── play_2x.png ├── slice01.png ├── slice16.png ├── slice32.png ├── slice48.png ├── slice64.png ├── vu_on_2x.png ├── action_crop.png ├── action_cut.png ├── action_load.png ├── action_ok.png ├── action_redo.png ├── action_trim.png ├── action_undo.png ├── action_zoom.png ├── arrow_down.png ├── arrow_up_2x.png ├── button_2x.png ├── button_loop.png ├── slice01_2x.png ├── slice16_2x.png ├── slice32_2x.png ├── slice48_2x.png ├── slice64_2x.png ├── action_cancel.png ├── action_clear.png ├── action_cut_2x.png ├── action_export.png ├── action_match.png ├── action_ok_2x.png ├── action_reset.png ├── action_sample.png ├── arrow_down_2x.png ├── knob_63frames.png ├── slider_handle.png ├── action_cancel_2x.png ├── action_clear_2x.png ├── action_crop_2x.png ├── action_export_2x.png ├── action_load_2x.png ├── action_match_2x.png ├── action_norm_0dB.png ├── action_norm_3dB.png ├── action_norm_6dB.png ├── action_redo_2x.png ├── action_reset_2x.png ├── action_sample_2x.png ├── action_trim_2x.png ├── action_undo_2x.png ├── action_zoom_2x.png ├── button_loop_2x.png ├── button_reverse.png ├── knob_63frames_2x.png ├── quick_edit_mode.png ├── sample_input_In1.png ├── sample_input_In2.png ├── slider_handle_2x.png ├── action_norm_0dB_2x.png ├── action_norm_3dB_2x.png ├── action_norm_6dB_2x.png ├── button_reverse_2x.png ├── quick_edit_mode_2x.png ├── routing_mono_mono.png ├── main_view_background.png ├── routing_mono_mono_2x.png ├── routing_mono_stereo.png ├── sample_input_In1_2x.png ├── sample_input_In2_2x.png ├── edit_io_tab_background.png ├── main_view_background_2x.png ├── routing_mono_stereo_2x.png ├── action_switch_edit_io_tab.png ├── edit_edit_tab_background.png ├── edit_io_tab_background_2x.png ├── edit_sample_tab_background.png ├── main_edit_tab_background.png ├── main_play_tab_background.png ├── action_switch_edit_edit_tab.png ├── action_switch_edit_io_tab_2x.png ├── action_toggle_slice_loop_all.png ├── edit_edit_tab_background_2x.png ├── main_edit_tab_background_2x.png ├── main_play_tab_background_2x.png ├── main_settings_tab_background.png ├── action_switch_edit_edit_tab_2x.png ├── action_switch_edit_sample_tab.png ├── action_toggle_slice_loop_all_2x.png ├── edit_sample_tab_background_2x.png ├── main_settings_tab_background_2x.png ├── action_switch_edit_sample_tab_2x.png ├── gen_1x.sh └── SampleSplitter.rc ├── design ├── arrow.pxd │ ├── metadata.info │ └── QuickLook │ │ ├── Icon.tiff │ │ ├── Preview.tiff │ │ └── Thumbnail.tiff ├── button.pxd │ ├── metadata.info │ ├── QuickLook │ │ ├── Icon.tiff │ │ └── Thumbnail.tiff │ └── data │ │ ├── 287C7798-BE79-45F0-9A9B-EB81967A6B87 │ │ ├── 57406634-FC30-4CF7-AC34-3E8D5E174336 │ │ ├── 6DC5459C-78DA-471F-ACEF-968D43CF4982 │ │ ├── 7D15BB51-903E-4DE4-A057-57AE7D8E28E9 │ │ ├── AAC7BF79-A101-47AA-8ACD-CC8922AFF958 │ │ └── AF6E2A65-5804-4EBC-BAA9-A94649D0260D ├── arrow_2x.pxd │ ├── metadata.info │ └── QuickLook │ │ ├── Icon.tiff │ │ ├── Preview.tiff │ │ └── Thumbnail.tiff ├── button_2x.pxd │ ├── metadata.info │ ├── QuickLook │ │ ├── Icon.tiff │ │ └── Thumbnail.tiff │ └── data │ │ ├── 3A25AF41-8924-41F2-846F-8FD5B3DEE5FF │ │ ├── 682AD6C9-CAE4-4EF7-AED3-5B91BFF5E518 │ │ ├── 7E522AE1-24B3-4E62-9447-23BB72811384 │ │ ├── A3178AA1-516A-4423-A73B-C246912EB6EC │ │ ├── A9A46D1B-7A2A-4838-9570-48ADF18D14DD │ │ └── DC5AA48E-5F8E-4258-917A-42651AAA0D3D ├── vu_on_2x.pxd │ ├── metadata.info │ ├── QuickLook │ │ ├── Icon.tiff │ │ └── Thumbnail.tiff │ └── data │ │ ├── selectionForContentTransform │ │ ├── shapeSelection │ │ │ ├── path │ │ │ └── meta │ │ └── meta │ │ └── B84B1640-58AD-4A50-AA7F-FD7EDC6D983F ├── routing_2x.pxd │ ├── metadata.info │ └── QuickLook │ │ ├── Icon.tiff │ │ └── Thumbnail.tiff ├── quick_edit_mode_2x.pxd │ ├── metadata.info │ ├── QuickLook │ │ ├── Icon.tiff │ │ └── Thumbnail.tiff │ └── data │ │ ├── 34066B15-F167-4DA0-8C78-ECE3454B2651 │ │ └── 58CBF356-2EBA-4BC4-BA75-7937CFC46D98 ├── main_view_background_2x.pxd │ ├── metadata.info │ ├── QuickLook │ │ ├── Icon.tiff │ │ └── Thumbnail.tiff │ └── data │ │ ├── 330577ED-9209-4311-A5DC-9CE851E3A834 │ │ ├── 585AB0B8-39D1-4820-9605-DD0B08B95DC2 │ │ ├── 7F7C1718-5D97-4124-9E61-0C5954ED4ED6 │ │ ├── 9DD3F1AA-AEC5-45CC-BBB7-235ECC7A9441 │ │ ├── AA83A3EC-A440-4133-9E29-50BA687BC2AB │ │ ├── D25B854A-AE5C-47A4-88A6-F1DB54A2F85D │ │ └── D69F90B0-BF42-4AA7-9B22-D4BDFE948703 ├── edit_io_tab_background_2x.pxd │ ├── metadata.info │ └── QuickLook │ │ ├── Icon.tiff │ │ ├── Preview.tiff │ │ └── Thumbnail.tiff ├── edit_edit_tab_background_2x.pxd │ ├── metadata.info │ └── QuickLook │ │ ├── Icon.tiff │ │ └── Thumbnail.tiff ├── edit_sample_tab_background_2x.pxd │ ├── metadata.info │ └── QuickLook │ │ ├── Icon.tiff │ │ ├── Preview.tiff │ │ └── Thumbnail.tiff ├── main_edit_tab_background_2x.pxd │ ├── metadata.info │ ├── QuickLook │ │ ├── Icon.tiff │ │ ├── Preview.tiff │ │ └── Thumbnail.tiff │ └── data │ │ └── selectionForContentTransform │ │ ├── shapeSelection │ │ ├── path │ │ └── meta │ │ └── meta ├── main_play_tab_background_2x.pxd │ ├── metadata.info │ ├── QuickLook │ │ ├── Icon.tiff │ │ └── Thumbnail.tiff │ └── data │ │ ├── 285BB19A-ED9C-4A06-AC08-3F65ACB30401 │ │ ├── 4E1034FC-49B5-40ED-BA0F-681FBE4DA601 │ │ ├── 59DEB769-6DE6-4AD6-BD48-6822A9797CA1 │ │ ├── 69EAA01C-790B-49D6-A094-AFFF84137B7E │ │ ├── 87591C71-DDBD-42CC-9AC9-8E4E31E5892F │ │ ├── A70D3805-A9B7-4FD7-87A9-9C9699714787 │ │ ├── AF7D814E-AE17-4EA4-80C3-A2A94E3EFEC1 │ │ ├── BEA5BFD7-7F04-44F1-916A-AAD98F269323 │ │ ├── DBF4C854-43C6-4B8F-8B30-B8FB9A8AA8C5 │ │ ├── E4941AD5-E0D0-48A1-8F2E-881EEB311471 │ │ └── FFDA3E94-79AC-4371-9E1F-8BEC69B43135 ├── main_settings_tab_background_2x.pxd │ ├── metadata.info │ ├── QuickLook │ │ ├── Icon.tiff │ │ └── Thumbnail.tiff │ └── data │ │ ├── 2C21821A-BE1F-48B8-85CF-FC3D7FC26338 │ │ ├── 4E1034FC-49B5-40ED-BA0F-681FBE4DA601 │ │ ├── 59DEB769-6DE6-4AD6-BD48-6822A9797CA1 │ │ ├── 648CAFA0-4B88-4261-9810-E10EE2073964 │ │ ├── 702DC976-3392-4C26-A60D-F0C6412BE723 │ │ ├── 87591C71-DDBD-42CC-9AC9-8E4E31E5892F │ │ └── BEA5BFD7-7F04-44F1-916A-AAD98F269323 ├── routing_mono.svg ├── routing_stereo.svg └── button-style.css ├── LICENSE.txt ├── external └── miniaudio │ ├── version.txt │ ├── .gitignore │ ├── miniaudio.c │ ├── CMakeLists.txt │ └── LICENSE ├── archive ├── README-win_64bits.txt └── README-macOS_64bits.txt ├── src └── cpp │ ├── GUI │ ├── SampleLoaderView.h │ ├── PadController.h │ ├── SampleInfoView.h │ ├── SelectedSliceSettingView.cpp │ ├── SampleEditController.h │ ├── SampleLoaderView.cpp │ ├── PadView.h │ ├── LargeFileDialogController.h │ ├── SlicesActionViews.cpp │ ├── SampleEditScrollbarView.h │ ├── Waveform.h │ ├── SliceSettingView.h │ ├── ErrorMessageView.h │ ├── LargeFileDialogController.cpp │ ├── SliceSettingView.cpp │ ├── SliceNumberView.cpp │ ├── ErrorMessageView.cpp │ ├── SampleFileLoader.h │ ├── OffsettedSliceSettingView.cpp │ ├── SampleDisplayView.h │ ├── SamplingStateView.cpp │ ├── PadKeyView.cpp │ ├── SampleSplitterController.h │ ├── CurrentSample.h │ ├── PadController.cpp │ ├── PadView.cpp │ ├── SampleEditScrollbarView.cpp │ ├── SampleInfoView.cpp │ ├── WaveformView.h │ ├── SampleEditView.h │ ├── SampleSaverView.cpp │ ├── UndoHistory.h │ ├── SamplingButtonView.cpp │ ├── SampleSplitterController.cpp │ ├── SampleMgr.h │ ├── SampleOverviewView.cpp │ └── WaveformView.cpp │ ├── version.h.in │ ├── SharedSampleBuffersMgr.h │ ├── SampleSplitter_VST3.cpp │ ├── SampleStorage.h │ ├── Sampler.h │ ├── FilePath.h │ ├── SampleSplitterCIDs.h │ ├── RT │ └── SampleSplitterProcessor.h │ ├── Sampler.hpp │ └── FilePath.cpp ├── .github └── workflows │ ├── run-tests-macos-action.yml │ └── run-tests-windows-action.yml ├── mac └── Info.plist ├── r8brain-free-src.cmake ├── fetch_jamba.cmake ├── audio-unit ├── audiounitconfig.h └── Info.plist ├── libsndfile.cmake └── configure.py /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | .idea 3 | build 4 | cmake-build-* -------------------------------------------------------------------------------- /resource/bankA.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pongasoft/vst-sam-spl-64/HEAD/resource/bankA.png -------------------------------------------------------------------------------- /resource/bankB.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pongasoft/vst-sam-spl-64/HEAD/resource/bankB.png -------------------------------------------------------------------------------- /resource/bankC.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pongasoft/vst-sam-spl-64/HEAD/resource/bankC.png -------------------------------------------------------------------------------- /resource/bankD.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pongasoft/vst-sam-spl-64/HEAD/resource/bankD.png -------------------------------------------------------------------------------- /resource/button.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pongasoft/vst-sam-spl-64/HEAD/resource/button.png -------------------------------------------------------------------------------- /resource/edit.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pongasoft/vst-sam-spl-64/HEAD/resource/edit.png -------------------------------------------------------------------------------- /resource/play.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pongasoft/vst-sam-spl-64/HEAD/resource/play.png -------------------------------------------------------------------------------- /resource/vu_on.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pongasoft/vst-sam-spl-64/HEAD/resource/vu_on.png -------------------------------------------------------------------------------- /resource/arrow_up.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pongasoft/vst-sam-spl-64/HEAD/resource/arrow_up.png -------------------------------------------------------------------------------- /resource/bankA_2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pongasoft/vst-sam-spl-64/HEAD/resource/bankA_2x.png -------------------------------------------------------------------------------- /resource/bankB_2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pongasoft/vst-sam-spl-64/HEAD/resource/bankB_2x.png -------------------------------------------------------------------------------- /resource/bankC_2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pongasoft/vst-sam-spl-64/HEAD/resource/bankC_2x.png -------------------------------------------------------------------------------- /resource/bankD_2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pongasoft/vst-sam-spl-64/HEAD/resource/bankD_2x.png -------------------------------------------------------------------------------- /resource/edit_2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pongasoft/vst-sam-spl-64/HEAD/resource/edit_2x.png -------------------------------------------------------------------------------- /resource/play_2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pongasoft/vst-sam-spl-64/HEAD/resource/play_2x.png -------------------------------------------------------------------------------- /resource/slice01.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pongasoft/vst-sam-spl-64/HEAD/resource/slice01.png -------------------------------------------------------------------------------- /resource/slice16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pongasoft/vst-sam-spl-64/HEAD/resource/slice16.png -------------------------------------------------------------------------------- /resource/slice32.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pongasoft/vst-sam-spl-64/HEAD/resource/slice32.png -------------------------------------------------------------------------------- /resource/slice48.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pongasoft/vst-sam-spl-64/HEAD/resource/slice48.png -------------------------------------------------------------------------------- /resource/slice64.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pongasoft/vst-sam-spl-64/HEAD/resource/slice64.png -------------------------------------------------------------------------------- /resource/vu_on_2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pongasoft/vst-sam-spl-64/HEAD/resource/vu_on_2x.png -------------------------------------------------------------------------------- /resource/action_crop.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pongasoft/vst-sam-spl-64/HEAD/resource/action_crop.png -------------------------------------------------------------------------------- /resource/action_cut.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pongasoft/vst-sam-spl-64/HEAD/resource/action_cut.png -------------------------------------------------------------------------------- /resource/action_load.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pongasoft/vst-sam-spl-64/HEAD/resource/action_load.png -------------------------------------------------------------------------------- /resource/action_ok.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pongasoft/vst-sam-spl-64/HEAD/resource/action_ok.png -------------------------------------------------------------------------------- /resource/action_redo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pongasoft/vst-sam-spl-64/HEAD/resource/action_redo.png -------------------------------------------------------------------------------- /resource/action_trim.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pongasoft/vst-sam-spl-64/HEAD/resource/action_trim.png -------------------------------------------------------------------------------- /resource/action_undo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pongasoft/vst-sam-spl-64/HEAD/resource/action_undo.png -------------------------------------------------------------------------------- /resource/action_zoom.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pongasoft/vst-sam-spl-64/HEAD/resource/action_zoom.png -------------------------------------------------------------------------------- /resource/arrow_down.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pongasoft/vst-sam-spl-64/HEAD/resource/arrow_down.png -------------------------------------------------------------------------------- /resource/arrow_up_2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pongasoft/vst-sam-spl-64/HEAD/resource/arrow_up_2x.png -------------------------------------------------------------------------------- /resource/button_2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pongasoft/vst-sam-spl-64/HEAD/resource/button_2x.png -------------------------------------------------------------------------------- /resource/button_loop.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pongasoft/vst-sam-spl-64/HEAD/resource/button_loop.png -------------------------------------------------------------------------------- /resource/slice01_2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pongasoft/vst-sam-spl-64/HEAD/resource/slice01_2x.png -------------------------------------------------------------------------------- /resource/slice16_2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pongasoft/vst-sam-spl-64/HEAD/resource/slice16_2x.png -------------------------------------------------------------------------------- /resource/slice32_2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pongasoft/vst-sam-spl-64/HEAD/resource/slice32_2x.png -------------------------------------------------------------------------------- /resource/slice48_2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pongasoft/vst-sam-spl-64/HEAD/resource/slice48_2x.png -------------------------------------------------------------------------------- /resource/slice64_2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pongasoft/vst-sam-spl-64/HEAD/resource/slice64_2x.png -------------------------------------------------------------------------------- /resource/action_cancel.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pongasoft/vst-sam-spl-64/HEAD/resource/action_cancel.png -------------------------------------------------------------------------------- /resource/action_clear.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pongasoft/vst-sam-spl-64/HEAD/resource/action_clear.png -------------------------------------------------------------------------------- /resource/action_cut_2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pongasoft/vst-sam-spl-64/HEAD/resource/action_cut_2x.png -------------------------------------------------------------------------------- /resource/action_export.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pongasoft/vst-sam-spl-64/HEAD/resource/action_export.png -------------------------------------------------------------------------------- /resource/action_match.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pongasoft/vst-sam-spl-64/HEAD/resource/action_match.png -------------------------------------------------------------------------------- /resource/action_ok_2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pongasoft/vst-sam-spl-64/HEAD/resource/action_ok_2x.png -------------------------------------------------------------------------------- /resource/action_reset.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pongasoft/vst-sam-spl-64/HEAD/resource/action_reset.png -------------------------------------------------------------------------------- /resource/action_sample.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pongasoft/vst-sam-spl-64/HEAD/resource/action_sample.png -------------------------------------------------------------------------------- /resource/arrow_down_2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pongasoft/vst-sam-spl-64/HEAD/resource/arrow_down_2x.png -------------------------------------------------------------------------------- /resource/knob_63frames.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pongasoft/vst-sam-spl-64/HEAD/resource/knob_63frames.png -------------------------------------------------------------------------------- /resource/slider_handle.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pongasoft/vst-sam-spl-64/HEAD/resource/slider_handle.png -------------------------------------------------------------------------------- /resource/action_cancel_2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pongasoft/vst-sam-spl-64/HEAD/resource/action_cancel_2x.png -------------------------------------------------------------------------------- /resource/action_clear_2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pongasoft/vst-sam-spl-64/HEAD/resource/action_clear_2x.png -------------------------------------------------------------------------------- /resource/action_crop_2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pongasoft/vst-sam-spl-64/HEAD/resource/action_crop_2x.png -------------------------------------------------------------------------------- /resource/action_export_2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pongasoft/vst-sam-spl-64/HEAD/resource/action_export_2x.png -------------------------------------------------------------------------------- /resource/action_load_2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pongasoft/vst-sam-spl-64/HEAD/resource/action_load_2x.png -------------------------------------------------------------------------------- /resource/action_match_2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pongasoft/vst-sam-spl-64/HEAD/resource/action_match_2x.png -------------------------------------------------------------------------------- /resource/action_norm_0dB.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pongasoft/vst-sam-spl-64/HEAD/resource/action_norm_0dB.png -------------------------------------------------------------------------------- /resource/action_norm_3dB.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pongasoft/vst-sam-spl-64/HEAD/resource/action_norm_3dB.png -------------------------------------------------------------------------------- /resource/action_norm_6dB.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pongasoft/vst-sam-spl-64/HEAD/resource/action_norm_6dB.png -------------------------------------------------------------------------------- /resource/action_redo_2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pongasoft/vst-sam-spl-64/HEAD/resource/action_redo_2x.png -------------------------------------------------------------------------------- /resource/action_reset_2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pongasoft/vst-sam-spl-64/HEAD/resource/action_reset_2x.png -------------------------------------------------------------------------------- /resource/action_sample_2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pongasoft/vst-sam-spl-64/HEAD/resource/action_sample_2x.png -------------------------------------------------------------------------------- /resource/action_trim_2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pongasoft/vst-sam-spl-64/HEAD/resource/action_trim_2x.png -------------------------------------------------------------------------------- /resource/action_undo_2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pongasoft/vst-sam-spl-64/HEAD/resource/action_undo_2x.png -------------------------------------------------------------------------------- /resource/action_zoom_2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pongasoft/vst-sam-spl-64/HEAD/resource/action_zoom_2x.png -------------------------------------------------------------------------------- /resource/button_loop_2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pongasoft/vst-sam-spl-64/HEAD/resource/button_loop_2x.png -------------------------------------------------------------------------------- /resource/button_reverse.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pongasoft/vst-sam-spl-64/HEAD/resource/button_reverse.png -------------------------------------------------------------------------------- /resource/knob_63frames_2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pongasoft/vst-sam-spl-64/HEAD/resource/knob_63frames_2x.png -------------------------------------------------------------------------------- /resource/quick_edit_mode.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pongasoft/vst-sam-spl-64/HEAD/resource/quick_edit_mode.png -------------------------------------------------------------------------------- /resource/sample_input_In1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pongasoft/vst-sam-spl-64/HEAD/resource/sample_input_In1.png -------------------------------------------------------------------------------- /resource/sample_input_In2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pongasoft/vst-sam-spl-64/HEAD/resource/sample_input_In2.png -------------------------------------------------------------------------------- /resource/slider_handle_2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pongasoft/vst-sam-spl-64/HEAD/resource/slider_handle_2x.png -------------------------------------------------------------------------------- /design/arrow.pxd/metadata.info: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pongasoft/vst-sam-spl-64/HEAD/design/arrow.pxd/metadata.info -------------------------------------------------------------------------------- /design/button.pxd/metadata.info: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pongasoft/vst-sam-spl-64/HEAD/design/button.pxd/metadata.info -------------------------------------------------------------------------------- /resource/action_norm_0dB_2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pongasoft/vst-sam-spl-64/HEAD/resource/action_norm_0dB_2x.png -------------------------------------------------------------------------------- /resource/action_norm_3dB_2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pongasoft/vst-sam-spl-64/HEAD/resource/action_norm_3dB_2x.png -------------------------------------------------------------------------------- /resource/action_norm_6dB_2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pongasoft/vst-sam-spl-64/HEAD/resource/action_norm_6dB_2x.png -------------------------------------------------------------------------------- /resource/button_reverse_2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pongasoft/vst-sam-spl-64/HEAD/resource/button_reverse_2x.png -------------------------------------------------------------------------------- /resource/quick_edit_mode_2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pongasoft/vst-sam-spl-64/HEAD/resource/quick_edit_mode_2x.png -------------------------------------------------------------------------------- /resource/routing_mono_mono.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pongasoft/vst-sam-spl-64/HEAD/resource/routing_mono_mono.png -------------------------------------------------------------------------------- /design/arrow_2x.pxd/metadata.info: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pongasoft/vst-sam-spl-64/HEAD/design/arrow_2x.pxd/metadata.info -------------------------------------------------------------------------------- /design/button_2x.pxd/metadata.info: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pongasoft/vst-sam-spl-64/HEAD/design/button_2x.pxd/metadata.info -------------------------------------------------------------------------------- /design/vu_on_2x.pxd/metadata.info: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pongasoft/vst-sam-spl-64/HEAD/design/vu_on_2x.pxd/metadata.info -------------------------------------------------------------------------------- /resource/main_view_background.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pongasoft/vst-sam-spl-64/HEAD/resource/main_view_background.png -------------------------------------------------------------------------------- /resource/routing_mono_mono_2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pongasoft/vst-sam-spl-64/HEAD/resource/routing_mono_mono_2x.png -------------------------------------------------------------------------------- /resource/routing_mono_stereo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pongasoft/vst-sam-spl-64/HEAD/resource/routing_mono_stereo.png -------------------------------------------------------------------------------- /resource/sample_input_In1_2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pongasoft/vst-sam-spl-64/HEAD/resource/sample_input_In1_2x.png -------------------------------------------------------------------------------- /resource/sample_input_In2_2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pongasoft/vst-sam-spl-64/HEAD/resource/sample_input_In2_2x.png -------------------------------------------------------------------------------- /design/arrow.pxd/QuickLook/Icon.tiff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pongasoft/vst-sam-spl-64/HEAD/design/arrow.pxd/QuickLook/Icon.tiff -------------------------------------------------------------------------------- /design/routing_2x.pxd/metadata.info: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pongasoft/vst-sam-spl-64/HEAD/design/routing_2x.pxd/metadata.info -------------------------------------------------------------------------------- /resource/edit_io_tab_background.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pongasoft/vst-sam-spl-64/HEAD/resource/edit_io_tab_background.png -------------------------------------------------------------------------------- /resource/main_view_background_2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pongasoft/vst-sam-spl-64/HEAD/resource/main_view_background_2x.png -------------------------------------------------------------------------------- /resource/routing_mono_stereo_2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pongasoft/vst-sam-spl-64/HEAD/resource/routing_mono_stereo_2x.png -------------------------------------------------------------------------------- /LICENSE.txt: -------------------------------------------------------------------------------- 1 | General Public License (GPL) Version 3 2 | Details of these licenses can be found at: www.gnu.org/licenses/gpl-3.0.html 3 | -------------------------------------------------------------------------------- /design/arrow.pxd/QuickLook/Preview.tiff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pongasoft/vst-sam-spl-64/HEAD/design/arrow.pxd/QuickLook/Preview.tiff -------------------------------------------------------------------------------- /design/arrow_2x.pxd/QuickLook/Icon.tiff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pongasoft/vst-sam-spl-64/HEAD/design/arrow_2x.pxd/QuickLook/Icon.tiff -------------------------------------------------------------------------------- /design/button.pxd/QuickLook/Icon.tiff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pongasoft/vst-sam-spl-64/HEAD/design/button.pxd/QuickLook/Icon.tiff -------------------------------------------------------------------------------- /design/vu_on_2x.pxd/QuickLook/Icon.tiff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pongasoft/vst-sam-spl-64/HEAD/design/vu_on_2x.pxd/QuickLook/Icon.tiff -------------------------------------------------------------------------------- /resource/action_switch_edit_io_tab.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pongasoft/vst-sam-spl-64/HEAD/resource/action_switch_edit_io_tab.png -------------------------------------------------------------------------------- /resource/edit_edit_tab_background.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pongasoft/vst-sam-spl-64/HEAD/resource/edit_edit_tab_background.png -------------------------------------------------------------------------------- /resource/edit_io_tab_background_2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pongasoft/vst-sam-spl-64/HEAD/resource/edit_io_tab_background_2x.png -------------------------------------------------------------------------------- /resource/edit_sample_tab_background.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pongasoft/vst-sam-spl-64/HEAD/resource/edit_sample_tab_background.png -------------------------------------------------------------------------------- /resource/main_edit_tab_background.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pongasoft/vst-sam-spl-64/HEAD/resource/main_edit_tab_background.png -------------------------------------------------------------------------------- /resource/main_play_tab_background.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pongasoft/vst-sam-spl-64/HEAD/resource/main_play_tab_background.png -------------------------------------------------------------------------------- /design/arrow.pxd/QuickLook/Thumbnail.tiff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pongasoft/vst-sam-spl-64/HEAD/design/arrow.pxd/QuickLook/Thumbnail.tiff -------------------------------------------------------------------------------- /design/button_2x.pxd/QuickLook/Icon.tiff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pongasoft/vst-sam-spl-64/HEAD/design/button_2x.pxd/QuickLook/Icon.tiff -------------------------------------------------------------------------------- /design/routing_2x.pxd/QuickLook/Icon.tiff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pongasoft/vst-sam-spl-64/HEAD/design/routing_2x.pxd/QuickLook/Icon.tiff -------------------------------------------------------------------------------- /resource/action_switch_edit_edit_tab.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pongasoft/vst-sam-spl-64/HEAD/resource/action_switch_edit_edit_tab.png -------------------------------------------------------------------------------- /resource/action_switch_edit_io_tab_2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pongasoft/vst-sam-spl-64/HEAD/resource/action_switch_edit_io_tab_2x.png -------------------------------------------------------------------------------- /resource/action_toggle_slice_loop_all.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pongasoft/vst-sam-spl-64/HEAD/resource/action_toggle_slice_loop_all.png -------------------------------------------------------------------------------- /resource/edit_edit_tab_background_2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pongasoft/vst-sam-spl-64/HEAD/resource/edit_edit_tab_background_2x.png -------------------------------------------------------------------------------- /resource/main_edit_tab_background_2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pongasoft/vst-sam-spl-64/HEAD/resource/main_edit_tab_background_2x.png -------------------------------------------------------------------------------- /resource/main_play_tab_background_2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pongasoft/vst-sam-spl-64/HEAD/resource/main_play_tab_background_2x.png -------------------------------------------------------------------------------- /resource/main_settings_tab_background.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pongasoft/vst-sam-spl-64/HEAD/resource/main_settings_tab_background.png -------------------------------------------------------------------------------- /design/arrow_2x.pxd/QuickLook/Preview.tiff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pongasoft/vst-sam-spl-64/HEAD/design/arrow_2x.pxd/QuickLook/Preview.tiff -------------------------------------------------------------------------------- /design/arrow_2x.pxd/QuickLook/Thumbnail.tiff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pongasoft/vst-sam-spl-64/HEAD/design/arrow_2x.pxd/QuickLook/Thumbnail.tiff -------------------------------------------------------------------------------- /design/button.pxd/QuickLook/Thumbnail.tiff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pongasoft/vst-sam-spl-64/HEAD/design/button.pxd/QuickLook/Thumbnail.tiff -------------------------------------------------------------------------------- /design/quick_edit_mode_2x.pxd/metadata.info: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pongasoft/vst-sam-spl-64/HEAD/design/quick_edit_mode_2x.pxd/metadata.info -------------------------------------------------------------------------------- /design/vu_on_2x.pxd/QuickLook/Thumbnail.tiff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pongasoft/vst-sam-spl-64/HEAD/design/vu_on_2x.pxd/QuickLook/Thumbnail.tiff -------------------------------------------------------------------------------- /external/miniaudio/version.txt: -------------------------------------------------------------------------------- 1 | From https://github.com/mackron/miniaudio@9a7663496fc06f7a9439c752fd7666ca93328c20 (master as of 2023/04/08) 2 | 3 | -------------------------------------------------------------------------------- /resource/action_switch_edit_edit_tab_2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pongasoft/vst-sam-spl-64/HEAD/resource/action_switch_edit_edit_tab_2x.png -------------------------------------------------------------------------------- /resource/action_switch_edit_sample_tab.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pongasoft/vst-sam-spl-64/HEAD/resource/action_switch_edit_sample_tab.png -------------------------------------------------------------------------------- /resource/action_toggle_slice_loop_all_2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pongasoft/vst-sam-spl-64/HEAD/resource/action_toggle_slice_loop_all_2x.png -------------------------------------------------------------------------------- /resource/edit_sample_tab_background_2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pongasoft/vst-sam-spl-64/HEAD/resource/edit_sample_tab_background_2x.png -------------------------------------------------------------------------------- /resource/main_settings_tab_background_2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pongasoft/vst-sam-spl-64/HEAD/resource/main_settings_tab_background_2x.png -------------------------------------------------------------------------------- /design/button_2x.pxd/QuickLook/Thumbnail.tiff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pongasoft/vst-sam-spl-64/HEAD/design/button_2x.pxd/QuickLook/Thumbnail.tiff -------------------------------------------------------------------------------- /design/routing_2x.pxd/QuickLook/Thumbnail.tiff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pongasoft/vst-sam-spl-64/HEAD/design/routing_2x.pxd/QuickLook/Thumbnail.tiff -------------------------------------------------------------------------------- /design/vu_on_2x.pxd/data/selectionForContentTransform/shapeSelection/path: -------------------------------------------------------------------------------- 1 | 3.2.0M@L@$L@$@8L@@8E -------------------------------------------------------------------------------- /resource/action_switch_edit_sample_tab_2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pongasoft/vst-sam-spl-64/HEAD/resource/action_switch_edit_sample_tab_2x.png -------------------------------------------------------------------------------- /design/main_view_background_2x.pxd/metadata.info: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pongasoft/vst-sam-spl-64/HEAD/design/main_view_background_2x.pxd/metadata.info -------------------------------------------------------------------------------- /design/quick_edit_mode_2x.pxd/QuickLook/Icon.tiff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pongasoft/vst-sam-spl-64/HEAD/design/quick_edit_mode_2x.pxd/QuickLook/Icon.tiff -------------------------------------------------------------------------------- /design/edit_io_tab_background_2x.pxd/metadata.info: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pongasoft/vst-sam-spl-64/HEAD/design/edit_io_tab_background_2x.pxd/metadata.info -------------------------------------------------------------------------------- /design/edit_edit_tab_background_2x.pxd/metadata.info: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pongasoft/vst-sam-spl-64/HEAD/design/edit_edit_tab_background_2x.pxd/metadata.info -------------------------------------------------------------------------------- /design/edit_sample_tab_background_2x.pxd/metadata.info: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pongasoft/vst-sam-spl-64/HEAD/design/edit_sample_tab_background_2x.pxd/metadata.info -------------------------------------------------------------------------------- /design/main_edit_tab_background_2x.pxd/metadata.info: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pongasoft/vst-sam-spl-64/HEAD/design/main_edit_tab_background_2x.pxd/metadata.info -------------------------------------------------------------------------------- /design/main_play_tab_background_2x.pxd/metadata.info: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pongasoft/vst-sam-spl-64/HEAD/design/main_play_tab_background_2x.pxd/metadata.info -------------------------------------------------------------------------------- /design/main_view_background_2x.pxd/QuickLook/Icon.tiff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pongasoft/vst-sam-spl-64/HEAD/design/main_view_background_2x.pxd/QuickLook/Icon.tiff -------------------------------------------------------------------------------- /design/quick_edit_mode_2x.pxd/QuickLook/Thumbnail.tiff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pongasoft/vst-sam-spl-64/HEAD/design/quick_edit_mode_2x.pxd/QuickLook/Thumbnail.tiff -------------------------------------------------------------------------------- /design/edit_io_tab_background_2x.pxd/QuickLook/Icon.tiff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pongasoft/vst-sam-spl-64/HEAD/design/edit_io_tab_background_2x.pxd/QuickLook/Icon.tiff -------------------------------------------------------------------------------- /design/main_settings_tab_background_2x.pxd/metadata.info: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pongasoft/vst-sam-spl-64/HEAD/design/main_settings_tab_background_2x.pxd/metadata.info -------------------------------------------------------------------------------- /design/button.pxd/data/287C7798-BE79-45F0-9A9B-EB81967A6B87: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pongasoft/vst-sam-spl-64/HEAD/design/button.pxd/data/287C7798-BE79-45F0-9A9B-EB81967A6B87 -------------------------------------------------------------------------------- /design/button.pxd/data/57406634-FC30-4CF7-AC34-3E8D5E174336: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pongasoft/vst-sam-spl-64/HEAD/design/button.pxd/data/57406634-FC30-4CF7-AC34-3E8D5E174336 -------------------------------------------------------------------------------- /design/button.pxd/data/6DC5459C-78DA-471F-ACEF-968D43CF4982: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pongasoft/vst-sam-spl-64/HEAD/design/button.pxd/data/6DC5459C-78DA-471F-ACEF-968D43CF4982 -------------------------------------------------------------------------------- /design/button.pxd/data/7D15BB51-903E-4DE4-A057-57AE7D8E28E9: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pongasoft/vst-sam-spl-64/HEAD/design/button.pxd/data/7D15BB51-903E-4DE4-A057-57AE7D8E28E9 -------------------------------------------------------------------------------- /design/button.pxd/data/AAC7BF79-A101-47AA-8ACD-CC8922AFF958: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pongasoft/vst-sam-spl-64/HEAD/design/button.pxd/data/AAC7BF79-A101-47AA-8ACD-CC8922AFF958 -------------------------------------------------------------------------------- /design/button.pxd/data/AF6E2A65-5804-4EBC-BAA9-A94649D0260D: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pongasoft/vst-sam-spl-64/HEAD/design/button.pxd/data/AF6E2A65-5804-4EBC-BAA9-A94649D0260D -------------------------------------------------------------------------------- /design/edit_edit_tab_background_2x.pxd/QuickLook/Icon.tiff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pongasoft/vst-sam-spl-64/HEAD/design/edit_edit_tab_background_2x.pxd/QuickLook/Icon.tiff -------------------------------------------------------------------------------- /design/edit_io_tab_background_2x.pxd/QuickLook/Preview.tiff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pongasoft/vst-sam-spl-64/HEAD/design/edit_io_tab_background_2x.pxd/QuickLook/Preview.tiff -------------------------------------------------------------------------------- /design/main_edit_tab_background_2x.pxd/QuickLook/Icon.tiff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pongasoft/vst-sam-spl-64/HEAD/design/main_edit_tab_background_2x.pxd/QuickLook/Icon.tiff -------------------------------------------------------------------------------- /design/main_play_tab_background_2x.pxd/QuickLook/Icon.tiff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pongasoft/vst-sam-spl-64/HEAD/design/main_play_tab_background_2x.pxd/QuickLook/Icon.tiff -------------------------------------------------------------------------------- /design/main_view_background_2x.pxd/QuickLook/Thumbnail.tiff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pongasoft/vst-sam-spl-64/HEAD/design/main_view_background_2x.pxd/QuickLook/Thumbnail.tiff -------------------------------------------------------------------------------- /design/edit_io_tab_background_2x.pxd/QuickLook/Thumbnail.tiff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pongasoft/vst-sam-spl-64/HEAD/design/edit_io_tab_background_2x.pxd/QuickLook/Thumbnail.tiff -------------------------------------------------------------------------------- /design/edit_sample_tab_background_2x.pxd/QuickLook/Icon.tiff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pongasoft/vst-sam-spl-64/HEAD/design/edit_sample_tab_background_2x.pxd/QuickLook/Icon.tiff -------------------------------------------------------------------------------- /design/main_edit_tab_background_2x.pxd/QuickLook/Preview.tiff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pongasoft/vst-sam-spl-64/HEAD/design/main_edit_tab_background_2x.pxd/QuickLook/Preview.tiff -------------------------------------------------------------------------------- /design/vu_on_2x.pxd/data/B84B1640-58AD-4A50-AA7F-FD7EDC6D983F: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pongasoft/vst-sam-spl-64/HEAD/design/vu_on_2x.pxd/data/B84B1640-58AD-4A50-AA7F-FD7EDC6D983F -------------------------------------------------------------------------------- /design/button_2x.pxd/data/3A25AF41-8924-41F2-846F-8FD5B3DEE5FF: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pongasoft/vst-sam-spl-64/HEAD/design/button_2x.pxd/data/3A25AF41-8924-41F2-846F-8FD5B3DEE5FF -------------------------------------------------------------------------------- /design/button_2x.pxd/data/682AD6C9-CAE4-4EF7-AED3-5B91BFF5E518: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pongasoft/vst-sam-spl-64/HEAD/design/button_2x.pxd/data/682AD6C9-CAE4-4EF7-AED3-5B91BFF5E518 -------------------------------------------------------------------------------- /design/button_2x.pxd/data/7E522AE1-24B3-4E62-9447-23BB72811384: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pongasoft/vst-sam-spl-64/HEAD/design/button_2x.pxd/data/7E522AE1-24B3-4E62-9447-23BB72811384 -------------------------------------------------------------------------------- /design/button_2x.pxd/data/A3178AA1-516A-4423-A73B-C246912EB6EC: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pongasoft/vst-sam-spl-64/HEAD/design/button_2x.pxd/data/A3178AA1-516A-4423-A73B-C246912EB6EC -------------------------------------------------------------------------------- /design/button_2x.pxd/data/A9A46D1B-7A2A-4838-9570-48ADF18D14DD: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pongasoft/vst-sam-spl-64/HEAD/design/button_2x.pxd/data/A9A46D1B-7A2A-4838-9570-48ADF18D14DD -------------------------------------------------------------------------------- /design/button_2x.pxd/data/DC5AA48E-5F8E-4258-917A-42651AAA0D3D: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pongasoft/vst-sam-spl-64/HEAD/design/button_2x.pxd/data/DC5AA48E-5F8E-4258-917A-42651AAA0D3D -------------------------------------------------------------------------------- /design/edit_edit_tab_background_2x.pxd/QuickLook/Thumbnail.tiff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pongasoft/vst-sam-spl-64/HEAD/design/edit_edit_tab_background_2x.pxd/QuickLook/Thumbnail.tiff -------------------------------------------------------------------------------- /design/edit_sample_tab_background_2x.pxd/QuickLook/Preview.tiff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pongasoft/vst-sam-spl-64/HEAD/design/edit_sample_tab_background_2x.pxd/QuickLook/Preview.tiff -------------------------------------------------------------------------------- /design/main_edit_tab_background_2x.pxd/QuickLook/Thumbnail.tiff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pongasoft/vst-sam-spl-64/HEAD/design/main_edit_tab_background_2x.pxd/QuickLook/Thumbnail.tiff -------------------------------------------------------------------------------- /design/main_play_tab_background_2x.pxd/QuickLook/Thumbnail.tiff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pongasoft/vst-sam-spl-64/HEAD/design/main_play_tab_background_2x.pxd/QuickLook/Thumbnail.tiff -------------------------------------------------------------------------------- /design/main_settings_tab_background_2x.pxd/QuickLook/Icon.tiff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pongasoft/vst-sam-spl-64/HEAD/design/main_settings_tab_background_2x.pxd/QuickLook/Icon.tiff -------------------------------------------------------------------------------- /design/edit_sample_tab_background_2x.pxd/QuickLook/Thumbnail.tiff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pongasoft/vst-sam-spl-64/HEAD/design/edit_sample_tab_background_2x.pxd/QuickLook/Thumbnail.tiff -------------------------------------------------------------------------------- /design/main_settings_tab_background_2x.pxd/QuickLook/Thumbnail.tiff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pongasoft/vst-sam-spl-64/HEAD/design/main_settings_tab_background_2x.pxd/QuickLook/Thumbnail.tiff -------------------------------------------------------------------------------- /design/quick_edit_mode_2x.pxd/data/34066B15-F167-4DA0-8C78-ECE3454B2651: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pongasoft/vst-sam-spl-64/HEAD/design/quick_edit_mode_2x.pxd/data/34066B15-F167-4DA0-8C78-ECE3454B2651 -------------------------------------------------------------------------------- /design/quick_edit_mode_2x.pxd/data/58CBF356-2EBA-4BC4-BA75-7937CFC46D98: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pongasoft/vst-sam-spl-64/HEAD/design/quick_edit_mode_2x.pxd/data/58CBF356-2EBA-4BC4-BA75-7937CFC46D98 -------------------------------------------------------------------------------- /design/main_view_background_2x.pxd/data/330577ED-9209-4311-A5DC-9CE851E3A834: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pongasoft/vst-sam-spl-64/HEAD/design/main_view_background_2x.pxd/data/330577ED-9209-4311-A5DC-9CE851E3A834 -------------------------------------------------------------------------------- /design/main_view_background_2x.pxd/data/585AB0B8-39D1-4820-9605-DD0B08B95DC2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pongasoft/vst-sam-spl-64/HEAD/design/main_view_background_2x.pxd/data/585AB0B8-39D1-4820-9605-DD0B08B95DC2 -------------------------------------------------------------------------------- /design/main_view_background_2x.pxd/data/7F7C1718-5D97-4124-9E61-0C5954ED4ED6: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pongasoft/vst-sam-spl-64/HEAD/design/main_view_background_2x.pxd/data/7F7C1718-5D97-4124-9E61-0C5954ED4ED6 -------------------------------------------------------------------------------- /design/main_view_background_2x.pxd/data/9DD3F1AA-AEC5-45CC-BBB7-235ECC7A9441: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pongasoft/vst-sam-spl-64/HEAD/design/main_view_background_2x.pxd/data/9DD3F1AA-AEC5-45CC-BBB7-235ECC7A9441 -------------------------------------------------------------------------------- /design/main_view_background_2x.pxd/data/AA83A3EC-A440-4133-9E29-50BA687BC2AB: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pongasoft/vst-sam-spl-64/HEAD/design/main_view_background_2x.pxd/data/AA83A3EC-A440-4133-9E29-50BA687BC2AB -------------------------------------------------------------------------------- /design/main_view_background_2x.pxd/data/D25B854A-AE5C-47A4-88A6-F1DB54A2F85D: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pongasoft/vst-sam-spl-64/HEAD/design/main_view_background_2x.pxd/data/D25B854A-AE5C-47A4-88A6-F1DB54A2F85D -------------------------------------------------------------------------------- /design/main_view_background_2x.pxd/data/D69F90B0-BF42-4AA7-9B22-D4BDFE948703: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pongasoft/vst-sam-spl-64/HEAD/design/main_view_background_2x.pxd/data/D69F90B0-BF42-4AA7-9B22-D4BDFE948703 -------------------------------------------------------------------------------- /design/main_play_tab_background_2x.pxd/data/285BB19A-ED9C-4A06-AC08-3F65ACB30401: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pongasoft/vst-sam-spl-64/HEAD/design/main_play_tab_background_2x.pxd/data/285BB19A-ED9C-4A06-AC08-3F65ACB30401 -------------------------------------------------------------------------------- /design/main_play_tab_background_2x.pxd/data/4E1034FC-49B5-40ED-BA0F-681FBE4DA601: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pongasoft/vst-sam-spl-64/HEAD/design/main_play_tab_background_2x.pxd/data/4E1034FC-49B5-40ED-BA0F-681FBE4DA601 -------------------------------------------------------------------------------- /design/main_play_tab_background_2x.pxd/data/59DEB769-6DE6-4AD6-BD48-6822A9797CA1: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pongasoft/vst-sam-spl-64/HEAD/design/main_play_tab_background_2x.pxd/data/59DEB769-6DE6-4AD6-BD48-6822A9797CA1 -------------------------------------------------------------------------------- /design/main_play_tab_background_2x.pxd/data/69EAA01C-790B-49D6-A094-AFFF84137B7E: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pongasoft/vst-sam-spl-64/HEAD/design/main_play_tab_background_2x.pxd/data/69EAA01C-790B-49D6-A094-AFFF84137B7E -------------------------------------------------------------------------------- /design/main_play_tab_background_2x.pxd/data/87591C71-DDBD-42CC-9AC9-8E4E31E5892F: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pongasoft/vst-sam-spl-64/HEAD/design/main_play_tab_background_2x.pxd/data/87591C71-DDBD-42CC-9AC9-8E4E31E5892F -------------------------------------------------------------------------------- /design/main_play_tab_background_2x.pxd/data/A70D3805-A9B7-4FD7-87A9-9C9699714787: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pongasoft/vst-sam-spl-64/HEAD/design/main_play_tab_background_2x.pxd/data/A70D3805-A9B7-4FD7-87A9-9C9699714787 -------------------------------------------------------------------------------- /design/main_play_tab_background_2x.pxd/data/AF7D814E-AE17-4EA4-80C3-A2A94E3EFEC1: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pongasoft/vst-sam-spl-64/HEAD/design/main_play_tab_background_2x.pxd/data/AF7D814E-AE17-4EA4-80C3-A2A94E3EFEC1 -------------------------------------------------------------------------------- /design/main_play_tab_background_2x.pxd/data/BEA5BFD7-7F04-44F1-916A-AAD98F269323: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pongasoft/vst-sam-spl-64/HEAD/design/main_play_tab_background_2x.pxd/data/BEA5BFD7-7F04-44F1-916A-AAD98F269323 -------------------------------------------------------------------------------- /design/main_play_tab_background_2x.pxd/data/DBF4C854-43C6-4B8F-8B30-B8FB9A8AA8C5: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pongasoft/vst-sam-spl-64/HEAD/design/main_play_tab_background_2x.pxd/data/DBF4C854-43C6-4B8F-8B30-B8FB9A8AA8C5 -------------------------------------------------------------------------------- /design/main_play_tab_background_2x.pxd/data/E4941AD5-E0D0-48A1-8F2E-881EEB311471: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pongasoft/vst-sam-spl-64/HEAD/design/main_play_tab_background_2x.pxd/data/E4941AD5-E0D0-48A1-8F2E-881EEB311471 -------------------------------------------------------------------------------- /design/main_play_tab_background_2x.pxd/data/FFDA3E94-79AC-4371-9E1F-8BEC69B43135: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pongasoft/vst-sam-spl-64/HEAD/design/main_play_tab_background_2x.pxd/data/FFDA3E94-79AC-4371-9E1F-8BEC69B43135 -------------------------------------------------------------------------------- /design/main_settings_tab_background_2x.pxd/data/2C21821A-BE1F-48B8-85CF-FC3D7FC26338: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pongasoft/vst-sam-spl-64/HEAD/design/main_settings_tab_background_2x.pxd/data/2C21821A-BE1F-48B8-85CF-FC3D7FC26338 -------------------------------------------------------------------------------- /design/main_settings_tab_background_2x.pxd/data/4E1034FC-49B5-40ED-BA0F-681FBE4DA601: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pongasoft/vst-sam-spl-64/HEAD/design/main_settings_tab_background_2x.pxd/data/4E1034FC-49B5-40ED-BA0F-681FBE4DA601 -------------------------------------------------------------------------------- /design/main_settings_tab_background_2x.pxd/data/59DEB769-6DE6-4AD6-BD48-6822A9797CA1: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pongasoft/vst-sam-spl-64/HEAD/design/main_settings_tab_background_2x.pxd/data/59DEB769-6DE6-4AD6-BD48-6822A9797CA1 -------------------------------------------------------------------------------- /design/main_settings_tab_background_2x.pxd/data/648CAFA0-4B88-4261-9810-E10EE2073964: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pongasoft/vst-sam-spl-64/HEAD/design/main_settings_tab_background_2x.pxd/data/648CAFA0-4B88-4261-9810-E10EE2073964 -------------------------------------------------------------------------------- /design/main_settings_tab_background_2x.pxd/data/702DC976-3392-4C26-A60D-F0C6412BE723: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pongasoft/vst-sam-spl-64/HEAD/design/main_settings_tab_background_2x.pxd/data/702DC976-3392-4C26-A60D-F0C6412BE723 -------------------------------------------------------------------------------- /design/main_settings_tab_background_2x.pxd/data/87591C71-DDBD-42CC-9AC9-8E4E31E5892F: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pongasoft/vst-sam-spl-64/HEAD/design/main_settings_tab_background_2x.pxd/data/87591C71-DDBD-42CC-9AC9-8E4E31E5892F -------------------------------------------------------------------------------- /design/main_settings_tab_background_2x.pxd/data/BEA5BFD7-7F04-44F1-916A-AAD98F269323: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pongasoft/vst-sam-spl-64/HEAD/design/main_settings_tab_background_2x.pxd/data/BEA5BFD7-7F04-44F1-916A-AAD98F269323 -------------------------------------------------------------------------------- /design/main_edit_tab_background_2x.pxd/data/selectionForContentTransform/shapeSelection/path: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pongasoft/vst-sam-spl-64/HEAD/design/main_edit_tab_background_2x.pxd/data/selectionForContentTransform/shapeSelection/path -------------------------------------------------------------------------------- /external/miniaudio/.gitignore: -------------------------------------------------------------------------------- 1 | \#issues/ 2 | _private/ 3 | examples/build/vc6/ 4 | examples/build/vc15/ 5 | examples/build/bin/ 6 | tests/_build/bin/ 7 | tests/_build/res/output/ 8 | tests/_build/tcc/ 9 | tests/_build/vc6/ 10 | tests/_build/vc15/ 11 | tools/_build/ 12 | *.vcxproj.user 13 | .vs/ 14 | .idea/ 15 | -------------------------------------------------------------------------------- /design/vu_on_2x.pxd/data/selectionForContentTransform/shapeSelection/meta: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | backingScale 6 | 1 7 | pathFilename 8 | path 9 | version 10 | 1 11 | 12 | 13 | -------------------------------------------------------------------------------- /design/main_edit_tab_background_2x.pxd/data/selectionForContentTransform/shapeSelection/meta: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | backingScale 6 | 1 7 | pathFilename 8 | path 9 | version 10 | 1 11 | 12 | 13 | -------------------------------------------------------------------------------- /archive/README-win_64bits.txt: -------------------------------------------------------------------------------- 1 | Install instructions 2 | ==================== 3 | 4 | Windows (64 bit) 5 | ---------------- 6 | The directory structure in this archive matches the file system, so you can simply 7 | copy it under C:\Program Files 8 | 9 | Or if you prefer to install each file individually: 10 | 11 | For VST3, copy Common Files\VST3\SAM-SPL64.vst3 under 12 | - C:\Program Files\Common Files\VST3 (may require admin access) 13 | - or any DAW specific path (64bits) 14 | 15 | Usage 16 | ===== 17 | Check the documentation at https://pongasoft.com/vst/SAM-SPL64.html 18 | -------------------------------------------------------------------------------- /src/cpp/GUI/SampleLoaderView.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include "../Plugin.h" 5 | 6 | namespace pongasoft::VST::SampleSplitter::GUI { 7 | 8 | using namespace VSTGUI; 9 | using namespace pongasoft::VST::GUI; 10 | using namespace pongasoft::VST::GUI::Views; 11 | 12 | class SampleLoaderView : public StateAwareView 13 | { 14 | public: 15 | explicit SampleLoaderView(const CRect &iSize) : StateAwareView(iSize) {}; 16 | 17 | void onClick() override; 18 | 19 | public: 20 | using Creator = Views::CustomViewCreator; 21 | }; 22 | 23 | } 24 | 25 | -------------------------------------------------------------------------------- /design/vu_on_2x.pxd/data/selectionForContentTransform/meta: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | backingScale 6 | 1 7 | mode 8 | 0 9 | shapeSelectionFilename 10 | shapeSelection 11 | size 12 | 13 | NC10UHpTVFAQAAAAQBQAAAAAAABAOAAAAAAAAA== 14 | 15 | softness 16 | 0.0 17 | timestamp 18 | 578158309.21179605 19 | transform 20 | 21 | NC10UHNuclQwAAAAP/AAAAAAAJoAAAAAAAAAAAAAAAAAAAAAP/AAAAAAAABAdf////// 22 | +wAAAAAAAAAA 23 | 24 | version 25 | 1 26 | 27 | 28 | -------------------------------------------------------------------------------- /design/main_edit_tab_background_2x.pxd/data/selectionForContentTransform/meta: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | backingScale 6 | 1 7 | mode 8 | 0 9 | shapeSelectionFilename 10 | shapeSelection 11 | size 12 | 13 | NC10UHpTVFAQAAAAQHkAAAAAAABAYYAAAAAAAA== 14 | 15 | softness 16 | 0.0 17 | timestamp 18 | 579113934.17835796 19 | transform 20 | 21 | NC10UHNuclQwAAAAP/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP/AAAAAAAAAAAAAAAAAA 22 | AAAAAAAAAAAA 23 | 24 | version 25 | 1 26 | 27 | 28 | -------------------------------------------------------------------------------- /.github/workflows/run-tests-macos-action.yml: -------------------------------------------------------------------------------- 1 | name: Build (macOS) 2 | 3 | on: 4 | push: 5 | branches: 6 | - 'master' 7 | tags-ignore: 8 | - '*' 9 | 10 | jobs: 11 | run_tests: 12 | 13 | runs-on: macos-14 14 | 15 | steps: 16 | - uses: actions/checkout@v4 17 | with: 18 | fetch-depth: 0 19 | 20 | - name: Configure Project 21 | working-directory: ${{github.workspace}} 22 | run: ${{github.workspace}}/configure.py -- -DJAMBA_DOWNLOAD_VSTSDK=ON 23 | 24 | - name: Run test/validate/archive (Release) 25 | working-directory: ${{github.workspace}}/build 26 | run: ./jamba.sh --release -b test validate archive 27 | 28 | - name: Upload Build Artifacts 29 | uses: actions/upload-artifact@v4 30 | with: 31 | name: archive-macos 32 | path: ${{github.workspace}}/build/*.zip 33 | -------------------------------------------------------------------------------- /design/routing_mono.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /.github/workflows/run-tests-windows-action.yml: -------------------------------------------------------------------------------- 1 | name: Build (Windows) 2 | 3 | on: 4 | push: 5 | branches: 6 | - 'master' 7 | tags-ignore: 8 | - '*' 9 | 10 | jobs: 11 | run_tests: 12 | runs-on: windows-2022 13 | 14 | steps: 15 | - uses: actions/checkout@v4 16 | with: 17 | fetch-depth: 0 18 | 19 | - name: Configure Project 20 | working-directory: ${{github.workspace}} 21 | run: python ${{github.workspace}}\configure.py -G "Visual Studio 17 2022" -- -DJAMBA_DOWNLOAD_VSTSDK=ON -A x64 22 | 23 | - name: Run test/validate/archive (Release) 24 | working-directory: ${{github.workspace}}/build 25 | run: .\jamba.bat --release -b test validate archive 26 | 27 | - name: Upload Build Artifacts 28 | uses: actions/upload-artifact@v4 29 | with: 30 | name: archive-windows 31 | path: ${{github.workspace}}/build/*.zip 32 | -------------------------------------------------------------------------------- /mac/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | NSHumanReadableCopyright 6 | 2018 pongasoft 7 | CFBundleDevelopmentRegion 8 | English 9 | CFBundleExecutable 10 | @MACOSX_BUNDLE_EXECUTABLE_NAME@ 11 | CFBundleIconFile 12 | 13 | CFBundleIdentifier 14 | pongasoft.vst.SampleSplitter 15 | CFBundleInfoDictionaryVersion 16 | 6.0 17 | CFBundlePackageType 18 | BNDL 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | 1.0 23 | CFBundleShortVersionString 24 | 1.0 25 | CSResourcesFileMapped 26 | 27 | 28 | 29 | -------------------------------------------------------------------------------- /external/miniaudio/miniaudio.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2023 pongasoft 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not 5 | * use this file except in compliance with the License. You may obtain a copy of 6 | * the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | * License for the specific language governing permissions and limitations under 14 | * the License. 15 | * 16 | * @author Yan Pujante 17 | */ 18 | 19 | #define STB_VORBIS_HEADER_ONLY 20 | #include /* Enables Vorbis decoding. */ 21 | 22 | #define MINIAUDIO_IMPLEMENTATION 23 | 24 | #include "miniaudio.h" 25 | 26 | /* stb_vorbis implementation must come after the implementation of miniaudio. */ 27 | #undef STB_VORBIS_HEADER_ONLY 28 | #include -------------------------------------------------------------------------------- /src/cpp/version.h.in: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #define MAJOR_VERSION_STR "@PLUGIN_MAJOR_VERSION@" 4 | #define MAJOR_VERSION_INT @PLUGIN_MAJOR_VERSION@ 5 | 6 | #define MINOR_VERSION_STR "@PLUGIN_MINOR_VERSION@" 7 | #define MINOR_VERSION_INT @PLUGIN_MINOR_VERSION@ 8 | 9 | #define PATCH_NUMBER_STR "@PLUGIN_PATCH_VERSION@" 10 | #define PATCH_NUMBER_INT @PLUGIN_PATCH_VERSION@ 11 | 12 | // Version with build number 13 | #define FULL_VERSION_STR "@PLUGIN_VERSION@" 14 | 15 | // Architecture 16 | #define BUILD_ARCHIVE_ARCHITECTURE "@JAMBA_ARCHIVE_ARCHITECTURE@" 17 | 18 | // Audio Unit version (as an hex int) 19 | #define AU_VERSION_INT 0x@AU_PLUGIN_VERSION_HEX@ 20 | 21 | #define stringOriginalFilename "SAM-SPL 64.vst3" 22 | #define stringFileDescription "SampleSplitter plugin by pongasoft (@JAMBA_ARCHIVE_ARCHITECTURE@)" 23 | #define stringCompanyName "pongasoft\0" 24 | #define stringLegalCopyright "© 2018-2022 pongasoft" 25 | 26 | #ifndef NDEBUG 27 | #define stringPluginName "SAM-SPL 64_Debug" 28 | #else 29 | #define stringPluginName "SAM-SPL 64" 30 | #endif 31 | -------------------------------------------------------------------------------- /external/miniaudio/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2023 pongasoft 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); you may not 4 | # use this file except in compliance with the License. You may obtain a copy of 5 | # the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 11 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 12 | # License for the specific language governing permissions and limitations under 13 | # the License. 14 | # 15 | # @author Yan Pujante 16 | 17 | cmake_minimum_required(VERSION 3.17) 18 | 19 | project(miniaudio) 20 | 21 | set(MINIAUDIO_ROOT_DIR "${CMAKE_CURRENT_LIST_DIR}") 22 | 23 | add_library(miniaudio miniaudio.c) 24 | target_include_directories(miniaudio PUBLIC "${MINIAUDIO_ROOT_DIR}") 25 | target_compile_definitions(miniaudio PUBLIC MA_NO_DEVICE_IO MA_ENABLE_ONLY_SPECIFIC_BACKENDS MA_NO_RESOURCE_MANAGER MA_NO_NODE_GRAPH MA_NO_ENGINE MA_NO_THREADING MA_NO_GENERATION) 26 | -------------------------------------------------------------------------------- /src/cpp/GUI/PadController.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include "../Plugin.h" 5 | #include "PadView.h" 6 | 7 | namespace pongasoft::VST::SampleSplitter::GUI { 8 | 9 | using namespace pongasoft::VST::GUI; 10 | 11 | class PadController : public Views::StateAwareCustomController 12 | { 13 | public: 14 | // Constructor 15 | explicit PadController(IController *iBaseController) : Views::StateAwareCustomController(iBaseController) {} 16 | 17 | ~PadController() override = default; 18 | 19 | void registerParameters() override; 20 | 21 | CView *verifyView(CView *view, const UIAttributes &attributes, const IUIDescription *description) override; 22 | 23 | protected: 24 | void onParameterChange(ParamID iParamID) override; 25 | 26 | protected: 27 | void setSlice(int iPadIndex); 28 | 29 | protected: 30 | GUIVstParam fNumSlices{}; 31 | GUIVstParam fPadBank{}; 32 | GUIVstParam fSelectedSlice{}; 33 | GUIJmbParam fPlayingState{}; 34 | 35 | PadView *fPads[NUM_PADS]{}; 36 | }; 37 | 38 | } -------------------------------------------------------------------------------- /src/cpp/GUI/SampleInfoView.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include "../Plugin.h" 6 | 7 | namespace pongasoft::VST::SampleSplitter::GUI { 8 | 9 | using namespace VSTGUI; 10 | using namespace pongasoft::VST::GUI::Views; 11 | 12 | /** 13 | * This class renders information about the sample. 14 | */ 15 | class SampleInfoView : public StateAwareCustomViewAdapter 16 | { 17 | public: 18 | // Constructor 19 | explicit SampleInfoView(const CRect &iSize) : StateAwareCustomViewAdapter(iSize) 20 | {}; 21 | 22 | void registerParameters() override; 23 | 24 | void onParameterChange(ParamID iParamID) override; 25 | 26 | protected: 27 | void computeInfo(); 28 | 29 | public: 30 | class Creator : public TCustomViewCreator 31 | { 32 | public: 33 | explicit Creator(char const *iViewName = nullptr, char const *iDisplayName = nullptr) noexcept : 34 | TCustomViewCreator(iViewName, iDisplayName, UIViewCreator::kCTextLabel) 35 | { 36 | } 37 | }; 38 | }; 39 | 40 | } -------------------------------------------------------------------------------- /src/cpp/GUI/SelectedSliceSettingView.cpp: -------------------------------------------------------------------------------- 1 | #include "../Plugin.h" 2 | #include "SliceSettingView.h" 3 | 4 | namespace pongasoft::VST::SampleSplitter::GUI { 5 | 6 | using namespace pongasoft::VST::GUI::Views; 7 | 8 | /** 9 | * Toggle button for a setting (reverse or loop) for the selected slice 10 | */ 11 | class SelectedSliceSettingView : public SliceSettingView 12 | { 13 | public: 14 | explicit SelectedSliceSettingView(CRect const &iSize) : SliceSettingView(iSize) {} 15 | 16 | void registerParameters() override 17 | { 18 | fSelectedSlice = registerCallback(fParams->fSelectedSlice, [this]() { setToggleFromSetting(); }); 19 | SliceSettingView::registerParameters(); 20 | } 21 | 22 | int getSlice() override { return *fSelectedSlice; }; 23 | 24 | protected: 25 | GUIVstParam fSelectedSlice{}; 26 | 27 | public: 28 | // Creator 29 | using Creator = CustomViewCreator; 30 | }; 31 | 32 | SelectedSliceSettingView::Creator __gSampleSplitterSelectedSliceSettingViewCreator("SampleSplitter::SelectedSliceSetting", "SampleSplitter - Selected Slice Setting"); 33 | 34 | } -------------------------------------------------------------------------------- /archive/README-macOS_64bits.txt: -------------------------------------------------------------------------------- 1 | Install instructions 2 | ==================== 3 | 4 | macOS (64 bits) 5 | --------------- 6 | For a single user, install under $HOME/Library/Audio/Plug-ins 7 | For all users, install under /Library/Audio/Plug-ins (may require admin access) 8 | 9 | The directory structure in this archive matches the file system, so you can simply 10 | copy it under $HOME/Library/Audio/Plug-ins (or /Library/Audio/Plug-ins) 11 | 12 | Or if you prefer to install each file individually: 13 | 14 | For VST3, copy VST3/SAM-SPL64.vst3 under 15 | - $HOME/Library/Audio/Plug-ins/VST3 for a single user 16 | - or /Library/Audio/Plug-ins/VST3 for all users (may require admin access) 17 | - or any DAW specific path (64bits) 18 | 19 | For Audio Unit, copy Components/SAM-SPL64.component under $HOME/Library/Audio/Plug-ins/Components 20 | - $HOME/Library/Audio/Plug-ins/Components for a single user 21 | - or /Library/Audio/Plug-ins/Components for all users (may require admin access) 22 | - Note: you may have to reboot your computer for the Audio Unit to appear in Logic 23 | (or kill the AudioComponentRegistrar process(es)) 24 | 25 | Usage 26 | ===== 27 | Check the documentation at https://pongasoft.com/vst/SAM-SPL64.html 28 | -------------------------------------------------------------------------------- /src/cpp/GUI/SampleEditController.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include "../Plugin.h" 6 | #include "SampleMgr.h" 7 | 8 | namespace pongasoft::VST::SampleSplitter::GUI { 9 | 10 | using namespace pongasoft::VST::GUI; 11 | 12 | class SampleEditController : public Views::StateAwareCustomController 13 | { 14 | public: 15 | // Constructor 16 | explicit SampleEditController(IController *iBaseController) : Views::StateAwareCustomController(iBaseController) {} 17 | 18 | ~SampleEditController() override = default; 19 | 20 | CView *verifyView(CView *view, const UIAttributes &attributes, const IUIDescription *description) override; 21 | 22 | void registerParameters() override; 23 | 24 | private: 25 | GUIVstParam fNumSlices{}; 26 | 27 | protected: 28 | Views::TextButtonView::OnClickListener processAction(SampleAction::Type iActionType); 29 | 30 | void initButton(Views::TextButtonView *iButton, SampleAction::Type iActionType, bool iEnabledOnSelection); 31 | 32 | int32 computeSliceSizeInSamples() const; 33 | NumSlice computeNumSlices(int32 iSliceSizeInSamples) const; 34 | }; 35 | 36 | } -------------------------------------------------------------------------------- /src/cpp/GUI/SampleLoaderView.cpp: -------------------------------------------------------------------------------- 1 | #include "SampleLoaderView.h" 2 | #include 3 | 4 | namespace pongasoft { 5 | namespace VST { 6 | namespace SampleSplitter { 7 | namespace GUI { 8 | 9 | 10 | //------------------------------------------------------------------------ 11 | // SampleLoaderView::onClick 12 | //------------------------------------------------------------------------ 13 | void SampleLoaderView::onClick() 14 | { 15 | auto selector = VSTGUI::owned(CNewFileSelector::create(getFrame(), CNewFileSelector::kSelectFile)); 16 | if(selector) 17 | { 18 | //selector->addFileExtension(CFileExtension("AIFF", "aif", "audio/x-aiff")); 19 | //selector->addFileExtension(CFileExtension("WAVE", "wav", "audio/x-wav")); 20 | selector->setTitle("Choose A Sample"); 21 | if(selector->runModal()) 22 | { 23 | if(selector->getNumSelectedFiles() > 0) 24 | { 25 | auto filename = selector->getSelectedFile(0); 26 | fState->maybeLoadSample(filename); 27 | } 28 | } 29 | } 30 | TextButtonView::onClick(); 31 | } 32 | 33 | // the creator 34 | SampleLoaderView::Creator __gSampleSplitterSampleLoaderCreator("SampleSplitter::SampleLoader", "SampleSplitter - SampleLoader"); 35 | 36 | } 37 | } 38 | } 39 | } -------------------------------------------------------------------------------- /src/cpp/SharedSampleBuffersMgr.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2020 pongasoft 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not 5 | * use this file except in compliance with the License. You may obtain a copy of 6 | * the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | * License for the specific language governing permissions and limitations under 14 | * the License. 15 | * 16 | * @author Yan Pujante 17 | */ 18 | 19 | #ifndef VST_SAM_SPL_64_SHAREDSAMPLEBUFFERSMGR_H 20 | #define VST_SAM_SPL_64_SHAREDSAMPLEBUFFERSMGR_H 21 | 22 | #include "SharedObjectMgr.h" 23 | #include "SampleBuffers.h" 24 | 25 | namespace pongasoft::VST::SampleSplitter { 26 | 27 | template 28 | using SharedSampleBuffersMgr = SharedObjectMgr, int64>; 29 | 30 | using SharedSampleBuffersMgr32 = SharedSampleBuffersMgr; 31 | 32 | using SharedSampleBuffersVersion = SharedSampleBuffersMgr32::version_type; 33 | 34 | } 35 | 36 | #endif //VST_SAM_SPL_64_SHAREDSAMPLEBUFFERSMGR_H 37 | -------------------------------------------------------------------------------- /design/routing_stereo.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /resource/gen_1x.sh: -------------------------------------------------------------------------------- 1 | #! /bin/bash 2 | 3 | # The purpose of this script is to automatically generate the 1x resolution images from the 2x images 4 | # It assumes ImageMagick is installed and available from the path 5 | # It needs to be run from the directory where it lives 6 | # It displays the entries for CMakeLists.txt so that it can be copy/pasted 7 | 8 | RESIZE="-resize" 9 | #RESIZE="-adaptive-resize" 10 | 11 | for filename in *_background_2x.png; do 12 | [ -e "$filename" ] || continue 13 | base=${filename%_2x.png} 14 | # echo "Processing $filename => ${base}.png" 15 | convert "$filename" $RESIZE "50%" "${base}.png" 16 | done 17 | 18 | #for filename in *_2x.png; do 19 | # [ -e "$filename" ] || continue 20 | # base=${filename%_2x.png} 21 | ## echo "Processing $filename => ${base}.png" 22 | #echo convert "$filename" $RESIZE "50%" "${base}.png" 23 | #done 24 | 25 | echo "########## SampleSlitter.uidesc ##########" 26 | for filename in *_2x.png; do 27 | [ -e "$filename" ] || continue 28 | base=${filename%_2x.png} 29 | echo "" 30 | echo "" 31 | done 32 | 33 | echo "########## CMakefile.txt ##########" 34 | 35 | # Display CMakeLists.txt so that it can be copy/pasted 36 | for filename in *_2x.png; do 37 | [ -e "$filename" ] || continue 38 | base=${filename%_2x.png} 39 | echo "\"\${RES_DIR}/${base}.png\"" 40 | echo "\"\${RES_DIR}/$filename\"" 41 | done -------------------------------------------------------------------------------- /src/cpp/GUI/PadView.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include "../Plugin.h" 5 | 6 | namespace pongasoft::VST::SampleSplitter::GUI { 7 | 8 | using namespace pongasoft::VST::GUI::Views; 9 | 10 | class PadView : public StateAwareView 11 | { 12 | public: 13 | explicit PadView(CRect const &iSize) : StateAwareView(iSize) {} 14 | 15 | inline bool isEnabled() const { return fEnabled; } 16 | 17 | void setSlice(int iSlice, bool iEnabled); 18 | 19 | inline float getPercentPlayed() const { return fPercentPlayed; } 20 | inline bool isPlaying() const { return getPercentPlayed() != PERCENT_PLAYED_NOT_PLAYING; } 21 | void setPercentPlayed(float iPercentPlayed); 22 | 23 | void draw(CDrawContext *iContext) override; 24 | 25 | void registerParameters() override; 26 | 27 | void setControlValue(const int32 &iControlValue) override; 28 | 29 | protected: 30 | bool fEnabled{true}; 31 | float fPercentPlayed{-1}; 32 | 33 | int fSlice{-1}; 34 | GUIVstParam fSelectedSlice{}; 35 | 36 | public: 37 | CLASS_METHODS_NOCOPY(PadView, MomentaryButtonView) 38 | 39 | // Creator 40 | class Creator : public CustomViewCreator 41 | { 42 | public: 43 | explicit Creator(char const *iViewName = nullptr, char const *iDisplayName = nullptr) noexcept : 44 | CustomViewCreator(iViewName, iDisplayName) 45 | { 46 | } 47 | }; 48 | }; 49 | 50 | } 51 | -------------------------------------------------------------------------------- /resource/SampleSplitter.rc: -------------------------------------------------------------------------------- 1 | #include 2 | #include "version.h" 3 | 4 | #define APSTUDIO_READONLY_SYMBOLS 5 | 6 | #include "vst3_resources.rc" 7 | 8 | ///////////////////////////////////////////////////////////////////////////// 9 | // Version 10 | ///////////////////////////////////////////////////////////////////////////// 11 | VS_VERSION_INFO VERSIONINFO 12 | FILEVERSION MAJOR_VERSION_INT,MINOR_VERSION_INT,PATCH_NUMBER_INT 13 | PRODUCTVERSION MAJOR_VERSION_INT,MINOR_VERSION_INT,PATCH_NUMBER_INT 14 | FILEFLAGSMASK 0x3fL 15 | #ifdef _DEBUG 16 | FILEFLAGS 0x1L 17 | #else 18 | FILEFLAGS 0x0L 19 | #endif 20 | FILEOS 0x40004L 21 | FILETYPE 0x1L 22 | FILESUBTYPE 0x0L 23 | BEGIN 24 | BLOCK "StringFileInfo" 25 | BEGIN 26 | BLOCK "040004e4" 27 | BEGIN 28 | VALUE "FileVersion", FULL_VERSION_STR"\0" 29 | VALUE "ProductVersion", FULL_VERSION_STR"\0" 30 | VALUE "OriginalFilename", stringOriginalFilename"\0" 31 | VALUE "FileDescription", stringFileDescription"\0" 32 | VALUE "InternalName", stringFileDescription"\0" 33 | VALUE "ProductName", stringFileDescription"\0" 34 | VALUE "CompanyName", stringCompanyName"\0" 35 | VALUE "LegalCopyright", stringLegalCopyright"\0" 36 | //VALUE "PrivateBuild", " \0" 37 | //VALUE "SpecialBuild", " \0" 38 | //VALUE "Comments", " \0" 39 | END 40 | END 41 | BLOCK "VarFileInfo" 42 | BEGIN 43 | VALUE "Translation", 0x400, 1252 44 | END 45 | END 46 | -------------------------------------------------------------------------------- /r8brain-free-src.cmake: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.12) 2 | 3 | include(FetchContent) 4 | 5 | set(R8BRAIN-FREE-SRC_GIT_REPO "https://github.com/avaneev/r8brain-free-src" CACHE STRING "r8brain-free-src git repository url" FORCE) 6 | set(R8BRAIN-FREE-SRC_GIT_TAG 6453d7756c1449afda66cc98a9b406006900fc13 CACHE STRING "r8brain-free-src git tag" FORCE) 7 | 8 | if(R8BRAIN-FREE-SRC_ROOT_DIR) 9 | message(STATUS "Using r8brain-free-src from local ${R8BRAIN-FREE-SRC_ROOT_DIR}") 10 | FetchContent_Populate(r8brain-free-src 11 | QUIET 12 | SOURCE_DIR "${R8BRAIN-FREE-SRC_ROOT_DIR}" 13 | BINARY_DIR "${CMAKE_BINARY_DIR}/r8brain-free-src-build" 14 | ) 15 | else() 16 | message(STATUS "Fetching r8brain-free-src ${R8BRAIN-FREE-SRC_GIT_REPO}/tree/${R8BRAIN-FREE-SRC_GIT_TAG}") 17 | FetchContent_Populate(r8brain-free-src 18 | GIT_REPOSITORY ${R8BRAIN-FREE-SRC_GIT_REPO} 19 | GIT_TAG ${R8BRAIN-FREE-SRC_GIT_TAG} 20 | GIT_CONFIG advice.detachedHead=false 21 | GIT_SHALLOW false 22 | SOURCE_DIR "${CMAKE_BINARY_DIR}/r8brain-free-src" 23 | BINARY_DIR "${CMAKE_BINARY_DIR}/r8brain-free-src-build" 24 | ) 25 | endif() 26 | 27 | 28 | # No CMakeLists.txt included => creating one 29 | file(WRITE "${r8brain-free-src_SOURCE_DIR}/CMakeLists.txt" 30 | [=[ 31 | project(r8brain-free-src) 32 | add_library(r8brain-free-src r8bbase.cpp) 33 | ]=] 34 | ) 35 | 36 | add_subdirectory(${r8brain-free-src_SOURCE_DIR} ${r8brain-free-src_BINARY_DIR} EXCLUDE_FROM_ALL) 37 | 38 | include_directories(${r8brain-free-src_SOURCE_DIR}) 39 | -------------------------------------------------------------------------------- /src/cpp/GUI/LargeFileDialogController.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2020 pongasoft 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not 5 | * use this file except in compliance with the License. You may obtain a copy of 6 | * the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | * License for the specific language governing permissions and limitations under 14 | * the License. 15 | * 16 | * @author Yan Pujante 17 | */ 18 | 19 | #ifndef SAMSPL64_LARGEFILEDIALOGCONTROLLER_H 20 | #define SAMSPL64_LARGEFILEDIALOGCONTROLLER_H 21 | 22 | #include 23 | #include "../Plugin.h" 24 | 25 | namespace pongasoft::VST::SampleSplitter::GUI { 26 | 27 | using namespace pongasoft::VST::GUI; 28 | 29 | /** 30 | * Handles Ok/Cancel action after trying to load a large file 31 | */ 32 | class LargeFileDialogController : public Views::StateAwareCustomController 33 | { 34 | public: 35 | // Constructor 36 | explicit LargeFileDialogController(IController *iBaseController) : Views::StateAwareCustomController(iBaseController) {} 37 | ~LargeFileDialogController() override = default; 38 | 39 | CView *verifyView(CView *view, const UIAttributes &attributes, const IUIDescription *description) override; 40 | }; 41 | 42 | } 43 | 44 | #endif //SAMSPL64_LARGEFILEDIALOGCONTROLLER_H -------------------------------------------------------------------------------- /src/cpp/GUI/SlicesActionViews.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include "../Plugin.h" 3 | 4 | namespace pongasoft::VST::SampleSplitter::GUI { 5 | 6 | using namespace pongasoft::VST::GUI::Views; 7 | 8 | /** 9 | * Button to toggle looping all slices */ 10 | class ToggleSliceLoopAllView : public StateAwareView 11 | { 12 | public: 13 | explicit ToggleSliceLoopAllView(const CRect &iSize) : StateAwareView(iSize) {} 14 | 15 | void onClick() override 16 | { 17 | auto &settings = fState->fSlicesSettings; 18 | if(settings.update(settings->toggleLoopAll())) 19 | settings.broadcast(); 20 | } 21 | 22 | public: 23 | using Creator = CustomViewCreator; 24 | }; 25 | 26 | ToggleSliceLoopAllView::Creator __gSampleSplitterToggleSliceLoopAllViewCreator("SampleSplitter::ToggleSliceLoopAll", "SampleSplitter - Toggle Slice Loop All"); 27 | 28 | /** 29 | * Button to reset the settings of all slices */ 30 | class ResetSliceSettingsView : public StateAwareView 31 | { 32 | public: 33 | explicit ResetSliceSettingsView(const CRect &iSize) : StateAwareView(iSize) {} 34 | 35 | void onClick() override 36 | { 37 | auto &settings = fState->fSlicesSettings; 38 | if(settings.update(SlicesSettings{})) 39 | settings.broadcast(); 40 | } 41 | 42 | public: 43 | using Creator = CustomViewCreator; 44 | }; 45 | 46 | ResetSliceSettingsView::Creator __gSampleSplitterResetSliceSettingsViewCreator("SampleSplitter::ResetSliceSettings", "SampleSplitter - Reset Slice Settings"); 47 | } -------------------------------------------------------------------------------- /src/cpp/GUI/SampleEditScrollbarView.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | 6 | #include "../Plugin.h" 7 | 8 | namespace pongasoft::VST::SampleSplitter::GUI { 9 | 10 | using namespace VSTGUI; 11 | using namespace pongasoft::VST::GUI::Views; 12 | 13 | 14 | class SampleEditScrollbarView : public StateAwareView 15 | { 16 | public: 17 | explicit SampleEditScrollbarView(const CRect &iSize) : StateAwareView(iSize) {} 18 | 19 | // get/setSelectionColor 20 | CColor const &getSelectionColor() const { return fSelectionColor; } 21 | void setSelectionColor(CColor const &iColor) { fSelectionColor = iColor; } 22 | 23 | void draw(CDrawContext *iContext) override; 24 | 25 | protected: 26 | void drawLeftHandle(CDrawContext *iContext) override; 27 | 28 | void drawRightHandle(CDrawContext *iContext) override; 29 | 30 | void drawScrollbar(CDrawContext *iContext) override; 31 | 32 | protected: 33 | void registerParameters() override; 34 | 35 | protected: 36 | using PixelRange = pongasoft::VST::GUI::Range; 37 | 38 | CColor fSelectionColor{255, 255, 255, 100}; 39 | 40 | public: 41 | CLASS_METHODS_NOCOPY(SampleEditScrollbarView, ScrollbarView) 42 | 43 | // Creator 44 | class Creator : public CustomViewCreator 45 | { 46 | public: 47 | explicit Creator(char const *iViewName = nullptr, char const *iDisplayName = nullptr) noexcept : 48 | CustomViewCreator(iViewName, iDisplayName) 49 | { 50 | registerColorAttribute("selection-color", &SampleEditScrollbarView::getSelectionColor, &SampleEditScrollbarView::setSelectionColor); 51 | } 52 | }; 53 | 54 | }; 55 | 56 | } 57 | 58 | 59 | -------------------------------------------------------------------------------- /src/cpp/GUI/Waveform.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | 7 | #include "../SampleBuffers.h" 8 | 9 | 10 | namespace pongasoft { 11 | namespace VST { 12 | namespace SampleSplitter { 13 | namespace GUI { 14 | 15 | using namespace VSTGUI; 16 | using namespace pongasoft::VST::GUI; 17 | 18 | /** 19 | * Represents the waveform 20 | */ 21 | class Waveform 22 | { 23 | public: 24 | /** 25 | * Look and feel of the waveform */ 26 | struct LAF 27 | { 28 | CColor fColor{}; 29 | CColor fAxisColor{}; 30 | CCoord fVerticalSpacing{}; 31 | Margin fMargin{}; 32 | CColor fZeroCrossingColor{kTransparentCColor}; 33 | }; 34 | 35 | public: 36 | /** 37 | * Generates a bitmap (waveform graphics representation) for the samples 38 | */ 39 | static BitmapPtr createBitmap(COffscreenContext *iContext, 40 | SampleBuffers32 const *iSamples, 41 | LAF const &iLAF, 42 | double iOffsetPercent = 0, 43 | double iZoomPercent = 0, 44 | int32 *oStartOffset = nullptr, 45 | int32 *oEndOffset = nullptr); 46 | 47 | /** 48 | * Compute oOffsetPercent and oZoomPercent from start/end offset 49 | */ 50 | static bool computeFromOffset(int32 iNumSamples, 51 | CCoord iWidth, 52 | LAF const &iLAF, 53 | int32 iStartOffset, 54 | int32 iEndOffset, 55 | double &oOffsetPercent, 56 | double &oZoomPercent); 57 | }; 58 | 59 | 60 | } 61 | } 62 | } 63 | } -------------------------------------------------------------------------------- /fetch_jamba.cmake: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.19) 2 | 3 | include(FetchContent) 4 | 5 | set(JAMBA_GIT_REPO "https://github.com/pongasoft/jamba" CACHE STRING "Jamba git repository url") 6 | set(JAMBA_GIT_TAG v7.1.4 CACHE STRING "Jamba git tag") 7 | set(JAMBA_DOWNLOAD_URL "${JAMBA_GIT_REPO}/archive/refs/tags/v7.1.4.zip" CACHE STRING "Jamba download url") 8 | set(JAMBA_DOWNLOAD_URL_HASH "SHA256=015a2e1b18f118f23673b995530407b7f47924a06969766451a43af7011917c8" CACHE STRING "Jamba download url hash") 9 | 10 | if(JAMBA_ROOT_DIR) 11 | message(STATUS "Using jamba from local ${JAMBA_ROOT_DIR}") 12 | FetchContent_Declare(jamba 13 | SOURCE_DIR "${JAMBA_ROOT_DIR}" 14 | SOURCE_SUBDIR "do_not_make_available" # invalid folder to not execute jamba/CMakeLists.txt 15 | ) 16 | else() 17 | if(JAMBA_DOWNLOAD_URL STREQUAL "" OR JAMBA_DOWNLOAD_URL_HASH STREQUAL "") 18 | message(STATUS "Fetching jamba from ${JAMBA_GIT_REPO}/tree/${JAMBA_GIT_TAG}") 19 | FetchContent_Declare(jamba 20 | GIT_REPOSITORY ${JAMBA_GIT_REPO} 21 | GIT_TAG ${JAMBA_GIT_TAG} 22 | GIT_CONFIG advice.detachedHead=false 23 | GIT_SHALLOW true 24 | SOURCE_DIR "${CMAKE_BINARY_DIR}/jamba" 25 | SOURCE_SUBDIR "do_not_make_available" 26 | ) 27 | else() 28 | message(STATUS "Fetching jamba from ${JAMBA_DOWNLOAD_URL}") 29 | FetchContent_Declare(jamba 30 | URL "${JAMBA_DOWNLOAD_URL}" 31 | URL_HASH "${JAMBA_DOWNLOAD_URL_HASH}" 32 | DOWNLOAD_EXTRACT_TIMESTAMP true 33 | SOURCE_DIR "${CMAKE_BINARY_DIR}/jamba" 34 | SOURCE_SUBDIR "do_not_make_available" 35 | ) 36 | endif() 37 | endif() 38 | 39 | FetchContent_MakeAvailable(jamba) 40 | 41 | set(JAMBA_ROOT_DIR ${jamba_SOURCE_DIR}) 42 | 43 | -------------------------------------------------------------------------------- /audio-unit/audiounitconfig.h: -------------------------------------------------------------------------------- 1 | #include "version.h" 2 | 3 | // Check https://developer.apple.com/library/archive/documentation/General/Conceptual/ExtensibilityPG/AudioUnit.html for various types 4 | 5 | /* Bundle Identifier */ 6 | #define kAudioUnitBundleIdentifier pongasoft.vst3.SamSpl64.audiounit 7 | 8 | /* Version Number (computed in version.h from version in CMakeLists.txt) */ 9 | #define kAudioUnitVersion AU_VERSION_INT 10 | 11 | /* Company Name + Effect Name */ 12 | #define kAUPluginName pongasoft: Sam-Spl 64 13 | 14 | /* A product name for the audio unit, such as TremoloUnit */ 15 | #define kAUPluginDescription Sam-Spl 64 16 | 17 | /* 18 | The specific variant of the Audio Unit. The four possible types and their values are: 19 | Effect (aufx), Generator (augn), Instrument (aumu), and Music Effect (aufm). 20 | */ 21 | #define kAUPluginType aumu 22 | 23 | /* A subtype code for the audio unit, such as tmlo. This value must be exactly 4 alphanumeric characters. */ 24 | #define kAUPluginSubType unkw 25 | 26 | /* A manufacturer code for the audio unit, such as Aaud. This value must be exactly 4 alphanumeric characters. 27 | * This value should be unique across audio units of the same manufacturer 28 | * Manufacturer OSType should have at least one non-lower case character */ 29 | #define kAUPluginManufacturer Psft 30 | 31 | // Definitions for the resource file 32 | #define kAudioUnitName "pongasoft: Sam-Spl 64" // same as kAUPluginName 33 | #define kAudioUnitDescription "Sam-Spl 64" // same as kAUPluginDescription 34 | #define kAudioUnitType 'aumu' // same as kAUPluginType 35 | #define kAudioUnitComponentSubType 'unkw' // same as kAUPluginSubType 36 | #define kAudioUnitComponentManuf 'Psft' // same as kAUPluginManufacturer 37 | 38 | #define kAudioUnitCarbonView 1 // if 0 no Carbon view support will be added 39 | -------------------------------------------------------------------------------- /src/cpp/GUI/SliceSettingView.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include "../Plugin.h" 5 | 6 | namespace pongasoft::VST::SampleSplitter::GUI { 7 | 8 | using namespace pongasoft::VST::GUI::Views; 9 | 10 | /** 11 | * Toggle button for a setting (reverse or loop) for a slice 12 | */ 13 | class SliceSettingView : public StateAwareView 14 | { 15 | public: 16 | enum Type 17 | { 18 | kReverseSetting, 19 | kLoopSetting 20 | }; 21 | 22 | public: 23 | explicit SliceSettingView(CRect const &iSize) : StateAwareView(iSize) {} 24 | 25 | // get/setType 26 | SliceSettingView::Type getType() const { return fType; } 27 | void setType(SliceSettingView::Type iType) { fType = iType; } 28 | 29 | virtual int getSlice() { return -1; }; 30 | 31 | void registerParameters() override; 32 | 33 | void onParameterChange(ParamID iParamID) override; 34 | 35 | protected: 36 | void setToggleFromSetting(); 37 | 38 | protected: 39 | GUIJmbParam fSlicesSettings{}; 40 | 41 | SliceSettingView::Type fType{}; 42 | 43 | public: 44 | // Creator 45 | class Creator : public CustomViewCreator 46 | { 47 | public: 48 | explicit Creator(char const *iViewName = nullptr, char const *iDisplayName = nullptr) noexcept : 49 | CustomViewCreator(iViewName, iDisplayName) 50 | { 51 | registerListAttribute("type", 52 | &SliceSettingView::getType, 53 | &SliceSettingView::setType, 54 | { 55 | {"reverse", Type::kReverseSetting}, 56 | {"loop", Type::kLoopSetting} 57 | }); 58 | } 59 | }; 60 | 61 | }; 62 | 63 | } -------------------------------------------------------------------------------- /libsndfile.cmake: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.12) 2 | 3 | include(FetchContent) 4 | 5 | set(LIBSNDFILE_GIT_REPO "https://github.com/erikd/libsndfile" CACHE STRING "libsndfile git repository url" FORCE) 6 | set(LIBSNDFILE_GIT_TAG c11deaa04ec84161996824061f6d705970972e2e CACHE STRING "libsndfile git tag" FORCE) 7 | 8 | if(LIBSNDFILE_ROOT_DIR) 9 | message(STATUS "Using libsndfile from local ${LIBSNDFILE_ROOT_DIR}") 10 | FetchContent_Populate(libsndfile 11 | QUIET 12 | SOURCE_DIR "${LIBSNDFILE_ROOT_DIR}" 13 | BINARY_DIR "${CMAKE_BINARY_DIR}/libsndfile-build" 14 | ) 15 | else() 16 | message(STATUS "Fetching libsndfile from ${LIBSNDFILE_GIT_REPO}/tree/${LIBSNDFILE_GIT_TAG}") 17 | FetchContent_Populate(libsndfile 18 | QUIET 19 | GIT_REPOSITORY ${LIBSNDFILE_GIT_REPO} 20 | GIT_TAG ${LIBSNDFILE_GIT_TAG} 21 | GIT_CONFIG advice.detachedHead=false 22 | # GIT_SHALLOW true 23 | SOURCE_DIR "${CMAKE_BINARY_DIR}/libsndfile" 24 | BINARY_DIR "${CMAKE_BINARY_DIR}/libsndfile-build" 25 | ) 26 | endif() 27 | 28 | set(LIBSNDFILE_ROOT_DIR ${libsndfile_SOURCE_DIR}) 29 | set(LIBSNDFILE_INCLUDE_DIR "${libsndfile_BINARY_DIR}/src") 30 | 31 | function(libsndfile_build) 32 | option(BUILD_PROGRAMS "Build programs" OFF) 33 | option(BUILD_EXAMPLES "Build examples" OFF) 34 | option(BUILD_TESTING "Build examples" OFF) 35 | option(ENABLE_CPACK "Enable CPack support" OFF) 36 | option(ENABLE_PACKAGE_CONFIG "Generate and install package config file" OFF) 37 | option(BUILD_REGTEST "Build regtest" OFF) 38 | # finally we include libsndfile itself 39 | add_subdirectory(${libsndfile_SOURCE_DIR} ${libsndfile_BINARY_DIR} EXCLUDE_FROM_ALL) 40 | # copying .hh for c++ support 41 | file(COPY "${libsndfile_SOURCE_DIR}/src/sndfile.hh" DESTINATION ${LIBSNDFILE_INCLUDE_DIR}) 42 | endfunction() 43 | 44 | libsndfile_build() 45 | 46 | include_directories(${LIBSNDFILE_INCLUDE_DIR}) 47 | -------------------------------------------------------------------------------- /src/cpp/GUI/ErrorMessageView.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2023 pongasoft 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not 5 | * use this file except in compliance with the License. You may obtain a copy of 6 | * the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | * License for the specific language governing permissions and limitations under 14 | * the License. 15 | * 16 | * @author Yan Pujante 17 | */ 18 | 19 | #ifndef VST_SAM_SPL_64_ERROR_MESSAGE_VIEW_H 20 | #define VST_SAM_SPL_64_ERROR_MESSAGE_VIEW_H 21 | 22 | #include 23 | #include "../Plugin.h" 24 | 25 | namespace pongasoft::VST::SampleSplitter::GUI { 26 | 27 | using namespace pongasoft::VST::GUI::Views; 28 | 29 | class ErrorMessageView : public StateAwareView 30 | { 31 | public: 32 | explicit ErrorMessageView(CRect const &iSize) : StateAwareView(iSize) {} 33 | 34 | void registerParameters() override; 35 | 36 | void onParameterChange(ParamID iParamID) override; 37 | 38 | CMouseEventResult onMouseDown(CPoint &where, const CButtonState &buttons) override; 39 | 40 | protected: 41 | GUIJmbParam fErrorMessage{}; 42 | 43 | public: 44 | CLASS_METHODS_NOCOPY(ErrorMessageView, DebugParamDisplayView) 45 | 46 | // Creator 47 | class Creator : public CustomViewCreator 48 | { 49 | public: 50 | explicit Creator(char const *iViewName = nullptr, char const *iDisplayName = nullptr) noexcept : 51 | CustomViewCreator(iViewName, iDisplayName) 52 | { 53 | } 54 | }; 55 | }; 56 | 57 | } 58 | 59 | #endif //VST_SAM_SPL_64_ERROR_MESSAGE_VIEW_H -------------------------------------------------------------------------------- /design/button-style.css: -------------------------------------------------------------------------------- 1 | body { 2 | margin: 0; 3 | background: transparent; 4 | } 5 | 6 | table { 7 | border-spacing: 0; 8 | margin: 0; 9 | padding: 0; 10 | } 11 | 12 | td { 13 | padding-top: 0; 14 | padding-left: 0; 15 | } 16 | 17 | .scale-1x td { 18 | padding-right: 4px; 19 | padding-bottom: 4px; 20 | } 21 | 22 | .scale-2x td { 23 | padding-right: 8px; 24 | padding-bottom: 8px; 25 | } 26 | 27 | .scale-1x .button-frame { 28 | border-radius: 3px; 29 | } 30 | 31 | .scale-2x .button-frame { 32 | border-radius: 4px; 33 | } 34 | 35 | .scale-1x .button-frame { 36 | border: solid 1px black; 37 | } 38 | 39 | .scale-2x .button-frame { 40 | border: solid 2px black; 41 | } 42 | 43 | .button { 44 | display: flex; 45 | justify-content:center; 46 | align-items:center; 47 | } 48 | 49 | .scale-1x .specular-light-on { 50 | border-radius: 2px; 51 | border-top: solid 1px rgba(255,255,255,0.5); 52 | border-left: solid 1px rgba(255,255,255,0.5); 53 | border-right: solid 1px rgba(255,255,255,0.1); 54 | border-bottom: solid 1px rgba(255,255,255,0.1); 55 | } 56 | 57 | .scale-1x .specular-light-off { 58 | margin: 1px; 59 | } 60 | 61 | .scale-2x .specular-light-on { 62 | border-radius: 2px; 63 | border-top: solid 2px rgba(255,255,255,0.5); 64 | border-left: solid 2px rgba(255,255,255,0.5); 65 | border-right: solid 2px rgba(255,255,255,0.1); 66 | border-bottom: solid 2px rgba(255,255,255,0.1); 67 | } 68 | 69 | .scale-2x .specular-light-off { 70 | margin: 2px; 71 | } 72 | 73 | .button-disabled { 74 | background: rgb(77,77,77); 75 | color: rgb(54,54,54); 76 | display: inline-block; 77 | } 78 | 79 | .button-off { 80 | background: rgb(129,135,135); 81 | box-shadow: 2px 2px 2px 0 rgba(0,0,0,0.5); 82 | display: inline-block; 83 | } 84 | 85 | .button-on { 86 | background: rgb(213,131,33); 87 | box-shadow: 1px 1px 1px 0 rgba(0,0,0,0.5); 88 | display: inline-block; 89 | } 90 | 91 | .button-on .title { 92 | margin-right: -1px; 93 | margin-bottom: -1px; 94 | } 95 | -------------------------------------------------------------------------------- /src/cpp/GUI/LargeFileDialogController.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2020 pongasoft 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not 5 | * use this file except in compliance with the License. You may obtain a copy of 6 | * the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | * License for the specific language governing permissions and limitations under 14 | * the License. 15 | * 16 | * @author Yan Pujante 17 | */ 18 | 19 | #include "LargeFileDialogController.h" 20 | #include 21 | 22 | namespace pongasoft::VST::SampleSplitter::GUI { 23 | 24 | //------------------------------------------------------------------------ 25 | // LargeFileDialogController::verifyView 26 | //------------------------------------------------------------------------ 27 | VSTGUI::CView *LargeFileDialogController::verifyView(CView *iView, 28 | const UIAttributes &iAttributes, 29 | const IUIDescription * /* iDescription */) 30 | { 31 | auto button = dynamic_cast(iView); 32 | 33 | if(button) 34 | { 35 | switch(button->getCustomViewTag()) 36 | { 37 | case ESampleSplitterParamID::kOkAction: 38 | button->setOnClickListener([this] () -> void { 39 | fState->loadSample(*fState->fLargeFilePath); 40 | fState->fLargeFilePath.update(""); 41 | fState->dismissDialog(); 42 | }); 43 | break; 44 | 45 | case ESampleSplitterParamID::kCancelAction: 46 | button->setOnClickListener([this] () -> void { 47 | fState->fLargeFilePath.update(""); 48 | fState->dismissDialog(); 49 | }); 50 | break; 51 | } 52 | } 53 | 54 | return iView; 55 | } 56 | 57 | } -------------------------------------------------------------------------------- /src/cpp/GUI/SliceSettingView.cpp: -------------------------------------------------------------------------------- 1 | #include "SliceSettingView.h" 2 | 3 | namespace pongasoft::VST::SampleSplitter::GUI { 4 | 5 | //------------------------------------------------------------------------ 6 | // SliceSettingView::registerParameters 7 | //------------------------------------------------------------------------ 8 | void SliceSettingView::registerParameters() 9 | { 10 | ToggleButtonView::registerParameters(); 11 | fSlicesSettings = registerCallback(fState->fSlicesSettings, [this]() { setToggleFromSetting() ;}); 12 | setToggleFromSetting(); 13 | } 14 | 15 | //------------------------------------------------------------------------ 16 | // SliceSettingView::setToggleFromSetting 17 | //------------------------------------------------------------------------ 18 | void SliceSettingView::setToggleFromSetting() 19 | { 20 | // implementation note: no need to explicitly call markDirty() because redrawing this view is tied to 21 | // the state of the toggle which is explicitly set in this method 22 | switch(fType) 23 | { 24 | case kReverseSetting: 25 | setOnOrOff(fSlicesSettings->isReverse(getSlice())); 26 | break; 27 | 28 | case kLoopSetting: 29 | setOnOrOff(fSlicesSettings->isLoop(getSlice())); 30 | break; 31 | } 32 | } 33 | 34 | //------------------------------------------------------------------------ 35 | // SliceSettingView::onParameterChange 36 | //------------------------------------------------------------------------ 37 | void SliceSettingView::onParameterChange(ParamID iParamID) 38 | { 39 | // implementation note: this is called only when the toggle changes since the other 40 | // parameters are using callbacks 41 | switch(fType) 42 | { 43 | case kReverseSetting: 44 | if(fSlicesSettings.update(fSlicesSettings->reverse(getSlice(), isOn()))) 45 | fSlicesSettings.broadcast(); 46 | break; 47 | 48 | case kLoopSetting: 49 | if(fSlicesSettings.update(fSlicesSettings->loop(getSlice(), isOn()))) 50 | fSlicesSettings.broadcast(); 51 | break; 52 | } 53 | 54 | ToggleButtonView::onParameterChange(iParamID); 55 | } 56 | 57 | 58 | } -------------------------------------------------------------------------------- /src/cpp/GUI/SliceNumberView.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include "../Plugin.h" 5 | 6 | namespace pongasoft::VST::SampleSplitter::GUI { 7 | 8 | using namespace pongasoft::VST::GUI::Views; 9 | 10 | /** 11 | * Displays the slice number (based on offset + bank) */ 12 | class SliceNumberView : public StateAwareCustomViewAdapter 13 | { 14 | public: 15 | using super_type = StateAwareCustomViewAdapter; 16 | 17 | public: 18 | explicit SliceNumberView(CRect const &iSize) : StateAwareCustomViewAdapter(iSize) {} 19 | 20 | // registerParameters 21 | void registerParameters() override 22 | { 23 | registerCallback(fParams->fPadBank, 24 | [this](GUIVstParam &iParam) { 25 | if(fSliceOffset >= 0) 26 | { 27 | auto computedSlice = fSliceOffset + iParam.value() * NUM_PADS; 28 | setText(std::to_string(computedSlice)); 29 | } 30 | else 31 | setText(""); 32 | }, 33 | true); 34 | } 35 | 36 | int getSliceOffset() const { return fSliceOffset; } 37 | void setSliceOffset(int offset) { fSliceOffset = offset; } 38 | 39 | protected: 40 | int fSliceOffset{-1}; 41 | 42 | public: 43 | // Creator 44 | class Creator : public CustomViewCreator 45 | { 46 | public: 47 | explicit Creator(char const *iViewName = nullptr, char const *iDisplayName = nullptr) noexcept : 48 | CustomViewCreator(iViewName, iDisplayName, VSTGUI::UIViewCreator::kCTextLabel) 49 | { 50 | registerIntAttribute("slice-offset", 51 | &SliceNumberView::getSliceOffset, 52 | &SliceNumberView::setSliceOffset); 53 | } 54 | }; 55 | }; 56 | 57 | SliceNumberView::Creator __gSampleSplitterSliceNumberViewCreator("SampleSplitter::SliceNumber", "SampleSplitter - Slice Number"); 58 | 59 | } -------------------------------------------------------------------------------- /src/cpp/GUI/ErrorMessageView.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2023 pongasoft 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not 5 | * use this file except in compliance with the License. You may obtain a copy of 6 | * the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | * License for the specific language governing permissions and limitations under 14 | * the License. 15 | * 16 | * @author Yan Pujante 17 | */ 18 | 19 | #include "ErrorMessageView.h" 20 | 21 | namespace pongasoft::VST::SampleSplitter::GUI { 22 | 23 | //------------------------------------------------------------------------ 24 | // ErrorMessageView::registerParameters 25 | //------------------------------------------------------------------------ 26 | void ErrorMessageView::registerParameters() 27 | { 28 | DebugParamDisplayView::registerParameters(); 29 | fErrorMessage = registerParam(fParams->fErrorMessage); 30 | } 31 | 32 | //------------------------------------------------------------------------ 33 | // ErrorMessageView::onParameterChange 34 | //------------------------------------------------------------------------ 35 | void ErrorMessageView::onParameterChange(ParamID iParamID) 36 | { 37 | if(*fErrorMessage != std::nullopt) 38 | DebugParamDisplayView::onParameterChange(iParamID); 39 | else 40 | ParamDisplayView::onParameterChange(iParamID); 41 | } 42 | 43 | //------------------------------------------------------------------------ 44 | // ErrorMessageView::onMouseDown 45 | //------------------------------------------------------------------------ 46 | CMouseEventResult ErrorMessageView::onMouseDown(CPoint &where, const CButtonState &buttons) 47 | { 48 | if(!(buttons & kLButton)) 49 | return kMouseEventNotHandled; 50 | 51 | fState->clearError(); 52 | return kMouseEventHandled; 53 | } 54 | 55 | ErrorMessageView::Creator __gSampleSplitterErrorMessageCreator("SampleSplitter::ErrorMessage", "SampleSplitter - Error Message"); 56 | 57 | } -------------------------------------------------------------------------------- /src/cpp/GUI/SampleFileLoader.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2023 pongasoft 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not 5 | * use this file except in compliance with the License. You may obtain a copy of 6 | * the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | * License for the specific language governing permissions and limitations under 14 | * the License. 15 | * 16 | * @author Yan Pujante 17 | */ 18 | 19 | #ifndef VST_SAM_SPL_64_SAMPLE_FILE_LOADER_H 20 | #define VST_SAM_SPL_64_SAMPLE_FILE_LOADER_H 21 | 22 | #include 23 | #include 24 | #include 25 | #include "../FilePath.h" 26 | #include 27 | 28 | using namespace Steinberg; 29 | 30 | namespace pongasoft::VST::SampleSplitter { 31 | template 32 | class SampleBuffers; 33 | using SampleBuffers32 = SampleBuffers; 34 | } 35 | 36 | namespace pongasoft::VST::SampleSplitter::GUI { 37 | 38 | /** 39 | * The point of this (abstract) class is to allow for different loaders */ 40 | class SampleFileLoader 41 | { 42 | public: 43 | struct SampleInfo 44 | { 45 | Vst::SampleRate fSampleRate; 46 | int32 fNumChannels; 47 | int32 fNumSamples; // an int32 can contain over 3h worth of samples at 192000 48 | 49 | constexpr int64 getTotalSize() const { return static_cast(fNumChannels) * static_cast(fNumSamples); } 50 | }; 51 | 52 | public: 53 | using load_result_t = std::variant, std::string>; 54 | 55 | public: 56 | virtual ~SampleFileLoader() = default; 57 | 58 | virtual bool isValid() const = 0; 59 | virtual std::string error() const = 0; 60 | virtual load_result_t load() = 0; 61 | virtual std::optional info() = 0; 62 | 63 | static std::unique_ptr create(UTF8Path const &iFilePath); 64 | 65 | // Checks if the file is supported by Sndfile or miniaudio 66 | static inline bool isSupportedFileType(UTF8Path const &iFilePath) { return create(iFilePath)->isValid(); } 67 | }; 68 | 69 | 70 | 71 | } 72 | 73 | #endif //VST_SAM_SPL_64_SAMPLE_FILE_LOADER_H -------------------------------------------------------------------------------- /src/cpp/SampleSplitter_VST3.cpp: -------------------------------------------------------------------------------- 1 | //------------------------------------------------------------------------------------------------------------ 2 | // This file contains the standard boilerplate code that VST3 sdk requires to instantiate the plugin 3 | // components 4 | //------------------------------------------------------------------------------------------------------------ 5 | #include "FilePath.h" 6 | 7 | #include "SampleSplitterCIDs.h" 8 | 9 | #include "version.h" 10 | #include "RT/SampleSplitterProcessor.h" 11 | #include "GUI/SampleSplitterController.h" 12 | 13 | #include 14 | 15 | using namespace pongasoft::VST; 16 | 17 | #ifndef NDEBUG 18 | #if SMTG_OS_WINDOWS 19 | #include 20 | //------------------------------------------------------------------------ 21 | // called after library was loaded 22 | static Steinberg::ModuleInitializer InitPlugin([] () { 23 | auto stdoutHandle = GetStdHandle(STD_OUTPUT_HANDLE); 24 | if(stdoutHandle <= 0) 25 | { 26 | auto logFilePath = pongasoft::VST::SampleSplitter::createTempFilePath("out.log"); 27 | // this will NOT work if the path contains UT8-encoded characters but is a workaround to the 28 | // fact that loguru does not support wchar_t... see https://github.com/emilk/loguru/issues/100 29 | // Should be using logFilePath.toNativePath() if/when loguru supports windows files... 30 | loguru::add_file(logFilePath.c_str(), loguru::Truncate, loguru::Verbosity_MAX); 31 | } 32 | }); 33 | #endif 34 | #endif 35 | 36 | //------------------------------------------------------------------------ 37 | // VST3 Plugin Main entry point 38 | //------------------------------------------------------------------------ 39 | SMTG_EXPORT_SYMBOL Steinberg::IPluginFactory* PLUGIN_API GetPluginFactory() 40 | { 41 | return JambaPluginFactory::GetNonDistributableVST3PluginFactory< 42 | pongasoft::VST::SampleSplitter::RT::SampleSplitterProcessor, // processor class (Real Time) 43 | pongasoft::VST::SampleSplitter::GUI::SampleSplitterController // controller class (GUI) 44 | >("pongasoft", // company/vendor 45 | "https://www.pongasoft.com", // url 46 | "support@pongasoft.com", // email 47 | stringPluginName, // plugin name 48 | FULL_VERSION_STR, // plugin version 49 | Vst::PlugType::kInstrumentSampler // Instrument type! 50 | ); 51 | } 52 | -------------------------------------------------------------------------------- /src/cpp/GUI/OffsettedSliceSettingView.cpp: -------------------------------------------------------------------------------- 1 | #include "../Plugin.h" 2 | #include "SliceSettingView.h" 3 | 4 | namespace pongasoft::VST::SampleSplitter::GUI { 5 | 6 | using namespace pongasoft::VST::GUI::Views; 7 | 8 | /** 9 | * Toggle button for a setting (reverse or loop) for the slice defined by an offset and a pad bank. 10 | * 11 | * Ex: Offset 0 Bank A => Slice 0, Offset 15 Bank D => Slice 63 12 | */ 13 | class OffsettedSliceSettingView : public SliceSettingView 14 | { 15 | public: 16 | explicit OffsettedSliceSettingView(CRect const &iSize) : SliceSettingView(iSize) {} 17 | 18 | void registerParameters() override 19 | { 20 | fPadBank = registerCallback(fParams->fPadBank, [this]() { computeSlice(); setToggleFromSetting(); }); 21 | fSelectedSlice = registerParam(fParams->fSelectedSlice, false); 22 | computeSlice(); 23 | SliceSettingView::registerParameters(); 24 | } 25 | 26 | int getSlice() override { return fComputedSlice; }; 27 | 28 | int getSliceOffset() const { return fSliceOffset; } 29 | void setSliceOffset(int offset) { fSliceOffset = offset; } 30 | 31 | // Overriding to select the slice when clicking it 32 | CMouseEventResult onMouseDown(CPoint &where, const CButtonState &buttons) override 33 | { 34 | // we select the slice when clicked 35 | fSelectedSlice = getSlice(); 36 | return ToggleButtonView::onMouseDown(where, buttons); 37 | } 38 | 39 | protected: 40 | void computeSlice() 41 | { 42 | if(fSliceOffset >= 0) 43 | fComputedSlice = fSliceOffset + *fPadBank * NUM_PADS; 44 | } 45 | 46 | protected: 47 | GUIVstParam fPadBank{}; 48 | GUIVstParam fSelectedSlice{}; 49 | int fSliceOffset{-1}; 50 | 51 | int fComputedSlice{-1}; 52 | 53 | public: 54 | // Creator 55 | class Creator : public CustomViewCreator 56 | { 57 | public: 58 | explicit Creator(char const *iViewName = nullptr, char const *iDisplayName = nullptr) noexcept : 59 | CustomViewCreator(iViewName, iDisplayName) 60 | { 61 | registerIntAttribute("slice-offset", 62 | &OffsettedSliceSettingView::getSliceOffset, 63 | &OffsettedSliceSettingView::setSliceOffset); 64 | } 65 | }; 66 | }; 67 | 68 | OffsettedSliceSettingView::Creator __gSampleSplitterOffsettedSliceSettingViewCreator("SampleSplitter::OffsettedSliceSetting", "SampleSplitter - Offsetted Slice Setting"); 69 | 70 | } -------------------------------------------------------------------------------- /src/cpp/SampleStorage.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | 6 | #include "SampleBuffers.h" 7 | #include "FilePath.h" 8 | 9 | namespace pongasoft { 10 | namespace VST { 11 | namespace SampleSplitter { 12 | 13 | using namespace Steinberg; 14 | 15 | /** 16 | * Information relating to the sample */ 17 | struct SampleInfo 18 | { 19 | SampleRate fSampleRate{-1}; 20 | int32 fNumChannels{-1}; 21 | int32 fNumSamples{-1}; 22 | }; 23 | 24 | /** 25 | * Defines the interface to how a sample is stored while the plugin is running (memory or temporary file). The 26 | * sample is maintained in its original form (ex wav, aiff, etc..). */ 27 | class SampleStorage 28 | { 29 | public: 30 | enum ESampleMajorFormat 31 | { 32 | kSampleFormatWAV, 33 | kSampleFormatAIFF 34 | }; 35 | 36 | enum ESampleMinorFormat 37 | { 38 | kSampleFormatPCM16, 39 | kSampleFormatPCM24, 40 | kSampleFormatPCM32 41 | }; 42 | 43 | public: 44 | // Destructor 45 | virtual ~SampleStorage() = default; 46 | 47 | // The size of the sample (in number of bytes) 48 | virtual uint64 getSize() const = 0; 49 | 50 | virtual UTF8Path const &getFilePath() const = 0; 51 | 52 | // Called to save the sample to the plugin state 53 | virtual tresult copyTo(IBStreamer &oStreamer) const = 0; 54 | 55 | // clone 56 | virtual std::unique_ptr clone() const = 0; 57 | 58 | // "reads" the sample and convert it into buffers of individual 32 bits samples 59 | virtual std::unique_ptr toBuffers(SampleRate iSampleRate) const = 0; 60 | 61 | // "reads" the sample and convert it into buffers of individual 32 bits samples 62 | virtual std::unique_ptr toBuffers() const = 0; 63 | 64 | /** 65 | * Retrieves information about the sample (without reading the whole buffer) 66 | * 67 | * @param oSampleInfo 68 | * @return kResultOk if read successfully (in which case oSampleInfo is populated with the right data) 69 | */ 70 | virtual tresult getSampleInfo(SampleInfo &oSampleInfo) const = 0; 71 | 72 | /** 73 | * Retrieves information about the sample (without reading the whole buffer) 74 | * 75 | * @return the info about the sample if could read it, `nullptr` otherwise 76 | */ 77 | virtual std::unique_ptr getSampleInfo() const 78 | { 79 | SampleInfo sampleInfo; 80 | if(getSampleInfo(sampleInfo) == kResultOk) 81 | return std::make_unique(sampleInfo); 82 | else 83 | return nullptr; 84 | } 85 | }; 86 | 87 | } 88 | } 89 | } -------------------------------------------------------------------------------- /src/cpp/GUI/SampleDisplayView.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "WaveformView.h" 4 | 5 | namespace pongasoft { 6 | namespace VST { 7 | namespace SampleSplitter { 8 | namespace GUI { 9 | 10 | using namespace VSTGUI; 11 | using namespace pongasoft::VST::GUI; 12 | 13 | /** 14 | * This class renders the sample currently loaded as a waveform. 15 | */ 16 | class SampleDisplayView : public WaveformView 17 | { 18 | public: 19 | // Constructor 20 | explicit SampleDisplayView(const CRect &iSize) : WaveformView(iSize) 21 | {}; 22 | 23 | // get/setSelectionColor 24 | CColor const &getSelectionColor() const { return fSelectionColor; } 25 | void setSelectionColor(CColor const &iColor) { fSelectionColor = iColor; } 26 | 27 | // draw 28 | void draw(CDrawContext *iContext) override; 29 | 30 | // registerParameters 31 | void registerParameters() override; 32 | 33 | // mouse handling 34 | CMouseEventResult onMouseDown(CPoint &where, const CButtonState &buttons) override; 35 | CMouseEventResult onMouseUp(CPoint &where, const CButtonState &buttons) override; 36 | CMouseEventResult onMouseMoved(CPoint &where, const CButtonState &buttons) override; 37 | CMouseEventResult onMouseCancel() override; 38 | 39 | //------------------------------------------------------------------------ 40 | // slice line color 41 | //------------------------------------------------------------------------ 42 | CColor const &getSliceLineColor() const { return fSliceLineColor; } 43 | void setSliceLineColor(const CColor &iColor) { fSliceLineColor = iColor; } 44 | 45 | protected: 46 | // generateBitmap 47 | void generateBitmap(CurrentSample const &iCurrentSample) override; 48 | 49 | // computeSelectedSlice 50 | int computeSelectedSlice(CPoint const &iWhere) const; 51 | 52 | private: 53 | CColor fSelectionColor{255, 255, 255, 100}; 54 | CColor fSliceLineColor{kTransparentCColor}; 55 | 56 | GUIVstParam fNumSlices{}; 57 | 58 | GUIVstParam fSelectedSlice{}; 59 | GUIVstParamEditor fSelectedSliceEditor{nullptr}; 60 | 61 | public: 62 | class Creator : public Views::CustomViewCreator 63 | { 64 | public: 65 | explicit Creator(char const *iViewName = nullptr, char const *iDisplayName = nullptr) noexcept : 66 | CustomViewCreator(iViewName, iDisplayName) 67 | { 68 | registerColorAttribute("selection-color", &SampleDisplayView::getSelectionColor, &SampleDisplayView::setSelectionColor); 69 | registerColorAttribute("slice-line-color", &SampleDisplayView::getSliceLineColor, &SampleDisplayView::setSliceLineColor); 70 | } 71 | }; 72 | }; 73 | 74 | } 75 | } 76 | } 77 | } 78 | 79 | -------------------------------------------------------------------------------- /src/cpp/GUI/SamplingStateView.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include "../Plugin.h" 6 | 7 | namespace pongasoft::VST::SampleSplitter::GUI { 8 | 9 | using namespace VSTGUI; 10 | using namespace pongasoft::VST::GUI; 11 | 12 | /** 13 | * Sampling state - display text depending on state of sampling 14 | */ 15 | class SamplingStateView : public Views::StateAwareCustomViewAdapter 16 | { 17 | public: 18 | using super_type = Views::StateAwareCustomViewAdapter; 19 | 20 | public: 21 | //------------------------------------------------------------------------ 22 | // Constructor 23 | //------------------------------------------------------------------------ 24 | explicit SamplingStateView(const CRect &iSize) : super_type(iSize) {}; 25 | 26 | //------------------------------------------------------------------------ 27 | // registerParameters 28 | //------------------------------------------------------------------------ 29 | void registerParameters() override 30 | { 31 | registerParam(fState->fSamplingState); 32 | } 33 | 34 | //------------------------------------------------------------------------ 35 | // onParameterChange 36 | //------------------------------------------------------------------------ 37 | void onParameterChange(ParamID iParamID) override 38 | { 39 | if(iParamID == fState->fSamplingState.getParamID()) 40 | { 41 | auto percentSampled = fState->fSamplingState->fPercentSampled; 42 | 43 | if(percentSampled == PERCENT_SAMPLED_WAITING) 44 | setText("Waiting..."); 45 | else 46 | { 47 | if(percentSampled == 0) 48 | setText(""); 49 | else 50 | { 51 | auto text = Steinberg::String().printf("%2d%%", static_cast(percentSampled * 100)); 52 | setText(text.text8()); 53 | } 54 | } 55 | } 56 | 57 | CustomViewAdapter::onParameterChange(iParamID); 58 | } 59 | 60 | public: 61 | class Creator : public Views::CustomViewCreator 62 | { 63 | public: 64 | explicit Creator(char const *iViewName = nullptr, char const *iDisplayName = nullptr) : 65 | CustomViewCreator(iViewName, iDisplayName, VSTGUI::UIViewCreator::kCTextLabel) 66 | { 67 | } 68 | }; 69 | }; 70 | 71 | // the creator 72 | SamplingStateView::Creator __gSampleSplitterSamplingStateCreator("SampleSplitter::SamplingStateView", "SampleSplitter - SamplingState"); 73 | 74 | } 75 | 76 | -------------------------------------------------------------------------------- /src/cpp/GUI/PadKeyView.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include "../Plugin.h" 5 | 6 | namespace pongasoft::VST::SampleSplitter::GUI { 7 | 8 | using namespace VSTGUI; 9 | using namespace pongasoft::VST::GUI; 10 | 11 | /** 12 | * Displays the key associated to the pad 13 | */ 14 | class PadKeyView : public Views::StateAwareCustomViewAdapter 15 | { 16 | private: 17 | using super_type = Views::StateAwareCustomViewAdapter; 18 | 19 | public: 20 | //------------------------------------------------------------------------ 21 | // Constructor 22 | //------------------------------------------------------------------------ 23 | explicit PadKeyView(const CRect &iSize) : super_type(iSize) {}; 24 | 25 | //------------------------------------------------------------------------ 26 | // registerParameters 27 | //------------------------------------------------------------------------ 28 | void registerParameters() override 29 | { 30 | fSelectedSlice = registerParam(fParams->fSelectedSlice); 31 | fRootKey = registerParam(fParams->fRootKey); 32 | 33 | setText(computePadKey()); 34 | } 35 | 36 | //------------------------------------------------------------------------ 37 | // onParameterChange 38 | //------------------------------------------------------------------------ 39 | void onParameterChange(ParamID iParamID) override 40 | { 41 | super_type::onParameterChange(iParamID); 42 | 43 | setText(computePadKey()); 44 | } 45 | 46 | private: 47 | //------------------------------------------------------------------------ 48 | // computePadKey 49 | //------------------------------------------------------------------------ 50 | UTF8String computePadKey() 51 | { 52 | auto rootKey = *fRootKey + *fSelectedSlice; 53 | 54 | if(rootKey < 0 || rootKey >= NUM_ROOT_KEYS) 55 | return "N/A"; 56 | else 57 | return UTF8String(Steinberg::String(KEYS.at(rootKey).c_str()).text8()); 58 | } 59 | 60 | 61 | private: 62 | GUIVstParam fSelectedSlice{}; 63 | GUIVstParam fRootKey{}; 64 | 65 | public: 66 | class Creator : public Views::CustomViewCreator 67 | { 68 | public: 69 | explicit Creator(char const *iViewName = nullptr, char const *iDisplayName = nullptr) : 70 | CustomViewCreator(iViewName, iDisplayName, VSTGUI::UIViewCreator::kCTextLabel) 71 | { 72 | } 73 | }; 74 | }; 75 | 76 | // the creator 77 | PadKeyView::Creator __gKeyRootCreator("SampleSplitter::PadKeyView", "SampleSplitter - PadKey"); 78 | 79 | } 80 | 81 | -------------------------------------------------------------------------------- /external/miniaudio/LICENSE: -------------------------------------------------------------------------------- 1 | This software is available as a choice of the following licenses. Choose 2 | whichever you prefer. 3 | 4 | =============================================================================== 5 | ALTERNATIVE 1 - Public Domain (www.unlicense.org) 6 | =============================================================================== 7 | This is free and unencumbered software released into the public domain. 8 | 9 | Anyone is free to copy, modify, publish, use, compile, sell, or distribute this 10 | software, either in source code form or as a compiled binary, for any purpose, 11 | commercial or non-commercial, and by any means. 12 | 13 | In jurisdictions that recognize copyright laws, the author or authors of this 14 | software dedicate any and all copyright interest in the software to the public 15 | domain. We make this dedication for the benefit of the public at large and to 16 | the detriment of our heirs and successors. We intend this dedication to be an 17 | overt act of relinquishment in perpetuity of all present and future rights to 18 | this software under copyright law. 19 | 20 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 21 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 22 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 23 | AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN 24 | ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 25 | WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 26 | 27 | For more information, please refer to 28 | 29 | =============================================================================== 30 | ALTERNATIVE 2 - MIT No Attribution 31 | =============================================================================== 32 | Copyright 2023 David Reid 33 | 34 | Permission is hereby granted, free of charge, to any person obtaining a copy of 35 | this software and associated documentation files (the "Software"), to deal in 36 | the Software without restriction, including without limitation the rights to 37 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies 38 | of the Software, and to permit persons to whom the Software is furnished to do 39 | so. 40 | 41 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 42 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 43 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 44 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 45 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 46 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 47 | SOFTWARE. -------------------------------------------------------------------------------- /src/cpp/GUI/SampleSplitterController.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include "../Plugin.h" 6 | 7 | namespace pongasoft::VST::SampleSplitter::GUI { 8 | 9 | using namespace pongasoft::VST::GUI; 10 | 11 | //------------------------------------------------------------------------ 12 | // SampleSplitterController - Main GUI Controller 13 | //------------------------------------------------------------------------ 14 | class SampleSplitterController : public GUIController, public ParamAware 15 | { 16 | public: 17 | //------------------------------------------------------------------------ 18 | // UUID() method used to create the controller 19 | //------------------------------------------------------------------------ 20 | static inline ::Steinberg::FUID UUID() { return SampleSplitterControllerUID; }; 21 | 22 | //------------------------------------------------------------------------ 23 | // Factory method used to create the controller 24 | //------------------------------------------------------------------------ 25 | static FUnknown *createInstance(void * /*context*/) { return (IEditController *) new SampleSplitterController(); } 26 | 27 | public: 28 | // Constructor 29 | SampleSplitterController(); 30 | 31 | // Destructor -- overridden for debugging purposes only 32 | ~SampleSplitterController() override; 33 | 34 | // getGUIState 35 | GUIState *getGUIState() override { return &fState; } 36 | 37 | protected: 38 | // initialize 39 | tresult PLUGIN_API initialize(FUnknown *context) override; 40 | 41 | // registerParameters 42 | void registerParameters() override; 43 | 44 | public: 45 | IController *createCustomController(UTF8StringPtr iName, 46 | IUIDescription const *iDescription, 47 | IController *iBaseController) override; 48 | 49 | private: 50 | // The controller gets its own copy of the parameters (defined in Plugin.h) 51 | SampleSplitterParameters fParams; 52 | 53 | // The state accessible in the controller and views 54 | SampleSplitterGUIState fState; 55 | 56 | // Manages the samples shared between UI and RT (owned by RT) 57 | SharedSampleBuffersMgr32 *fSharedSampleBuffersMgr{}; 58 | 59 | // Current view type 60 | GUIVstParam fViewType{}; 61 | GUIRawVstParam fOffsetPercent{}; 62 | GUIRawVstParam fZoomPercent{}; 63 | GUIVstParam fSamplingInput{}; 64 | GUIVstParam fEditingMode{}; 65 | GUIVstParam fSampling{}; 66 | 67 | // remember previous sampling input to restore it when switching between tabs 68 | ESamplingInput fPreviousSamplingInput{ESamplingInput::kSamplingInput1}; 69 | }; 70 | 71 | } 72 | 73 | -------------------------------------------------------------------------------- /src/cpp/GUI/CurrentSample.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2020 pongasoft 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not 5 | * use this file except in compliance with the License. You may obtain a copy of 6 | * the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | * License for the specific language governing permissions and limitations under 14 | * the License. 15 | * 16 | * @author Yan Pujante 17 | */ 18 | 19 | #ifndef VST_SAM_SPL_64_CURRENTSAMPLE_H 20 | #define VST_SAM_SPL_64_CURRENTSAMPLE_H 21 | 22 | #include "../SampleBuffers.h" 23 | 24 | namespace pongasoft::VST::SampleSplitter::GUI { 25 | 26 | class CurrentSample 27 | { 28 | public: 29 | enum class Source 30 | { 31 | kUnknown, kFile, kSampling 32 | }; 33 | enum class UpdateType 34 | { 35 | kNone, kAction, kUndo 36 | }; 37 | 38 | public: 39 | 40 | CurrentSample() = default; // param API 41 | 42 | CurrentSample(CurrentSample const &iOther) = default; // param API 43 | 44 | CurrentSample(std::shared_ptr iBuffers, 45 | SampleRate iOriginalSampleRate, 46 | Source iSource, 47 | UpdateType iUpdateType) : 48 | fBuffers{std::move(iBuffers)}, fOriginalSampleRate{iOriginalSampleRate}, fSource{iSource}, fUpdateType{iUpdateType} 49 | { 50 | // empty 51 | } 52 | 53 | // empty 54 | inline bool empty() const { return fBuffers == nullptr; } 55 | 56 | // hasSamples 57 | inline bool hasSamples() const { return !empty() && fBuffers->hasSamples(); } 58 | 59 | // getSampleRate 60 | inline SampleRate getSampleRate() const { DCHECK_F(!empty()); return fBuffers->getSampleRate(); } 61 | 62 | // getOriginalSampleRate 63 | inline SampleRate getOriginalSampleRate() const { DCHECK_F(!empty()); return fOriginalSampleRate; } 64 | 65 | // getNumChannels 66 | inline int32 getNumChannels() const { DCHECK_F(!empty()); return fBuffers->getNumChannels(); }; 67 | 68 | // getNumSamples 69 | inline int32 getNumSamples() const { DCHECK_F(!empty()); return fBuffers->getNumSamples(); } 70 | 71 | // getBuffers 72 | inline SampleBuffers32 const *getBuffers() const { return fBuffers != nullptr ? fBuffers.get() : nullptr; } 73 | 74 | // getSharedBuffers 75 | inline std::shared_ptr getSharedBuffers() const { return fBuffers; } 76 | 77 | // getSource 78 | inline Source getSource() const { return fSource; } 79 | 80 | // getUpdateType 81 | inline UpdateType getUpdateType() const { return fUpdateType; } 82 | 83 | private: 84 | std::shared_ptr fBuffers{}; 85 | SampleRate fOriginalSampleRate{}; 86 | Source fSource{Source::kUnknown}; 87 | UpdateType fUpdateType{UpdateType::kNone}; 88 | }; 89 | 90 | 91 | 92 | } 93 | 94 | #endif //VST_SAM_SPL_64_CURRENTSAMPLE_H -------------------------------------------------------------------------------- /src/cpp/GUI/PadController.cpp: -------------------------------------------------------------------------------- 1 | #include "PadController.h" 2 | #include "PadView.h" 3 | 4 | namespace pongasoft::VST::SampleSplitter::GUI { 5 | 6 | //------------------------------------------------------------------------ 7 | // PadController::verifyView 8 | //------------------------------------------------------------------------ 9 | CView *PadController::verifyView(CView *iView, 10 | const UIAttributes &iAttributes, 11 | const IUIDescription * /* iDescription */) 12 | { 13 | auto pad = dynamic_cast(iView); 14 | if(pad) 15 | { 16 | int index = static_cast(pad->getControlTag() - ESampleSplitterParamID::kPad1); 17 | DCHECK_F(index >= 0 && index < NUM_PADS); 18 | fPads[index] = pad; 19 | int slice = *fPadBank * NUM_PADS + index; 20 | pad->setSlice(slice, slice < fNumSlices->intValue()); 21 | pad->setPercentPlayed(fPlayingState->fPercentPlayed[slice]); 22 | return pad; 23 | } 24 | 25 | return iView; 26 | } 27 | 28 | //------------------------------------------------------------------------ 29 | // PadController::registerParameters 30 | //------------------------------------------------------------------------ 31 | void PadController::registerParameters() 32 | { 33 | fNumSlices = registerParam(fParams->fNumSlices); 34 | fPadBank = registerParam(fParams->fPadBank); 35 | fPlayingState = registerParam(fState->fPlayingState); 36 | fSelectedSlice = registerParam(fParams->fSelectedSlice, false); 37 | registerCallback(fParams->fSelectedSliceViaMidi, [this](GUIVstParam &iSelectedSliceViaMidi){ 38 | if(fSelectedSlice != iSelectedSliceViaMidi && iSelectedSliceViaMidi < fNumSlices->intValue()) 39 | { 40 | fSelectedSlice.copyValueFrom(iSelectedSliceViaMidi); 41 | // it is possible that the slice selected via MIDI is on a different bank => switch to it 42 | fPadBank = *iSelectedSliceViaMidi / NUM_PADS; 43 | } 44 | }); 45 | } 46 | 47 | //------------------------------------------------------------------------ 48 | // PadController::setSlice 49 | //------------------------------------------------------------------------ 50 | void PadController::setSlice(int iPadIndex) 51 | { 52 | DCHECK_F(iPadIndex >= 0 && iPadIndex < NUM_PADS); 53 | auto pad = fPads[iPadIndex]; 54 | if(pad) 55 | { 56 | int slice = *fPadBank * NUM_PADS + iPadIndex; 57 | pad->setSlice(slice, slice < fNumSlices->intValue()); 58 | } 59 | } 60 | 61 | //------------------------------------------------------------------------ 62 | // PadController::onParameterChange 63 | //------------------------------------------------------------------------ 64 | void PadController::onParameterChange(ParamID iParamID) 65 | { 66 | if(iParamID == fNumSlices.getParamID() || iParamID == fPadBank.getParamID()) 67 | { 68 | for(int i = 0; i < NUM_PADS; i++) 69 | setSlice(i); 70 | } 71 | 72 | if(iParamID == fPadBank.getParamID() || iParamID == fPlayingState.getParamID()) 73 | { 74 | int slice = *fPadBank * NUM_PADS; 75 | for(auto pad : fPads) 76 | { 77 | if(pad) 78 | pad->setPercentPlayed(fPlayingState->fPercentPlayed[slice++]); 79 | } 80 | } 81 | } 82 | 83 | } -------------------------------------------------------------------------------- /src/cpp/GUI/PadView.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | #include "PadView.h" 5 | 6 | namespace pongasoft::VST::SampleSplitter::GUI { 7 | 8 | //------------------------------------------------------------------------ 9 | // PadView::setSlice 10 | //------------------------------------------------------------------------ 11 | void PadView::setSlice(int iSlice, bool iEnabled) 12 | { 13 | bool dirty = false; 14 | 15 | if(fSlice != iSlice) 16 | { 17 | fSlice = iSlice; 18 | dirty = true; 19 | } 20 | 21 | if(fEnabled != iEnabled) 22 | { 23 | fEnabled = iEnabled; 24 | dirty = true; 25 | } 26 | 27 | if(dirty) 28 | markDirty(); 29 | } 30 | 31 | //------------------------------------------------------------------------ 32 | // PadView::draw 33 | //------------------------------------------------------------------------ 34 | void PadView::draw(CDrawContext *iContext) 35 | { 36 | drawBackColor(iContext); 37 | 38 | auto rdc = pongasoft::VST::GUI::RelativeDrawContext{this, iContext}; 39 | 40 | if(isEnabled()) 41 | { 42 | if(isPlaying()) 43 | { 44 | drawOn(iContext); 45 | 46 | auto width = getWidth() * fPercentPlayed; 47 | // handle reverse 48 | if(width < 0) 49 | width = getWidth() + width; 50 | // rdc.fillRect(0, 0, width, getHeight(), CColor{255,255,255,120}); 51 | rdc.drawLine(width, 0, width, getHeight(), kWhiteCColor); 52 | } 53 | else 54 | { 55 | drawOff(iContext); 56 | } 57 | } 58 | else 59 | { 60 | // not enabled 61 | drawOff(iContext); 62 | iContext->setFillColor(CColor{0, 0, 0, 120}); 63 | iContext->drawRect(getViewSize(), kDrawFilled); 64 | } 65 | 66 | if(fSlice == fSelectedSlice) 67 | { 68 | rdc.drawRect(rdc.getViewSize(), kWhiteCColor); 69 | } 70 | } 71 | 72 | //------------------------------------------------------------------------ 73 | // PadView::setPercentPlayed 74 | //------------------------------------------------------------------------ 75 | void PadView::setPercentPlayed(float iPercentPlayed) 76 | { 77 | if(iPercentPlayed != fPercentPlayed) 78 | { 79 | fPercentPlayed = iPercentPlayed; 80 | markDirty(); 81 | } 82 | } 83 | 84 | //------------------------------------------------------------------------ 85 | // PadView::registerParameters 86 | //------------------------------------------------------------------------ 87 | void PadView::registerParameters() 88 | { 89 | MomentaryButtonView::registerParameters(); 90 | fSelectedSlice = registerParam(fParams->fSelectedSlice); 91 | } 92 | 93 | //------------------------------------------------------------------------ 94 | // PadView::setControlValue 95 | //------------------------------------------------------------------------ 96 | void PadView::setControlValue(const int32 &iControlValue) 97 | { 98 | TCustomControlView::setControlValue(iControlValue); 99 | 100 | if(isOn()) 101 | fSelectedSlice.setValue(fSlice); 102 | } 103 | 104 | PadView::Creator __gSampleSplitterPadViewCreator("SampleSplitter::Pad", "SampleSplitter - Pad"); 105 | 106 | } -------------------------------------------------------------------------------- /src/cpp/GUI/SampleEditScrollbarView.cpp: -------------------------------------------------------------------------------- 1 | #include "SampleEditScrollbarView.h" 2 | 3 | namespace pongasoft::VST::SampleSplitter::GUI { 4 | 5 | //------------------------------------------------------------------------ 6 | // SampleEditScrollbarView::registerParameters 7 | //------------------------------------------------------------------------ 8 | void SampleEditScrollbarView::registerParameters() 9 | { 10 | ScrollbarView::registerParameters(); 11 | registerParam(fState->fWESelectedSampleRange); 12 | registerParam(fState->fCurrentSample); // needed for drawing the selection 13 | registerParam(fState->fSampleRate); // needed for drawing the selection 14 | } 15 | 16 | //------------------------------------------------------------------------ 17 | // SampleEditScrollbarView::draw 18 | //------------------------------------------------------------------------ 19 | void SampleEditScrollbarView::draw(CDrawContext *iContext) 20 | { 21 | 22 | if(!fState->fWESelectedSampleRange->isSingleValue()) 23 | { 24 | auto numSamples = fState->fCurrentSample->getNumSamples(); 25 | if(numSamples > 0) 26 | { 27 | recompute(); 28 | 29 | PixelRange fullRange(fZoomBox.getMinLeft() + fScrollbarGutterSpacing + fLeftHandleRect.getWidth(), 30 | fZoomBox.getMaxRight() - fScrollbarGutterSpacing - fRightHandleRect.getWidth()); 31 | 32 | auto range = 33 | SampleRange(0, numSamples).mapSubRange(*fState->fWESelectedSampleRange, fullRange); 34 | 35 | // make sure that there is at least one line drawn (0.25 seems to be the magic number...) 36 | range.fTo = std::max(range.fFrom + 0.25, range.fTo); 37 | 38 | auto rdc = pongasoft::VST::GUI::RelativeDrawContext{this, iContext}; 39 | 40 | rdc.fillRect(range.fFrom, 0, range.fTo, getHeight(), getSelectionColor()); 41 | } 42 | 43 | } 44 | 45 | ScrollbarView::draw(iContext); 46 | } 47 | 48 | //------------------------------------------------------------------------ 49 | // SampleEditScrollbarView::drawLeftHandle 50 | //------------------------------------------------------------------------ 51 | void SampleEditScrollbarView::drawLeftHandle(CDrawContext *iContext) 52 | { 53 | iContext->setFillColor(fZoomHandlesColor); 54 | iContext->drawRect(fLeftHandleRect, kDrawFilled); 55 | } 56 | 57 | //------------------------------------------------------------------------ 58 | // SampleEditScrollbarView::drawRightHandle 59 | //------------------------------------------------------------------------ 60 | void SampleEditScrollbarView::drawRightHandle(CDrawContext *iContext) 61 | { 62 | iContext->setFillColor(fZoomHandlesColor); 63 | iContext->drawRect(fRightHandleRect, kDrawFilled); 64 | } 65 | 66 | //------------------------------------------------------------------------ 67 | // SampleEditScrollbarView::drawScrollbar 68 | //------------------------------------------------------------------------ 69 | void SampleEditScrollbarView::drawScrollbar(CDrawContext *iContext) 70 | { 71 | ScrollbarView::drawScrollbar(iContext); 72 | } 73 | 74 | // the creator 75 | SampleEditScrollbarView::Creator __gSampleSplitterSampleEditScrollbarCreator("SampleSplitter::SampleEditScrollbarView", "SampleSplitter - SampleEditScrollbarView"); 76 | 77 | } 78 | -------------------------------------------------------------------------------- /src/cpp/Sampler.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include "SampleBuffers.h" 6 | 7 | namespace pongasoft { 8 | namespace VST { 9 | namespace SampleSplitter { 10 | 11 | /** 12 | * Keeps track of the state the sampler is in. 13 | */ 14 | enum class ESamplerState 15 | { 16 | kNotSampling, 17 | kSampling, 18 | kDoneSampling 19 | }; 20 | 21 | /** 22 | * Generic Sampler. Typical usage pattern: 23 | * 24 | * Sampler32 sampler(2); // stereo 25 | * 26 | * sampler.init(48000, 100000); // this allocates memory 27 | * sampler.start(); 28 | * sampler.sample(in, startOffset); // may not start at the beginning of the buffer 29 | * for ... { 30 | * if { sampler.sample(in, -1, stopOffset); sampler.stop(); } 31 | * else { sample.sample(in); } 32 | * 33 | * if(!sampler.isSampling()) { 34 | * sampler.stop(); 35 | * sampler.copyTo(otherBuffer); 36 | * break; 37 | * } 38 | * } 39 | * sampler.dispose(); // this releases memory 40 | * 41 | * @tparam SampleType the type of the samples this sampler store 42 | */ 43 | template 44 | class Sampler : public Utils::Disposable 45 | { 46 | public: 47 | using SampleBuffersT = SampleBuffers; 48 | 49 | public: 50 | // Constructor 51 | explicit Sampler(int32 iNumChannels) : fNumChannels{iNumChannels}, fCurrent{0}, fState{ESamplerState::kNotSampling} {}; 52 | 53 | // initializes this sampler (allocate enough memory for iMaxSamples) 54 | void init(SampleRate iSampleRate, int32 iMaxSamples); 55 | 56 | // isInitialized 57 | bool isInitialized() const { return fBuffers != nullptr; } 58 | 59 | // start 60 | void start(bool iResetCurrent = true); 61 | 62 | // stop 63 | inline void stop() { fState = ESamplerState::kNotSampling; } 64 | 65 | // getPercentSampled 66 | float getPercentSampled() const; 67 | 68 | // returns true if the sampler is currently sampling (start has been called and it has not reached the maximum 69 | // number of samples) 70 | inline bool isSampling() const { return fState == ESamplerState::kSampling; } 71 | 72 | // free resources 73 | void dispose() override; 74 | 75 | /** 76 | * Sample the in buffer (which can be a different type) and return the end state. If the sampler is not sampling, 77 | * then doesn't do anything. 78 | * 79 | * @param iStartOffset optional start offset in the in buffer to start sampling from 80 | * @param iEndOffset optional end offset in the in buffer to stop sampling at 81 | * @return state 82 | */ 83 | template 84 | ESamplerState sample(AudioBuffers &iIn, int32 iStartOffset = -1, int32 iEndOffset = -1); 85 | 86 | /** 87 | * After sampling, we acquire the buffers and reset for more sampling */ 88 | std::unique_ptr acquireBuffers(); 89 | 90 | private: 91 | int32 fNumChannels; 92 | int32 fCurrent; 93 | ESamplerState fState; 94 | std::unique_ptr fBuffers{}; 95 | }; 96 | 97 | // shortcut types 98 | using Sampler32 = Sampler; 99 | using Sampler64 = Sampler; 100 | 101 | } 102 | } 103 | } 104 | 105 | 106 | -------------------------------------------------------------------------------- /src/cpp/GUI/SampleInfoView.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include "SampleInfoView.h" 3 | 4 | #include 5 | 6 | namespace pongasoft { 7 | namespace VST { 8 | namespace SampleSplitter { 9 | namespace GUI { 10 | 11 | //------------------------------------------------------------------------ 12 | // SampleInfoView::registerParameters 13 | //------------------------------------------------------------------------ 14 | void SampleInfoView::registerParameters() 15 | { 16 | registerParam(fState->fCurrentSample); 17 | registerParam(fState->fWESelectedSampleRange); 18 | computeInfo(); 19 | } 20 | 21 | //------------------------------------------------------------------------ 22 | // SampleInfoView::onParameterChange 23 | //------------------------------------------------------------------------ 24 | void SampleInfoView::onParameterChange(ParamID iParamID) 25 | { 26 | computeInfo(); 27 | CustomViewAdapter::onParameterChange(iParamID); 28 | } 29 | 30 | namespace internal { 31 | //------------------------------------------------------------------------ 32 | // formatDuration 33 | //------------------------------------------------------------------------ 34 | Steinberg::String formatDuration(SampleRate iSampleRate, int32 iNumSamples) 35 | { 36 | using namespace std::chrono; 37 | 38 | SampleRateBasedClock clock(iSampleRate); 39 | milliseconds ms(clock.getTimeForSampleCount(static_cast(iNumSamples))); 40 | 41 | auto secs = duration_cast(ms); 42 | ms -= duration_cast(secs); 43 | auto mins = duration_cast(secs); 44 | secs -= duration_cast(mins); 45 | 46 | if(mins.count() > 0) 47 | { 48 | return Steinberg::String().printf("%lim %lli.%llis", 49 | mins.count(), 50 | secs.count(), 51 | ms.count()); 52 | } 53 | else 54 | { 55 | return Steinberg::String().printf("%lli.%llis", 56 | secs.count(), 57 | ms.count()); 58 | } 59 | } 60 | } 61 | 62 | //------------------------------------------------------------------------ 63 | // SampleInfoView::computeInfo 64 | //------------------------------------------------------------------------ 65 | void SampleInfoView::computeInfo() 66 | { 67 | Steinberg::String s(""); 68 | 69 | auto const ¤tSample = *fState->fCurrentSample; 70 | auto const ¤tFile = *fState->fSampleFile; 71 | 72 | if(currentSample.hasSamples() && !currentFile.empty()) 73 | { 74 | s.printf("%s @ %d | %llu bytes - %s - %d [%s]", 75 | SampleFile::extractFilename(currentFile.getOriginalFilePath()).c_str(), 76 | static_cast(currentSample.getOriginalSampleRate()), 77 | currentFile.getFileSize(), 78 | currentSample.getNumChannels() == 2 ? "stereo" : "mono", 79 | currentSample.getNumSamples(), 80 | internal::formatDuration(currentSample.getSampleRate(), currentSample.getNumSamples()).text8()); 81 | } 82 | 83 | setText(UTF8String(s)); 84 | } 85 | 86 | // the creator 87 | SampleInfoView::Creator __gSampleSplitterSampleInfoCreator("SampleSplitter::SampleInfoView", "SampleSplitter - SampleInfoView"); 88 | 89 | } 90 | } 91 | } 92 | } -------------------------------------------------------------------------------- /src/cpp/GUI/WaveformView.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include "../Plugin.h" 5 | #include 6 | 7 | namespace pongasoft::VST::SampleSplitter::GUI { 8 | 9 | using namespace VSTGUI; 10 | using namespace pongasoft::VST::GUI; 11 | 12 | /** 13 | * Base class to handle waveform display 14 | */ 15 | class WaveformView : public Views::StateAwareCustomView, public VSTGUI::IDropTarget 16 | { 17 | public: 18 | // Constructor 19 | explicit WaveformView(const CRect &iSize) : Views::StateAwareCustomView(iSize) 20 | {}; 21 | 22 | // get/setWaveformColor 23 | CColor const &getWaveformColor() const { return fWaveformColor; } 24 | void setWaveformColor(CColor const &iColor) { fWaveformColor = iColor; fBitmap = nullptr; } 25 | 26 | // get/setWaveformAxisColor 27 | CColor const &getWaveformAxisColor() const { return fWaveformAxisColor; } 28 | void setWaveformAxisColor(CColor const &iColor) { fWaveformAxisColor = iColor; fBitmap = nullptr; } 29 | 30 | // get/setVerticalSpacing 31 | CCoord getVerticalSpacing() const { return fVerticalSpacing; } 32 | void setVerticalSpacing(CCoord iVerticalSpacing) { fVerticalSpacing = iVerticalSpacing; fBitmap = nullptr; } 33 | 34 | // margin : whitespace around the waveform 35 | Margin const &getMargin() const { return fMargin; } 36 | void setMargin(Margin const &iMargin) { fMargin = iMargin; fBitmap = nullptr; } 37 | 38 | // draw 39 | void draw(CDrawContext *iContext) override; 40 | 41 | // registerParameters 42 | void registerParameters() override; 43 | 44 | // setViewSize -> handle resizing to recompute the bitmap 45 | void setViewSize(const CRect &rect, bool invalid) override; 46 | 47 | // handle drag/drop 48 | DragOperation onDragEnter(DragEventData data) override; 49 | DragOperation onDragMove(DragEventData data) override; 50 | void onDragLeave(DragEventData data) override; 51 | bool onDrop(DragEventData data) override; 52 | 53 | SharedPointer getDropTarget() override; 54 | 55 | public: 56 | CLASS_METHODS_NOCOPY(WaveformView, ToggleButtonView) 57 | 58 | protected: 59 | // onParameterChange 60 | void onParameterChange(ParamID iParamID) override; 61 | 62 | // generateBitmap 63 | virtual void generateBitmap(CurrentSample const &iCurrentSample) {}; 64 | 65 | protected: 66 | CColor fWaveformColor{kWhiteCColor}; 67 | CColor fWaveformAxisColor{kBlackCColor}; 68 | CCoord fVerticalSpacing{}; 69 | Margin fMargin{}; 70 | 71 | BitmapSPtr fBitmap{}; 72 | 73 | GUIJmbParam fCurrentSample{}; 74 | GUIJmbParam fSampleRate{}; 75 | DragOperation fDragOperation{DragOperation::None}; 76 | 77 | public: 78 | class Creator : public Views::CustomViewCreator> 79 | { 80 | public: 81 | explicit Creator(char const *iViewName = nullptr, char const *iDisplayName = nullptr) noexcept : 82 | CustomViewCreator(iViewName, iDisplayName) 83 | { 84 | registerColorAttribute("waveform-color", &WaveformView::getWaveformColor, &WaveformView::setWaveformColor); 85 | registerColorAttribute("waveform-axis-color", &WaveformView::getWaveformAxisColor, &WaveformView::setWaveformAxisColor); 86 | registerMarginAttribute("margin", &WaveformView::getMargin, &WaveformView::setMargin); 87 | registerDoubleAttribute("vertical-spacing", &WaveformView::getVerticalSpacing, &WaveformView::setVerticalSpacing); 88 | } 89 | }; 90 | }; 91 | 92 | } 93 | 94 | -------------------------------------------------------------------------------- /src/cpp/FilePath.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | #if SMTG_OS_WINDOWS 6 | #define NOMINMAX 7 | #include 8 | #include 9 | #define ENABLE_SNDFILE_WINDOWS_PROTOTYPES 1 10 | #endif 11 | 12 | #include 13 | #include 14 | #include 15 | #include 16 | 17 | namespace pongasoft { 18 | namespace VST { 19 | namespace SampleSplitter { 20 | 21 | /** 22 | * Implementation note: On Windows, file paths are wchar_t type and on macOS they are char (utf8 encoded). 23 | */ 24 | #if SMTG_OS_WINDOWS 25 | using path_char_type = wchar_t; 26 | #else 27 | using path_char_type = char; 28 | #endif 29 | 30 | /** 31 | * Defines the aliases to use when the underlying char array (either represented as a std::string or char const *) 32 | * represents a properly utf-8 encoded string 33 | */ 34 | using UTF8CPPString = std::string; 35 | using UTF8CString = char const *; 36 | 37 | /** 38 | * Generic class to encapsulate a UTF-8 encoded path with method to convert to native path. The SDK uses UTF-8 39 | * encoded strings throughout. For example, the `CNewFileSelector` class returns 40 | * `UTF8StringPtr` filenames. This class is used in APIs to enforce the fact that the path is UTF-8 encoded 41 | * and in order to use it for actually opening a file, you should use the native path like this 42 | * 43 | * std::ifstream input(path.toNativePath(), std::fstream::binary) 44 | * std::ofstream output(path.toNativePath(), std::fstream::binary) 45 | * 46 | * @tparam CharT 47 | */ 48 | template 49 | class basic_UTF8Path 50 | { 51 | public: 52 | // actual type for the platform specific native path encoding (char or wchar_t) 53 | using NativePath = std::basic_string; 54 | 55 | public: 56 | basic_UTF8Path() : fPath() {} 57 | 58 | basic_UTF8Path(VSTGUI::UTF8String iPath) : fPath(std::move(iPath)) {} 59 | basic_UTF8Path(UTF8CPPString iPath) : fPath(std::move(iPath)) {} 60 | basic_UTF8Path(UTF8CString iPath) : fPath(iPath) {} 61 | 62 | inline VSTGUI::UTF8String const &utf8_str() const { return fPath; } 63 | inline UTF8CPPString const &cpp_str() const { return fPath.getString(); } 64 | inline UTF8CString c_str() const { return fPath.data(); } 65 | 66 | NativePath toNativePath() const; 67 | static basic_UTF8Path fromNativePath(NativePath const &iPath); 68 | 69 | private: 70 | VSTGUI::UTF8String fPath; 71 | }; 72 | 73 | /** 74 | * Instantiation of the template with the proper type for the platform 75 | */ 76 | using UTF8Path = basic_UTF8Path; 77 | 78 | /** 79 | * @return the temporary path where temporary files can be created (os specific) */ 80 | UTF8Path getTemporaryPath(); 81 | 82 | /** 83 | * Creates a temporary file path from a temporary filename 84 | * @return the full path to the file 85 | */ 86 | UTF8Path createTempFilePath(UTF8Path const &iFilename); 87 | 88 | // basic_UTF8Path::toNativePath => char implementation 89 | template<> 90 | std::basic_string basic_UTF8Path::toNativePath() const; 91 | 92 | // basic_UTF8Path::fromNativePath => char implementation 93 | template<> 94 | basic_UTF8Path basic_UTF8Path::fromNativePath(const std::basic_string &iPath); 95 | 96 | // basic_UTF8Path::toNativePath => wchar_t implementation 97 | template<> 98 | std::basic_string basic_UTF8Path::toNativePath() const; 99 | 100 | // basic_UTF8Path::fromNativePath => wchar_t implementation 101 | template<> 102 | basic_UTF8Path basic_UTF8Path::fromNativePath(const std::basic_string &iPath); 103 | 104 | } 105 | } 106 | } -------------------------------------------------------------------------------- /src/cpp/GUI/SampleEditView.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "WaveformView.h" 4 | #include "SampleMgr.h" 5 | 6 | namespace pongasoft { 7 | namespace VST { 8 | namespace SampleSplitter { 9 | namespace GUI { 10 | 11 | using namespace VSTGUI; 12 | using namespace pongasoft::VST::GUI; 13 | 14 | /** 15 | * This class renders the sample currently loaded as a waveform. 16 | */ 17 | class SampleEditView : public WaveformView 18 | { 19 | public: 20 | // Constructor 21 | explicit SampleEditView(const CRect &iSize) : WaveformView(iSize) 22 | {}; 23 | 24 | // get/setSliceLineColor 25 | CColor const &getSliceLineColor() const { return fSliceLineColor; } 26 | void setSliceLineColor(const CColor &iColor) { fSliceLineColor = iColor; } 27 | 28 | // get/setBPMLineColor 29 | const CColor &getBPMLineColor() const { return fBPMLineColor; } 30 | void setBPMLineColor(const CColor &iColor) { fBPMLineColor = iColor; } 31 | 32 | // get/setSelectionColor 33 | CColor const &getSelectionColor() const { return fSelectionColor; } 34 | void setSelectionColor(CColor const &iColor) { fSelectionColor = iColor; } 35 | 36 | // draw 37 | void draw(CDrawContext *iContext) override; 38 | 39 | // registerParameters 40 | void registerParameters() override; 41 | 42 | // mouse handling 43 | CMouseEventResult onMouseDown(CPoint &where, const CButtonState &buttons) override; 44 | CMouseEventResult onMouseUp(CPoint &where, const CButtonState &buttons) override; 45 | CMouseEventResult onMouseMoved(CPoint &where, const CButtonState &buttons) override; 46 | CMouseEventResult onMouseCancel() override; 47 | 48 | protected: 49 | using PixelRange = Range; 50 | struct Slices; 51 | 52 | // generateBitmap 53 | void generateBitmap(CurrentSample const &iCurrentSample) override; 54 | 55 | void onParameterChange(ParamID iParamID) override; 56 | void adjustParameters(); 57 | void adjustParametersAfterCut(SampleAction const &iCutAction); 58 | 59 | // zoomToSelection 60 | void zoomToSelection(); 61 | 62 | Slices *computeSlices(PixelRange const &iHorizontalRange); 63 | 64 | void updateSelectedSampleRange(SampleRange const &iRange); 65 | 66 | void initState(GUIState *iGUIState) override; 67 | 68 | private: 69 | CColor fSliceLineColor{kTransparentCColor}; 70 | CColor fBPMLineColor{kTransparentCColor}; 71 | CColor fSelectionColor{255, 255, 255, 100}; 72 | 73 | GUIRawVstParam fOffsetPercent{}; 74 | GUIRawVstParam fZoomPercent{}; 75 | GUIVstParam fShowZeroCrossing{}; 76 | GUIVstParam fNumSlices{}; 77 | GUIJmbParam fHostInfo{}; 78 | GUIJmbParam fPlayingState{}; 79 | GUIVstParam fZoomToSelection{}; 80 | 81 | struct RangeEditor; 82 | 83 | // this is denormalized (from fWESelectedSampleRange) because recomputing is expensive 84 | PixelRange fSelectedPixelRange{-1}; 85 | std::unique_ptr fSelectionEditor{}; 86 | 87 | // the range of visible samples 88 | SampleRange fVisibleSampleRange{}; 89 | 90 | std::unique_ptr fSlices{}; 91 | 92 | public: 93 | class Creator : public Views::CustomViewCreator 94 | { 95 | public: 96 | explicit Creator(char const *iViewName = nullptr, char const *iDisplayName = nullptr) noexcept : 97 | CustomViewCreator(iViewName, iDisplayName) 98 | { 99 | registerColorAttribute("slice-line-color", &SampleEditView::getSliceLineColor, &SampleEditView::setSliceLineColor); 100 | registerColorAttribute("bpm-line-color", &SampleEditView::getBPMLineColor, &SampleEditView::setBPMLineColor); 101 | registerColorAttribute("selection-color", &SampleEditView::getSelectionColor, &SampleEditView::setSelectionColor); 102 | } 103 | }; 104 | }; 105 | 106 | } 107 | } 108 | } 109 | } 110 | 111 | -------------------------------------------------------------------------------- /src/cpp/GUI/SampleSaverView.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include "../Plugin.h" 5 | 6 | #include "SampleMgr.h" 7 | 8 | namespace pongasoft::VST::SampleSplitter::GUI { 9 | 10 | using namespace VSTGUI; 11 | using namespace pongasoft::VST::GUI; 12 | 13 | /** 14 | * Handles saving/exporting the file 15 | */ 16 | class SampleSaverView : public Views::StateAwareView 17 | { 18 | public: 19 | using super_type = Views::StateAwareView; 20 | 21 | public: 22 | //------------------------------------------------------------------------ 23 | // Constructor 24 | //------------------------------------------------------------------------ 25 | explicit SampleSaverView(const CRect &iSize) : super_type(iSize) {}; 26 | 27 | //------------------------------------------------------------------------ 28 | // registerParameters 29 | //------------------------------------------------------------------------ 30 | void registerParameters() override 31 | { 32 | TextButtonView::registerParameters(); 33 | 34 | registerCallback(fState->fCurrentSample, [this] (GUIJmbParam &iParam) { 35 | setMouseEnabled(iParam->hasSamples()); 36 | }, true); 37 | 38 | // this view is not interested to be notified on these param changes, but it uses them (hence false) 39 | fExportSampleMajorFormat = registerParam(fParams->fExportSampleMajorFormat, false); 40 | fExportSampleMinorFormat = registerParam(fParams->fExportSampleMinorFormat, false); 41 | } 42 | 43 | //------------------------------------------------------------------------ 44 | // onClick 45 | //------------------------------------------------------------------------ 46 | void onClick() override 47 | { 48 | auto selector = VSTGUI::owned(CNewFileSelector::create(getFrame(), CNewFileSelector::kSelectSaveFile)); 49 | if(selector) 50 | { 51 | auto const extension = fExportSampleMajorFormat == SampleFile::ESampleMajorFormat::kSampleFormatWAV ? 52 | CFileExtension("WAVE", "wav", "audio/x-wav") : 53 | CFileExtension("AIFF", "aif", "audio/x-aiff"); 54 | selector->setDefaultExtension(extension); 55 | selector->setTitle("Save Sample To"); 56 | selector->setDefaultSaveName(UTF8String(Steinberg::String().printf("sample.%s", extension.getExtension().data()))); 57 | if(selector->runModal()) 58 | { 59 | if(selector->getNumSelectedFiles() > 0) 60 | { 61 | auto filename = std::string(selector->getSelectedFile(0)); 62 | auto expectedExtension = std::string(".") + extension.getExtension().getString(); 63 | if(filename.size() < expectedExtension.size() || 64 | filename.substr(filename.size() - expectedExtension.size()) != expectedExtension) 65 | { 66 | filename += expectedExtension; 67 | } 68 | if(!fState->fSampleMgr->save(filename, *fExportSampleMajorFormat, *fExportSampleMinorFormat)) 69 | DLOG_F(WARNING, "Could not save %s", filename.data()); 70 | else 71 | DLOG_F(INFO, "Successfully saved %s", filename.data()); 72 | } 73 | } 74 | } 75 | TextButtonView::onClick(); 76 | } 77 | 78 | protected: 79 | GUIVstParam fExportSampleMajorFormat{}; 80 | GUIVstParam fExportSampleMinorFormat{}; 81 | 82 | public: 83 | // Creator 84 | using Creator = Views::CustomViewCreator; 85 | }; 86 | 87 | // the creator 88 | SampleSaverView::Creator __gSampleSplitterSampleSaverCreator("SampleSplitter::SampleSaver", "SampleSplitter - SampleSaver"); 89 | 90 | } 91 | 92 | -------------------------------------------------------------------------------- /src/cpp/GUI/UndoHistory.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2020 pongasoft 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not 5 | * use this file except in compliance with the License. You may obtain a copy of 6 | * the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | * License for the specific language governing permissions and limitations under 14 | * the License. 15 | * 16 | * @author Yan Pujante 17 | */ 18 | 19 | #ifndef VST_SAM_SPL_64_UNDOHISTORY_H 20 | #define VST_SAM_SPL_64_UNDOHISTORY_H 21 | 22 | #include 23 | 24 | namespace pongasoft::VST::SampleSplitter::GUI { 25 | 26 | /** 27 | * Encapsulates an action on `CurrentSample` as an object (in order to be able to handle undo/redo) */ 28 | struct SampleAction 29 | { 30 | enum class Type { kCut, kCrop, kTrim, kNormalize0, kNormalize3, kNormalize6, kResample, kLoad, kSample }; 31 | 32 | explicit SampleAction(Type iType) : fType{iType} {} 33 | 34 | Type fType; 35 | NumSlice fNumSlices{}; // used in undo 36 | SampleRange fSelectedSampleRange{-1}; // used with kCut/kCrop and undo 37 | Percent fOffsetPercent{}; // used in undo 38 | Percent fZoomPercent{}; // used in undo 39 | UTF8Path fFilePath{}; // used with kLoad 40 | SharedSampleBuffersVersion fRTVersion; // used with kSample 41 | }; 42 | 43 | class UndoHistory 44 | { 45 | public: 46 | /** 47 | * These objects are saved in the undo history in order to be replayed: `fAction` applied on `fFile` provides 48 | * the new CurrentSample 49 | */ 50 | struct Entry 51 | { 52 | Entry(SampleAction iAction, CurrentSample const &iSample, SampleFile iFile) : 53 | fAction{std::move(iAction)}, 54 | fSource{iSample.getSource()}, 55 | fUpdateType{iSample.getUpdateType()}, 56 | fFile(std::move(iFile)) 57 | {} 58 | 59 | SampleAction fAction; 60 | CurrentSample::Source fSource; 61 | CurrentSample::UpdateType fUpdateType; 62 | SampleFile fFile; 63 | }; 64 | 65 | public: 66 | void addEntry(SampleAction iAction, CurrentSample const &iSample, SampleFile iFile) 67 | { 68 | UndoHistory::Entry undoEntry{iAction, iSample, std::move(iFile)}; 69 | fUndoHistory.push_front(undoEntry); 70 | } 71 | 72 | void clearRedoHistory() { fRedoHistory.clear(); } 73 | 74 | Entry undo() 75 | { 76 | DCHECK_F(hasUndoHistory()); 77 | auto lastExecutedAction = fUndoHistory.front(); 78 | fUndoHistory.pop_front(); 79 | fRedoHistory.push_front(lastExecutedAction.fAction); 80 | return lastExecutedAction; 81 | } 82 | 83 | SampleAction redo() 84 | { 85 | DCHECK_F(hasRedoHistory()); 86 | auto lastAction = fRedoHistory.front(); 87 | fRedoHistory.pop_front(); 88 | return lastAction; 89 | } 90 | 91 | // getLastUndoEntry 92 | inline Entry const *getLastUndoEntry() const { 93 | return fUndoHistory.empty() ? nullptr : &fUndoHistory.front(); 94 | } 95 | 96 | /** 97 | * Clears the entire undo/redo history 98 | * 99 | * @return `true` if there was anything to clear */ 100 | bool clearActionHistory() 101 | { 102 | if(hasActionHistory()) 103 | { 104 | fUndoHistory.clear(); 105 | fRedoHistory.clear(); 106 | return true; 107 | } 108 | return false; 109 | } 110 | 111 | 112 | // hasUndoHistory 113 | inline bool hasUndoHistory() const { return !fUndoHistory.empty(); } 114 | // hasRedoHistory 115 | inline bool hasRedoHistory() const { return !fRedoHistory.empty(); } 116 | // hasActionHistory 117 | inline bool hasActionHistory() const { return hasUndoHistory() || hasRedoHistory(); } 118 | 119 | private: 120 | std::forward_list fUndoHistory{}; 121 | std::forward_list fRedoHistory{}; 122 | 123 | }; 124 | 125 | } 126 | 127 | #endif //VST_SAM_SPL_64_UNDOHISTORY_H 128 | -------------------------------------------------------------------------------- /src/cpp/GUI/SamplingButtonView.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include "../Plugin.h" 5 | 6 | namespace pongasoft::VST::SampleSplitter::GUI { 7 | 8 | using namespace VSTGUI; 9 | using namespace pongasoft::VST::GUI; 10 | 11 | /** 12 | * Sampling button - enabled/disabled depending on input and show progress when sampling 13 | */ 14 | class SamplingButtonView : public Views::StateAwareView 15 | { 16 | public: 17 | using super_type = Views::StateAwareView; 18 | 19 | public: 20 | //------------------------------------------------------------------------ 21 | // Constructor 22 | //------------------------------------------------------------------------ 23 | explicit SamplingButtonView(const CRect &iSize) : super_type(iSize) {}; 24 | 25 | // get/set progress bar margin 26 | Margin const &getProgressBarMargin() const { return fProgressBarMargin; } 27 | void setProgressBarMargin(Margin const &iMargin) { fProgressBarMargin = iMargin; } 28 | 29 | // get/set progress bar color 30 | const CColor &getProgressBarColor() const { return fProgressBarColor; } 31 | void setProgressBarColor(const CColor &iColor) { fProgressBarColor = iColor; } 32 | 33 | //------------------------------------------------------------------------ 34 | // draw 35 | //------------------------------------------------------------------------ 36 | void draw(CDrawContext *iContext) override 37 | { 38 | TextButtonView::draw(iContext); 39 | 40 | auto percentSampled = fState->fSamplingState->fPercentSampled; 41 | 42 | if(percentSampled > 0 && percentSampled <= 1.0) 43 | { 44 | auto rdc = pongasoft::VST::GUI::RelativeDrawContext{this, iContext}; 45 | auto width = getWidth() * percentSampled; 46 | rdc.fillRect(0 + fProgressBarMargin.fLeft, 47 | 0 + fProgressBarMargin.fTop, 48 | width - fProgressBarMargin.fRight, 49 | getHeight() - fProgressBarMargin.fBottom, 50 | fProgressBarColor); 51 | } 52 | } 53 | 54 | //------------------------------------------------------------------------ 55 | // registerParameters 56 | //------------------------------------------------------------------------ 57 | void registerParameters() override 58 | { 59 | TextButtonView::registerParameters(); 60 | 61 | auto callback = [this](GUIVstParam &iParam) { 62 | if(iParam.getValue() == ESamplingInput::kSamplingOff) 63 | { 64 | setMouseEnabled(false); 65 | unClick(); 66 | } 67 | else 68 | setMouseEnabled(true); 69 | }; 70 | 71 | registerCallback(fParams->fSamplingInput, 72 | std::move(callback), 73 | true); 74 | 75 | registerParam(fState->fSamplingState); 76 | } 77 | 78 | protected: 79 | Margin fProgressBarMargin{}; 80 | CColor fProgressBarColor{255,255,255,120}; 81 | 82 | public: 83 | class Creator : public Views::CustomViewCreator 84 | { 85 | public: 86 | explicit Creator(char const *iViewName = nullptr, char const *iDisplayName = nullptr) noexcept : 87 | CustomViewCreator(iViewName, iDisplayName) 88 | { 89 | registerMarginAttribute("progress-bar-margin", 90 | &SamplingButtonView::getProgressBarMargin, 91 | &SamplingButtonView::setProgressBarMargin); 92 | registerColorAttribute("progress-bar-color", 93 | &SamplingButtonView::getProgressBarColor, 94 | &SamplingButtonView::setProgressBarColor); 95 | } 96 | 97 | }; 98 | }; 99 | 100 | // the creator 101 | SamplingButtonView::Creator __gSampleSplitterSamplingButtonCreator("SampleSplitter::SamplingButtonView", "SampleSplitter - SamplingButton"); 102 | 103 | } 104 | 105 | -------------------------------------------------------------------------------- /src/cpp/SampleSplitterCIDs.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | 6 | namespace pongasoft::VST::SampleSplitter { 7 | 8 | #ifndef NDEBUG 9 | static const ::Steinberg::FUID SampleSplitterProcessorUID(0x96df4309, 0xbfcb4f89, 0x9c58202f, 0xda6ab1f1); 10 | static const ::Steinberg::FUID SampleSplitterControllerUID(0xa4a65a05, 0xc59e4b5e, 0xbf80fbde, 0x26f174eb); 11 | #else 12 | static const ::Steinberg::FUID SampleSplitterProcessorUID(0x8dc749df, 0x8f164a07, 0x8fe50394, 0xb2632d61); 13 | static const ::Steinberg::FUID SampleSplitterControllerUID(0x3eaace1e, 0x6ef14c74, 0x9cc54f8f, 0x33088aad); 14 | #endif 15 | 16 | //------------------------------------------------------------------------ 17 | // Parameters and Custom view ids 18 | //------------------------------------------------------------------------ 19 | enum ESampleSplitterParamID : Steinberg::Vst::ParamID 20 | { 21 | //------------------------------------------------------------------------ 22 | // Vst Parameters 23 | //------------------------------------------------------------------------ 24 | 25 | // Pads 26 | kPad1 = 2001, 27 | // ... 28 | // kPad16 2016 29 | 30 | __deprecated_kNumSlices = 2100, 31 | kNumSlices = 2101, 32 | kPadBank = 2110, 33 | kSelectedSlice = 2120, 34 | kSelectedSliceViaMidi = 2121, 35 | kFollowMidiSelection = 2125, 36 | kPlayModeHold = 2130, 37 | kPolyphonic = 2140, 38 | kXFade = 2141, 39 | kInputRouting = 2142, 40 | kRootKey = 2145, 41 | kViewType = 2150, 42 | kEditingMode = 2155, 43 | 44 | // sampling related properties 45 | kSamplingInput = 2200, 46 | kSamplingInputGain = 2201, 47 | kSamplingMonitor = 2210, 48 | kSamplingDuration = 2211, 49 | kSampling = 2220, 50 | kSamplingLeftVuPPM = 2230, 51 | kSamplingRightVuPPM = 2231, 52 | kSamplingTrigger = 2240, 53 | 54 | 55 | // editing related properties 56 | kWEOffsetPercent = 2300, 57 | kWEZoomPercent = 2301, 58 | kWEShowZeroCrossing = 2302, 59 | kWEPlaySelection = 2303, 60 | kWEZoomToSelection = 2304, 61 | 62 | // saving related properties 63 | kExportSampleMajorFormat = 2400, 64 | kExportSampleMinorFormat = 2401, 65 | 66 | 67 | //------------------------------------------------------------------------ 68 | // Jmb Parameters 69 | //------------------------------------------------------------------------ 70 | 71 | // the sample rate (communicated from RT to UI) 72 | kSampleRate = 3000, 73 | 74 | // info about the host (communicated from RT to UI) 75 | kHostInfo = 3005, 76 | 77 | // The sample file 78 | kSampleFile = 3100, 79 | kCurrentSample = 3101, 80 | kUndoHistory = 3103, 81 | 82 | // The sample buffers sent by the GUI to RT (message) 83 | kGUINewSampleMessage = 3102, 84 | 85 | // The sample buffers sent from the RT to the GUI after sampling (message) 86 | fRTNewSampleMessage = 3105, 87 | fSamplingState = 3106, 88 | 89 | // keep track of settings for each slice 90 | kSlicesSettings = 3110, 91 | kSlicesQuickEdit = 3120, 92 | 93 | // The playing state 94 | kPlayingState = 3200, 95 | 96 | // editing related properties 97 | kWESelectedSampleRange = 3300, 98 | 99 | // string with the plugin version 100 | kPluginVersion = 3400, 101 | 102 | // a large file path 103 | kLargeFilePath = 3500, 104 | 105 | // error message 106 | kErrorMessage = 3510, 107 | 108 | // the shared buffers mgr 109 | kSharedBuffersMgr = 3600, 110 | 111 | //------------------------------------------------------------------------ 112 | // Custom View Tag (not tied to params) 113 | //------------------------------------------------------------------------ 114 | kNormalize0Action = 5000, 115 | kNormalize3Action = 5001, 116 | kNormalize6Action = 5002, 117 | kTrimAction = 5003, 118 | kCutAction = 5004, 119 | kCropAction = 5005, 120 | kResampleAction = 5006, 121 | kUndoAction = 5010, 122 | kRedoAction = 5011, 123 | kClearHistoryAction = 5012, 124 | kSampleAction = 5020, 125 | kOkAction = 5100, 126 | kCancelAction = 5101 127 | }; 128 | 129 | } 130 | -------------------------------------------------------------------------------- /audio-unit/Info.plist: -------------------------------------------------------------------------------- 1 | //----------------------------------------------------------------------------- 2 | // LICENSE 3 | // (c) 2018, Steinberg Media Technologies GmbH, All Rights Reserved 4 | //----------------------------------------------------------------------------- 5 | // Redistribution and use in source and binary forms, with or without modification, 6 | // are permitted provided that the following conditions are met: 7 | // 8 | // * Redistributions of source code must retain the above copyright notice, 9 | // this list of conditions and the following disclaimer. 10 | // * Redistributions in binary form must reproduce the above copyright notice, 11 | // this list of conditions and the following disclaimer in the documentation 12 | // and/or other materials provided with the distribution. 13 | // * Neither the name of the Steinberg Media Technologies nor the names of its 14 | // contributors may be used to endorse or promote products derived from this 15 | // software without specific prior written permission. 16 | // 17 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 18 | // ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 19 | // WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 20 | // IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 21 | // INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 22 | // BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 23 | // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 24 | // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE 25 | // OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 26 | // OF THE POSSIBILITY OF SUCH DAMAGE. 27 | //----------------------------------------------------------------------------- 28 | 29 | #include "audiounitconfig.h" 30 | 31 | 32 | 33 | 34 | 35 | CFBundleDevelopmentRegion 36 | English 37 | CFBundleExecutable 38 | $(EXECUTABLE_NAME) 39 | CFBundleIdentifier 40 | kAudioUnitBundleIdentifier 41 | CFBundleName 42 | $(PRODUCT_NAME) 43 | CFBundleInfoDictionaryVersion 44 | 6.0 45 | CFBundlePackageType 46 | BNDL 47 | CFBundleSignature 48 | ???? 49 | CFBundleVersion 50 | 1.0 51 | CSResourcesFileMapped 52 | yes 53 | 54 | /* 55 | The "AudioUnit SupportedNumChannels" key is only necessary if you build an effect not an instrument. 56 | You should describe all supported channel configurations. 57 | This example says that it supports Stereo/Stereo or Mono/Mono. 58 | */ 59 | 60 | AudioUnit SupportedNumChannels 61 | 62 | 63 | Outputs 64 | 2 65 | Inputs 66 | 2 67 | 68 | 69 | Outputs 70 | 0 71 | Inputs 72 | 1 73 | 74 | 75 | Outputs 76 | 1 77 | Inputs 78 | 1 79 | 80 | 81 | 82 | AudioUnit Version 83 | kAudioUnitVersion 84 | 85 | /* 86 | Support for the new AUPlugIn model in Mac OS X 10.7 87 | */ 88 | AudioComponents 89 | 90 | 91 | description 92 | kAUPluginDescription 93 | factoryFunction 94 | AUWrapperFactory 95 | manufacturer 96 | kAUPluginManufacturer 97 | name 98 | kAUPluginName 99 | subtype 100 | kAUPluginSubType 101 | type 102 | kAUPluginType 103 | version 104 | kAudioUnitVersion 105 | 106 | 107 | 108 | 109 | 110 | -------------------------------------------------------------------------------- /src/cpp/RT/SampleSplitterProcessor.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include "../Plugin.h" 6 | #include "../Sampler.hpp" 7 | 8 | namespace pongasoft::VST::SampleSplitter::RT { 9 | 10 | using namespace pongasoft::VST::RT; 11 | 12 | //------------------------------------------------------------------------ 13 | // SampleSplitterProcessor - Real Time Processor 14 | //------------------------------------------------------------------------ 15 | class SampleSplitterProcessor : public RTProcessor 16 | { 17 | public: 18 | //------------------------------------------------------------------------ 19 | // UUID() method used to create the processor 20 | //------------------------------------------------------------------------ 21 | static inline ::Steinberg::FUID UUID() { return SampleSplitterProcessorUID; }; 22 | 23 | //------------------------------------------------------------------------ 24 | // Factory method used to create the processor 25 | //------------------------------------------------------------------------ 26 | static FUnknown *createInstance(void * /*context*/) { return (IAudioProcessor *) new SampleSplitterProcessor(); } 27 | 28 | public: 29 | // Constructor 30 | SampleSplitterProcessor(); 31 | 32 | // Destructor 33 | ~SampleSplitterProcessor() override; 34 | 35 | // getRTState 36 | RTState *getRTState() override { return &fState; } 37 | 38 | /** Called at first after constructor (setup input/output) */ 39 | tresult PLUGIN_API initialize(FUnknown *context) override; 40 | 41 | // Called at the end before destructor 42 | tresult PLUGIN_API terminate() override; 43 | 44 | // This is where the setup happens which depends on sample rate, etc.. 45 | tresult PLUGIN_API setupProcessing(ProcessSetup &setup) override; 46 | 47 | protected: 48 | // processInputs 49 | tresult processInputs(ProcessData &data) override; 50 | 51 | // processHostInfo 52 | tresult processHostInfo(ProcessData &data); 53 | 54 | // genericProcessInputs 55 | template 56 | tresult genericProcessInputs(ProcessData &data); 57 | 58 | // processSampling 59 | template 60 | tresult processSampling(ProcessData &data); 61 | 62 | // processInputs32Bits 63 | tresult processInputs32Bits(ProcessData &data) override { return genericProcessInputs(data); } 64 | 65 | // processInputs64Bits 66 | tresult processInputs64Bits(ProcessData &data) override { return genericProcessInputs(data); } 67 | 68 | // processMonoInput 69 | template 70 | void processMonoInput(AudioBuffers &out) const; 71 | 72 | /** 73 | * will determine which pad is selected 74 | */ 75 | void handlePadSelection(); 76 | 77 | /** 78 | * will determine which note is selected 79 | */ 80 | void handleNoteSelection(ProcessData &data); 81 | 82 | /** 83 | * @return `-1` if the host is not playing, otherwise the playing offset */ 84 | int32 getHostPlayingOffset(ProcessData &iData) const; 85 | 86 | /** 87 | * Determines the offset at which sampling should start. 88 | * @return `-1` if should not start 89 | */ 90 | template 91 | int32 getStartSamplingOffset(ProcessData &iData, AudioBuffers &iBuffers) const; 92 | 93 | /** 94 | * Initializes the sampler if it is possible (for example, cannot initialize the sampler while sampling...) 95 | * 96 | * @return `true` if the sampler was initialized, `false` otherwise 97 | */ 98 | bool maybeInitSampler(ProcessData &iData); 99 | 100 | private: 101 | // The processor gets its own copy of the parameters (defined in Plugin.h) 102 | SampleSplitterParameters fParams; 103 | 104 | // The state 105 | SampleSplitterRTState fState; 106 | 107 | // The clock (based on frame rate) 108 | SampleRateBasedClock fClock; 109 | 110 | // Limit how often the data is sent to the UI 111 | SampleRateBasedClock::RateLimiter fRateLimiter; 112 | SampleRateBasedClock::RateLimiter fSamplingRateLimiter; 113 | 114 | // The sampler 115 | Sampler32 fSampler; 116 | bool fWaitingForSampling; 117 | 118 | // Counter to keep track of frames (used in pad selection) 119 | uint32 fFrameCount{}; 120 | }; 121 | 122 | } 123 | 124 | -------------------------------------------------------------------------------- /src/cpp/Sampler.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "Sampler.h" 4 | 5 | namespace pongasoft { 6 | namespace VST { 7 | namespace SampleSplitter { 8 | 9 | //------------------------------------------------------------------------ 10 | // Sampler::start 11 | //------------------------------------------------------------------------ 12 | template 13 | void Sampler::start(bool iResetCurrent) 14 | { 15 | DLOG_F(INFO, "Sampler::start()"); 16 | DCHECK_F(fBuffers != nullptr); 17 | fState = ESamplerState::kSampling; 18 | if(iResetCurrent) 19 | fCurrent = 0; 20 | } 21 | 22 | //------------------------------------------------------------------------ 23 | // Sampler::init 24 | //------------------------------------------------------------------------ 25 | template 26 | void Sampler::init(SampleRate iSampleRate, int32 iMaxSamples) 27 | { 28 | DLOG_F(INFO, "Sampler::init(%f, %d)", iSampleRate, iMaxSamples); 29 | fBuffers = std::make_unique(iSampleRate, fNumChannels, iMaxSamples); 30 | fCurrent = 0; 31 | fState = ESamplerState::kNotSampling; 32 | } 33 | 34 | //------------------------------------------------------------------------ 35 | // Sampler::getPercentSampled 36 | //------------------------------------------------------------------------ 37 | template 38 | float Sampler::getPercentSampled() const 39 | { 40 | DCHECK_F(fBuffers != nullptr); 41 | if(fState == ESamplerState::kSampling) 42 | { 43 | return fCurrent / static_cast(fBuffers->getNumSamples()); 44 | } 45 | return 0; 46 | } 47 | 48 | 49 | //------------------------------------------------------------------------ 50 | // Sampler::sample 51 | //------------------------------------------------------------------------ 52 | template 53 | template 54 | ESamplerState Sampler::sample(AudioBuffers &iIn, int32 iStartOffset, int32 iEndOffset) 55 | { 56 | if(fState != ESamplerState::kSampling) 57 | return fState; 58 | 59 | DCHECK_F(fBuffers != nullptr); 60 | 61 | auto localBuffersNumSamples = fBuffers->getNumSamples(); 62 | auto inNumSamples = iIn.getNumSamples(); 63 | 64 | if(iStartOffset == -1) 65 | iStartOffset = 0; 66 | 67 | if(iEndOffset == -1) 68 | iEndOffset = inNumSamples; 69 | 70 | // making sure offset remain within the bounds 71 | iStartOffset = clamp(iStartOffset, ZERO_INT32, inNumSamples - 1); 72 | iEndOffset = clamp(iEndOffset, ZERO_INT32, inNumSamples); 73 | 74 | auto numChannels = std::min(fBuffers->getNumChannels(), iIn.getNumChannels()); 75 | 76 | int32 newCurrent = fCurrent; 77 | 78 | for(int32 c = 0; c < numChannels; c++) 79 | { 80 | int32 current = fCurrent; 81 | 82 | auto channel = iIn.getAudioChannel(c); 83 | if(!channel.isActive()) 84 | continue; 85 | 86 | auto audioBuffer = channel.getBuffer(); // we know it is not null here 87 | auto sampleBuffer = fBuffers->getChannelBuffer(c); 88 | 89 | for(int32 i = iStartOffset; i < iEndOffset; i++) 90 | { 91 | if(current == localBuffersNumSamples) 92 | break; 93 | 94 | sampleBuffer[current++] = static_cast(audioBuffer[i]); 95 | } 96 | 97 | newCurrent = current; 98 | } 99 | 100 | fCurrent = newCurrent; 101 | 102 | if(localBuffersNumSamples == fCurrent) 103 | fState = ESamplerState::kDoneSampling; 104 | 105 | return fState; 106 | } 107 | 108 | //------------------------------------------------------------------------ 109 | // Sampler::dispose 110 | //------------------------------------------------------------------------ 111 | template 112 | void Sampler::dispose() 113 | { 114 | DLOG_F(INFO, "Sampler::dispose()"); 115 | fBuffers = nullptr; 116 | fCurrent = 0; 117 | fState = ESamplerState::kNotSampling; 118 | } 119 | 120 | //------------------------------------------------------------------------ 121 | // Sampler::acquireBuffers 122 | //------------------------------------------------------------------------ 123 | template 124 | std::unique_ptr::SampleBuffersT> Sampler::acquireBuffers() 125 | { 126 | DLOG_F(INFO, "Sampler::acquireBuffers()"); 127 | 128 | if(!fBuffers) 129 | return nullptr; 130 | 131 | return fBuffers->first(fCurrent); 132 | } 133 | 134 | } 135 | } 136 | } -------------------------------------------------------------------------------- /src/cpp/GUI/SampleSplitterController.cpp: -------------------------------------------------------------------------------- 1 | #include "SampleSplitterController.h" 2 | #include "PadController.h" 3 | #include "SampleEditController.h" 4 | #include "LargeFileDialogController.h" 5 | 6 | namespace pongasoft::VST::SampleSplitter::GUI { 7 | 8 | //------------------------------------------------------------------------ 9 | // Constructor 10 | //------------------------------------------------------------------------ 11 | SampleSplitterController::SampleSplitterController() : 12 | GUIController("SampleSplitter.uidesc", "main_view"), 13 | fParams{}, 14 | fState{fParams} 15 | { 16 | DLOG_F(INFO, "SampleSplitterController()"); 17 | } 18 | 19 | //------------------------------------------------------------------------ 20 | // Destructor 21 | //------------------------------------------------------------------------ 22 | SampleSplitterController::~SampleSplitterController() 23 | { 24 | DLOG_F(INFO, "~SampleSplitterController()"); 25 | } 26 | 27 | //------------------------------------------------------------------------ 28 | // SampleSplitterController::initialize 29 | //------------------------------------------------------------------------ 30 | tresult SampleSplitterController::initialize(FUnknown *context) 31 | { 32 | tresult res = GUIController::initialize(context); 33 | 34 | DLOG_F(INFO, "SampleSplitterController::initialize"); 35 | 36 | //------------------------------------------------------------------------ 37 | // In debug mode this code displays the order in which the GUI parameters 38 | // will be saved 39 | //------------------------------------------------------------------------ 40 | #ifndef NDEBUG 41 | if(res == kResultOk) 42 | { 43 | using Key = Debug::ParamDisplay::Key; 44 | DLOG_F(INFO, "GUI Save State - Version=%d --->\n%s", 45 | fParams.getGUISaveStateOrder().fVersion, 46 | Debug::ParamTable::from(getGUIState(), true).keys({Key::kID, Key::kTitle}).full().toString().c_str()); 47 | } 48 | #endif 49 | 50 | return res; 51 | } 52 | 53 | //------------------------------------------------------------------------ 54 | // SampleSplitterController::registerParameters 55 | //------------------------------------------------------------------------ 56 | void SampleSplitterController::registerParameters() 57 | { 58 | // we initialize the parameters for the manager 59 | fState.fSampleMgr->registerParameters(); 60 | 61 | // we need access to these parameters in the callback 62 | fSampling = registerParam(fParams.fSampling, false); 63 | fSamplingInput = registerParam(fParams.fSamplingInput, false); 64 | fOffsetPercent = registerParam(fParams.fWEOffsetPercent, false); 65 | fZoomPercent = registerParam(fParams.fWEZoomPercent, false); 66 | 67 | auto handleSamplingInput = [this]() { 68 | if(fViewType == EViewType::kEditSampleViewType && fEditingMode == EEditingMode::kEditingSampling) 69 | { 70 | if(fSamplingInput == ESamplingInput::kSamplingOff) 71 | { 72 | fSamplingInput = fPreviousSamplingInput; 73 | } 74 | } 75 | else 76 | { 77 | if(fSamplingInput != ESamplingInput::kSamplingOff) 78 | { 79 | // make sure we stop sampling 80 | fPreviousSamplingInput = *fSamplingInput; 81 | fSamplingInput = ESamplingInput::kSamplingOff; 82 | fSampling = false; 83 | } 84 | } 85 | }; 86 | 87 | // Handle view change 88 | fViewType = registerCallback(fParams.fViewType, handleSamplingInput); 89 | 90 | // Handle editing mode change 91 | fEditingMode = registerCallback(fParams.fEditingMode, handleSamplingInput); 92 | } 93 | 94 | //------------------------------------------------------------------------ 95 | // SampleSplitterController::createCustomController 96 | //------------------------------------------------------------------------ 97 | IController *SampleSplitterController::createCustomController(UTF8StringPtr iName, 98 | IUIDescription const * /* iDescription */, 99 | IController *iBaseController) 100 | { 101 | auto name = UTF8StringView(iName); 102 | 103 | if(name == "PadController") 104 | { 105 | return new PadController(iBaseController); 106 | } 107 | 108 | if(name == "SampleEditController") 109 | { 110 | return new SampleEditController(iBaseController); 111 | } 112 | 113 | if(name == "LargeFileDialogController") 114 | { 115 | return new LargeFileDialogController(iBaseController); 116 | } 117 | 118 | return nullptr; 119 | } 120 | 121 | } 122 | -------------------------------------------------------------------------------- /src/cpp/GUI/SampleMgr.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2020 pongasoft 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not 5 | * use this file except in compliance with the License. You may obtain a copy of 6 | * the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | * License for the specific language governing permissions and limitations under 14 | * the License. 15 | * 16 | * @author Yan Pujante 17 | */ 18 | 19 | #ifndef VST_SAM_SPL_64_SAMPLEMGR_H 20 | #define VST_SAM_SPL_64_SAMPLEMGR_H 21 | 22 | 23 | #include 24 | #include 25 | 26 | #include "../SharedSampleBuffersMgr.h" 27 | #include "../Plugin.h" 28 | 29 | #include "UndoHistory.h" 30 | #include "SampleFile.h" 31 | 32 | namespace pongasoft::VST::SampleSplitter::GUI { 33 | 34 | using namespace pongasoft::VST::GUI::Views; 35 | using namespace pongasoft::VST::GUI::Params; 36 | 37 | /** 38 | * Sample manager */ 39 | class SampleMgr : public ParamAware, public StateAware 40 | { 41 | public: 42 | // initState - set after gui state is created 43 | void initState(VST::GUI::GUIState *iGUIState) override; 44 | 45 | // registerParameters 46 | void registerParameters() override; 47 | 48 | /** 49 | * Direct selection from the user (from file selection of drag & drop) 50 | */ 51 | tresult loadSampleFromUser(UTF8Path const &iFilePath); 52 | 53 | /** 54 | * After the plugin is restored */ 55 | tresult loadSampleFromState(); 56 | 57 | /** 58 | * Save this sample to another file 59 | * 60 | * @param iFilePath 61 | * @return `true` if successful, `false` otherwise 62 | */ 63 | bool save(UTF8Path const &iFilePath, 64 | SampleFile::ESampleMajorFormat iMajorFormat, 65 | SampleFile::ESampleMinorFormat iMinorFormat) const; 66 | 67 | /** 68 | * Executes the provided action on the current sample. Add current sample to undo history: 69 | * 70 | * - iAction + fCurrent stored as last UndoEntry 71 | * - iAction applied on fCurrent -> new fCurrent 72 | * 73 | * @return `true` if successful, `false` otherwise 74 | */ 75 | bool executeAction(SampleAction const &iAction); 76 | 77 | /** 78 | * Reverts the last action and add it to the redo history 79 | * 80 | * @return `true` if successful, `false` otherwise (or if nothing to undo) 81 | */ 82 | bool undoLastAction(); 83 | 84 | /** 85 | * Redo the last undone action. 86 | * 87 | * @return `true` if successful, `false` otherwise (or if nothing to redo) 88 | */ 89 | bool redoLastUndo(); 90 | 91 | protected: 92 | /** 93 | * Executes the provided action on the current sample. Add current sample to undo history: 94 | * 95 | * - iAction + fCurrent stored as last UndoEntry 96 | * - iAction applied on fCurrent -> new fCurrent 97 | * 98 | * @return `true` if successful, `false` otherwise 99 | */ 100 | bool doExecuteAction(SampleAction const &iAction, bool iClearUndoHistory); 101 | 102 | protected: 103 | // getSharedMgr 104 | SharedSampleBuffersMgr32 *getSharedMgr() const; 105 | 106 | // loadSampleFromSampling 107 | tresult loadSampleFromSampling(SharedSampleBuffersVersion iVersion); 108 | 109 | // Called when RT sends the mgr pointer to UI (need to copy UI buffer) 110 | tresult onMgrReceived(SharedSampleBuffersMgr32 *iMgr); 111 | 112 | // Called when sample rate changes 113 | tresult onSampleRateChanged(SampleRate iSampleRate); 114 | 115 | // executeBufferAction 116 | CurrentSample executeBufferAction(SampleAction const &iAction); 117 | 118 | // resetSettings 119 | void resetSettings(); 120 | 121 | private: 122 | GUIRawVstParam fOffsetPercent{}; 123 | GUIRawVstParam fZoomPercent{}; 124 | GUIVstParam fNumSlices{}; 125 | GUIJmbParam fGUINewSampleMessage; 126 | 127 | // this is for the case when we have not received the mgr from the RT which could be due to 128 | // 1. using only the editor (so RT will never send it) 129 | // 2. order in which events happen (since messaging is asynchronous, I am not sure there is a guarantee to when 130 | // the message is actually delivered! 131 | mutable std::unique_ptr fGUIOnlyMgr{}; 132 | }; 133 | 134 | } 135 | 136 | #endif //VST_SAM_SPL_64_SAMPLEMGR_H -------------------------------------------------------------------------------- /src/cpp/GUI/SampleOverviewView.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | #include "WaveformView.h" 6 | #include "Waveform.h" 7 | 8 | namespace pongasoft::VST::SampleSplitter::GUI { 9 | 10 | using namespace VSTGUI; 11 | using namespace pongasoft::VST::GUI; 12 | 13 | /** 14 | * This class renders the sample currently loaded as a waveform. 15 | */ 16 | class SampleOverviewView : public WaveformView 17 | { 18 | public: 19 | // Constructor 20 | explicit SampleOverviewView(const CRect &iSize) : WaveformView(iSize) 21 | {}; 22 | 23 | //------------------------------------------------------------------------ 24 | // slice line color 25 | //------------------------------------------------------------------------ 26 | CColor const &getSliceLineColor() const { return fSliceLineColor; } 27 | void setSliceLineColor(const CColor &iColor) { fSliceLineColor = iColor; } 28 | 29 | //------------------------------------------------------------------------ 30 | // BPM line color 31 | //------------------------------------------------------------------------ 32 | const CColor &getBPMLineColor() const { return fBPMLineColor; } 33 | void setBPMLineColor(const CColor &iColor) { fBPMLineColor = iColor; } 34 | 35 | //------------------------------------------------------------------------ 36 | // registerParameters 37 | //------------------------------------------------------------------------ 38 | void registerParameters() override 39 | { 40 | WaveformView::registerParameters(); 41 | 42 | fNumSlices = registerParam(fParams->fNumSlices); 43 | // fHostInfo = registerParam(fState->fHostInfo); 44 | } 45 | 46 | //------------------------------------------------------------------------ 47 | // draw 48 | //------------------------------------------------------------------------ 49 | void draw(CDrawContext *iContext) override 50 | { 51 | WaveformView::draw(iContext); 52 | if(fBitmap) 53 | { 54 | fBitmap->draw(iContext, getViewSize()); 55 | 56 | auto rdc = pongasoft::VST::GUI::RelativeDrawContext{this, iContext}; 57 | 58 | SampleRange visibleRange(0, fNumSamples); 59 | 60 | auto color = getSliceLineColor(); 61 | if(!CColorUtils::isTransparent(color)) 62 | { 63 | auto sliceSizeInPixels = getWidth() / fNumSlices->realValue(); 64 | 65 | auto sliceIndex = sliceSizeInPixels; 66 | 67 | for(auto i = 1; i < fNumSlices->intValue(); i++) 68 | { 69 | rdc.drawLine(sliceIndex, 0, sliceIndex, getHeight(), color); 70 | sliceIndex += sliceSizeInPixels; 71 | } 72 | } 73 | } 74 | } 75 | 76 | protected: 77 | //------------------------------------------------------------------------ 78 | // generateBitmap 79 | //------------------------------------------------------------------------ 80 | void generateBitmap(CurrentSample const &iCurrentSample) override 81 | { 82 | auto buffers = iCurrentSample.getSharedBuffers(); 83 | if(buffers && buffers->hasSamples()) 84 | { 85 | auto context = COffscreenContext::create({getWidth(), getHeight()}, getFrame()->getScaleFactor()); 86 | 87 | fBitmap = Waveform::createBitmap(context, 88 | buffers.get(), 89 | {getWaveformColor(), getWaveformAxisColor(), 2, getMargin()}); 90 | fNumSamples = buffers->getNumSamples(); 91 | } 92 | else 93 | { 94 | fBitmap = nullptr; 95 | fNumSamples = -1; 96 | } 97 | } 98 | 99 | protected: 100 | CColor fSliceLineColor{kTransparentCColor}; 101 | CColor fBPMLineColor{kTransparentCColor}; 102 | 103 | GUIVstParam fNumSlices{}; 104 | // GUIJmbParam fHostInfo{}; 105 | 106 | int32 fNumSamples{-1}; 107 | 108 | public: 109 | class Creator : public Views::CustomViewCreator 110 | { 111 | public: 112 | explicit Creator(char const *iViewName = nullptr, char const *iDisplayName = nullptr) noexcept : 113 | CustomViewCreator(iViewName, iDisplayName) 114 | { 115 | registerColorAttribute("slice-line-color", &SampleOverviewView::getSliceLineColor, &SampleOverviewView::setSliceLineColor); 116 | registerColorAttribute("bpm-line-color", &SampleOverviewView::getBPMLineColor, &SampleOverviewView::setBPMLineColor); 117 | } 118 | }; 119 | }; 120 | 121 | // the creator 122 | SampleOverviewView::Creator __gSampleSplitterSampleOverviewCreator("SampleSplitter::SampleOverviewView", "SampleSplitter - SampleOverviewView"); 123 | } -------------------------------------------------------------------------------- /configure.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | 3 | # Copyright (c) 2020 pongasoft 4 | # 5 | # Licensed under the Apache License, Version 2.0 (the "License"); you may not 6 | # use this file except in compliance with the License. You may obtain a copy of 7 | # the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, software 12 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 13 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 14 | # License for the specific language governing permissions and limitations under 15 | # the License. 16 | # 17 | # @author Yan Pujante 18 | 19 | import argparse 20 | import os 21 | import sys 22 | import platform 23 | 24 | parser = argparse.ArgumentParser(allow_abbrev=False, 25 | usage='configure.py [--h] [--n] [--f] [--r] [---vst3 VST3_SDK_ROOT] [---vst2 VST2_SDK_ROOT] [--G GENERATOR] [--B BUILD_DIR] [--- ]', 26 | formatter_class=argparse.RawDescriptionHelpFormatter, 27 | epilog=''' 28 | Notes 29 | ---vst3 defaults to /Users/Shared/Steinberg/VST_SDK. 30 | ---vst2 defaults to /Users/Shared/Steinberg/VST_SDK. 31 | 32 | -G defaults to "Xcode" on macOS and "Visual Studio 16 2019" for Windows10 33 | run 'cmake --help' to get the list of generators supported 34 | 35 | For single-config generators, Debug is used by default and can be changed with -r for Release 36 | For multi-config generators, -r is ignored 37 | 38 | To provide extra options to CMake you do it this way 39 | python3 configure.py -- -Wdev 40 | 41 | Examples 42 | # Specify an explicit path to the VST3 sdk and uses default generator 43 | python3 configure.py ---vst3 /opt/local/VST_SDK.3.7.0 44 | 45 | # Use default paths and uses another generator 46 | python3 configure.py -G "CodeBlocks - Unix Makefiles" 47 | 48 | # Use defaults 49 | python3 configure.py 50 | ''') 51 | parser.add_argument("-n", "--dry-run", help="Dry run (prints what it is going to do)", action="store_true", dest="dry_run") 52 | parser.add_argument("-f", "--force", help="Force a regeneration (delete and recreate build folder)", action="store_true") 53 | parser.add_argument("--vst3", help="Path to the VST3 SDK (optional)", dest="vst3_sdk_root") 54 | parser.add_argument("--vst2", help="Path to the VST2 SDK (optional)", dest="vst2_sdk_root") 55 | parser.add_argument("-r", "--release", help="Use CMake Release build type (for single-config generators)", action="store_true") 56 | parser.add_argument("-G", "--generator", help="CMake generator (optional)") 57 | parser.add_argument("-B", "--build-dir", help="Build folder (defaults to ./build)", dest="build_dir") 58 | parser.add_argument('cmake_options', help="Any options for cmake", nargs=argparse.REMAINDER) 59 | 60 | args = parser.parse_args() 61 | 62 | # The CMakeLists.txt file is a sibling of this script 63 | this_script_root_dir = os.path.dirname(os.path.realpath(sys.argv[0])) 64 | 65 | # VST3_SDK_ROOT 66 | vst3_sdk_root = [f'-DVST3_SDK_ROOT:PATH={args.vst3_sdk_root}'] if args.vst3_sdk_root else [] 67 | 68 | # VST2_SDK_ROOT 69 | vst2_sdk_root = [f'-DVST2_SDK_ROOT:PATH={args.vst2_sdk_root}'] if args.vst2_sdk_root else [] 70 | 71 | # CMake generator 72 | cmake_generator = ['-G'] 73 | if args.generator: 74 | cmake_generator.append(args.generator) 75 | else: 76 | if platform.system() == 'Darwin': 77 | cmake_generator.append('Xcode') 78 | else: 79 | cmake_generator.append('Visual Studio 16 2019') 80 | 81 | # CMake options 82 | cmake_options = [] if not args.cmake_options else args.cmake_options[1:] 83 | 84 | # CMake build type (for single config generators) 85 | cmake_build_type = [f'-DCMAKE_BUILD_TYPE={"Release" if args.release else "Debug"}'] 86 | 87 | # CMake build directory 88 | build_dir = args.build_dir if args.build_dir else 'build' 89 | cmake_build_dir = ['-B', build_dir] 90 | 91 | # CMake command 92 | cmake_command = ['cmake', 93 | *cmake_build_dir, 94 | *vst3_sdk_root, *vst2_sdk_root, 95 | *cmake_build_type, 96 | *cmake_generator, 97 | *cmake_options, 98 | this_script_root_dir] 99 | 100 | if args.dry_run: 101 | escaped_command = ' '.join([f'"{x}"' for x in cmake_command[1:]]) 102 | print(f'cmake {escaped_command}') 103 | else: 104 | if args.force: 105 | import shutil 106 | if os.path.exists(build_dir): 107 | shutil.rmtree(build_dir) 108 | 109 | import subprocess 110 | subprocess.run(cmake_command) 111 | 112 | 113 | 114 | 115 | 116 | -------------------------------------------------------------------------------- /src/cpp/FilePath.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | #include "FilePath.h" 7 | 8 | #if !SMTG_OS_WINDOWS 9 | #include 10 | #endif 11 | 12 | namespace pongasoft { 13 | namespace VST { 14 | namespace SampleSplitter { 15 | 16 | using namespace Steinberg; 17 | 18 | //------------------------------------------------------------------------ 19 | // getTemporaryPath 20 | //------------------------------------------------------------------------ 21 | UTF8Path getTemporaryPath() 22 | { 23 | // Implementation notes: 24 | // * this code is inspired by boost library 25 | // https://github.com/boostorg/filesystem/blob/boost-1.69.0/src/operations.cpp#L1857 26 | // Although it would be ideally preferable to use the boost library directly 27 | // as of this writing (Feb 2019), having to download and compile the library in order to use it 28 | // does not fit very well with how this project is structured (dependencies are downloaded). 29 | // * the boost library does not use GetTempPath which is available in Windows but rely on 30 | // environment variables instead 31 | 32 | #if SMTG_OS_WINDOWS 33 | // Windows Implementation 34 | 35 | // From https://docs.microsoft.com/en-us/windows/desktop/FileIO/creating-and-using-a-temporary-file 36 | path_char_type lpTempPathBuffer[MAX_PATH]; 37 | auto dwRetVal = GetTempPath(MAX_PATH,lpTempPathBuffer); 38 | if(dwRetVal > MAX_PATH || (dwRetVal == 0)) 39 | { 40 | LOG_F(ERROR, "Cannot get access to temporary folder"); 41 | return UTF8Path("C:\\Temp"); 42 | } 43 | return UTF8Path::fromNativePath(lpTempPathBuffer); 44 | #else 45 | // other implementation 46 | const char* val = nullptr; 47 | 48 | #pragma clang diagnostic push 49 | #pragma clang diagnostic ignored "-Wunused-value" 50 | (val = std::getenv("TMPDIR" )) || 51 | (val = std::getenv("TMP" )) || 52 | (val = std::getenv("TEMP" )) || 53 | (val = std::getenv("TEMPDIR")); 54 | #pragma clang diagnostic pop 55 | 56 | if(!val) 57 | val = "/tmp"; 58 | 59 | return UTF8Path::fromNativePath(val); 60 | 61 | #endif 62 | } 63 | 64 | //------------------------------------------------------------------------ 65 | // createTempFilePath 66 | //------------------------------------------------------------------------ 67 | UTF8Path createTempFilePath(UTF8Path const &iFilename) 68 | { 69 | // this id will be unique across multiple instances of the plugin running in the same DAW 70 | static std::atomic unique_id(0); 71 | // this id will be unique to a DAW (very unlikely that 2 DAWs could start at exactly the same time) 72 | static auto time_id = Clock::getCurrentTimeMillis(); 73 | 74 | std::ostringstream tempFilename; 75 | 76 | auto now = Clock::getCurrentTimeMillis(); 77 | 78 | tempFilename << "sam_spl64_" << time_id << "_" << (now - time_id) << "_" << unique_id.fetch_add(1); 79 | 80 | const auto &filepath = iFilename.cpp_str(); 81 | 82 | auto found = filepath.rfind('.'); 83 | if(found == std::string::npos) 84 | tempFilename << ".raw"; 85 | else 86 | tempFilename << filepath.substr(found); 87 | 88 | UTF8Path tempFilePath = getTemporaryPath(); 89 | return tempFilePath.cpp_str() + tempFilename.str(); 90 | } 91 | 92 | //------------------------------------------------------------------------ 93 | // basic_UTF8Path::toNativePath 94 | //------------------------------------------------------------------------ 95 | template<> 96 | std::basic_string basic_UTF8Path::toNativePath() const 97 | { 98 | return fPath.data(); 99 | } 100 | 101 | //------------------------------------------------------------------------ 102 | // basic_UTF8Path::fromNativePath 103 | //------------------------------------------------------------------------ 104 | template<> 105 | basic_UTF8Path basic_UTF8Path::fromNativePath(const std::basic_string &iPath) 106 | { 107 | return iPath; 108 | } 109 | 110 | //------------------------------------------------------------------------ 111 | // basic_UTF8Path::toNativePath 112 | //------------------------------------------------------------------------ 113 | template<> 114 | std::basic_string basic_UTF8Path::toNativePath() const 115 | { 116 | std::wstring_convert> converter; 117 | return converter.from_bytes(fPath.data()); 118 | } 119 | 120 | //------------------------------------------------------------------------ 121 | // basic_UTF8Path::fromNativePath 122 | //------------------------------------------------------------------------ 123 | template<> 124 | basic_UTF8Path basic_UTF8Path::fromNativePath(const std::basic_string &iPath) 125 | { 126 | std::wstring_convert> converter; 127 | return converter.to_bytes(iPath); 128 | } 129 | 130 | 131 | } 132 | } 133 | } -------------------------------------------------------------------------------- /src/cpp/GUI/WaveformView.cpp: -------------------------------------------------------------------------------- 1 | #include "../FilePath.h" 2 | 3 | #include "WaveformView.h" 4 | #include "Waveform.h" 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include "SampleFileLoader.h" 10 | 11 | namespace pongasoft::VST::SampleSplitter::GUI { 12 | 13 | //------------------------------------------------------------------------ 14 | // WaveformView::registerParameters 15 | //------------------------------------------------------------------------ 16 | void WaveformView::registerParameters() 17 | { 18 | fCurrentSample = registerParam(fState->fCurrentSample); 19 | fSampleRate = registerParam(fState->fSampleRate); 20 | } 21 | 22 | //------------------------------------------------------------------------ 23 | // WaveformView::draw 24 | //------------------------------------------------------------------------ 25 | void WaveformView::draw(CDrawContext *iContext) 26 | { 27 | CustomView::draw(iContext); 28 | 29 | if(!fBitmap && fState->fCurrentSample->hasSamples()) 30 | generateBitmap(fCurrentSample.getValue()); 31 | } 32 | 33 | //------------------------------------------------------------------------ 34 | // WaveformView::setViewSize 35 | //------------------------------------------------------------------------ 36 | void WaveformView::setViewSize(const CRect &rect, bool invalid) 37 | { 38 | if(getViewSize().getSize() != rect.getSize()) 39 | fBitmap = nullptr; 40 | 41 | CView::setViewSize(rect, invalid); 42 | } 43 | 44 | //------------------------------------------------------------------------ 45 | // WaveformView::onParameterChange 46 | //------------------------------------------------------------------------ 47 | void WaveformView::onParameterChange(ParamID iParamID) 48 | { 49 | if(iParamID == fCurrentSample.getParamID() || iParamID == fSampleRate.getParamID()) 50 | fBitmap = nullptr; 51 | 52 | CustomView::onParameterChange(iParamID); 53 | } 54 | 55 | namespace internal { 56 | 57 | //------------------------------------------------------------------------ 58 | // internal::findFilePath 59 | //------------------------------------------------------------------------ 60 | std::optional findFilePath(IDataPackage *iDrag) 61 | { 62 | for(uint32_t i = 0; i < iDrag->getCount(); i++) 63 | { 64 | void const *buffer; 65 | IDataPackage::Type type; 66 | iDrag->getData(i, buffer, type); 67 | if(type == IDataPackage::kFilePath) 68 | { 69 | return std::string{static_cast(buffer), iDrag->getDataSize(i)}; 70 | } 71 | } 72 | return std::nullopt; 73 | } 74 | 75 | //------------------------------------------------------------------------ 76 | // internal::findValidFile => is there a valid file embedded? 77 | //------------------------------------------------------------------------ 78 | bool findValidFile(IDataPackage *iDrag) 79 | { 80 | if(auto filePath = findFilePath(iDrag)) 81 | return SampleFileLoader::isSupportedFileType(UTF8Path(*filePath)); 82 | else 83 | return false; 84 | } 85 | 86 | } 87 | 88 | //------------------------------------------------------------------------ 89 | // WaveformView::onDragEnter 90 | //------------------------------------------------------------------------ 91 | DragOperation WaveformView::onDragEnter(DragEventData data) 92 | { 93 | fDragOperation = internal::findValidFile(data.drag) ? DragOperation::Copy : DragOperation::None; 94 | return fDragOperation; 95 | } 96 | 97 | //------------------------------------------------------------------------ 98 | // WaveformView::onDragMove 99 | //------------------------------------------------------------------------ 100 | DragOperation WaveformView::onDragMove(DragEventData data) 101 | { 102 | return fDragOperation; 103 | } 104 | 105 | //------------------------------------------------------------------------ 106 | // WaveformView::onDragLeave 107 | //------------------------------------------------------------------------ 108 | void WaveformView::onDragLeave(DragEventData data) 109 | { 110 | fDragOperation = DragOperation::None; 111 | } 112 | 113 | //------------------------------------------------------------------------ 114 | // WaveformView::onDrop 115 | //------------------------------------------------------------------------ 116 | bool WaveformView::onDrop(DragEventData data) 117 | { 118 | auto filepath = internal::findFilePath(data.drag); 119 | 120 | if(filepath) 121 | { 122 | return fState->maybeLoadSample(*filepath) == kResultOk; 123 | } 124 | 125 | fDragOperation = DragOperation::None; 126 | 127 | return true; 128 | } 129 | 130 | //------------------------------------------------------------------------ 131 | // WaveformView::getDropTarget 132 | //------------------------------------------------------------------------ 133 | SharedPointer WaveformView::getDropTarget() 134 | { 135 | fDragOperation = DragOperation::None; 136 | return this; 137 | } 138 | 139 | 140 | } --------------------------------------------------------------------------------