├── .gitignore ├── .gitmodules ├── Builds ├── LinuxMakefile │ └── Makefile ├── MacOSX │ ├── Info-App.plist │ ├── Info.plist │ ├── RecentFilesMenuTemplate.nib │ └── juce2push2.xcodeproj │ │ └── project.pbxproj └── VisualStudio2013 │ ├── juce2push2.sln │ ├── juce2push2.vcxproj │ ├── juce2push2.vcxproj.filters │ └── resources.rc ├── JuceLibraryCode ├── AppConfig.h ├── BinaryData.cpp ├── BinaryData.h ├── JuceHeader.h ├── ReadMe.txt ├── juce_audio_basics.cpp ├── juce_audio_basics.mm ├── juce_audio_devices.cpp ├── juce_audio_devices.mm ├── juce_audio_formats.cpp ├── juce_audio_formats.mm ├── juce_audio_processors.cpp ├── juce_audio_processors.mm ├── juce_audio_utils.cpp ├── juce_audio_utils.mm ├── juce_core.cpp ├── juce_core.mm ├── juce_cryptography.cpp ├── juce_cryptography.mm ├── juce_data_structures.cpp ├── juce_data_structures.mm ├── juce_events.cpp ├── juce_events.mm ├── juce_graphics.cpp ├── juce_graphics.mm ├── juce_gui_basics.cpp ├── juce_gui_basics.mm ├── juce_gui_extra.cpp └── juce_gui_extra.mm ├── LICENSE ├── README.md ├── Resources └── PushStartup.png ├── Source ├── Macros.h ├── Main.cpp ├── MainComponent.cpp ├── Push2Demo.cpp ├── Push2Demo.h ├── Result.cpp ├── Result.h ├── libusb │ ├── config.h │ ├── config_msvc.h │ ├── config_xcode.h │ └── libusb_platform_wrapper.c └── push2 │ ├── JuceToPush2DisplayBridge.cpp │ ├── JuceToPush2DisplayBridge.h │ ├── Push2-Bitmap.h │ ├── Push2-Display.h │ ├── Push2-Usb-Communicator.cpp │ └── Push2-UsbCommunicator.h └── juce2push2.jucer /.gitignore: -------------------------------------------------------------------------------- 1 | Builds/MacOSX/build/ 2 | Builds/VisualStudio2013/Debug/ 3 | Builds/VisualStudio2013/Release/ 4 | -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "modules/JUCE"] 2 | path = modules/JUCE 3 | url = https://github.com/WeAreROLI/JUCE.git 4 | [submodule "modules/libusb"] 5 | path = modules/libusb 6 | url = https://github.com/libusb/libusb.git 7 | -------------------------------------------------------------------------------- /Builds/LinuxMakefile/Makefile: -------------------------------------------------------------------------------- 1 | # Automatically generated makefile, created by the Projucer 2 | # Don't edit this file! Your changes will be overwritten when you re-save the Projucer project! 3 | 4 | # (this disables dependency generation if multiple architectures are set) 5 | DEPFLAGS := $(if $(word 2, $(TARGET_ARCH)), , -MMD) 6 | 7 | ifndef STRIP 8 | STRIP=strip 9 | endif 10 | 11 | ifndef AR 12 | AR=ar 13 | endif 14 | 15 | ifndef CONFIG 16 | CONFIG=Debug 17 | endif 18 | 19 | ifeq ($(CONFIG),Debug) 20 | JUCE_BINDIR := build 21 | JUCE_LIBDIR := build 22 | JUCE_OBJDIR := build/intermediate/Debug 23 | JUCE_OUTDIR := build 24 | 25 | ifeq ($(TARGET_ARCH),) 26 | TARGET_ARCH := -march=native 27 | endif 28 | 29 | JUCE_CPPFLAGS := $(DEPFLAGS) -DLINUX=1 -DDEBUG=1 -D_DEBUG=1 -DJUCER_LINUX_MAKE_6D53C8B4=1 -DJUCE_APP_VERSION=1.0.0 -DJUCE_APP_VERSION_HEX=0x10000 $(shell pkg-config --cflags alsa freetype2 libcurl x11 xext xinerama) -pthread -I../../JuceLibraryCode -I../../modules/JUCE/modules -I../../Source -I../../Source/libusb -I../../modules/libusb/libusb 30 | JUCE_CFLAGS += $(CFLAGS) $(JUCE_CPPFLAGS) $(TARGET_ARCH) -g -ggdb -O0 31 | JUCE_CXXFLAGS += $(CXXFLAGS) $(JUCE_CFLAGS) -std=c++11 32 | JUCE_LDFLAGS += $(LDFLAGS) $(TARGET_ARCH) -L$(JUCE_BINDIR) -L$(JUCE_LIBDIR) -L/usr/X11R6/lib/ $(shell pkg-config --libs alsa freetype2 libcurl x11 xext xinerama) -ldl -lpthread -lrt -lusb-1.0 33 | 34 | TARGET := juce2push2 35 | BLDCMD = $(CXX) -o $(JUCE_OUTDIR)/$(TARGET) $(OBJECTS) $(JUCE_LDFLAGS) $(RESOURCES) $(TARGET_ARCH) 36 | CLEANCMD = rm -rf $(JUCE_OUTDIR)/$(TARGET) $(JUCE_OBJDIR) 37 | endif 38 | 39 | ifeq ($(CONFIG),Release) 40 | JUCE_BINDIR := build 41 | JUCE_LIBDIR := build 42 | JUCE_OBJDIR := build/intermediate/Release 43 | JUCE_OUTDIR := build 44 | 45 | ifeq ($(TARGET_ARCH),) 46 | TARGET_ARCH := -march=native 47 | endif 48 | 49 | JUCE_CPPFLAGS := $(DEPFLAGS) -DLINUX=1 -DNDEBUG=1 -DJUCER_LINUX_MAKE_6D53C8B4=1 -DJUCE_APP_VERSION=1.0.0 -DJUCE_APP_VERSION_HEX=0x10000 $(shell pkg-config --cflags alsa freetype2 libcurl x11 xext xinerama) -pthread -I../../JuceLibraryCode -I../../modules/JUCE/modules -I../../Source -I../../Source/libusb -I../../modules/libusb/libusb 50 | JUCE_CFLAGS += $(CFLAGS) $(JUCE_CPPFLAGS) $(TARGET_ARCH) -O3 51 | JUCE_CXXFLAGS += $(CXXFLAGS) $(JUCE_CFLAGS) -std=c++11 52 | JUCE_LDFLAGS += $(LDFLAGS) $(TARGET_ARCH) -L$(JUCE_BINDIR) -L$(JUCE_LIBDIR) -fvisibility=hidden -L/usr/X11R6/lib/ $(shell pkg-config --libs alsa freetype2 libcurl x11 xext xinerama) -ldl -lpthread -lrt -lusb-1.0 53 | 54 | TARGET := juce2push2 55 | BLDCMD = $(CXX) -o $(JUCE_OUTDIR)/$(TARGET) $(OBJECTS) $(JUCE_LDFLAGS) $(RESOURCES) $(TARGET_ARCH) 56 | CLEANCMD = rm -rf $(JUCE_OUTDIR)/$(TARGET) $(JUCE_OBJDIR) 57 | endif 58 | 59 | OBJECTS := \ 60 | $(JUCE_OBJDIR)/Push2-Usb-Communicator_c7d88633.o \ 61 | $(JUCE_OBJDIR)/JuceToPush2DisplayBridge_50b55e3b.o \ 62 | $(JUCE_OBJDIR)/libusb_platform_wrapper_fdf8d8e0.o \ 63 | $(JUCE_OBJDIR)/Push2Demo_b450aa3c.o \ 64 | $(JUCE_OBJDIR)/MainComponent_a6ffb4a5.o \ 65 | $(JUCE_OBJDIR)/Main_90ebc5c2.o \ 66 | $(JUCE_OBJDIR)/Result_7479126.o \ 67 | $(JUCE_OBJDIR)/BinaryData_ce4232d4.o \ 68 | $(JUCE_OBJDIR)/juce_audio_basics_6b797ca1.o \ 69 | $(JUCE_OBJDIR)/juce_audio_devices_a742c38b.o \ 70 | $(JUCE_OBJDIR)/juce_audio_formats_5a29c68a.o \ 71 | $(JUCE_OBJDIR)/juce_audio_processors_dea3173d.o \ 72 | $(JUCE_OBJDIR)/juce_audio_utils_c7eb679f.o \ 73 | $(JUCE_OBJDIR)/juce_core_75b14332.o \ 74 | $(JUCE_OBJDIR)/juce_cryptography_6de2ebff.o \ 75 | $(JUCE_OBJDIR)/juce_data_structures_72d3da2c.o \ 76 | $(JUCE_OBJDIR)/juce_events_d2be882c.o \ 77 | $(JUCE_OBJDIR)/juce_graphics_9c18891e.o \ 78 | $(JUCE_OBJDIR)/juce_gui_basics_8a6da59c.o \ 79 | $(JUCE_OBJDIR)/juce_gui_extra_4a026f23.o \ 80 | 81 | .PHONY: clean 82 | 83 | $(JUCE_OUTDIR)/$(TARGET): check-pkg-config $(OBJECTS) $(RESOURCES) 84 | @echo Linking juce2push2 85 | -@mkdir -p $(JUCE_BINDIR) 86 | -@mkdir -p $(JUCE_LIBDIR) 87 | -@mkdir -p $(JUCE_OUTDIR) 88 | @$(BLDCMD) 89 | 90 | check-pkg-config: 91 | @command -v pkg-config >/dev/null 2>&1 || { echo >&2 "pkg-config not installed. Please, install it."; exit 1; } 92 | @pkg-config --print-errors alsa freetype2 libcurl x11 xext xinerama 93 | 94 | clean: 95 | @echo Cleaning juce2push2 96 | @$(CLEANCMD) 97 | 98 | strip: 99 | @echo Stripping juce2push2 100 | -@$(STRIP) --strip-unneeded $(JUCE_OUTDIR)/$(TARGET) 101 | 102 | $(JUCE_OBJDIR)/Push2-Usb-Communicator_c7d88633.o: ../../Source/push2/Push2-Usb-Communicator.cpp 103 | -@mkdir -p $(JUCE_OBJDIR) 104 | @echo "Compiling Push2-Usb-Communicator.cpp" 105 | @$(CXX) $(JUCE_CXXFLAGS) -o "$@" -c "$<" 106 | 107 | $(JUCE_OBJDIR)/JuceToPush2DisplayBridge_50b55e3b.o: ../../Source/push2/JuceToPush2DisplayBridge.cpp 108 | -@mkdir -p $(JUCE_OBJDIR) 109 | @echo "Compiling JuceToPush2DisplayBridge.cpp" 110 | @$(CXX) $(JUCE_CXXFLAGS) -o "$@" -c "$<" 111 | 112 | $(JUCE_OBJDIR)/libusb_platform_wrapper_fdf8d8e0.o: ../../Source/libusb/libusb_platform_wrapper.c 113 | -@mkdir -p $(JUCE_OBJDIR) 114 | @echo "Compiling libusb_platform_wrapper.c" 115 | @$(CC) $(JUCE_CFLAGS) -o "$@" -c "$<" 116 | 117 | $(JUCE_OBJDIR)/Push2Demo_b450aa3c.o: ../../Source/Push2Demo.cpp 118 | -@mkdir -p $(JUCE_OBJDIR) 119 | @echo "Compiling Push2Demo.cpp" 120 | @$(CXX) $(JUCE_CXXFLAGS) -o "$@" -c "$<" 121 | 122 | $(JUCE_OBJDIR)/MainComponent_a6ffb4a5.o: ../../Source/MainComponent.cpp 123 | -@mkdir -p $(JUCE_OBJDIR) 124 | @echo "Compiling MainComponent.cpp" 125 | @$(CXX) $(JUCE_CXXFLAGS) -o "$@" -c "$<" 126 | 127 | $(JUCE_OBJDIR)/Main_90ebc5c2.o: ../../Source/Main.cpp 128 | -@mkdir -p $(JUCE_OBJDIR) 129 | @echo "Compiling Main.cpp" 130 | @$(CXX) $(JUCE_CXXFLAGS) -o "$@" -c "$<" 131 | 132 | $(JUCE_OBJDIR)/Result_7479126.o: ../../Source/Result.cpp 133 | -@mkdir -p $(JUCE_OBJDIR) 134 | @echo "Compiling Result.cpp" 135 | @$(CXX) $(JUCE_CXXFLAGS) -o "$@" -c "$<" 136 | 137 | $(JUCE_OBJDIR)/BinaryData_ce4232d4.o: ../../JuceLibraryCode/BinaryData.cpp 138 | -@mkdir -p $(JUCE_OBJDIR) 139 | @echo "Compiling BinaryData.cpp" 140 | @$(CXX) $(JUCE_CXXFLAGS) -o "$@" -c "$<" 141 | 142 | $(JUCE_OBJDIR)/juce_audio_basics_6b797ca1.o: ../../JuceLibraryCode/juce_audio_basics.cpp 143 | -@mkdir -p $(JUCE_OBJDIR) 144 | @echo "Compiling juce_audio_basics.cpp" 145 | @$(CXX) $(JUCE_CXXFLAGS) -o "$@" -c "$<" 146 | 147 | $(JUCE_OBJDIR)/juce_audio_devices_a742c38b.o: ../../JuceLibraryCode/juce_audio_devices.cpp 148 | -@mkdir -p $(JUCE_OBJDIR) 149 | @echo "Compiling juce_audio_devices.cpp" 150 | @$(CXX) $(JUCE_CXXFLAGS) -o "$@" -c "$<" 151 | 152 | $(JUCE_OBJDIR)/juce_audio_formats_5a29c68a.o: ../../JuceLibraryCode/juce_audio_formats.cpp 153 | -@mkdir -p $(JUCE_OBJDIR) 154 | @echo "Compiling juce_audio_formats.cpp" 155 | @$(CXX) $(JUCE_CXXFLAGS) -o "$@" -c "$<" 156 | 157 | $(JUCE_OBJDIR)/juce_audio_processors_dea3173d.o: ../../JuceLibraryCode/juce_audio_processors.cpp 158 | -@mkdir -p $(JUCE_OBJDIR) 159 | @echo "Compiling juce_audio_processors.cpp" 160 | @$(CXX) $(JUCE_CXXFLAGS) -o "$@" -c "$<" 161 | 162 | $(JUCE_OBJDIR)/juce_audio_utils_c7eb679f.o: ../../JuceLibraryCode/juce_audio_utils.cpp 163 | -@mkdir -p $(JUCE_OBJDIR) 164 | @echo "Compiling juce_audio_utils.cpp" 165 | @$(CXX) $(JUCE_CXXFLAGS) -o "$@" -c "$<" 166 | 167 | $(JUCE_OBJDIR)/juce_core_75b14332.o: ../../JuceLibraryCode/juce_core.cpp 168 | -@mkdir -p $(JUCE_OBJDIR) 169 | @echo "Compiling juce_core.cpp" 170 | @$(CXX) $(JUCE_CXXFLAGS) -o "$@" -c "$<" 171 | 172 | $(JUCE_OBJDIR)/juce_cryptography_6de2ebff.o: ../../JuceLibraryCode/juce_cryptography.cpp 173 | -@mkdir -p $(JUCE_OBJDIR) 174 | @echo "Compiling juce_cryptography.cpp" 175 | @$(CXX) $(JUCE_CXXFLAGS) -o "$@" -c "$<" 176 | 177 | $(JUCE_OBJDIR)/juce_data_structures_72d3da2c.o: ../../JuceLibraryCode/juce_data_structures.cpp 178 | -@mkdir -p $(JUCE_OBJDIR) 179 | @echo "Compiling juce_data_structures.cpp" 180 | @$(CXX) $(JUCE_CXXFLAGS) -o "$@" -c "$<" 181 | 182 | $(JUCE_OBJDIR)/juce_events_d2be882c.o: ../../JuceLibraryCode/juce_events.cpp 183 | -@mkdir -p $(JUCE_OBJDIR) 184 | @echo "Compiling juce_events.cpp" 185 | @$(CXX) $(JUCE_CXXFLAGS) -o "$@" -c "$<" 186 | 187 | $(JUCE_OBJDIR)/juce_graphics_9c18891e.o: ../../JuceLibraryCode/juce_graphics.cpp 188 | -@mkdir -p $(JUCE_OBJDIR) 189 | @echo "Compiling juce_graphics.cpp" 190 | @$(CXX) $(JUCE_CXXFLAGS) -o "$@" -c "$<" 191 | 192 | $(JUCE_OBJDIR)/juce_gui_basics_8a6da59c.o: ../../JuceLibraryCode/juce_gui_basics.cpp 193 | -@mkdir -p $(JUCE_OBJDIR) 194 | @echo "Compiling juce_gui_basics.cpp" 195 | @$(CXX) $(JUCE_CXXFLAGS) -o "$@" -c "$<" 196 | 197 | $(JUCE_OBJDIR)/juce_gui_extra_4a026f23.o: ../../JuceLibraryCode/juce_gui_extra.cpp 198 | -@mkdir -p $(JUCE_OBJDIR) 199 | @echo "Compiling juce_gui_extra.cpp" 200 | @$(CXX) $(JUCE_CXXFLAGS) -o "$@" -c "$<" 201 | 202 | -include $(OBJECTS:%.o=%.d) 203 | -------------------------------------------------------------------------------- /Builds/MacOSX/Info-App.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | CFBundleExecutable 7 | ${EXECUTABLE_NAME} 8 | CFBundleIconFile 9 | 10 | CFBundleIdentifier 11 | $(PRODUCT_BUNDLE_IDENTIFIER) 12 | CFBundleName 13 | juce2push2 14 | CFBundleDisplayName 15 | juce2push2 16 | CFBundlePackageType 17 | APPL 18 | CFBundleSignature 19 | ???? 20 | CFBundleShortVersionString 21 | 1.0.0 22 | CFBundleVersion 23 | 1.0.0 24 | NSHumanReadableCopyright 25 | ableton 26 | NSHighResolutionCapable 27 | 28 | 29 | 30 | -------------------------------------------------------------------------------- /Builds/MacOSX/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | CFBundleExecutable 7 | ${EXECUTABLE_NAME} 8 | CFBundleIconFile 9 | 10 | CFBundleIdentifier 11 | $(PRODUCT_BUNDLE_IDENTIFIER) 12 | CFBundleName 13 | juce2push2 14 | CFBundlePackageType 15 | APPL 16 | CFBundleSignature 17 | ???? 18 | CFBundleShortVersionString 19 | 1.0.0 20 | CFBundleVersion 21 | 1.0.0 22 | NSHumanReadableCopyright 23 | ableton 24 | NSHighResolutionCapable 25 | 26 | 27 | 28 | -------------------------------------------------------------------------------- /Builds/MacOSX/RecentFilesMenuTemplate.nib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Ableton/push2-display-with-juce/48e9be846bda686b97a0df7635d80e63a51a5e4b/Builds/MacOSX/RecentFilesMenuTemplate.nib -------------------------------------------------------------------------------- /Builds/VisualStudio2013/juce2push2.sln: -------------------------------------------------------------------------------- 1 | Microsoft Visual Studio Solution File, Format Version 11.00 2 | # Visual Studio 2013 3 | Project("{C2A7433A-C4B1-0E6D-2C50-53CD32161608}") = "juce2push2", "juce2push2.vcxproj", "{98C628F8-1DA7-CBFD-7AAE-4DB426CA576D}" 4 | EndProject 5 | Global 6 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 7 | Debug|Win32 = Debug|Win32 8 | Release|Win32 = Release|Win32 9 | EndGlobalSection 10 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 11 | {98C628F8-1DA7-CBFD-7AAE-4DB426CA576D}.Debug|Win32.ActiveCfg = Debug|Win32 12 | {98C628F8-1DA7-CBFD-7AAE-4DB426CA576D}.Debug|Win32.Build.0 = Debug|Win32 13 | {98C628F8-1DA7-CBFD-7AAE-4DB426CA576D}.Release|Win32.ActiveCfg = Release|Win32 14 | {98C628F8-1DA7-CBFD-7AAE-4DB426CA576D}.Release|Win32.Build.0 = Release|Win32 15 | EndGlobalSection 16 | GlobalSection(SolutionProperties) = preSolution 17 | HideSolutionNode = FALSE 18 | EndGlobalSection 19 | EndGlobal 20 | -------------------------------------------------------------------------------- /Builds/VisualStudio2013/resources.rc: -------------------------------------------------------------------------------- 1 | #ifdef JUCE_USER_DEFINED_RC_FILE 2 | #include JUCE_USER_DEFINED_RC_FILE 3 | #else 4 | 5 | #undef WIN32_LEAN_AND_MEAN 6 | #define WIN32_LEAN_AND_MEAN 7 | #include 8 | 9 | VS_VERSION_INFO VERSIONINFO 10 | FILEVERSION 1,0,0,0 11 | BEGIN 12 | BLOCK "StringFileInfo" 13 | BEGIN 14 | BLOCK "040904E4" 15 | BEGIN 16 | VALUE "CompanyName", "ableton\0" 17 | VALUE "FileDescription", "juce2push2\0" 18 | VALUE "FileVersion", "1.0.0\0" 19 | VALUE "ProductName", "juce2push2\0" 20 | VALUE "ProductVersion", "1.0.0\0" 21 | END 22 | END 23 | 24 | BLOCK "VarFileInfo" 25 | BEGIN 26 | VALUE "Translation", 0x409, 1252 27 | END 28 | END 29 | 30 | #endif 31 | -------------------------------------------------------------------------------- /JuceLibraryCode/AppConfig.h: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | IMPORTANT! This file is auto-generated each time you save your 4 | project - if you alter its contents, your changes may be overwritten! 5 | 6 | There's a section below where you can add your own custom code safely, and the 7 | Projucer will preserve the contents of that block, but the best way to change 8 | any of these definitions is by using the Projucer's project settings. 9 | 10 | Any commented-out settings will assume their default values. 11 | 12 | */ 13 | 14 | #ifndef __JUCE_APPCONFIG_KHUPU8__ 15 | #define __JUCE_APPCONFIG_KHUPU8__ 16 | 17 | //============================================================================== 18 | // [BEGIN_USER_CODE_SECTION] 19 | 20 | // (You can add your own code in this section, and the Projucer will not overwrite it) 21 | 22 | // [END_USER_CODE_SECTION] 23 | 24 | //============================================================================== 25 | #define JUCE_MODULE_AVAILABLE_juce_audio_basics 1 26 | #define JUCE_MODULE_AVAILABLE_juce_audio_devices 1 27 | #define JUCE_MODULE_AVAILABLE_juce_audio_formats 1 28 | #define JUCE_MODULE_AVAILABLE_juce_audio_processors 1 29 | #define JUCE_MODULE_AVAILABLE_juce_audio_utils 1 30 | #define JUCE_MODULE_AVAILABLE_juce_core 1 31 | #define JUCE_MODULE_AVAILABLE_juce_cryptography 1 32 | #define JUCE_MODULE_AVAILABLE_juce_data_structures 1 33 | #define JUCE_MODULE_AVAILABLE_juce_events 1 34 | #define JUCE_MODULE_AVAILABLE_juce_graphics 1 35 | #define JUCE_MODULE_AVAILABLE_juce_gui_basics 1 36 | #define JUCE_MODULE_AVAILABLE_juce_gui_extra 1 37 | 38 | //============================================================================== 39 | #ifndef JUCE_STANDALONE_APPLICATION 40 | #ifdef JucePlugin_Build_Standalone 41 | #define JUCE_STANDALONE_APPLICATION JucePlugin_Build_Standalone 42 | #else 43 | #define JUCE_STANDALONE_APPLICATION 1 44 | #endif 45 | #endif 46 | 47 | #define JUCE_GLOBAL_MODULE_SETTINGS_INCLUDED 1 48 | 49 | //============================================================================== 50 | // juce_audio_devices flags: 51 | 52 | #ifndef JUCE_ASIO 53 | //#define JUCE_ASIO 54 | #endif 55 | 56 | #ifndef JUCE_WASAPI 57 | //#define JUCE_WASAPI 58 | #endif 59 | 60 | #ifndef JUCE_WASAPI_EXCLUSIVE 61 | //#define JUCE_WASAPI_EXCLUSIVE 62 | #endif 63 | 64 | #ifndef JUCE_DIRECTSOUND 65 | //#define JUCE_DIRECTSOUND 66 | #endif 67 | 68 | #ifndef JUCE_ALSA 69 | //#define JUCE_ALSA 70 | #endif 71 | 72 | #ifndef JUCE_JACK 73 | //#define JUCE_JACK 74 | #endif 75 | 76 | #ifndef JUCE_USE_ANDROID_OPENSLES 77 | //#define JUCE_USE_ANDROID_OPENSLES 78 | #endif 79 | 80 | //============================================================================== 81 | // juce_audio_formats flags: 82 | 83 | #ifndef JUCE_USE_FLAC 84 | //#define JUCE_USE_FLAC 85 | #endif 86 | 87 | #ifndef JUCE_USE_OGGVORBIS 88 | //#define JUCE_USE_OGGVORBIS 89 | #endif 90 | 91 | #ifndef JUCE_USE_MP3AUDIOFORMAT 92 | //#define JUCE_USE_MP3AUDIOFORMAT 93 | #endif 94 | 95 | #ifndef JUCE_USE_LAME_AUDIO_FORMAT 96 | //#define JUCE_USE_LAME_AUDIO_FORMAT 97 | #endif 98 | 99 | #ifndef JUCE_USE_WINDOWS_MEDIA_FORMAT 100 | //#define JUCE_USE_WINDOWS_MEDIA_FORMAT 101 | #endif 102 | 103 | //============================================================================== 104 | // juce_audio_processors flags: 105 | 106 | #ifndef JUCE_PLUGINHOST_VST 107 | //#define JUCE_PLUGINHOST_VST 108 | #endif 109 | 110 | #ifndef JUCE_PLUGINHOST_VST3 111 | //#define JUCE_PLUGINHOST_VST3 112 | #endif 113 | 114 | #ifndef JUCE_PLUGINHOST_AU 115 | //#define JUCE_PLUGINHOST_AU 116 | #endif 117 | 118 | //============================================================================== 119 | // juce_audio_utils flags: 120 | 121 | #ifndef JUCE_USE_CDREADER 122 | //#define JUCE_USE_CDREADER 123 | #endif 124 | 125 | #ifndef JUCE_USE_CDBURNER 126 | //#define JUCE_USE_CDBURNER 127 | #endif 128 | 129 | //============================================================================== 130 | // juce_core flags: 131 | 132 | #ifndef JUCE_FORCE_DEBUG 133 | //#define JUCE_FORCE_DEBUG 134 | #endif 135 | 136 | #ifndef JUCE_LOG_ASSERTIONS 137 | //#define JUCE_LOG_ASSERTIONS 138 | #endif 139 | 140 | #ifndef JUCE_CHECK_MEMORY_LEAKS 141 | //#define JUCE_CHECK_MEMORY_LEAKS 142 | #endif 143 | 144 | #ifndef JUCE_DONT_AUTOLINK_TO_WIN32_LIBRARIES 145 | //#define JUCE_DONT_AUTOLINK_TO_WIN32_LIBRARIES 146 | #endif 147 | 148 | #ifndef JUCE_INCLUDE_ZLIB_CODE 149 | //#define JUCE_INCLUDE_ZLIB_CODE 150 | #endif 151 | 152 | #ifndef JUCE_USE_CURL 153 | //#define JUCE_USE_CURL 154 | #endif 155 | 156 | #ifndef JUCE_CATCH_UNHANDLED_EXCEPTIONS 157 | //#define JUCE_CATCH_UNHANDLED_EXCEPTIONS 158 | #endif 159 | 160 | #ifndef JUCE_ALLOW_STATIC_NULL_VARIABLES 161 | //#define JUCE_ALLOW_STATIC_NULL_VARIABLES 162 | #endif 163 | 164 | //============================================================================== 165 | // juce_graphics flags: 166 | 167 | #ifndef JUCE_USE_COREIMAGE_LOADER 168 | //#define JUCE_USE_COREIMAGE_LOADER 169 | #endif 170 | 171 | #ifndef JUCE_USE_DIRECTWRITE 172 | //#define JUCE_USE_DIRECTWRITE 173 | #endif 174 | 175 | //============================================================================== 176 | // juce_gui_basics flags: 177 | 178 | #ifndef JUCE_ENABLE_REPAINT_DEBUGGING 179 | //#define JUCE_ENABLE_REPAINT_DEBUGGING 180 | #endif 181 | 182 | #ifndef JUCE_USE_XSHM 183 | //#define JUCE_USE_XSHM 184 | #endif 185 | 186 | #ifndef JUCE_USE_XRENDER 187 | //#define JUCE_USE_XRENDER 188 | #endif 189 | 190 | #ifndef JUCE_USE_XCURSOR 191 | //#define JUCE_USE_XCURSOR 192 | #endif 193 | 194 | //============================================================================== 195 | // juce_gui_extra flags: 196 | 197 | #ifndef JUCE_WEB_BROWSER 198 | //#define JUCE_WEB_BROWSER 199 | #endif 200 | 201 | #ifndef JUCE_ENABLE_LIVE_CONSTANT_EDITOR 202 | //#define JUCE_ENABLE_LIVE_CONSTANT_EDITOR 203 | #endif 204 | 205 | 206 | #endif // __JUCE_APPCONFIG_KHUPU8__ 207 | -------------------------------------------------------------------------------- /JuceLibraryCode/BinaryData.cpp: -------------------------------------------------------------------------------- 1 | /* ==================================== JUCER_BINARY_RESOURCE ==================================== 2 | 3 | This is an auto-generated file: Any edits you make may be overwritten! 4 | 5 | */ 6 | 7 | namespace BinaryData 8 | { 9 | 10 | //================== PushStartup.png ================== 11 | static const unsigned char temp_binary_data_0[] = 12 | "\x89PNG\r\n" 13 | "\x1a\n" 14 | "\0\0\0\rIHDR\0\0\x03\xc0\0\0\0\xa0\x08\x03\0\0\0\xf4\x14\xf5n\0\0\0\tpHYs\0\0\x0b\x13\0\0\x0b\x13\x01\0\x9a\x9c\x18\0\0""8*iTXtXML:com.adobe.xmp\0\0\0\0\0\n" 15 | "\n" 16 | " \n" 17 | " \n" 25 | " Adobe Photoshop CC 2015 (Macintosh)\n" 26 | " 2016-03-23T09:23:57+01:00\n" 27 | " 2016-03-23T10:27:20+01:00\n" 28 | " 2016-03-23T10:27:20+01:00\n" 29 | " image/png\n" 30 | " 2\n" 31 | " xmp.iid:9a3588b9-fc5b-4ecd-b9b5-f168e448c8ce\n" 32 | " xmp.did:9a3588b9-fc5b-4ecd-b9b5-f168e448c8ce\n" 33 | " xmp.did:9a3588b9-fc5b-4ecd-b9b5-f168e448c8ce\n" 34 | " \n" 35 | " \n" 36 | " \n" 37 | " created\n" 38 | " xmp.iid:9a3588b9-fc5b-4ecd-b9b5-f168e448c8ce\n" 39 | " 2016-03-23T09:23:57+01:00\n" 40 | " Adobe Photoshop CC 2015 (Macintosh)\n" 41 | " \n" 42 | " \n" 43 | " \n" 44 | " 1\n" 45 | " 720000/10000\n" 46 | " 720000/10000\n" 47 | " 2\n" 48 | " 65535\n" 49 | " 960\n" 50 | " 160\n" 51 | " \n" 52 | " \n" 53 | "\n" 54 | " \n" 55 | " \n" 56 | " \n" 57 | " \n" 58 | " \n" 59 | " \n" 60 | " \n" 61 | " \n" 62 | " \n" 63 | " \n" 64 | " \n" 65 | " \n" 66 | " \n" 67 | " \n" 68 | " \n" 69 | " \n" 70 | " \n" 71 | " \n" 72 | " \n" 73 | " \n" 74 | " \n" 75 | " \n" 76 | " \n" 77 | " \n" 78 | " \n" 79 | " \n" 80 | " \n" 81 | " \n" 82 | " \n" 83 | " \n" 84 | " \n" 85 | " \n" 86 | " \n" 87 | " \n" 88 | " \n" 89 | " \n" 90 | " \n" 91 | " \n" 92 | " \n" 93 | " \n" 94 | " \n" 95 | " \n" 96 | " \n" 97 | " \n" 98 | " \n" 99 | " \n" 100 | " \n" 101 | " \n" 102 | " \n" 103 | " \n" 104 | " \n" 105 | " \n" 106 | " \n" 107 | " \n" 108 | " \n" 109 | " \n" 110 | " \n" 111 | " \n" 112 | " \n" 113 | " \n" 114 | " \n" 115 | " \n" 116 | " \n" 117 | " \n" 118 | " \n" 119 | " \n" 120 | " \n" 121 | " \n" 122 | " \n" 123 | " \n" 124 | " \n" 125 | " \n" 126 | " \n" 127 | " \n" 128 | " \n" 129 | " \n" 130 | " \n" 131 | " \n" 132 | " \n" 133 | " \n" 134 | " \n" 135 | " \n" 136 | " \n" 137 | " \n" 138 | " \n" 139 | " \n" 140 | " \n" 141 | " \n" 142 | " \n" 143 | " \n" 144 | " \n" 145 | " \n" 146 | " \n" 147 | " \n" 148 | " \n" 149 | " \n" 150 | " \n" 151 | " \n" 152 | " \n" 153 | " \n" 154 | " \n" 155 | " \n" 156 | " \n" 157 | " \n" 158 | " \n" 159 | " \n" 160 | " \n" 161 | " \n" 162 | " \n" 163 | " \n" 164 | " \n" 165 | " \n" 166 | " \n" 167 | " \n" 168 | " \n" 169 | " \n" 170 | " \n" 171 | " \n" 172 | " \n" 173 | " \n" 174 | "\x94\xb3Y\xd0\0\0\0 cHRM\0\0z%\0\0\x80\x83\0\0\xf9\xff\0\0\x80\xe9\0\0u0\0\0\xea`\0\0:\x98\0\0\x17o\x92_\xc5""F\0\0\x03\0PLTE\0\0\0\xff\xff\xff\xef\xef\xef\xdf\xdf\xdf\xcf\xcf\xcf\xbf\xbf\xbf\xaf\xaf\xaf\x9f\x9f\x9f\x8f\x8f\x8f\x80" 175 | "\x80\x80\xff\xff\xff\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" 176 | "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" 177 | "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" 178 | "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" 179 | "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" 180 | "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\xd4\x83\x03" 181 | "\xfc\0\0\0\x0btRNS\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\0JO\x01\xf2\0\0\x03\x1dIDATx\xda\xec\xdc\xdbr\xa2@\x14@\xd1\x1c\xa0\x81>\xff\xff\xc1\xf3\xe0\x05T\xe2%:\x02Uk=)\x86\xb6JjGll\x7f\x12\xd8\xad\x1f/\x01\x08\x18\x10""0 `\x10""0 `@\xc0\x80\x80""A" 182 | "\xc0\x80\x80\x01\x01\x83\x80\x01\x01\x03\x02\x06\x04\x0c\x02\x06\x04\x0c\x08\x18\x10""0\x08\x18\x10""0 `\x10""0 `@\xc0\x80\x80""A\xc0\x80\x80\x01\x01\x03\x02\x06\x01\x03\x02\x06\x04\x0c\x02\x06\x04\x0c\x08\x18\x10""0\x08\x18\x10""0 `\x10""0 `@\xc0\x80" 183 | "\x80""A\xc0\x80\x80\x01\x01\x03\x02\x06\x01\x03\x02\x06\x04\x0c\x02\x06\x04\x0c\x08\x18\x10""0\x08\x18\x10""0 `\xbe,\"\"\xbc\x0c\x02\xe6\xe9R\x9e\xb8u\x9f\x80\x05\x8c\x80\x05,`6\x10\xf0\xf4@S\x04,`v\x1bpD4U\xc0\x02""f\xb7\x01G\x14\x01\x0b\x98\xd5\x02" 184 | "\xfe\xe3\xc8""3\xbd\x80\x05\xcc\xce\x02.\xa5\x94\xe6\x0f\x93\\\x02\x16""0\x1b\x08\xf8p\xb3\x8f\x88\x88V\xc0\x02""f\x8f\x01\xe7\xf0\xea@\x02\x16""0\xdb\t8\xdb\x88\x88*`\x01\xb3N\xc0\x7f\x9c\x85>\xdd\xa9/ND\x0bX\xc0l(\xe0\x14\xb0\x80\x11""0\x02""f\x85\x80" 185 | "\x87\x88\x88\xe1z\xeb\xc5\xdf\xf9-\xe0\xe6r\x94\xc3\xcd\xf1\xb8mp\x9c\x04\xcc[\x01\xbf""3\xf2)\xcf;\x01""7W\xff\x07\"\"\xa2\x9b\xbeJ\xed@\t\x98\xb5\x02\xeeg\xef\xa3\xcb\x01\xf7\xb3""7\xf2v\xe9\r\xbfs\xa4\x04\xcc\xf7" 186 | "\x03\x9e/Hztb=\xe6p\x9e\xe9\xfa\xaf\x8b\x8d\x11\xb0\x80_\r\xb8y\xf4\xc9x\xc8\xccl.w\xae\x99Y^_\n" 187 | "\x81\x80\x05\xfc\xd9\x80\xdb|\x14pw\xbbsNg\xe0>\x05\x0b\x98""7\x02~o=p[\xf3""a\xc0\xb3?:n\x18\x96\xf6""A\xc0|-\xe0RJ\xa9\xcb\xcf""7\xbf\xd3\xc6\xd5z\xa5_/\x17#`\xbe\x17\xf0\x9d\xe7[\x1c\xbe\x15\xb0\x80\xd9_\xc0\xd3\x85\xe0\"`\x01\xb3\xbb\x80\xb3""6\xf3" 188 | "\x82\x05,`>\x19\xf0;#?\x15\xf0\x94\xb0\x80\x05\xcc\x0e\x03>\xfdpG/`\x01\xb3\x97\x80/.\xf0\xf6\xa7sh\x01\x0b\x98-\x06\xdc\xcc~[\xa7\x9f&\xad\x86\xc3_V\x01\x0b\x98-\x07\xdc_\xaf\x19\x1c\x8f\xa7\xce%\xf3\xf8\xb5I\xa7\xd0\x02\xe6\xd3\x01\x7fj\x16\xfa""8P" 189 | "Wk\x17\xd7_\xc4\xaa\xc5$\x96\x80\xd9v\xc0\xe5r\xa7""1\xf3""4yu\xb3\x9cP\xc0\x02""fk\x01g\xb7\xb0\xce\xb7\x8d\xa5\x05\xfd\x02\x16""0\x9b\x0bx\xbez\x7f\xbc\xa9\xfa\xee\xaa""C\x04\xcc\xea\x01g\x0emDD7\xce""6\x1d>\x12\x9f\x17$\tX\xc0\x80\x80\x01\x01\x83\x80" 190 | "\x01\x01\x03\x02\x06\x01\x03\x02\x06\x04\x0c\x08\x18\x04\x0c\x08\x18\x10""0 `\x10""0 `@\xc0 `@\xc0\x80\x80\x01\x01\x83\x80\x01\x01\x03\x02\x06\x04\x0c\x02\x06\x04\x0c\x08\x18\x04\x0c\x08\x18\x10""0 `\x10""0 `@\xc0 `@\xc0\x80\x80\x01\x01\x83\x80\x01\x01" 191 | "\x03\x02\x06\x04\x0c\x02\x06\x04\x0c\x08\x18\x04\x0c\x08\x18\x10""0 `\x10""0 `@\xc0\x80\x80""A\xc0\x80\x80\x01\x01\x83\x80\x01\x01\x03\x02\x06\x04\x0c\x02\x06\x04\x0c\x08\x18\x04\x0c\x08\x18\xf8\xbe\x7f\0\0\0\xff\xff\x03\0\xba\xf5\x1b\xed\xe7/i@\0\0\0" 192 | "\0IEND\xae""B`\x82"; 193 | 194 | const char* PushStartup_png = (const char*) temp_binary_data_0; 195 | 196 | 197 | const char* getNamedResource (const char*, int&) throw(); 198 | const char* getNamedResource (const char* resourceNameUTF8, int& numBytes) throw() 199 | { 200 | unsigned int hash = 0; 201 | if (resourceNameUTF8 != 0) 202 | while (*resourceNameUTF8 != 0) 203 | hash = 31 * hash + (unsigned int) *resourceNameUTF8++; 204 | 205 | switch (hash) 206 | { 207 | case 0xc1e7b9cd: numBytes = 16112; return PushStartup_png; 208 | default: break; 209 | } 210 | 211 | numBytes = 0; 212 | return 0; 213 | } 214 | 215 | const char* namedResourceList[] = 216 | { 217 | "PushStartup_png" 218 | }; 219 | 220 | } 221 | -------------------------------------------------------------------------------- /JuceLibraryCode/BinaryData.h: -------------------------------------------------------------------------------- 1 | /* ========================================================================================= 2 | 3 | This is an auto-generated file: Any edits you make may be overwritten! 4 | 5 | */ 6 | 7 | #ifndef BINARYDATA_H_75001147_INCLUDED 8 | #define BINARYDATA_H_75001147_INCLUDED 9 | 10 | namespace BinaryData 11 | { 12 | extern const char* PushStartup_png; 13 | const int PushStartup_pngSize = 16112; 14 | 15 | // Points to the start of a list of resource names. 16 | extern const char* namedResourceList[]; 17 | 18 | // Number of elements in the namedResourceList array. 19 | const int namedResourceListSize = 1; 20 | 21 | // If you provide the name of one of the binary resource variables above, this function will 22 | // return the corresponding data and its size (or a null pointer if the name isn't found). 23 | const char* getNamedResource (const char* resourceNameUTF8, int& dataSizeInBytes) throw(); 24 | } 25 | 26 | #endif 27 | -------------------------------------------------------------------------------- /JuceLibraryCode/JuceHeader.h: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | IMPORTANT! This file is auto-generated each time you save your 4 | project - if you alter its contents, your changes may be overwritten! 5 | 6 | This is the header file that your files should include in order to get all the 7 | JUCE library headers. You should avoid including the JUCE headers directly in 8 | your own source files, because that wouldn't pick up the correct configuration 9 | options for your app. 10 | 11 | */ 12 | 13 | #ifndef __APPHEADERFILE_KHUPU8__ 14 | #define __APPHEADERFILE_KHUPU8__ 15 | 16 | #include "AppConfig.h" 17 | 18 | #include 19 | #include 20 | #include 21 | #include 22 | #include 23 | #include 24 | #include 25 | #include 26 | #include 27 | #include 28 | #include 29 | #include 30 | 31 | #include "BinaryData.h" 32 | 33 | #if ! DONT_SET_USING_JUCE_NAMESPACE 34 | // If your code uses a lot of JUCE classes, then this will obviously save you 35 | // a lot of typing, but can be disabled by setting DONT_SET_USING_JUCE_NAMESPACE. 36 | using namespace juce; 37 | #endif 38 | 39 | #if ! JUCE_DONT_DECLARE_PROJECTINFO 40 | namespace ProjectInfo 41 | { 42 | const char* const projectName = "juce2push2"; 43 | const char* const versionString = "1.0.0"; 44 | const int versionNumber = 0x10000; 45 | } 46 | #endif 47 | 48 | #endif // __APPHEADERFILE_KHUPU8__ 49 | -------------------------------------------------------------------------------- /JuceLibraryCode/ReadMe.txt: -------------------------------------------------------------------------------- 1 | 2 | Important Note!! 3 | ================ 4 | 5 | The purpose of this folder is to contain files that are auto-generated by the Projucer, 6 | and ALL files in this folder will be mercilessly DELETED and completely re-written whenever 7 | the Projucer saves your project. 8 | 9 | Therefore, it's a bad idea to make any manual changes to the files in here, or to 10 | put any of your own files in here if you don't want to lose them. (Of course you may choose 11 | to add the folder's contents to your version-control system so that you can re-merge your own 12 | modifications after the Projucer has saved its changes). 13 | -------------------------------------------------------------------------------- /JuceLibraryCode/juce_audio_basics.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | IMPORTANT! This file is auto-generated each time you save your 4 | project - if you alter its contents, your changes may be overwritten! 5 | 6 | */ 7 | 8 | #include "AppConfig.h" 9 | #include 10 | -------------------------------------------------------------------------------- /JuceLibraryCode/juce_audio_basics.mm: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | IMPORTANT! This file is auto-generated each time you save your 4 | project - if you alter its contents, your changes may be overwritten! 5 | 6 | */ 7 | 8 | #include "AppConfig.h" 9 | #include 10 | -------------------------------------------------------------------------------- /JuceLibraryCode/juce_audio_devices.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | IMPORTANT! This file is auto-generated each time you save your 4 | project - if you alter its contents, your changes may be overwritten! 5 | 6 | */ 7 | 8 | #include "AppConfig.h" 9 | #include 10 | -------------------------------------------------------------------------------- /JuceLibraryCode/juce_audio_devices.mm: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | IMPORTANT! This file is auto-generated each time you save your 4 | project - if you alter its contents, your changes may be overwritten! 5 | 6 | */ 7 | 8 | #include "AppConfig.h" 9 | #include 10 | -------------------------------------------------------------------------------- /JuceLibraryCode/juce_audio_formats.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | IMPORTANT! This file is auto-generated each time you save your 4 | project - if you alter its contents, your changes may be overwritten! 5 | 6 | */ 7 | 8 | #include "AppConfig.h" 9 | #include 10 | -------------------------------------------------------------------------------- /JuceLibraryCode/juce_audio_formats.mm: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | IMPORTANT! This file is auto-generated each time you save your 4 | project - if you alter its contents, your changes may be overwritten! 5 | 6 | */ 7 | 8 | #include "AppConfig.h" 9 | #include 10 | -------------------------------------------------------------------------------- /JuceLibraryCode/juce_audio_processors.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | IMPORTANT! This file is auto-generated each time you save your 4 | project - if you alter its contents, your changes may be overwritten! 5 | 6 | */ 7 | 8 | #include "AppConfig.h" 9 | #include 10 | -------------------------------------------------------------------------------- /JuceLibraryCode/juce_audio_processors.mm: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | IMPORTANT! This file is auto-generated each time you save your 4 | project - if you alter its contents, your changes may be overwritten! 5 | 6 | */ 7 | 8 | #include "AppConfig.h" 9 | #include 10 | -------------------------------------------------------------------------------- /JuceLibraryCode/juce_audio_utils.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | IMPORTANT! This file is auto-generated each time you save your 4 | project - if you alter its contents, your changes may be overwritten! 5 | 6 | */ 7 | 8 | #include "AppConfig.h" 9 | #include 10 | -------------------------------------------------------------------------------- /JuceLibraryCode/juce_audio_utils.mm: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | IMPORTANT! This file is auto-generated each time you save your 4 | project - if you alter its contents, your changes may be overwritten! 5 | 6 | */ 7 | 8 | #include "AppConfig.h" 9 | #include 10 | -------------------------------------------------------------------------------- /JuceLibraryCode/juce_core.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | IMPORTANT! This file is auto-generated each time you save your 4 | project - if you alter its contents, your changes may be overwritten! 5 | 6 | */ 7 | 8 | #include "AppConfig.h" 9 | #include 10 | -------------------------------------------------------------------------------- /JuceLibraryCode/juce_core.mm: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | IMPORTANT! This file is auto-generated each time you save your 4 | project - if you alter its contents, your changes may be overwritten! 5 | 6 | */ 7 | 8 | #include "AppConfig.h" 9 | #include 10 | -------------------------------------------------------------------------------- /JuceLibraryCode/juce_cryptography.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | IMPORTANT! This file is auto-generated each time you save your 4 | project - if you alter its contents, your changes may be overwritten! 5 | 6 | */ 7 | 8 | #include "AppConfig.h" 9 | #include 10 | -------------------------------------------------------------------------------- /JuceLibraryCode/juce_cryptography.mm: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | IMPORTANT! This file is auto-generated each time you save your 4 | project - if you alter its contents, your changes may be overwritten! 5 | 6 | */ 7 | 8 | #include "AppConfig.h" 9 | #include 10 | -------------------------------------------------------------------------------- /JuceLibraryCode/juce_data_structures.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | IMPORTANT! This file is auto-generated each time you save your 4 | project - if you alter its contents, your changes may be overwritten! 5 | 6 | */ 7 | 8 | #include "AppConfig.h" 9 | #include 10 | -------------------------------------------------------------------------------- /JuceLibraryCode/juce_data_structures.mm: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | IMPORTANT! This file is auto-generated each time you save your 4 | project - if you alter its contents, your changes may be overwritten! 5 | 6 | */ 7 | 8 | #include "AppConfig.h" 9 | #include 10 | -------------------------------------------------------------------------------- /JuceLibraryCode/juce_events.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | IMPORTANT! This file is auto-generated each time you save your 4 | project - if you alter its contents, your changes may be overwritten! 5 | 6 | */ 7 | 8 | #include "AppConfig.h" 9 | #include 10 | -------------------------------------------------------------------------------- /JuceLibraryCode/juce_events.mm: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | IMPORTANT! This file is auto-generated each time you save your 4 | project - if you alter its contents, your changes may be overwritten! 5 | 6 | */ 7 | 8 | #include "AppConfig.h" 9 | #include 10 | -------------------------------------------------------------------------------- /JuceLibraryCode/juce_graphics.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | IMPORTANT! This file is auto-generated each time you save your 4 | project - if you alter its contents, your changes may be overwritten! 5 | 6 | */ 7 | 8 | #include "AppConfig.h" 9 | #include 10 | -------------------------------------------------------------------------------- /JuceLibraryCode/juce_graphics.mm: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | IMPORTANT! This file is auto-generated each time you save your 4 | project - if you alter its contents, your changes may be overwritten! 5 | 6 | */ 7 | 8 | #include "AppConfig.h" 9 | #include 10 | -------------------------------------------------------------------------------- /JuceLibraryCode/juce_gui_basics.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | IMPORTANT! This file is auto-generated each time you save your 4 | project - if you alter its contents, your changes may be overwritten! 5 | 6 | */ 7 | 8 | #include "AppConfig.h" 9 | #include 10 | -------------------------------------------------------------------------------- /JuceLibraryCode/juce_gui_basics.mm: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | IMPORTANT! This file is auto-generated each time you save your 4 | project - if you alter its contents, your changes may be overwritten! 5 | 6 | */ 7 | 8 | #include "AppConfig.h" 9 | #include 10 | -------------------------------------------------------------------------------- /JuceLibraryCode/juce_gui_extra.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | IMPORTANT! This file is auto-generated each time you save your 4 | project - if you alter its contents, your changes may be overwritten! 5 | 6 | */ 7 | 8 | #include "AppConfig.h" 9 | #include 10 | -------------------------------------------------------------------------------- /JuceLibraryCode/juce_gui_extra.mm: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | IMPORTANT! This file is auto-generated each time you save your 4 | project - if you alter its contents, your changes may be overwritten! 5 | 6 | */ 7 | 8 | #include "AppConfig.h" 9 | #include 10 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2017 Ableton AG, Berlin 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy 4 | of this software and associated documentation files (the "Software"), to deal 5 | in the Software without restriction, including without limitation the rights 6 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | copies of the Software, and to permit persons to whom the Software is 8 | furnished to do so, subject to the following conditions: 9 | 10 | The above copyright notice and this permission notice shall be included in 11 | all copies or substantial portions of the Software. 12 | 13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 19 | THE SOFTWARE. 20 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # ARCHIVED REPOSITORY # 2 | 3 | This project is no longer being actively maintained and has been archived. The 4 | source code is still available for those who may find it useful. 5 | 6 | ## About this repository ## 7 | 8 | This repository contains C++ source code that demonstrates how to communicate 9 | with Ableton's Push 2 display. The example uses [JUCE](https://www.juce.com/), 10 | allowing the use of all the existing 11 | [juce::Graphics](https://www.juce.com/doc/classGraphics) methods to render the 12 | content of the display. Thanks to JUCE, it is also cross-platform and can be 13 | compiled using MacOS, Windows, and Linux. 14 | 15 | Together with our 16 | [Push interface description](https://github.com/Ableton/push-interface), this 17 | enables you to take full control of Push to develop custom software. 18 | 19 | To get an idea of what this can allow you to do, 20 | [here's an example video](https://www.youtube.com/watch?v=9HuNeQQoEmM) of 21 | Mutable Instrument's drum sequencer "Grid" running standalone on a Raspberry Pi 22 | driven from a Push 2. 23 | 24 | 25 | ### Note ### 26 | 27 | The low-level classes used to communicate with the display are _not_ tied to 28 | JUCE in any way. This means they can be extracted from this example and used in 29 | another framework if desired. 30 | 31 | 32 | ### License ### 33 | 34 | This software is distributed under the [MIT License](./LICENSE). 35 | 36 | 37 | ### Dependencies ### 38 | 39 | In order to communicate over USB, this example uses 40 | [libusb](http://www.libusb.org/). On MacOS and Windows, libusb is compiled as 41 | part of the example. On Linux, you will need to use your favorite package 42 | manager to install the development package; for example, 43 | 44 | `sudo apt-get install libusb-1.0-0-dev` 45 | 46 | Note that if you ship an application using libusb, you should ensure that you 47 | respect their 48 | [licensing terms](http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html). 49 | 50 | On Linux, you will also need to 51 | [fetch the packages needed for JUCE](https://forum.juce.com/t/list-of-juce-dependencies-under-linux/15121). 52 | 53 | 54 | ## How do I get set up? ## 55 | 56 | ### Setting up the repository ### 57 | 58 | Clone the repo (including the submodules for JUCE and libusb): 59 | 60 | `git clone --recurse-submodules https://github.com/Ableton/push2-display-with-juce.git` 61 | 62 | 63 | ### Building ### 64 | 65 | The example uses the standard JUCE folder structure and, although it doesn't 66 | make any sound, is based on the "Audio Application" template from the 67 | Introjucer. 68 | 69 | There are projects ready for Xcode and Visual Studio 2013, as well as a Linux 70 | Makefile-based system, all located in the `Builds` folder. 71 | 72 | 73 | ### Running ### 74 | 75 | Once the program is compiled, running it will open a window on the computer's 76 | screen and display an animation on the Push display. As a bonus, the computer 77 | window will display MIDI messages generated by touching the Push 2 pads, 78 | buttons, and knobs. 79 | 80 | **Note that by default on Linux, the USB port can only be used by root. Unless 81 | you change the device's permissions, you will need to sudo to execute the 82 | binary.** 83 | 84 | `cd Builds/LinuxMakefile/` 85 | 86 | `make` 87 | 88 | `sudo ./build/juce2push2` 89 | 90 | 91 | ### Customization ### 92 | 93 | If you would like to quickly hack some drawing of your own, have a look at the 94 | `Demo::drawFrame()` method in `juce2push2/Source/Push2Demo.cpp`. 95 | 96 | ### Maintainers ### 97 | 98 | * [@mre-ableton](https://github.com/mre-ableton) 99 | 100 | Happy coding! 101 | -------------------------------------------------------------------------------- /Resources/PushStartup.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Ableton/push2-display-with-juce/48e9be846bda686b97a0df7635d80e63a51a5e4b/Resources/PushStartup.png -------------------------------------------------------------------------------- /Source/Macros.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2017 Ableton AG, Berlin 2 | // 3 | // Permission is hereby granted, free of charge, to any person obtaining a 4 | // copy of this software and associated documentation files (the "Software"), 5 | // to deal in the Software without restriction, including without limitation 6 | // the rights to use, copy, modify, merge, publish, distribute, sublicense, 7 | // and/or sell copies of the Software, and to permit persons to whom the 8 | // Software is furnished to do so, subject to the following conditions: 9 | // 10 | // The above copyright notice and this permission notice shall be included in 11 | // all copies or substantial portions of the Software. 12 | // 13 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 16 | // THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 18 | // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 19 | // DEALINGS IN THE SOFTWARE. 20 | 21 | #pragma once 22 | 23 | #define MUnused(x) ((void) x) 24 | #define K(x) true 25 | -------------------------------------------------------------------------------- /Source/Main.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2017 Ableton AG, Berlin 2 | // 3 | // Permission is hereby granted, free of charge, to any person obtaining a 4 | // copy of this software and associated documentation files (the "Software"), 5 | // to deal in the Software without restriction, including without limitation 6 | // the rights to use, copy, modify, merge, publish, distribute, sublicense, 7 | // and/or sell copies of the Software, and to permit persons to whom the 8 | // Software is furnished to do so, subject to the following conditions: 9 | // 10 | // The above copyright notice and this permission notice shall be included in 11 | // all copies or substantial portions of the Software. 12 | // 13 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 16 | // THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 18 | // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 19 | // DEALINGS IN THE SOFTWARE. 20 | 21 | /* 22 | ============================================================================== 23 | 24 | This file was auto-generated by the Introjucer! 25 | 26 | It contains the basic startup code for a Juce application. 27 | 28 | ============================================================================== 29 | */ 30 | 31 | #include "../JuceLibraryCode/JuceHeader.h" 32 | #include "Macros.h" 33 | 34 | Component* createMainContentComponent(); 35 | 36 | //============================================================================== 37 | class juce2push2Application : public JUCEApplication 38 | { 39 | public: 40 | //============================================================================== 41 | juce2push2Application() {} 42 | 43 | const String getApplicationName() override { return ProjectInfo::projectName; } 44 | const String getApplicationVersion() override { return ProjectInfo::versionString; } 45 | bool moreThanOneInstanceAllowed() override { return true; } 46 | 47 | //============================================================================== 48 | void initialise (const String& commandLine) override 49 | { 50 | // This method is where you should put your application's initialisation code.. 51 | 52 | MUnused(commandLine); 53 | mainWindow = new MainWindow (getApplicationName()); 54 | } 55 | 56 | void shutdown() override 57 | { 58 | // Add your application's shutdown code here.. 59 | 60 | mainWindow = nullptr; // (deletes our window) 61 | } 62 | 63 | //============================================================================== 64 | void systemRequestedQuit() override 65 | { 66 | // This is called when the app is being asked to quit: you can ignore this 67 | // request and let the app carry on running, or call quit() to allow the app to close. 68 | quit(); 69 | } 70 | 71 | void anotherInstanceStarted (const String& commandLine) override 72 | { 73 | // When another instance of the app is launched while this one is running, 74 | // this method is invoked, and the commandLine parameter tells you what 75 | // the other instance's command-line arguments were. 76 | MUnused(commandLine); 77 | } 78 | 79 | //============================================================================== 80 | /* 81 | This class implements the desktop window that contains an instance of 82 | our MainContentComponent class. 83 | */ 84 | class MainWindow : public DocumentWindow 85 | { 86 | public: 87 | MainWindow (String name) : DocumentWindow (name, 88 | Colours::lightgrey, 89 | DocumentWindow::allButtons) 90 | { 91 | setUsingNativeTitleBar (true); 92 | setContentOwned (createMainContentComponent(), true); 93 | setResizable (true, true); 94 | 95 | centreWithSize (getWidth(), getHeight()); 96 | setVisible (true); 97 | } 98 | 99 | void closeButtonPressed() override 100 | { 101 | // This is called when the user tries to close this window. Here, we'll just 102 | // ask the app to quit when this happens, but you can change this to do 103 | // whatever you need. 104 | JUCEApplication::getInstance()->systemRequestedQuit(); 105 | } 106 | 107 | /* Note: Be careful if you override any DocumentWindow methods - the base 108 | class uses a lot of them, so by overriding you might break its functionality. 109 | It's best to do all your work in your content component instead, but if 110 | you really have to override any DocumentWindow methods, make sure your 111 | subclass also calls the superclass's method. 112 | */ 113 | 114 | private: 115 | JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (MainWindow) 116 | }; 117 | 118 | private: 119 | ScopedPointer mainWindow; 120 | }; 121 | 122 | //============================================================================== 123 | // This macro generates the main() routine that launches the app. 124 | START_JUCE_APPLICATION (juce2push2Application) 125 | -------------------------------------------------------------------------------- /Source/MainComponent.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2017 Ableton AG, Berlin 2 | // 3 | // Permission is hereby granted, free of charge, to any person obtaining a 4 | // copy of this software and associated documentation files (the "Software"), 5 | // to deal in the Software without restriction, including without limitation 6 | // the rights to use, copy, modify, merge, publish, distribute, sublicense, 7 | // and/or sell copies of the Software, and to permit persons to whom the 8 | // Software is furnished to do so, subject to the following conditions: 9 | // 10 | // The above copyright notice and this permission notice shall be included in 11 | // all copies or substantial portions of the Software. 12 | // 13 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 16 | // THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 18 | // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 19 | // DEALINGS IN THE SOFTWARE. 20 | 21 | /* 22 | ============================================================================== 23 | 24 | This file was auto-generated! 25 | 26 | ============================================================================== 27 | */ 28 | 29 | #ifndef MAINCOMPONENT_H_INCLUDED 30 | #define MAINCOMPONENT_H_INCLUDED 31 | 32 | #include "../JuceLibraryCode/JuceHeader.h" 33 | #include "../JuceLibraryCode/BinaryData.h" 34 | 35 | #include "Push2Demo.h" 36 | #include "Macros.h" 37 | 38 | #include 39 | #include 40 | #include 41 | 42 | //============================================================================== 43 | /* 44 | This component lives inside our window, and this is where you should put all 45 | your controls and content. 46 | */ 47 | class MainContentComponent : public AudioAppComponent 48 | { 49 | public: 50 | //============================================================================== 51 | MainContentComponent() 52 | { 53 | setSize (960, 600); 54 | 55 | // specify the number of input and output channels that we want to open 56 | setAudioChannels (2, 2); 57 | 58 | // Initialize a label to show the status of the connection 59 | status_.setColour(Label::textColourId, Colours::white); 60 | status_.setJustificationType(Justification::bottomLeft); 61 | addAndMakeVisible(status_); 62 | 63 | // Starts the demo class animating the display 64 | NBase::Result result = demo_.Init(); 65 | if (result.Succeeded()) 66 | { 67 | status_.setText("Push 2 connected", juce::dontSendNotification); 68 | demo_.SetMidiInputCallback( 69 | [this](const MidiMessage& message) 70 | { 71 | this->processMidiInput(message); 72 | }); 73 | } 74 | else 75 | { 76 | status_.setText(result.GetDescription(), juce::dontSendNotification); 77 | } 78 | } 79 | 80 | ~MainContentComponent() 81 | { 82 | shutdownAudio(); 83 | } 84 | 85 | void processMidiInput(const MidiMessage& message) 86 | { 87 | if (message.getRawDataSize() == 3) 88 | { 89 | auto data = message.getRawData(); 90 | std::ostringstream oss; 91 | oss << "Midi (" 92 | << message.getTimeStamp() << ") :" 93 | << "0x" << std::uppercase << std::setfill('0') << std::setw(2) << std::hex << int(data[0]) << " - " 94 | << "0x" << std::uppercase << std::setfill('0') << std::setw(2) << std::hex << int(data[1]) << " - " 95 | << "0x" << std::uppercase << std::setfill('0') << std::setw(2) << std::hex << int(data[2]); 96 | 97 | midiMessageStack_.push_back(oss.str()); 98 | if (midiMessageStack_.size() > 4) 99 | { 100 | midiMessageStack_.pop_front(); 101 | } 102 | 103 | const MessageManagerLock lock; 104 | 105 | std::string status; 106 | for (auto s : midiMessageStack_) 107 | { 108 | status += s + "\n"; 109 | } 110 | status_.setText(status, juce::dontSendNotification); 111 | } 112 | } 113 | 114 | //======================================================================= 115 | void prepareToPlay (int samplesPerBlockExpected, double sampleRate) override 116 | { 117 | // This function will be called when the audio device is started, or when 118 | // its settings (i.e. sample rate, block size, etc) are changed. 119 | 120 | // You can use this function to initialise any resources you might need, 121 | // but be careful - it will be called on the audio thread, not the GUI thread. 122 | 123 | // For more details, see the help for AudioProcessor::prepareToPlay() 124 | 125 | MUnused(samplesPerBlockExpected); 126 | MUnused(sampleRate); 127 | 128 | } 129 | 130 | void getNextAudioBlock (const AudioSourceChannelInfo& bufferToFill) override 131 | { 132 | // Your audio-processing code goes here! 133 | 134 | // For more details, see the help for AudioProcessor::getNextAudioBlock() 135 | 136 | // Right now we are not producing any data, in which case we need to clear the buffer 137 | // (to prevent the output of random noise) 138 | bufferToFill.clearActiveBufferRegion(); 139 | } 140 | 141 | void releaseResources() override 142 | { 143 | // This will be called when the audio device stops, or when it is being 144 | // restarted due to a setting change. 145 | 146 | // For more details, see the help for AudioProcessor::releaseResources() 147 | } 148 | 149 | //======================================================================= 150 | void paint (Graphics& g) override 151 | { 152 | // (Our component is opaque, so we must completely fill the background with a solid colour) 153 | g.fillAll (Colours::black); 154 | 155 | auto logo = ImageCache::getFromMemory(BinaryData::PushStartup_png, BinaryData::PushStartup_pngSize); 156 | g.drawImageAt(logo, (getWidth() - logo.getWidth()) / 2 , (getHeight() - logo.getHeight()) / 2); 157 | } 158 | 159 | void resized() override 160 | { 161 | const int kStatusSize = 100; 162 | status_.setBounds(0, getHeight() - kStatusSize, getWidth(), kStatusSize); 163 | } 164 | 165 | 166 | private: 167 | //============================================================================== 168 | 169 | // Your private member variables go here... 170 | 171 | Demo demo_; 172 | Label status_; 173 | std::deque midiMessageStack_; 174 | 175 | JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (MainContentComponent) 176 | }; 177 | 178 | 179 | // (This function is called by the app startup code to create our main component) 180 | Component* createMainContentComponent() { return new MainContentComponent(); } 181 | 182 | 183 | #endif // MAINCOMPONENT_H_INCLUDED 184 | -------------------------------------------------------------------------------- /Source/Push2Demo.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2017 Ableton AG, Berlin 2 | // 3 | // Permission is hereby granted, free of charge, to any person obtaining a 4 | // copy of this software and associated documentation files (the "Software"), 5 | // to deal in the Software without restriction, including without limitation 6 | // the rights to use, copy, modify, merge, publish, distribute, sublicense, 7 | // and/or sell copies of the Software, and to permit persons to whom the 8 | // Software is furnished to do so, subject to the following conditions: 9 | // 10 | // The above copyright notice and this permission notice shall be included in 11 | // all copies or substantial portions of the Software. 12 | // 13 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 16 | // THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 18 | // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 19 | // DEALINGS IN THE SOFTWARE. 20 | 21 | #include "Push2Demo.h" 22 | #include 23 | 24 | //------------------------------------------------------------------------------ 25 | 26 | namespace 27 | { 28 | bool SMatchSubStringNoCase(const std::string& haystack, const std::string& needle) 29 | { 30 | auto it = std::search( 31 | haystack.begin(), haystack.end(), 32 | needle.begin(), needle.end(), 33 | [](char ch1, char ch2) // case insensitive 34 | { 35 | return std::toupper(ch1) == std::toupper(ch2); 36 | }); 37 | return it != haystack.end(); 38 | } 39 | } 40 | 41 | 42 | //------------------------------------------------------------------------------ 43 | 44 | NBase::Result Demo::Init() 45 | { 46 | // First we initialise the low level push2 object 47 | NBase::Result result = push2Display_.Init(); 48 | RETURN_IF_FAILED_MESSAGE(result, "Failed to init push2"); 49 | 50 | // Then we initialise the juce to push bridge 51 | result = bridge_.Init(push2Display_); 52 | RETURN_IF_FAILED_MESSAGE(result, "Failed to init bridge"); 53 | 54 | // Initialises the midi input 55 | result = openMidiDevice(); 56 | RETURN_IF_FAILED_MESSAGE(result, "Failed to open midi device"); 57 | 58 | // Reset elapsed time 59 | elapsed_ = 0; 60 | 61 | // Start the timer to draw the animation 62 | startTimerHz(60); 63 | 64 | return NBase::Result::NoError; 65 | } 66 | 67 | 68 | //------------------------------------------------------------------------------ 69 | 70 | NBase::Result Demo::openMidiDevice() 71 | { 72 | // Look for an input device matching push 2 73 | 74 | auto devices = MidiInput::getDevices(); 75 | int deviceIndex = -1; 76 | int index = 0; 77 | for (auto& device: devices) 78 | { 79 | if (SMatchSubStringNoCase(device.toStdString(), "ableton push 2")) 80 | { 81 | deviceIndex = index; 82 | break; 83 | } 84 | index++; 85 | } 86 | 87 | if (deviceIndex == -1) 88 | { 89 | return NBase::Result("Failed to find input midi device for push2"); 90 | } 91 | 92 | // Try opening the device 93 | auto input = MidiInput::openDevice(deviceIndex, this); 94 | if (!input) 95 | { 96 | return NBase::Result("Failed to open input device"); 97 | } 98 | 99 | // Store and starts listening to the device 100 | midiInput_.reset(input); 101 | midiInput_->start(); 102 | 103 | return NBase::Result::NoError; 104 | } 105 | 106 | 107 | //------------------------------------------------------------------------------ 108 | 109 | void Demo::SetMidiInputCallback(const midicb_t& callback) 110 | { 111 | midiCallback_ = callback; 112 | } 113 | 114 | 115 | //------------------------------------------------------------------------------ 116 | 117 | void Demo::handleIncomingMidiMessage (MidiInput* /*source*/, const MidiMessage &message) 118 | { 119 | // if a callback has been set, forward the incoming message 120 | if (midiCallback_) 121 | { 122 | midiCallback_(message); 123 | } 124 | } 125 | 126 | 127 | //------------------------------------------------------------------------------ 128 | 129 | void Demo::timerCallback() 130 | { 131 | elapsed_ += 0.02f; 132 | drawFrame(); 133 | } 134 | 135 | 136 | //------------------------------------------------------------------------------ 137 | 138 | void Demo::drawFrame() 139 | { 140 | // Request a juce::Graphics from the bridge 141 | auto& g = bridge_.GetGraphic(); 142 | 143 | // Clear previous frame 144 | g.fillAll(juce::Colour(0xff000000)); 145 | 146 | // Create a path for the animated wave 147 | const auto height = ableton::Push2DisplayBitmap::kHeight; 148 | const auto width = ableton::Push2DisplayBitmap::kWidth; 149 | 150 | Path wavePath; 151 | 152 | const float waveStep = 10.0f; 153 | const float waveY = height * 0.44f; 154 | int i = 0; 155 | 156 | for (float x = waveStep * 0.5f; x < width; x += waveStep) 157 | { 158 | const float y1 = waveY + height * 0.10f * std::sin(i * 0.38f + elapsed_); 159 | const float y2 = waveY + height * 0.20f * std::sin(i * 0.20f + elapsed_ * 2.0f); 160 | 161 | wavePath.addLineSegment(Line(x, y1, x, y2), 2.0f); 162 | wavePath.addEllipse(x - waveStep * 0.3f, y1 - waveStep * 0.3f, waveStep * 0.6f, waveStep * 0.6f); 163 | wavePath.addEllipse(x - waveStep * 0.3f, y2 - waveStep * 0.3f, waveStep * 0.6f, waveStep * 0.6f); 164 | 165 | ++i; 166 | } 167 | 168 | // Draw the path 169 | g.setColour(juce::Colour::greyLevel(0.5f)); 170 | g.fillPath(wavePath); 171 | 172 | // Blit the logo on top 173 | auto logo = ImageCache::getFromMemory(BinaryData::PushStartup_png, BinaryData::PushStartup_pngSize); 174 | g.drawImageAt(logo, (width - logo.getWidth()) / 2 , (height - logo.getHeight()) / 2); 175 | 176 | // Tells the bridge we're done with drawing and the frame can be sent to the display 177 | bridge_.Flip(); 178 | } 179 | -------------------------------------------------------------------------------- /Source/Push2Demo.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2017 Ableton AG, Berlin 2 | // 3 | // Permission is hereby granted, free of charge, to any person obtaining a 4 | // copy of this software and associated documentation files (the "Software"), 5 | // to deal in the Software without restriction, including without limitation 6 | // the rights to use, copy, modify, merge, publish, distribute, sublicense, 7 | // and/or sell copies of the Software, and to permit persons to whom the 8 | // Software is furnished to do so, subject to the following conditions: 9 | // 10 | // The above copyright notice and this permission notice shall be included in 11 | // all copies or substantial portions of the Software. 12 | // 13 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 16 | // THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 18 | // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 19 | // DEALINGS IN THE SOFTWARE. 20 | 21 | #pragma once 22 | 23 | #include "push2/JuceToPush2DisplayBridge.h" 24 | #include 25 | 26 | /*! 27 | * A simple demo class that will draw some animation on the push display 28 | * and listen to incoming midi input from push 29 | */ 30 | 31 | class Demo 32 | : public Timer 33 | , public MidiInputCallback 34 | { 35 | public: 36 | 37 | /*! 38 | * Initialises and starts the demo 39 | * 40 | * \return the result of the initialisation process 41 | */ 42 | 43 | NBase::Result Init(); 44 | 45 | 46 | using midicb_t = std::function; 47 | 48 | /*! 49 | * Allows a client to hook a collback in order to process midi messages recieved from push2 50 | */ 51 | 52 | void SetMidiInputCallback(const midicb_t& func); 53 | 54 | private: 55 | 56 | /*! 57 | * renders a frame and send it to the push display 58 | */ 59 | 60 | void drawFrame(); 61 | 62 | /*! 63 | * look for the push 2 input device and starts listening to it 64 | * 65 | * \return the result of the initialisation process 66 | */ 67 | 68 | NBase::Result openMidiDevice(); 69 | 70 | /*! 71 | * the juce midi incoming message callback 72 | * @see juce::MidiInputCallback 73 | */ 74 | 75 | void handleIncomingMidiMessage (MidiInput *source, const MidiMessage &message) override; 76 | 77 | /*! 78 | * the juce timer callback 79 | * @see juce::Timer 80 | */ 81 | 82 | void timerCallback() override; 83 | 84 | 85 | private: 86 | ableton::Push2DisplayBridge bridge_; /*!< The bridge allowing to use juce::graphics for push */ 87 | ableton::Push2Display push2Display_; /*!< The low-level push2 class */ 88 | std::unique_ptr midiInput_; /*!< Push2's midi input */ 89 | midicb_t midiCallback_; /*!> The midi callback to call when incoming messages are recieved */ 90 | float elapsed_; /*!> Fake elapsed time used for the animation */ 91 | }; -------------------------------------------------------------------------------- /Source/Result.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2017 Ableton AG, Berlin 2 | // 3 | // Permission is hereby granted, free of charge, to any person obtaining a 4 | // copy of this software and associated documentation files (the "Software"), 5 | // to deal in the Software without restriction, including without limitation 6 | // the rights to use, copy, modify, merge, publish, distribute, sublicense, 7 | // and/or sell copies of the Software, and to permit persons to whom the 8 | // Software is furnished to do so, subject to the following conditions: 9 | // 10 | // The above copyright notice and this permission notice shall be included in 11 | // all copies or substantial portions of the Software. 12 | // 13 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 16 | // THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 18 | // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 19 | // DEALINGS IN THE SOFTWARE. 20 | 21 | #include "Result.h" 22 | #include 23 | 24 | using namespace NBase; 25 | 26 | Result Result::NoError ; 27 | 28 | Result::Result() 29 | :success_(true) 30 | ,error_("success") 31 | ,checked_(true) 32 | ,child_(0){} 33 | 34 | Result::Result(const std::string &error) 35 | :success_(false) 36 | ,error_(error) 37 | ,checked_(false) 38 | ,child_(0) {} 39 | 40 | Result::Result(const std::ostringstream &error) 41 | :success_(false) 42 | ,error_(error.str()) 43 | ,checked_(false) 44 | ,child_(0) {} 45 | 46 | Result::Result(Result &cause,const std::string &error) 47 | :success_(false) 48 | ,error_(error) 49 | ,checked_(false) 50 | ,child_(new Result(cause)) { 51 | cause.checked_ = true ; 52 | child_->checked_ = true; 53 | } 54 | 55 | Result::Result(const Result &other) { 56 | success_=other.success_ ; 57 | error_=other.error_ ; 58 | checked_ = false ; 59 | other.checked_ = true ; 60 | child_ = other.child_ ; 61 | other.child_ = 0 ; 62 | } 63 | 64 | Result::~Result() { 65 | assert(checked_) ; 66 | delete(child_) ; 67 | } 68 | 69 | Result &Result::operator =(const Result &other) { 70 | success_=other.success_ ; 71 | error_=other.error_ ; 72 | checked_ = false ; 73 | other.checked_ = true ; 74 | child_ = other.child_ ; 75 | other.child_=0 ; 76 | return *this; 77 | } 78 | 79 | bool Result::Failed() { 80 | checked_= true ; 81 | return !success_ ; 82 | } 83 | 84 | bool Result::Succeeded() { 85 | checked_= true ; 86 | return success_ ; 87 | } 88 | 89 | std::string Result::GetDescription() { 90 | std::string description = error_ ; 91 | if (child_) { 92 | description+="\n>>>> " ; 93 | description+=child_->GetDescription() ; 94 | } 95 | return description ; 96 | } 97 | -------------------------------------------------------------------------------- /Source/Result.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2017 Ableton AG, Berlin 2 | // 3 | // Permission is hereby granted, free of charge, to any person obtaining a 4 | // copy of this software and associated documentation files (the "Software"), 5 | // to deal in the Software without restriction, including without limitation 6 | // the rights to use, copy, modify, merge, publish, distribute, sublicense, 7 | // and/or sell copies of the Software, and to permit persons to whom the 8 | // Software is furnished to do so, subject to the following conditions: 9 | // 10 | // The above copyright notice and this permission notice shall be included in 11 | // all copies or substantial portions of the Software. 12 | // 13 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 16 | // THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 18 | // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 19 | // DEALINGS IN THE SOFTWARE. 20 | 21 | #pragma once 22 | 23 | #include 24 | #include 25 | 26 | namespace NBase 27 | { 28 | class Result 29 | { 30 | public: 31 | 32 | Result(const std::string &error) ; 33 | Result(const std::ostringstream &error) ; 34 | Result(Result &cause,const std::string &error) ; 35 | ~Result() ; 36 | Result(const Result &other) ; 37 | 38 | bool Failed() ; 39 | bool Succeeded() ; 40 | std::string GetDescription() ; 41 | 42 | Result &operator=(const Result &) ; 43 | 44 | static Result NoError ; 45 | protected: 46 | Result() ; 47 | private: 48 | bool success_ ; 49 | std::string error_ ; 50 | mutable bool checked_ ; 51 | mutable Result *child_ ; 52 | }; 53 | } 54 | 55 | #define RETURN_IF_FAILED_MESSAGE(r,m) if (r.Failed()) { return NBase::Result(r,m) ; } 56 | #define RETURN_IF_FAILED(r) if (r.Failed()) { return r ; } 57 | #define LOG_IF_FAILED(r,m) if (r.Failed()) { NBase::Result __combined(r,m); Trace::Error(__combined.GetDescription().c_str()) ; __combined.Failed();} 58 | 59 | -------------------------------------------------------------------------------- /Source/libusb/config.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2017 Ableton AG, Berlin 2 | // 3 | // Permission is hereby granted, free of charge, to any person obtaining a 4 | // copy of this software and associated documentation files (the "Software"), 5 | // to deal in the Software without restriction, including without limitation 6 | // the rights to use, copy, modify, merge, publish, distribute, sublicense, 7 | // and/or sell copies of the Software, and to permit persons to whom the 8 | // Software is furnished to do so, subject to the following conditions: 9 | // 10 | // The above copyright notice and this permission notice shall be included in 11 | // all copies or substantial portions of the Software. 12 | // 13 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 16 | // THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 18 | // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 19 | // DEALINGS IN THE SOFTWARE. 20 | 21 | #if defined(__APPLE__) 22 | #include "config_xcode.h" 23 | #elif defined(WIN32) 24 | #include "config_msvc.h" 25 | #else 26 | #include "config_linux.h" 27 | #endif 28 | -------------------------------------------------------------------------------- /Source/libusb/config_msvc.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2017 Ableton AG, Berlin 2 | // 3 | // Permission is hereby granted, free of charge, to any person obtaining a 4 | // copy of this software and associated documentation files (the "Software"), 5 | // to deal in the Software without restriction, including without limitation 6 | // the rights to use, copy, modify, merge, publish, distribute, sublicense, 7 | // and/or sell copies of the Software, and to permit persons to whom the 8 | // Software is furnished to do so, subject to the following conditions: 9 | // 10 | // The above copyright notice and this permission notice shall be included in 11 | // all copies or substantial portions of the Software. 12 | // 13 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 16 | // THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 18 | // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 19 | // DEALINGS IN THE SOFTWARE. 20 | 21 | /* config.h. Manual config for MSVC. */ 22 | 23 | #ifndef _MSC_VER 24 | #warn "msvc/config.h shouldn't be included for your development environment." 25 | #error "Please make sure the msvc/ directory is removed from your build path." 26 | #endif 27 | 28 | /* Disable: warning C4200: nonstandard extension used : zero-sized array in struct/union */ 29 | #pragma warning(disable:4200) 30 | /* Disable: warning C6258: Using TerminateThread does not allow proper thread clean up */ 31 | #pragma warning(disable: 6258) 32 | #if defined(_PREFAST_) 33 | /* Disable "Banned API" errors when using the MS's WDK OACR/Prefast */ 34 | #pragma warning(disable:28719) 35 | /* Disable "The function 'InitializeCriticalSection' must be called from within a try/except block" */ 36 | #pragma warning(disable:28125) 37 | #endif 38 | 39 | /* Default visibility */ 40 | #define DEFAULT_VISIBILITY /**/ 41 | 42 | /* Enable global message logging */ 43 | //#define ENABLE_LOGGING 1 44 | 45 | /* Uncomment to start with debug message logging enabled */ 46 | // #define ENABLE_DEBUG_LOGGING 1 47 | 48 | /* Uncomment to enabling logging to system log */ 49 | // #define USE_SYSTEM_LOGGING_FACILITY 50 | 51 | /* type of second poll() argument */ 52 | #define POLL_NFDS_TYPE unsigned int 53 | 54 | /* Windows/WinCE backend */ 55 | #if defined(_WIN32_WCE) 56 | #define OS_WINCE 1 57 | #define HAVE_MISSING_H 58 | #else 59 | #define OS_WINDOWS 1 60 | #define HAVE_SIGNAL_H 1 61 | #define HAVE_SYS_TYPES_H 1 62 | #endif 63 | -------------------------------------------------------------------------------- /Source/libusb/config_xcode.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2017 Ableton AG, Berlin 2 | // 3 | // Permission is hereby granted, free of charge, to any person obtaining a 4 | // copy of this software and associated documentation files (the "Software"), 5 | // to deal in the Software without restriction, including without limitation 6 | // the rights to use, copy, modify, merge, publish, distribute, sublicense, 7 | // and/or sell copies of the Software, and to permit persons to whom the 8 | // Software is furnished to do so, subject to the following conditions: 9 | // 10 | // The above copyright notice and this permission notice shall be included in 11 | // all copies or substantial portions of the Software. 12 | // 13 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 16 | // THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 18 | // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 19 | // DEALINGS IN THE SOFTWARE. 20 | 21 | /* config.h. Manually generated for Xcode. */ 22 | 23 | /* Default visibility */ 24 | #define DEFAULT_VISIBILITY /**/ 25 | 26 | /* Message logging */ 27 | // #define ENABLE_LOGGING 1 28 | 29 | /* Define to 1 if you have the `gettimeofday' function. */ 30 | #define HAVE_GETTIMEOFDAY 1 31 | 32 | /* Define to 1 if you have the header file. */ 33 | #define HAVE_POLL_H 1 34 | 35 | /* Define to 1 if you have the header file. */ 36 | #define HAVE_SYS_TIME_H 1 37 | 38 | /* Darwin backend */ 39 | #define OS_DARWIN 1 40 | 41 | /* type of second poll() argument */ 42 | #define POLL_NFDS_TYPE nfds_t 43 | 44 | /* Use POSIX Threads */ 45 | #define THREADS_POSIX 1 46 | 47 | /* Use GNU extensions */ 48 | #define _GNU_SOURCE 1 49 | -------------------------------------------------------------------------------- /Source/libusb/libusb_platform_wrapper.c: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2017 Ableton AG, Berlin 2 | // 3 | // Permission is hereby granted, free of charge, to any person obtaining a 4 | // copy of this software and associated documentation files (the "Software"), 5 | // to deal in the Software without restriction, including without limitation 6 | // the rights to use, copy, modify, merge, publish, distribute, sublicense, 7 | // and/or sell copies of the Software, and to permit persons to whom the 8 | // Software is furnished to do so, subject to the following conditions: 9 | // 10 | // The above copyright notice and this permission notice shall be included in 11 | // all copies or substantial portions of the Software. 12 | // 13 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 16 | // THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 18 | // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 19 | // DEALINGS IN THE SOFTWARE. 20 | 21 | #ifdef _WIN32 22 | 23 | # include "core.c" 24 | # include "descriptor.c" 25 | # include "hotplug.c" 26 | # include "io.c" 27 | # include "strerror.c" 28 | # include "sync.c" 29 | 30 | # include "os/poll_windows.c" 31 | # include "os/threads_windows.c" 32 | # include "os/windows_winusb.c" 33 | # include "os/windows_nt_common.c" 34 | 35 | #elif defined(__APPLE__) 36 | 37 | # include "core.c" 38 | # include "descriptor.c" 39 | # include "hotplug.c" 40 | # include "io.c" 41 | # include "strerror.c" 42 | # include "sync.c" 43 | 44 | # include "os/darwin_usb.c" 45 | # include "os/poll_posix.c" 46 | # include "os/threads_posix.c" 47 | 48 | #else 49 | // On linux, we link directly to the system library installed through 50 | // apt-get / pacman or any other package manages 51 | #endif 52 | -------------------------------------------------------------------------------- /Source/push2/JuceToPush2DisplayBridge.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2017 Ableton AG, Berlin 2 | // 3 | // Permission is hereby granted, free of charge, to any person obtaining a 4 | // copy of this software and associated documentation files (the "Software"), 5 | // to deal in the Software without restriction, including without limitation 6 | // the rights to use, copy, modify, merge, publish, distribute, sublicense, 7 | // and/or sell copies of the Software, and to permit persons to whom the 8 | // Software is furnished to do so, subject to the following conditions: 9 | // 10 | // The above copyright notice and this permission notice shall be included in 11 | // all copies or substantial portions of the Software. 12 | // 13 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 16 | // THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 18 | // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 19 | // DEALINGS IN THE SOFTWARE. 20 | 21 | #include "JuceToPush2DisplayBridge.h" 22 | #include "Push2-Bitmap.h" 23 | #include "Macros.h" 24 | #include 25 | 26 | using namespace ableton; 27 | 28 | //------------------------------------------------------------------------------ 29 | 30 | Push2DisplayBridge::Push2DisplayBridge() 31 | : push2Display_(nullptr) 32 | , image_(Image::RGB, Push2DisplayBitmap::kWidth, Push2DisplayBitmap::kHeight, !K(clearImage)) 33 | , graphics_(image_) 34 | {}; 35 | 36 | 37 | //------------------------------------------------------------------------------ 38 | 39 | NBase::Result Push2DisplayBridge::Init(ableton::Push2Display& display) 40 | { 41 | push2Display_ = &display; 42 | return NBase::Result::NoError; 43 | } 44 | 45 | 46 | //------------------------------------------------------------------------------ 47 | 48 | juce::Graphics& Push2DisplayBridge::GetGraphic() 49 | { 50 | return graphics_; 51 | } 52 | 53 | 54 | //------------------------------------------------------------------------------ 55 | 56 | void Push2DisplayBridge::Flip() 57 | { 58 | // Make sure the class was properly initialised 59 | assert(push2Display_); 60 | 61 | // Create a bitmap data to access the pixel rgb values 62 | juce::Image::BitmapData bmData(image_, juce::Image::BitmapData::readOnly); 63 | 64 | // Create a push display bitmap and get access to the pixel data 65 | Push2DisplayBitmap g; 66 | Push2DisplayBitmap::pixel_t* data = g.PixelData(); 67 | 68 | const int sizex = std::min( g.GetWidth(), image_.getWidth()); 69 | const int sizey = std::min( g.GetHeight(), image_.getHeight()); 70 | 71 | 72 | // Convert the pixels, applying the xor masking needed for the display to work 73 | static const uint16_t xOrMasks[2] = { 0xf3e7, 0xffe7 }; 74 | 75 | for (int y = 0; y < sizey; y++) 76 | { 77 | for (int x = 0; x < sizex ; x++) 78 | { 79 | juce::Colour c = bmData.getPixelColour(x, y); 80 | const auto pixel = Push2DisplayBitmap::SPixelFromRGB(c.getRed(), c.getGreen(), c.getBlue()); 81 | *data++ = pixel ^ xOrMasks[x % 2]; 82 | } 83 | data += (g.GetWidth() - sizex); 84 | } 85 | 86 | // Send the constructed push2 bitmap to the display 87 | NBase::Result result = push2Display_->Flip(g); 88 | assert(result.Succeeded()); 89 | } 90 | 91 | 92 | -------------------------------------------------------------------------------- /Source/push2/JuceToPush2DisplayBridge.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2017 Ableton AG, Berlin 2 | // 3 | // Permission is hereby granted, free of charge, to any person obtaining a 4 | // copy of this software and associated documentation files (the "Software"), 5 | // to deal in the Software without restriction, including without limitation 6 | // the rights to use, copy, modify, merge, publish, distribute, sublicense, 7 | // and/or sell copies of the Software, and to permit persons to whom the 8 | // Software is furnished to do so, subject to the following conditions: 9 | // 10 | // The above copyright notice and this permission notice shall be included in 11 | // all copies or substantial portions of the Software. 12 | // 13 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 16 | // THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 18 | // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 19 | // DEALINGS IN THE SOFTWARE. 20 | 21 | #pragma once 22 | 23 | #include "Push2-Display.h" 24 | #include "../JuceLibraryCode/JuceHeader.h" 25 | 26 | namespace ableton 27 | { 28 | /*! 29 | * Implements a bridge between juce::Graphics and push2 display format. 30 | */ 31 | 32 | class Push2DisplayBridge 33 | { 34 | public: 35 | 36 | Push2DisplayBridge(); 37 | 38 | /*! 39 | * Initialises the bridge 40 | * 41 | * \return the result of the initialisation process 42 | */ 43 | 44 | NBase::Result Init(ableton::Push2Display& display); 45 | 46 | /*! 47 | * Access a reference to the juce::Graphics of the bridge 48 | * the returned object can be used with juce's drawing primitives 49 | */ 50 | 51 | juce::Graphics& GetGraphic(); 52 | 53 | /*! 54 | * Tells the bridge the drawing is done and the bitmap can be sent to 55 | * the push display 56 | */ 57 | 58 | void Flip(); 59 | 60 | private: 61 | ableton::Push2Display* push2Display_; /*< The push display the bridge works on */ 62 | 63 | juce::Image image_; /*< The image used to render the pixel data */ 64 | juce::Graphics graphics_; /*< The graphics associated to the image */ 65 | }; 66 | } 67 | -------------------------------------------------------------------------------- /Source/push2/Push2-Bitmap.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2017 Ableton AG, Berlin 2 | // 3 | // Permission is hereby granted, free of charge, to any person obtaining a 4 | // copy of this software and associated documentation files (the "Software"), 5 | // to deal in the Software without restriction, including without limitation 6 | // the rights to use, copy, modify, merge, publish, distribute, sublicense, 7 | // and/or sell copies of the Software, and to permit persons to whom the 8 | // Software is furnished to do so, subject to the following conditions: 9 | // 10 | // The above copyright notice and this permission notice shall be included in 11 | // all copies or substantial portions of the Software. 12 | // 13 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 16 | // THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 18 | // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 19 | // DEALINGS IN THE SOFTWARE. 20 | 21 | #pragma once 22 | 23 | #include 24 | #include 25 | 26 | #include "Macros.h" 27 | 28 | namespace ableton 29 | { 30 | /*! 31 | * Utility class representing a bitmap in the pixelformat used by push. 32 | * 33 | * The display uses 16 bit per pixels in a 5:6:5 format 34 | * 35 | * MSB LSB 36 | * b b b b|b g g g|g g g r|r r r r 37 | */ 38 | 39 | class Push2DisplayBitmap 40 | { 41 | public: 42 | 43 | using pixel_t = uint16_t; 44 | 45 | static const int16_t kWidth = 960; 46 | static const int16_t kHeight = 160; 47 | 48 | Push2DisplayBitmap() 49 | { 50 | memset(pixelData_, 0, kWidth * kHeight * sizeof(pixel_t)); 51 | } 52 | 53 | /*! 54 | * \return the width of the bitmap 55 | */ 56 | 57 | int GetWidth() const 58 | { 59 | return kWidth; 60 | } 61 | 62 | /*! 63 | * \return the height of the bitmap 64 | */ 65 | 66 | int GetHeight() const 67 | { 68 | return kHeight; 69 | } 70 | 71 | /*! 72 | * \return pixel_t value in push display format from (r, g, b) 73 | */ 74 | 75 | inline static pixel_t SPixelFromRGB(unsigned char r, unsigned char g, unsigned char b) 76 | { 77 | pixel_t pixel = (b & 0xF8) >> 3; 78 | pixel <<= 6; 79 | pixel += (g & 0xFC) >> 2; 80 | pixel <<= 5; 81 | pixel += (r & 0xF8) >> 3; 82 | return pixel; 83 | } 84 | 85 | /*! 86 | * \return a pointer to the internal pixel data 87 | */ 88 | 89 | pixel_t* PixelData() 90 | { 91 | return pixelData_; 92 | } 93 | 94 | const pixel_t* PixelData(void *pDummy = nullptr) const 95 | { 96 | MUnused(pDummy); 97 | return pixelData_; 98 | } 99 | private: 100 | pixel_t pixelData_[kWidth * kHeight]; /*!< static memory block to store the pixel values */ 101 | }; 102 | 103 | } -------------------------------------------------------------------------------- /Source/push2/Push2-Display.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2017 Ableton AG, Berlin 2 | // 3 | // Permission is hereby granted, free of charge, to any person obtaining a 4 | // copy of this software and associated documentation files (the "Software"), 5 | // to deal in the Software without restriction, including without limitation 6 | // the rights to use, copy, modify, merge, publish, distribute, sublicense, 7 | // and/or sell copies of the Software, and to permit persons to whom the 8 | // Software is furnished to do so, subject to the following conditions: 9 | // 10 | // The above copyright notice and this permission notice shall be included in 11 | // all copies or substantial portions of the Software. 12 | // 13 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 16 | // THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 18 | // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 19 | // DEALINGS IN THE SOFTWARE. 20 | 21 | #pragma once 22 | 23 | #include "Result.h" 24 | #include "Push2-UsbCommunicator.h" 25 | #include 26 | #include 27 | 28 | namespace ableton 29 | { 30 | //===================================================================== 31 | 32 | class Push2Display 33 | { 34 | public: 35 | using pixel_t = Push2DisplayBitmap::pixel_t; 36 | 37 | Push2Display() 38 | { 39 | pixel_t* pData = dataSource_; 40 | for (uint8_t line = 0; line < kDataSourceHeight; line++) 41 | { 42 | memset(pData, 0, kDataSourceWidth*sizeof(pixel_t)); 43 | pData += kDataSourceWidth; 44 | } 45 | } 46 | 47 | NBase::Result Init() 48 | { 49 | return communicator_.Init(dataSource_); 50 | } 51 | 52 | // Transfers the bitmap into the output buffer sent to 53 | // the push display. The push display buffer has a larger stride 54 | // as the given bitmap 55 | 56 | NBase::Result Flip(const Push2DisplayBitmap& g) 57 | { 58 | const pixel_t* src = g.PixelData(); 59 | pixel_t* dst = dataSource_; 60 | 61 | const int graphicsWidth = g.GetWidth(); 62 | assert(g.GetHeight() == kDataSourceHeight); 63 | for (uint8_t line = 0; line < kDataSourceHeight; line++) 64 | { 65 | memcpy(dst, src, graphicsWidth * sizeof(pixel_t)); 66 | src += graphicsWidth; 67 | dst += kDataSourceWidth; 68 | } 69 | 70 | return NBase::Result::NoError; 71 | } 72 | 73 | private: 74 | static const int kDataSourceWidth = 1024; 75 | static const int kDataSourceHeight = 160; 76 | 77 | pixel_t dataSource_[kDataSourceWidth * kDataSourceHeight]; 78 | UsbCommunicator communicator_; 79 | }; 80 | } -------------------------------------------------------------------------------- /Source/push2/Push2-Usb-Communicator.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2017 Ableton AG, Berlin 2 | // 3 | // Permission is hereby granted, free of charge, to any person obtaining a 4 | // copy of this software and associated documentation files (the "Software"), 5 | // to deal in the Software without restriction, including without limitation 6 | // the rights to use, copy, modify, merge, publish, distribute, sublicense, 7 | // and/or sell copies of the Software, and to permit persons to whom the 8 | // Software is furnished to do so, subject to the following conditions: 9 | // 10 | // The above copyright notice and this permission notice shall be included in 11 | // all copies or substantial portions of the Software. 12 | // 13 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 16 | // THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 18 | // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 19 | // DEALINGS IN THE SOFTWARE. 20 | 21 | #include "Push2-UsbCommunicator.h" 22 | 23 | #include 24 | 25 | #ifdef _WIN32 26 | // see following link for a discussion of the 27 | // warning suppression: 28 | // http://sourceforge.net/mailarchive/forum.php? 29 | // thread_name=50F6011C.2020000%40akeo.ie&forum_name=libusbx-devel 30 | 31 | // Disable: warning C4200: nonstandard extension used: 32 | // zero-sized array in struct/union 33 | #pragma warning(disable:4200) 34 | #endif 35 | 36 | #include "../libusb/libusb.h" 37 | 38 | //------------------------------------------------------------------------------ 39 | 40 | namespace 41 | { 42 | using namespace ableton; 43 | 44 | //---------------------------------------------------------------------------- 45 | 46 | // Uses libusb to create a device handle for the push display 47 | 48 | NBase::Result SFindPushDisplayDeviceHandle(libusb_device_handle** pHandle) 49 | { 50 | using namespace NBase; 51 | 52 | int errorCode; 53 | 54 | // Initialises the library 55 | if ((errorCode = libusb_init(NULL)) < 0) 56 | { 57 | return NBase::Result("Failed to initialize usblib"); 58 | } 59 | 60 | libusb_set_debug(NULL, LIBUSB_LOG_LEVEL_ERROR); 61 | 62 | // Get a list of connected devices 63 | libusb_device** devices; 64 | ssize_t count; 65 | count = libusb_get_device_list(NULL, &devices); 66 | if (count < 0) 67 | { 68 | return Result("could not get usb device list"); 69 | } 70 | 71 | // Look for the one matching push2's decriptors 72 | libusb_device* device; 73 | libusb_device_handle* device_handle = NULL; 74 | 75 | char ErrorMsg[256]; 76 | 77 | // set message in case we get to the end of the list w/o finding a device 78 | sprintf(ErrorMsg, "display device not found\n"); 79 | 80 | for (int i = 0; (device = devices[i]) != NULL; i++) 81 | { 82 | struct libusb_device_descriptor descriptor; 83 | if ((errorCode = libusb_get_device_descriptor(device, &descriptor)) < 0) 84 | { 85 | sprintf(ErrorMsg, "could not get usb device descriptor, error: %d", errorCode); 86 | continue; 87 | } 88 | 89 | const uint16_t kAbletonVendorID = 0x2982; 90 | const uint16_t kPush2ProductID = 0x1967; 91 | 92 | if (descriptor.bDeviceClass == LIBUSB_CLASS_PER_INTERFACE 93 | && descriptor.idVendor == kAbletonVendorID 94 | && descriptor.idProduct == kPush2ProductID) 95 | { 96 | if ((errorCode = libusb_open(device, &device_handle)) < 0) 97 | { 98 | sprintf(ErrorMsg, "could not open device, error: %d", errorCode); 99 | } 100 | else if ((errorCode = libusb_claim_interface(device_handle, 0)) < 0) 101 | { 102 | sprintf(ErrorMsg, "could not claim device with interface 0, error: %d", errorCode); 103 | libusb_close(device_handle); 104 | device_handle = NULL; 105 | } 106 | else 107 | { 108 | break; // successfully opened 109 | } 110 | } 111 | } 112 | 113 | *pHandle = device_handle; 114 | libusb_free_device_list(devices, 1); 115 | 116 | return device_handle ? Result::NoError : Result(ErrorMsg); 117 | } 118 | 119 | //---------------------------------------------------------------------------- 120 | 121 | // Callback received whenever a transfer has been completed. 122 | // We defer the processing to the communicator class 123 | 124 | void LIBUSB_CALL SOnTransferFinished(libusb_transfer* transfer) 125 | { 126 | static_cast(transfer->user_data)->OnTransferFinished(transfer); 127 | } 128 | 129 | //---------------------------------------------------------------------------- 130 | 131 | // Allocate a libusb_transfer mapped to a transfer buffer. It also sets 132 | // up the callback needed to communicate the transfer is done 133 | 134 | libusb_transfer* SAllocateAndPrepareTransferChunk( 135 | libusb_device_handle* handle, 136 | UsbCommunicator* instance, 137 | unsigned char* buffer, 138 | int bufferSize) 139 | { 140 | // Allocate a transfer structure 141 | libusb_transfer* transfer = libusb_alloc_transfer(0); 142 | if (!transfer) 143 | { 144 | return nullptr; 145 | } 146 | 147 | // Sets the transfer characteristic 148 | const unsigned char kPush2BulkEPOut = 0x01; 149 | 150 | libusb_fill_bulk_transfer(transfer, handle, kPush2BulkEPOut, 151 | buffer, bufferSize, 152 | SOnTransferFinished, instance, 1000); 153 | return transfer; 154 | } 155 | } 156 | 157 | 158 | //------------------------------------------------------------------------------ 159 | 160 | UsbCommunicator::UsbCommunicator() 161 | :handle_(NULL) 162 | { 163 | } 164 | 165 | 166 | //------------------------------------------------------------------------------ 167 | 168 | NBase::Result UsbCommunicator::Init(const pixel_t* dataSource) 169 | { 170 | using namespace NBase; 171 | 172 | // Capture the data source 173 | dataSource_ = dataSource; 174 | 175 | // Initialise the handle 176 | NBase::Result result = SFindPushDisplayDeviceHandle(&handle_); 177 | RETURN_IF_FAILED_MESSAGE(result, "Failed to initialize handle"); 178 | assert(handle_ != NULL); 179 | 180 | // Initialise the transfer 181 | result = startSending(); 182 | RETURN_IF_FAILED_MESSAGE(result, "Failed to initiate send"); 183 | 184 | // We initiate a thread so we can recieve events from libusb 185 | terminate_ = false; 186 | pollThread_ = std::thread(&UsbCommunicator::PollUsbForEvents, this); 187 | 188 | return NBase::Result::NoError; 189 | } 190 | 191 | 192 | //------------------------------------------------------------------------------ 193 | 194 | UsbCommunicator::~UsbCommunicator() 195 | { 196 | // shutdown the polling thread 197 | terminate_ = true; 198 | if (pollThread_.joinable()) 199 | { 200 | pollThread_.join(); 201 | } 202 | } 203 | 204 | 205 | //------------------------------------------------------------------------------ 206 | 207 | NBase::Result UsbCommunicator::startSending() 208 | { 209 | using namespace NBase; 210 | 211 | currentLine_ = 0; 212 | 213 | // Allocates a transfer struct for the frame header 214 | 215 | static unsigned char frameHeader[16] = 216 | { 217 | 0xFF, 0xCC, 0xAA, 0x88, 218 | 0x00, 0x00, 0x00, 0x00, 219 | 0x00, 0x00, 0x00, 0x00, 220 | 0x00, 0x00, 0x00, 0x00 221 | }; 222 | 223 | frameHeaderTransfer_ = 224 | SAllocateAndPrepareTransferChunk(handle_, this, frameHeader, sizeof(frameHeader)); 225 | 226 | for (int i = 0; i < kSendBufferCount; i++) 227 | { 228 | unsigned char* buffer = (sendBuffers_ + i * kSendBufferSize); 229 | 230 | // Allocates a transfer struct for the send buffers 231 | 232 | libusb_transfer* transfer = 233 | SAllocateAndPrepareTransferChunk(handle_, this, buffer, kSendBufferSize); 234 | 235 | // Start a request for this buffer 236 | Result result = sendNextSlice(transfer); 237 | RETURN_IF_FAILED(result); 238 | } 239 | 240 | return Result::NoError; 241 | } 242 | 243 | 244 | //------------------------------------------------------------------------------ 245 | 246 | NBase::Result UsbCommunicator::sendNextSlice(libusb_transfer* transfer) 247 | { 248 | using namespace NBase; 249 | 250 | // Start of a new frame, so send header first 251 | if (currentLine_ == 0) 252 | { 253 | if (libusb_submit_transfer(frameHeaderTransfer_) < 0) 254 | { 255 | return Result("could not submit frame header transfer"); 256 | } 257 | } 258 | 259 | // Copy the next slice of the source data (represented by currentLine_) 260 | // to the transfer buffer 261 | 262 | unsigned char *dst = transfer->buffer; 263 | 264 | const char* src = (const char*)dataSource_ + kLineSize * currentLine_; 265 | unsigned char* end = dst + kSendBufferSize; 266 | 267 | while (dst < end) 268 | { 269 | *dst++ = *src++; 270 | } 271 | 272 | // Send it 273 | if (libusb_submit_transfer(transfer) < 0) 274 | { 275 | return Result("could not submit display data transfer,"); 276 | } 277 | 278 | // Update slice position 279 | currentLine_ += kLineCountPerSendBuffer; 280 | 281 | if (currentLine_ >= 160) 282 | { 283 | currentLine_ = 0; 284 | } 285 | 286 | return Result::NoError; 287 | } 288 | 289 | 290 | //------------------------------------------------------------------------------ 291 | 292 | void UsbCommunicator::OnTransferFinished(libusb_transfer* transfer) 293 | { 294 | if (transfer->status != LIBUSB_TRANSFER_COMPLETED) 295 | { 296 | assert(0); 297 | switch (transfer->status) 298 | { 299 | case LIBUSB_TRANSFER_ERROR: printf("transfer failed\n"); break; 300 | case LIBUSB_TRANSFER_TIMED_OUT: printf("transfer timed out\n"); break; 301 | case LIBUSB_TRANSFER_CANCELLED: printf("transfer was cancelled\n"); break; 302 | case LIBUSB_TRANSFER_STALL: printf("endpoint stalled/control request not supported\n"); break; 303 | case LIBUSB_TRANSFER_NO_DEVICE: printf("device was disconnected\n"); break; 304 | case LIBUSB_TRANSFER_OVERFLOW: printf("device sent more data than requested\n"); break; 305 | default: 306 | printf("snd transfer failed with status: %d\n", transfer->status); 307 | break; 308 | } 309 | } 310 | else if (transfer->length != transfer->actual_length) 311 | { 312 | assert(0); 313 | printf("only transferred %d of %d bytes\n", transfer->actual_length, transfer->length); 314 | } 315 | else if (transfer == frameHeaderTransfer_) 316 | { 317 | onFrameCompleted(); 318 | } 319 | else 320 | { 321 | NBase::Result result = sendNextSlice(transfer); 322 | assert(result.Succeeded()); 323 | } 324 | } 325 | 326 | 327 | //------------------------------------------------------------------------------ 328 | 329 | void UsbCommunicator::onFrameCompleted() 330 | { 331 | // Insert code here if you want anything to happen after each frame 332 | } 333 | 334 | 335 | //------------------------------------------------------------------------------ 336 | 337 | void UsbCommunicator::PollUsbForEvents() 338 | { 339 | static struct timeval timeout_500ms = {0 , 500000}; 340 | int terminate_main_loop = 0; 341 | 342 | while (!terminate_main_loop && !terminate_.load()) 343 | { 344 | if (libusb_handle_events_timeout_completed(NULL, &timeout_500ms, &terminate_main_loop) < 0) 345 | { 346 | assert(0); 347 | } 348 | } 349 | } 350 | -------------------------------------------------------------------------------- /Source/push2/Push2-UsbCommunicator.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2017 Ableton AG, Berlin 2 | // 3 | // Permission is hereby granted, free of charge, to any person obtaining a 4 | // copy of this software and associated documentation files (the "Software"), 5 | // to deal in the Software without restriction, including without limitation 6 | // the rights to use, copy, modify, merge, publish, distribute, sublicense, 7 | // and/or sell copies of the Software, and to permit persons to whom the 8 | // Software is furnished to do so, subject to the following conditions: 9 | // 10 | // The above copyright notice and this permission notice shall be included in 11 | // all copies or substantial portions of the Software. 12 | // 13 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 16 | // THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 18 | // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 19 | // DEALINGS IN THE SOFTWARE. 20 | 21 | #pragma once 22 | 23 | #include "Result.h" 24 | #include "Push2-Bitmap.h" 25 | 26 | #include 27 | #include 28 | 29 | #include 30 | 31 | // Forward declarations. This avoid having to include libusb.h from here 32 | // which leads to declaration conflicts with juce 33 | 34 | class libusb_transfer; 35 | class libusb_device_handle; 36 | 37 | namespace ableton 38 | { 39 | /*! 40 | * This class manages the communication with the Push 2 display over usb. 41 | * 42 | */ 43 | 44 | class UsbCommunicator 45 | { 46 | public: 47 | using pixel_t = Push2DisplayBitmap::pixel_t; 48 | 49 | // The display frame size is 960*160*2=300k, but we use 64 extra filler 50 | // pixels per line so that we get exactly 2048 bytes per line. The purpose 51 | // is that the device receives exactly 4 buffers of 512 bytes each per line, 52 | // so that the line boundary (which is where we save to SDRAM) does not fall 53 | // into the middle of a received buffer. Therefore we actually send 54 | // 1024*160*2=320k bytes per frame. 55 | 56 | static const int kLineSize = 2048; // total line size 57 | static const int kLineCountPerSendBuffer = 8; 58 | 59 | // The data sent to the display is sliced into chunks of kLineCountPerSendBuffer 60 | // and we use kSendBufferCount buffers to communicate so we can prepare the next 61 | // request without having to wait for the current one to be finished 62 | // The sent buffer size (kSendBufferSize) must a multiple of these 2k per line, 63 | // and is selected for optimal performance. 64 | 65 | static const int kSendBufferCount = 3; 66 | static const int kSendBufferSize = kLineCountPerSendBuffer * kLineSize; // buffer length in bytes 67 | 68 | UsbCommunicator(); 69 | ~UsbCommunicator(); 70 | 71 | /*! 72 | * Inialises the communicator. This will look for the usb descriptor matching 73 | * the display, allocate transfer buffers and start sending data. 74 | * 75 | * \param dataSource: The buffer holding the data to be sent to the display. 76 | * \return the result of the initialisation 77 | */ 78 | 79 | NBase::Result Init(const pixel_t* dataSource); 80 | 81 | /*! 82 | * Callback for when a transfer is finished and the next one needs to be 83 | * initiated 84 | */ 85 | 86 | void OnTransferFinished(libusb_transfer* transfer); 87 | 88 | /*! 89 | * Continuously poll events from libusb, possibly treating any error reported 90 | */ 91 | 92 | void PollUsbForEvents(); 93 | 94 | private: 95 | 96 | /*! 97 | * Initiate the send process 98 | */ 99 | 100 | NBase::Result startSending(); 101 | 102 | /*! 103 | * Send the next slice of data using the provided transfer struct 104 | */ 105 | 106 | NBase::Result sendNextSlice(libusb_transfer* transfer); 107 | 108 | /*! 109 | * Callback for when a full frame has been sent 110 | * Note that there's no real need of doing double buffering since the 111 | * display deals nicely with it already 112 | */ 113 | 114 | void onFrameCompleted(); 115 | 116 | const pixel_t* dataSource_; 117 | libusb_device_handle* handle_; 118 | libusb_transfer* frameHeaderTransfer_; 119 | std::thread pollThread_; 120 | uint8_t currentLine_; 121 | std::atomic terminate_; 122 | unsigned char sendBuffers_[kSendBufferCount * kSendBufferSize]; 123 | 124 | }; 125 | } 126 | -------------------------------------------------------------------------------- /juce2push2.jucer: -------------------------------------------------------------------------------- 1 | 2 | 3 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 14 | 16 | 18 | 20 | 21 | 22 | 23 | 24 | 26 | 27 | 28 | 29 | 30 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 43 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 66 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 88 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | --------------------------------------------------------------------------------