@@ -1,7 +1,30 @@ | |||
Tip: Use `git checkout v0.4.0` for example to check out any previous version mentioned here. | |||
### v0.5.1 (2017-12-19) | |||
### 0.6.0 (2018-03-29) | |||
- Released [*VCV Bridge*](https://vcvrack.com/manual/Core.html#Bridge) for interfacing Rack with your DAW | |||
- VST/AU effect plugins (Mac and 32/64-bit Windows) for using Rack as a send/return on a DAW track | |||
- Enables future VSTi/AU instrument plugins with MIDI and DAW clock transport to be added in a later Rack 0.6.* update | |||
- Updated [*Plugin Manager*](https://vcvrack.com/plugins.html) to handle open-source plugins | |||
- Potentially all plugins can be added with help from the [VCV Community](https://github.com/VCVRack/community/issues/248) | |||
- New *Module Browser* for adding modules to the rack | |||
- Launch by right-clicking on the rack or pressing <enter> | |||
- Add "favorite" modules by clicking on the star button | |||
- Navigate modules with arrow keys or mouse | |||
- Redesigned [Core](https://vcvrack.com/manual/Core.html) modules | |||
- Access to audio channels beyond the first 8 inputs/outputs | |||
- Improved AUDIO stability | |||
- Added retrigger output to MIDI-1 | |||
- Merged MIDI clock module with MIDI-1 | |||
- Fixed MIDI-4 sustain pedal in polyphonic modes | |||
- Improved sample rate conversion performance, is disabled entirely when not needed | |||
- Patch cable colors are saved to patch files | |||
- Added highlighting for active patch cables when hovering mouse over port | |||
- Added shadows to knobs and ports | |||
- Added File > "Disconnect cables" | |||
- Released [Rack SDK](https://github.com/VCVRack/Rack/issues/258#issuecomment-376293898) for compiling plugins without compiling Rack | |||
### 0.5.1 (2017-12-19) | |||
- Added Plugin Manager support | |||
- Fixed metadata panel in the Add Module window | |||
@@ -10,7 +33,7 @@ Tip: Use `git checkout v0.4.0` for example to check out any previous version men | |||
- Added Sequential Switch 1 & 2 | |||
### v0.5.0 (2017-11-21) | |||
### 0.5.0 (2017-11-21) | |||
- Added zoom scaling from 25% to 200% | |||
- Automatically scroll when dragging cables to the edge of the screen | |||
@@ -35,7 +58,7 @@ Tip: Use `git checkout v0.4.0` for example to check out any previous version men | |||
- Changed LED functions in ADSR | |||
### v0.4.0 (2017-10-13) | |||
### 0.4.0 (2017-10-13) | |||
- Cables can now stack on output ports | |||
- Added sub-menus for each plugin, includes optional plugin metadata like URLs | |||
@@ -58,7 +81,7 @@ Tip: Use `git checkout v0.4.0` for example to check out any previous version men | |||
- Added Keyframer/Mixer | |||
### v0.3.2 (2017-09-25) | |||
### 0.3.2 (2017-09-25) | |||
- Added key commands | |||
- Fixed "invisible knobs/ports" rendering bug for ~2010 Macs | |||
@@ -72,7 +95,7 @@ Tip: Use `git checkout v0.4.0` for example to check out any previous version men | |||
- Reverted SEQ3 to continuous gates | |||
### v0.3.1 (2017-09-13) | |||
### 0.3.1 (2017-09-13) | |||
- Fixed Windows open dialog current working directory graphics problem | |||
- Ctrl/Cmd-C/V to copy/paste from text and password fields | |||
@@ -83,6 +106,6 @@ Tip: Use `git checkout v0.4.0` for example to check out any previous version men | |||
- tweaks to Fundamental and Audible Instruments plugins | |||
### v0.3.0 (2017-09-10) | |||
### 0.3.0 (2017-09-10) | |||
- Knobcon public Beta release |
@@ -11,22 +11,13 @@ endif | |||
include arch.mk | |||
STRIP ?= strip | |||
# Sources and build flags | |||
SOURCES += $(wildcard src/*.cpp src/*/*.cpp) | |||
SOURCES += dep/nanovg/src/nanovg.c | |||
ifeq ($(ARCH), lin) | |||
SOURCES += dep/osdialog/osdialog_gtk2.c | |||
CFLAGS += $(shell pkg-config --cflags gtk+-2.0) | |||
LDFLAGS += -rdynamic \ | |||
-lpthread -lGL -ldl \ | |||
$(shell pkg-config --libs gtk+-2.0) \ | |||
-Ldep/lib -lGLEW -lglfw -ljansson -lspeexdsp -lcurl -lzip -lrtaudio -lrtmidi -lcrypto -lssl | |||
TARGET := Rack | |||
endif | |||
ifeq ($(ARCH), mac) | |||
SOURCES += dep/osdialog/osdialog_mac.m | |||
CXXFLAGS += -stdlib=libc++ | |||
@@ -48,6 +39,18 @@ ifeq ($(ARCH), win) | |||
OBJECTS += Rack.res | |||
endif | |||
ifeq ($(ARCH), lin) | |||
SOURCES += dep/osdialog/osdialog_gtk2.c | |||
CFLAGS += $(shell pkg-config --cflags gtk+-2.0) | |||
LDFLAGS += -rdynamic \ | |||
-lpthread -lGL -ldl -lX11 -lasound -ljack \ | |||
$(shell pkg-config --libs gtk+-2.0) \ | |||
-Ldep/lib \ | |||
-Wl,-Bstatic -lglfw3 -lGLEW -ljansson -lspeexdsp -lzip -lz -lrtmidi -lrtaudio -lcurl -lssl -lcrypto \ | |||
-Wl,-Bdynamic | |||
TARGET := Rack | |||
endif | |||
# Convenience targets | |||
@@ -111,7 +114,7 @@ ifeq ($(ARCH), mac) | |||
mkdir -p $(BUNDLE)/Contents/MacOS | |||
cp $(TARGET) $(BUNDLE)/Contents/MacOS/ | |||
strip -S $(BUNDLE)/Contents/MacOS/$(TARGET) | |||
$(STRIP) -S $(BUNDLE)/Contents/MacOS/$(TARGET) | |||
cp icon.icns $(BUNDLE)/Contents/Resources/ | |||
otool -L $(BUNDLE)/Contents/MacOS/$(TARGET) | |||
@@ -156,7 +159,7 @@ ifeq ($(ARCH), win) | |||
cp Bridge/vst/dist/VCV-Bridge-32.dll dist/Rack/Bridge/ | |||
cp -R LICENSE* res dist/Rack/ | |||
cp $(TARGET) dist/Rack/ | |||
strip dist/Rack/$(TARGET) | |||
$(STRIP) -s dist/Rack/$(TARGET) | |||
cp /mingw64/bin/libwinpthread-1.dll dist/Rack/ | |||
cp /mingw64/bin/zlib1.dll dist/Rack/ | |||
cp /mingw64/bin/libstdc++-6.dll dist/Rack/ | |||
@@ -181,18 +184,8 @@ endif | |||
ifeq ($(ARCH), lin) | |||
mkdir -p dist/Rack | |||
cp -R LICENSE* res dist/Rack/ | |||
cp $(TARGET) Rack.sh dist/Rack/ | |||
strip dist/Rack/$(TARGET) | |||
cp dep/lib/libspeexdsp.so dist/Rack/ | |||
cp dep/lib/libjansson.so.4 dist/Rack/ | |||
cp dep/lib/libGLEW.so.2.1 dist/Rack/ | |||
cp dep/lib/libglfw.so.3 dist/Rack/ | |||
cp dep/lib/libcurl.so.4 dist/Rack/ | |||
cp dep/lib/libzip.so.5 dist/Rack/ | |||
cp dep/lib/librtaudio.so dist/Rack/ | |||
cp dep/lib/librtmidi.so.4 dist/Rack/ | |||
cp dep/lib/libssl.so.1.1 dist/Rack/ | |||
cp dep/lib/libcrypto.so.1.1 dist/Rack/ | |||
cp $(TARGET) dist/Rack/ | |||
$(STRIP) -s dist/Rack/$(TARGET) | |||
cp plugins/Fundamental/dist/Fundamental-*.zip dist/Rack/Fundamental.zip | |||
# Make ZIP | |||
cd dist && zip -5 -r Rack-$(VERSION)-$(ARCH).zip Rack | |||
@@ -1,2 +0,0 @@ | |||
#!/bin/bash | |||
LD_LIBRARY_PATH=. ./Rack |
@@ -2,7 +2,7 @@ | |||
ifndef ARCH | |||
MACHINE = $(shell gcc -dumpmachine) | |||
MACHINE = $(shell $(CC) -dumpmachine) | |||
ifneq (, $(findstring linux, $(MACHINE))) | |||
# Linux | |||
ARCH = lin | |||
@@ -43,12 +43,12 @@ CXXFLAGS += $(FLAGS) | |||
# Derive object files from sources and place them before user-defined objects | |||
SOURCE_OBJECTS := $(patsubst %, build/%.o, $(SOURCES)) | |||
OBJECTS := $(patsubst %, build/%.o, $(SOURCES)) $(OBJECTS) | |||
DEPENDENCIES := $(patsubst %, build/%.d, $(SOURCES)) | |||
# Final targets | |||
$(TARGET): $(SOURCE_OBJECTS) $(OBJECTS) | |||
$(TARGET): $(OBJECTS) | |||
$(CXX) -o $@ $^ $(LDFLAGS) | |||
-include $(DEPENDENCIES) | |||
@@ -7,15 +7,16 @@ RACK_DIR ?= .. | |||
include $(RACK_DIR)/arch.mk | |||
ifeq ($(ARCH), lin) | |||
glew = lib/libGLEW.so | |||
glfw = lib/libglfw.so | |||
jansson = lib/libjansson.so | |||
libspeexdsp = lib/libspeexdsp.so | |||
libcurl = lib/libcurl.so | |||
libzip = lib/libzip.so | |||
rtmidi = lib/librtmidi.so | |||
rtaudio = lib/librtaudio.so | |||
openssl = lib/libssl.so | |||
glew = lib/libGLEW.a | |||
glfw = lib/libglfw3.a | |||
jansson = lib/libjansson.a | |||
libspeexdsp = lib/libspeexdsp.a | |||
libcurl = lib/libcurl.a | |||
libzip = lib/libzip.a | |||
zlib = lib/libz.a | |||
rtmidi = lib/librtmidi.a | |||
rtaudio = lib/librtaudio.a | |||
openssl = lib/libssl.a | |||
endif | |||
ifeq ($(ARCH), mac) | |||
@@ -62,7 +63,6 @@ $(glew): | |||
$(glfw): | |||
cd glfw && $(CMAKE) . \ | |||
-DBUILD_SHARED_LIBS=ON \ | |||
-DGLFW_COCOA_CHDIR_RESOURCES=OFF -DGLFW_COCOA_MENUBAR=ON -DGLFW_COCOA_RETINA_FRAMEBUFFER=ON | |||
$(MAKE) -C glfw | |||
$(MAKE) -C glfw install | |||
@@ -109,13 +109,20 @@ ifeq ($(ARCH),mac) | |||
otool -L $@ | |||
endif | |||
$(libzip): | |||
$(libzip): $(zlib) | |||
$(WGET) https://nih.at/libzip/libzip-1.2.0.tar.gz | |||
$(UNTAR) libzip-1.2.0.tar.gz | |||
cd libzip-1.2.0 && $(CONFIGURE) | |||
$(MAKE) -C libzip-1.2.0 | |||
$(MAKE) -C libzip-1.2.0 install | |||
$(zlib): | |||
$(WGET) https://www.zlib.net/zlib-1.2.11.tar.gz | |||
$(UNTAR) zlib-1.2.11.tar.gz | |||
cd zlib-1.2.11 && $(CONFIGURE) | |||
$(MAKE) -C zlib-1.2.11 | |||
$(MAKE) -C zlib-1.2.11 install | |||
$(rtmidi): | |||
$(WGET) https://vcvrack.com/downloads/dep/rtmidi.tgz | |||
$(UNTAR) rtmidi.tgz | |||
@@ -130,7 +137,7 @@ ifeq ($(ARCH),win) | |||
RTAUDIO_FLAGS += -DAUDIO_WINDOWS_DS=ON -DAUDIO_WINDOWS_WASAPI=ON -DAUDIO_WINDOWS_ASIO=ON | |||
endif | |||
ifeq ($(ARCH),lin) | |||
RTAUDIO_FLAGS += -DAUDIO_LINUX_ALSA=ON | |||
RTAUDIO_FLAGS += -DAUDIO_LINUX_ALSA=ON -DAUDIO_UNIX_JACK=ON | |||
endif | |||
ifdef RTAUDIO_ALL_APIS | |||
@@ -138,7 +145,7 @@ ifeq ($(ARCH),mac) | |||
RTAUDIO_FLAGS += -DAUDIO_UNIX_JACK=ON | |||
endif | |||
ifeq ($(ARCH),lin) | |||
RTAUDIO_FLAGS += -DAUDIO_LINUX_PULSE=ON -DAUDIO_UNIX_JACK=ON | |||
RTAUDIO_FLAGS += -DAUDIO_LINUX_PULSE=ON | |||
endif | |||
endif | |||
@@ -147,6 +154,8 @@ $(rtaudio): | |||
cd rtaudio/build && $(CMAKE) $(RTAUDIO_FLAGS) .. | |||
$(MAKE) -C rtaudio/build | |||
$(MAKE) -C rtaudio/build install | |||
# For some reason, it doesn't install the static library | |||
cp rtaudio/build/librtaudio_static.a lib/librtaudio.a | |||
$(nanovg): | |||
cp nanovg/src/*.h include/ | |||
@@ -6,6 +6,8 @@ ifndef SLUG | |||
$(error SLUG is not defined) | |||
endif | |||
STRIP ?= strip | |||
FLAGS += -DSLUG=$(SLUG) | |||
FLAGS += -fPIC | |||
FLAGS += -I$(RACK_DIR)/include -I$(RACK_DIR)/dep/include | |||
@@ -46,9 +48,9 @@ dist: all | |||
# Strip and copy plugin binary | |||
cp $(TARGET) dist/$(SLUG)/ | |||
ifeq ($(ARCH), mac) | |||
strip -S dist/$(SLUG)/$(TARGET) | |||
$(STRIP) -S dist/$(SLUG)/$(TARGET) | |||
else | |||
strip -s dist/$(SLUG)/$(TARGET) | |||
$(STRIP) -s dist/$(SLUG)/$(TARGET) | |||
endif | |||
# Copy distributables | |||
cp -R $(DISTRIBUTABLES) dist/$(SLUG)/ | |||
@@ -100,66 +100,39 @@ struct BrowserListItem : OpaqueWidget { | |||
struct ModelItem : BrowserListItem { | |||
Model *model; | |||
Label *authorLabel = NULL; | |||
ModelItem() { | |||
box.size.y = 2*BND_WIDGET_HEIGHT + 3*itemMargin; | |||
} | |||
Label *pluginLabel = NULL; | |||
void setModel(Model *model) { | |||
clearChildren(); | |||
assert(model); | |||
this->model = model; | |||
Label *nameLabel = Widget::create<Label>(Vec(0, 0 + itemMargin)); | |||
nameLabel->text = model->name; | |||
addChild(nameLabel); | |||
// Hide author label if filtering by author | |||
if (sAuthorFilter.empty()) { | |||
authorLabel = Widget::create<Label>(Vec(0, 0 + itemMargin)); | |||
authorLabel->alignment = Label::RIGHT_ALIGNMENT; | |||
authorLabel->text = model->author; | |||
authorLabel->color.a = 0.5; | |||
addChild(authorLabel); | |||
} | |||
SequentialLayout *layout2 = Widget::create<SequentialLayout>(Vec(7, BND_WIDGET_HEIGHT + itemMargin)); | |||
layout2->spacing = 0; | |||
addChild(layout2); | |||
FavoriteRadioButton *favoriteButton = new FavoriteRadioButton(); | |||
FavoriteRadioButton *favoriteButton = Widget::create<FavoriteRadioButton>(Vec(8, itemMargin)); | |||
favoriteButton->box.size.x = 20; | |||
favoriteButton->label = "★"; | |||
layout2->addChild(favoriteButton); | |||
addChild(favoriteButton); | |||
// Set favorite button initial state | |||
auto it = sFavoriteModels.find(model); | |||
if (it != sFavoriteModels.end()) | |||
favoriteButton->setValue(1); | |||
favoriteButton->model = model; | |||
// for (ModelTag tag : model->tags) { | |||
// Button *tagButton = new Button(); | |||
// tagButton->box.size.x = 120; | |||
// tagButton->text = gTagNames[tag]; | |||
// layout2->addChild(tagButton); | |||
// } | |||
Label *nameLabel = Widget::create<Label>(favoriteButton->box.getTopRight()); | |||
nameLabel->text = model->name; | |||
addChild(nameLabel); | |||
Label *tagsLabel = new Label(); | |||
tagsLabel->color.a = 0.5; | |||
int i = 0; | |||
for (ModelTag tag : model->tags) { | |||
if (i++ > 0) | |||
tagsLabel->text += ", "; | |||
tagsLabel->text += gTagNames[tag]; | |||
} | |||
layout2->addChild(tagsLabel); | |||
pluginLabel = Widget::create<Label>(Vec(0, itemMargin)); | |||
pluginLabel->alignment = Label::RIGHT_ALIGNMENT; | |||
pluginLabel->text = model->plugin->slug + " " + model->plugin->version; | |||
pluginLabel->color.a = 0.5; | |||
addChild(pluginLabel); | |||
} | |||
void step() override { | |||
BrowserListItem::step(); | |||
if (authorLabel) | |||
authorLabel->box.size.x = box.size.x - BND_SCROLLBAR_WIDTH; | |||
if (pluginLabel) | |||
pluginLabel->box.size.x = box.size.x - BND_SCROLLBAR_WIDTH; | |||
} | |||
void onAction(EventAction &e) override { | |||
@@ -213,7 +186,7 @@ struct TagItem : BrowserListItem { | |||
struct ClearFilterItem : BrowserListItem { | |||
ClearFilterItem() { | |||
Label *label = Widget::create<Label>(Vec(0, 0 + itemMargin)); | |||
label->text = "Clear filter"; | |||
label->text = "Back"; | |||
addChild(label); | |||
} | |||
@@ -310,7 +283,9 @@ struct ModuleBrowser : OpaqueWidget { | |||
std::set<ModelTag> availableTags; | |||
ModuleBrowser() { | |||
box.size.x = 400; | |||
box.size.x = 450; | |||
sAuthorFilter = ""; | |||
sTagFilter = NO_TAG; | |||
// Search | |||
searchField = new SearchModuleField(); | |||
@@ -481,7 +456,6 @@ void ClearFilterItem::onAction(EventAction &e) { | |||
ModuleBrowser *moduleBrowser = getAncestorOfType<ModuleBrowser>(); | |||
sAuthorFilter = ""; | |||
sTagFilter = NO_TAG; | |||
moduleBrowser->clearSearch(); | |||
moduleBrowser->refreshSearch(); | |||
e.consumed = false; | |||
} | |||