├── config.osx.make
├── icon.ico
├── assets
├── icon.ico
├── icon-mac.icns
├── icons_source
│ ├── dot.psd
│ └── icon.psd
├── Images.xcassets
│ └── AppIcon.appiconset
│ │ ├── appicon-16.png
│ │ ├── appicon-32.png
│ │ ├── appicon-64.png
│ │ ├── appicon-1024.png
│ │ ├── appicon-128.png
│ │ ├── appicon-256.png
│ │ ├── appicon-512.png
│ │ └── Contents.json
├── wix_db.txt
├── icon-mac
├── wix_config.wxi
├── wix_heat.xslt
├── wix_main.wxs
└── wix_files.wxs
├── docs
└── screenshot.png
├── bin
└── data
│ ├── konichiwa.wav
│ └── shaders
│ ├── osci.vert
│ ├── osci.geom
│ └── osci.frag
├── windows_dlls
├── msvcp140.dll
├── vcomp140.dll
├── vcruntime140.dll
└── api-ms-win-crt-runtime-l1-1-0.dll
├── OscilloscopeM1Debug.entitlements
├── oscilloscope.xcodeproj
├── project.xcworkspace
│ ├── contents.xcworkspacedata
│ └── xcshareddata
│ │ ├── IDEWorkspaceChecks.plist
│ │ └── WorkspaceSettings.xcsettings
└── xcshareddata
│ └── xcschemes
│ ├── oscilloscope Debug.xcscheme
│ └── oscilloscope Release.xcscheme
├── addons.make
├── src
├── version.h
├── util
│ ├── TexShare.h
│ ├── TexShare.cpp
│ ├── WickedLasers.h
│ ├── OsciVideoWriter.hpp
│ ├── ShaderLoader.h
│ ├── Audio.h
│ ├── Audio.cpp
│ ├── OsciAvAudioPlayer.h
│ └── WickedLasers.cpp
├── ui
│ ├── FaButton.h
│ ├── Dialogs.h
│ ├── FaToggleButton.h
│ ├── ExportScreen.h
│ ├── ConfigView.h
│ ├── Playlist.h
│ ├── PlayerOverlay.h
│ ├── Dialogs.cpp
│ ├── FMenu.h
│ ├── ExportScreen.cpp
│ ├── ConfigView.cpp
│ └── FMenu.cpp
├── OsciMesh.h
├── ofxIniSettings
│ ├── ofxIniExtras.h
│ ├── ofxIniSettings.h
│ └── ofxIniExtras.cpp
├── globals.h
├── OsciMesh.cpp
├── ofApp.h
├── main.cpp
└── globals.cpp
├── scripts
├── clean.sh
├── osx-config-template.sh
├── functions.sh
├── prepare.sh
├── osx-notarize.sh
├── osx-sign.sh
├── readme.md
└── dist.sh
├── resource.h
├── Oscilloscope.entitlements
├── Makefile
├── Project.xcconfig
├── .github
└── FUNDING.yml
├── openFrameworks-Info.plist
├── .gitmodules
├── LICENSE
├── Oscilloscope.sln
├── icon.rc
├── Oscilloscope.qbs
├── .gitignore
├── readme.md
└── config.make
/config.osx.make:
--------------------------------------------------------------------------------
1 | PLATFORM_CFLAGS=-DMA_MAX_CHANNELS=128
--------------------------------------------------------------------------------
/icon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kritzikratzi/Oscilloscope/HEAD/icon.ico
--------------------------------------------------------------------------------
/assets/icon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kritzikratzi/Oscilloscope/HEAD/assets/icon.ico
--------------------------------------------------------------------------------
/assets/icon-mac.icns:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kritzikratzi/Oscilloscope/HEAD/assets/icon-mac.icns
--------------------------------------------------------------------------------
/docs/screenshot.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kritzikratzi/Oscilloscope/HEAD/docs/screenshot.png
--------------------------------------------------------------------------------
/bin/data/konichiwa.wav:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kritzikratzi/Oscilloscope/HEAD/bin/data/konichiwa.wav
--------------------------------------------------------------------------------
/windows_dlls/msvcp140.dll:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kritzikratzi/Oscilloscope/HEAD/windows_dlls/msvcp140.dll
--------------------------------------------------------------------------------
/windows_dlls/vcomp140.dll:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kritzikratzi/Oscilloscope/HEAD/windows_dlls/vcomp140.dll
--------------------------------------------------------------------------------
/assets/icons_source/dot.psd:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kritzikratzi/Oscilloscope/HEAD/assets/icons_source/dot.psd
--------------------------------------------------------------------------------
/assets/icons_source/icon.psd:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kritzikratzi/Oscilloscope/HEAD/assets/icons_source/icon.psd
--------------------------------------------------------------------------------
/windows_dlls/vcruntime140.dll:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kritzikratzi/Oscilloscope/HEAD/windows_dlls/vcruntime140.dll
--------------------------------------------------------------------------------
/windows_dlls/api-ms-win-crt-runtime-l1-1-0.dll:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kritzikratzi/Oscilloscope/HEAD/windows_dlls/api-ms-win-crt-runtime-l1-1-0.dll
--------------------------------------------------------------------------------
/assets/Images.xcassets/AppIcon.appiconset/appicon-16.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kritzikratzi/Oscilloscope/HEAD/assets/Images.xcassets/AppIcon.appiconset/appicon-16.png
--------------------------------------------------------------------------------
/assets/Images.xcassets/AppIcon.appiconset/appicon-32.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kritzikratzi/Oscilloscope/HEAD/assets/Images.xcassets/AppIcon.appiconset/appicon-32.png
--------------------------------------------------------------------------------
/assets/Images.xcassets/AppIcon.appiconset/appicon-64.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kritzikratzi/Oscilloscope/HEAD/assets/Images.xcassets/AppIcon.appiconset/appicon-64.png
--------------------------------------------------------------------------------
/assets/Images.xcassets/AppIcon.appiconset/appicon-1024.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kritzikratzi/Oscilloscope/HEAD/assets/Images.xcassets/AppIcon.appiconset/appicon-1024.png
--------------------------------------------------------------------------------
/assets/Images.xcassets/AppIcon.appiconset/appicon-128.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kritzikratzi/Oscilloscope/HEAD/assets/Images.xcassets/AppIcon.appiconset/appicon-128.png
--------------------------------------------------------------------------------
/assets/Images.xcassets/AppIcon.appiconset/appicon-256.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kritzikratzi/Oscilloscope/HEAD/assets/Images.xcassets/AppIcon.appiconset/appicon-256.png
--------------------------------------------------------------------------------
/assets/Images.xcassets/AppIcon.appiconset/appicon-512.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kritzikratzi/Oscilloscope/HEAD/assets/Images.xcassets/AppIcon.appiconset/appicon-512.png
--------------------------------------------------------------------------------
/OscilloscopeM1Debug.entitlements:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/oscilloscope.xcodeproj/project.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/addons.make:
--------------------------------------------------------------------------------
1 | addons/ofxAvCodec
2 | addons/ofxFontAwesome
3 | addons/ofxFontStash2
4 | addons/ofxMightyUI
5 | addons/ofxNative
6 | addons/ofxSyphon
7 | addons/ofxSpout
8 | addons/ofxLibsamplerate
9 | addons/ofxLiblaserdock
10 |
--------------------------------------------------------------------------------
/src/version.h:
--------------------------------------------------------------------------------
1 | //
2 | // version.h
3 | // oscilloscope
4 | //
5 | // Created by Hansi on 21.09.20.
6 | //
7 |
8 | #ifndef version_h
9 | #define version_h
10 |
11 | const static string app_version = "1.1.0";
12 |
13 | #endif /* version_h */
14 |
--------------------------------------------------------------------------------
/bin/data/shaders/osci.vert:
--------------------------------------------------------------------------------
1 | #version 110
2 | uniform mat4 uMatrix;
3 | varying vec4 color;
4 | varying float brightness;
5 |
6 | void main()
7 | {
8 | gl_Position = uMatrix*vec4(gl_Vertex.xy,0,gl_Vertex.w);
9 | brightness = min(max(0.0,gl_Vertex.z),1.0);
10 |
11 | color = gl_Color;
12 | }
--------------------------------------------------------------------------------
/assets/wix_db.txt:
--------------------------------------------------------------------------------
1 | 1.0.10=27e537a7-c2d6-4000-99ef-60af66213a0c
2 | 1.0.11=c4e30d53-5c87-4e54-bb97-a9c8119ee30e
3 | 1.0.12=506dff4c-ce1d-489e-a370-b77795744aa9
4 | 1.0.13=e71bb848-089b-40e8-992a-83857e65f196
5 | 1.0.14=c50dae23-ae77-49e8-861b-4380ee9bc447
6 | 1.0.15=884f80b0-093e-431f-963f-caa8155af91e
7 | 1.1.0=42f454b6-bcae-4bd1-884b-e28e9b82b87d
8 |
--------------------------------------------------------------------------------
/oscilloscope.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | IDEDidComputeMac32BitWarning
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/oscilloscope.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | BuildSystemType
6 | Original
7 |
8 |
9 |
--------------------------------------------------------------------------------
/scripts/clean.sh:
--------------------------------------------------------------------------------
1 | #! /bin/bash
2 | basedir=$(dirname $0)
3 | pushd $basedir/../bin
4 | echo "Cleaning out $basedir folder ... "
5 |
6 | echo "----------------------------"
7 | git clean -ndx .
8 | echo "----------------------------"
9 |
10 | echo "Delete all the above files? "
11 | read -p "Are you sure? [y/N] " -n 1 -r
12 | echo # (optional) move to a new line
13 | if [[ $REPLY =~ ^[Yy]$ ]]
14 | then
15 | echo " ... Cleaning up"
16 | git clean -fdx .
17 | else
18 | echo " ... skipped"
19 | fi
20 | popd
--------------------------------------------------------------------------------
/resource.h:
--------------------------------------------------------------------------------
1 | //{{NO_DEPENDENCIES}}
2 | // Microsoft Visual C++ generated include file.
3 | // Used by icon.rc
4 | //
5 | #define MAIN_ICON 102
6 |
7 | // Next default values for new objects
8 | //
9 | #ifdef APSTUDIO_INVOKED
10 | #ifndef APSTUDIO_READONLY_SYMBOLS
11 | #define _APS_NEXT_RESOURCE_VALUE 102
12 | #define _APS_NEXT_COMMAND_VALUE 40001
13 | #define _APS_NEXT_CONTROL_VALUE 1000
14 | #define _APS_NEXT_SYMED_VALUE 101
15 | #endif
16 | #endif
17 |
--------------------------------------------------------------------------------
/src/util/TexShare.h:
--------------------------------------------------------------------------------
1 | //
2 | // SharedTex.hpp
3 | // Oscilloscope
4 | //
5 | // Created by Hansi on 27/06/19.
6 | //
7 | //
8 |
9 | #ifndef SharedTex_hpp
10 | #define SharedTex_hpp
11 |
12 | #include
13 | #include
14 | class ofTexture;
15 |
16 | class TexShareImpl;
17 | class TexShare{
18 | public:
19 | TexShare();
20 | ~TexShare();
21 | void setup(std::string name);
22 | void update(ofTexture & tex);
23 |
24 | private:
25 | std::unique_ptr impl;
26 | };
27 |
28 |
29 | #endif /* SharedTex_hpp */
30 |
--------------------------------------------------------------------------------
/scripts/osx-config-template.sh:
--------------------------------------------------------------------------------
1 | # You can find the developer id in your keychain (i guess)
2 | # Team-Id and Asc-Provider are shown with this command:
3 | # xcrun altool --list-providers -u your@apple-account.com -p your-app-specific-password
4 | DEVELOPER_IDENTITY="Developer ID Application: hansi raber"
5 | DEVELOPER_TEAMID="ABCD12EF"
6 | ASC_PROVIDER="yourname12341234"
7 |
8 | # Apple account user (your email address)
9 | NOTARIZE_USER="your@apple-account.com"
10 |
11 | # An app specific password (generated in your apple account settings)
12 | NOTARIZE_PASSWORD="your-app-specific-password"
13 |
--------------------------------------------------------------------------------
/src/ui/FaButton.h:
--------------------------------------------------------------------------------
1 | //
2 | // FAButton.h
3 | // OsciStudio
4 | //
5 | // Created by Hansi on 04.04.15.
6 | //
7 | // 20.12.2018: added optional fontName argument. this makes it easy to use with multiple versions of fontawesome
8 |
9 | #ifndef FaButton_h
10 | #define FaButton_h
11 |
12 | #include "ofxMightyUI.h"
13 |
14 | class FaButton : public mui::Button{
15 | public:
16 | FaButton( string icon, float x = 0, float y = 0, float width = 100, float height = 20, const string & fontName = "fontawesome-webfont.ttf" ) :
17 | mui::Button(icon, x, y, width, height ){
18 | this->label->fontName = fontName;
19 | this->label->commit();
20 | }
21 | };
22 | #endif
23 |
--------------------------------------------------------------------------------
/Oscilloscope.entitlements:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | com.apple.security.app-sandbox
6 |
7 | com.apple.security.application-groups
8 |
9 | com.apple.security.device.audio-input
10 |
11 | com.apple.security.device.microphone
12 |
13 | com.apple.security.device.usb
14 |
15 | com.apple.security.files.user-selected.read-write
16 |
17 | com.apple.security.network.client
18 |
19 |
20 |
21 |
--------------------------------------------------------------------------------
/Makefile:
--------------------------------------------------------------------------------
1 | # Attempt to load a config.make file.
2 | # If none is found, project defaults in config.project.make will be used.
3 | ifneq ($(wildcard config.make),)
4 | include config.make
5 | endif
6 |
7 | # make sure the the OF_ROOT location is defined
8 | ifndef OF_ROOT
9 | OF_ROOT=../../..
10 | endif
11 |
12 | copy_osx_files:
13 | cp -r $(OF_ROOT)/addons/ofxMightyUI/bin/data/ bin/$(APPNAME).app/Contents/Resources/
14 | cp -r $(OF_ROOT)/addons/ofxFontAwesome/bin/data/ bin/$(APPNAME).app/Contents/Resources/
15 |
16 |
17 | PROJECT_AFTER_OSX=make copy_osx_files
18 |
19 | # call the project makefile!
20 | include $(OF_ROOT)/libs/openFrameworksCompiled/project/makefileCommon/compile.project.mk
21 |
--------------------------------------------------------------------------------
/Project.xcconfig:
--------------------------------------------------------------------------------
1 | //THE PATH TO THE ROOT OF OUR OF PATH RELATIVE TO THIS PROJECT.
2 | //THIS NEEDS TO BE DEFINED BEFORE CoreOF.xcconfig IS INCLUDED
3 | OF_PATH = ../../..
4 |
5 | //THIS HAS ALL THE HEADER AND LIBS FOR OF CORE
6 | #include "../../../libs/openFrameworksCompiled/project/osx/CoreOF.xcconfig"
7 |
8 | //ICONS - NEW IN 0072
9 | ICON_NAME_DEBUG = icon-mac.icns
10 | ICON_NAME_RELEASE = icon-mac.icns
11 | ICON_FILE_PATH = $(OF_PATH)/libs/openFrameworksCompiled/project/osx/
12 |
13 | //IF YOU WANT AN APP TO HAVE A CUSTOM ICON - PUT THEM IN YOUR DATA FOLDER AND CHANGE ICON_FILE_PATH to:
14 | ICON_FILE_PATH = ./assets/
15 |
16 | OTHER_CFLAGS = $(OF_CORE_CFLAGS)
17 | OTHER_LDFLAGS = $(OF_CORE_LIBS) $(OF_CORE_FRAMEWORKS)
18 | HEADER_SEARCH_PATHS = $(OF_CORE_HEADERS)
19 |
--------------------------------------------------------------------------------
/.github/FUNDING.yml:
--------------------------------------------------------------------------------
1 | # These are supported funding model platforms
2 |
3 | github: [kritzikratzi] # Replace with up to 4 GitHub Sponsors-enabled usernames e.g., [user1, user2]
4 | patreon: # Replace with a single Patreon username
5 | open_collective: # Replace with a single Open Collective username
6 | ko_fi: # Replace with a single Ko-fi username
7 | tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel
8 | community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry
9 | liberapay: # Replace with a single Liberapay username
10 | issuehunt: # Replace with a single IssueHunt username
11 | otechie: # Replace with a single Otechie username
12 | custom: # Replace with up to 4 custom sponsorship URLs e.g., ['link1', 'link2']
13 |
--------------------------------------------------------------------------------
/assets/icon-mac:
--------------------------------------------------------------------------------
1 | How to use this icon:
2 |
3 | Step 1: Copy the icon to the clipboard
4 | a) Click on this file from the Finder
5 | b) Choose 'Get Info' from the 'File' menu.
6 | c) In the info window that pops up, click on the icon
7 | d) Choose 'Copy' from the 'Edit' menu.
8 | e) Close the info window
9 |
10 | Step 2: Paste the icon to the desired item
11 | a) Go to the item in the Finder that you want a custom icon
12 | b) Click the item (file, folder, disk, etc)
13 | b) Choose 'Get Info' from the 'File' menu.
14 | c) In the info window that pops up, click on the icon
15 | d) Choose 'Paste' from the 'Edit' menu.
16 | e) Close the info window
17 |
18 | Step 3:
19 | Enjoy your newly customized icon!
20 |
21 | For more thorough directions, see Apple's website at:
22 | http://www.apple.com/support/mac101/customize/6/
23 |
--------------------------------------------------------------------------------
/src/ui/Dialogs.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | #include "MuiCore.h"
4 | #include
5 |
6 | class Dialog : public mui::Container{
7 | public:
8 | Dialog();
9 | virtual ~Dialog();
10 |
11 | void layout() override;
12 | void draw() override;
13 |
14 | void show();
15 | void close();
16 |
17 | mui::Label * addLabel(const std::string & text);
18 | mui::Button * addButton(const std::string & text, const std::function & on_choice);
19 | private:
20 | void buttonPressed(const void * sender, ofTouchEventArgs & args);
21 |
22 | mui::Label * label;
23 | std::vector buttons;
24 | std::vector labels;
25 | mui::Container * blocker;
26 | };
27 |
28 | Dialog * show_yes_no_dialog(const std::string & message, const std::function & on_choice);
29 | Dialog * show_ok_dialog(const std::string & message, const std::function & on_choice);
30 |
--------------------------------------------------------------------------------
/assets/wix_config.wxi:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
--------------------------------------------------------------------------------
/openFrameworks-Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleIconFile
6 | icon-mac.icns
7 | CFBundleDevelopmentRegion
8 | English
9 | CFBundleExecutable
10 | ${EXECUTABLE_NAME}
11 | CFBundleIdentifier
12 | org.sd.oscilloscope
13 | CFBundleInfoDictionaryVersion
14 | 6.0
15 | CFBundlePackageType
16 | APPL
17 | CFBundleSignature
18 | ????
19 | CFBundleVersion
20 | 1.1.0
21 | LSApplicationCategoryType
22 | public.app-category.utilities
23 | NSHighResolutionCapable
24 |
25 | NSMicrophoneUsageDescription
26 | This app can display your microphone input as XY graph.
27 | NSServices
28 |
29 |
30 |
31 |
32 |
33 |
--------------------------------------------------------------------------------
/.gitmodules:
--------------------------------------------------------------------------------
1 | [submodule "addons/ofxMightyUI"]
2 | path = addons/ofxMightyUI
3 | url = https://github.com/kritzikratzi/ofxMightyUI
4 | [submodule "addons/ofxAvCodec"]
5 | path = addons/ofxAvCodec
6 | url = https://github.com/kritzikratzi/ofxAvCodec
7 | [submodule "addons/ofxFontAwesome"]
8 | path = addons/ofxFontAwesome
9 | url = https://github.com/kritzikratzi/ofxFontAwesome
10 | [submodule "addons/ofxFontStash2"]
11 | path = addons/ofxFontStash2
12 | url = https://github.com/kritzikratzi/ofxFontStash2
13 | [submodule "addons/ofxNative"]
14 | path = addons/ofxNative
15 | url = https://github.com/kritzikratzi/ofxNative.git
16 | [submodule "addons/ofxSpout"]
17 | path = addons/ofxSpout
18 | url = https://github.com/elliotwoods/ofxSpout.git
19 | [submodule "addons/ofxSyphon"]
20 | path = addons/ofxSyphon
21 | url = https://github.com/astellato/ofxSyphon.git
22 | [submodule "addons/ofxLibsamplerate"]
23 | path = addons/ofxLibsamplerate
24 | url = https://github.com/kritzikratzi/ofxLibsamplerate.git
25 | [submodule "addons/ofxLiblaserdock"]
26 | path = addons/ofxLiblaserdock
27 | url = https://github.com/kritzikratzi/ofxLiblaserdock.git
28 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2017 hansi raber
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/src/util/TexShare.cpp:
--------------------------------------------------------------------------------
1 | //
2 | // SharedTex.cpp
3 | // Oscilloscope
4 | //
5 | // Created by Hansi on 27/06/19.
6 | //
7 | //
8 |
9 | #include "TexShare.h"
10 | #include "ofMain.h"
11 |
12 | #ifdef TARGET_OSX
13 | #include "ofxSyphon.h"
14 | class TexShareImpl{
15 | public:
16 | ofxSyphonServer server;
17 |
18 | void setup(string name){
19 | server.setName(name);
20 | }
21 |
22 | void update(ofTexture &tex){
23 | server.publishTexture(&tex);
24 | }
25 | };
26 |
27 | #elif defined TARGET_WIN32
28 | #include "ofxSpout.h"
29 | class TexShareImpl{
30 | public:
31 | ofxSpout::Sender spoutSender;
32 |
33 | void setup(string name){
34 | spoutSender.init(name);
35 | }
36 |
37 | void update(ofTexture &tex){
38 | spoutSender.send(tex);
39 | }
40 | };
41 | #else
42 | class TexShareImpl{
43 | public:
44 | void setup(string name){}
45 | void update(ofTexture & tex){};
46 | };
47 | #endif
48 |
49 | TexShare::TexShare(){
50 | impl = make_unique();
51 | }
52 |
53 | TexShare::~TexShare() = default;
54 |
55 | void TexShare::setup(string name){
56 | impl->setup(name);
57 | }
58 |
59 | void TexShare::update(ofTexture &tex){
60 | impl->update(tex);
61 | }
62 |
--------------------------------------------------------------------------------
/src/OsciMesh.h:
--------------------------------------------------------------------------------
1 | //
2 | // OsciMesh.hpp
3 | // Oscilloscope
4 | //
5 | // Created by Hansi on 12.01.17.
6 | //
7 | //
8 |
9 | #ifndef OsciMesh_hpp
10 | #define OsciMesh_hpp
11 |
12 | #include "ofMain.h"
13 | #include "util/ShaderLoader.h"
14 |
15 | class OsciMesh{
16 | public:
17 | OsciMesh();
18 |
19 | static void init();
20 |
21 | // adds a lot of lines.
22 | // left: x coordinates (ranged -1..1)
23 | // right: y coordinates (ranged -1..1)
24 | // zMod: brightness control (ranged 0..1), nullable
25 | // stride: stride for left and right (doesn't apply to bright!)
26 | void addLines( float * left, float * right, float * bright, int N, int stride);
27 |
28 | // adds a line from a to b (xy = -1..1), with the brightness bright (0..1)
29 | inline void addLine( ofVec2f a, ofVec2f b, const float bright );
30 |
31 | void draw(ofMatrix4x4 & viewMatrix);
32 | void clear();
33 |
34 | // shader parameters
35 | float uSize;
36 | ofVec3f uRgb;
37 | float uIntensity;
38 | float uIntensityBase;
39 | float uHue;
40 |
41 | // it's a mesh. can you believe it?
42 | ofMesh mesh;
43 |
44 | private:
45 | ShaderLoader shaderLoader;
46 | ofShader shader;
47 | ofVec2f last;
48 | };
49 |
50 | #endif /* OsciMesh_hpp */
51 |
--------------------------------------------------------------------------------
/assets/wix_heat.xslt:
--------------------------------------------------------------------------------
1 |
2 |
3 |
11 |
12 |
18 |
19 |
20 |
21 |
22 | yes
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 | *** DO NOT EDIT: Generated by heat.exe; transformed by wix_heat.xsl
36 |
37 |
38 |
39 |
--------------------------------------------------------------------------------
/bin/data/shaders/osci.geom:
--------------------------------------------------------------------------------
1 | #version 120
2 | #extension GL_EXT_geometry_shader4 : enable
3 | #define EPS 1E-6
4 |
5 | varying vec3 texcoord;
6 | varying vec2 pos;
7 | uniform float uSize;
8 | uniform mat4 uMatrix;
9 |
10 | void main() {
11 | mat4 tmatrix = uMatrix;
12 | vec2 p0 = (gl_PositionIn[0]).xy;
13 | vec2 p1 = (gl_PositionIn[1]).xy;
14 | vec2 dir = p1 - p0;
15 | texcoord.z = length(dir);
16 |
17 | if (texcoord.z > EPS) {
18 | dir = dir / texcoord.z;
19 | } else {
20 | dir = vec2(1.0, 0.0);
21 | }
22 |
23 | vec2 norm = vec2(-dir.y, dir.x);
24 |
25 | dir *= uSize;
26 | norm *= uSize;
27 |
28 | texcoord.xy = vec2(-uSize, -uSize);
29 | gl_Position = tmatrix * vec4(p0 - dir - norm, 0.0, 1.0);
30 | pos = p0;
31 | EmitVertex();
32 |
33 | texcoord.xy = vec2(-uSize, uSize);
34 | gl_Position = tmatrix * vec4(p0 - dir + norm, 0.0, 1.0);
35 | EmitVertex();
36 |
37 | texcoord.xy = vec2(texcoord.z + uSize, -uSize);
38 | gl_Position = tmatrix * vec4(p1 + dir - norm, 0.0, 1.0);
39 | EmitVertex();
40 |
41 | texcoord.xy = vec2(texcoord.z + uSize, uSize);
42 | gl_Position = tmatrix * vec4(p1 + dir + norm, 0.0, 1.0);
43 | EmitVertex();
44 | }
45 |
--------------------------------------------------------------------------------
/scripts/functions.sh:
--------------------------------------------------------------------------------
1 |
2 | function readGlobal(){
3 | var=$(cat src/global_config.h | sed -e "s/#define $1 \(.*\)\$/\\1/" -e 't' -e 'd' | sed "s/\"//g")
4 | [ -z "${var}" ] && var="0"
5 | echo $var
6 | return 0
7 | }
8 |
9 | function promptWithDefault(){
10 | read -p "$1 [$2]: " var
11 | [ -z "${var}" ] && var="$2"
12 | echo "$var"
13 | return 0
14 | }
15 |
16 | function promptYesNo(){
17 | read -p "$1 [y/N] " -n 1 -r
18 | if [[ $REPLY =~ ^[Yy]$ ]]
19 | then
20 | echo
21 | return 0
22 | elif [[ $REPLY = "" ]]
23 | then
24 | return 1
25 | else
26 | echo
27 | return 1
28 | fi
29 | }
30 |
31 | function copyDataFiles(){
32 | dest=$1
33 | shift
34 | items=($@)
35 | for file in ${items[@]}
36 | do
37 | echo "- bin/data/$file -> $dest"
38 | cp -r bin/data/$file "$dest"
39 | done
40 | }
41 |
42 | function getOrCreateWixCode(){
43 | version="$1"
44 | var=""
45 | if [[ -f "assets/wix_db.txt" ]]
46 | then
47 | var=$(cat assets/wix_db.txt | sed -e "s|$1=\(.*\)\$|\\1|" -e 't' -e 'd')
48 | fi
49 |
50 | if [ -z "${var}" ]
51 | then
52 | var=$(uuidgen)
53 | addWixCode "$version" "$var"
54 | fi
55 | echo $var
56 | return 0
57 | }
58 |
59 | function addWixCode(){
60 | version="$1"
61 | code="$2"
62 |
63 | echo "$1=$2" >>assets/wix_db.txt
64 | return 0;
65 | }
--------------------------------------------------------------------------------
/src/ui/FaToggleButton.h:
--------------------------------------------------------------------------------
1 | //
2 | // FAButton.h
3 | // OsciStudio
4 | //
5 | // Created by Hansi on 04.04.15.
6 | //
7 | // 20.12.2018: added optional fontName argument. this makes it easy to use with multiple versions of fontawesome
8 |
9 |
10 | #ifndef FaToggleButton_h
11 | #define FaToggleButton_h
12 |
13 | #include "ofxMightyUI.h"
14 | #include "ofMain.h"
15 |
16 | class FaToggleButton : public mui::ToggleButton{
17 | public:
18 | FaToggleButton( string icon, string selectedIcon, float x = 0, float y = 0, float width = 100, float height = 20, const string & fontName = "fontawesome-webfont.ttf" ) :
19 | mui::ToggleButton(icon, x, y, width, height ), wasSelected(false){
20 | this->icon = icon;
21 | this->selectedIcon = selectedIcon;
22 | this->label->fontName = fontName;
23 | this->label->commit();
24 | this->fg = ofColor(255);
25 |
26 | ofAddListener( onPress, this, &FaToggleButton::onButtonPressed );
27 | }
28 |
29 | string icon;
30 | string selectedIcon;
31 |
32 | bool wasSelected;
33 |
34 | void commit(){
35 | if( wasSelected != selected ){
36 | wasSelected = selected;
37 | label->text = selected? selectedIcon:icon;
38 | label->commit();
39 | }
40 | }
41 |
42 | private:
43 | void onButtonPressed( const void * sender, ofTouchEventArgs &touch ){
44 | commit();
45 | }
46 | };
47 | #endif
48 |
--------------------------------------------------------------------------------
/bin/data/shaders/osci.frag:
--------------------------------------------------------------------------------
1 | #version 120
2 | #define EPS 1E-6
3 | #define TAU 6.283185307179586
4 | #define TAUR 2.5066282746310002
5 | #define SQRT2 1.4142135623730951
6 | uniform float uSize;
7 | uniform float uIntensity;
8 | uniform float uHue;
9 | uniform vec3 uRgb;
10 | uniform float uIntensityBase;
11 | varying vec4 color;
12 | varying float brightness;
13 |
14 | float erf(float x) {
15 | float s = sign(x), a = abs(x);
16 | x = 1.0 + (0.278393 + (0.230389 + (0.000972 + 0.078108 * a) * a) * a) * a;
17 | x *= x;
18 | return s - s / (x * x);
19 | }
20 |
21 | void main (void)
22 | {
23 | float len = color.z; // we pass in length ...
24 | vec2 xy = color.xy; // and xy through color
25 | float alpha;
26 |
27 | float sigma = uSize/(2.0+2.0*1000.0*uSize/50.0);
28 | /* if (len < EPS && ) {
29 | // If the beam segment is too short, just calculate intensity at the position.
30 | alpha = exp(-len*len/(2.0*sigma*sigma))/2.0/sqrt(uSize);
31 | alpha = 0.0;
32 | } else {*/
33 | // Otherwise, use analytical integral for accumulated intensity.
34 | alpha = erf(xy.x/SQRT2/sigma) - erf((xy.x-len)/SQRT2/sigma);
35 | alpha *= exp(-xy.y*xy.y/(2.0*sigma*sigma))/2.0/len*uSize;
36 | // }
37 |
38 | alpha = pow(alpha,1.0-uIntensityBase)*(0.01+min(0.99,uIntensity*3.0));
39 | gl_FragColor = vec4(uRgb, alpha*brightness);
40 |
41 | }
42 |
--------------------------------------------------------------------------------
/src/util/WickedLasers.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | #include "ofxMightyUI.h"
4 | #include "util/Audio.h"
5 | #include "samplerate.h"
6 | #include "OsciMesh.h"
7 |
8 | class CircleBuffer;
9 | class LaserdockDevice;
10 | struct LaserdockSample;
11 |
12 |
13 | class WickedLasers {
14 | public:
15 | WickedLasers();
16 | virtual ~WickedLasers();
17 |
18 | void addBuffer(float* buffer, int bufferSize, int nChannels, int sampleRate);
19 | void die();
20 |
21 | int bufferSize;
22 | MonoSample left;
23 | MonoSample right;
24 |
25 | float lx, ly;
26 | float s;
27 |
28 | void connect();
29 | void disconnect();
30 | bool isConnected();
31 | void resetBuffers();
32 |
33 | private:
34 |
35 | void processIncomming();
36 | void laser_fill_samples(LaserdockSample* samples, const uint32_t count, float* left, float* right);
37 | void of_update(ofEventArgs& args);
38 | void of_exit(ofEventArgs& args);
39 | ofVec3f last;
40 |
41 | float intensity = 1.0;
42 | bool invertX = false;
43 | bool invertY = false;
44 | bool flipXY = false;
45 |
46 | shared_ptr laserDevice;
47 | LaserdockSample* laserSamples; // we leak this
48 | mutex laserDeviceMutex;
49 |
50 | int visualSampleRate = 60000;
51 | vector targetBuffer;
52 |
53 | thread resampleThread;
54 | MonoSample incomming;
55 | static const int chunkSize = 1024;
56 | int sampleRate = 44100;
57 |
58 | SRC_STATE* resampleState;
59 | SRC_DATA resampleData;
60 |
61 | bool connected = false;
62 | bool shouldResetBuffers = false;
63 | bool exiting = false;
64 | };
65 |
--------------------------------------------------------------------------------
/src/ui/ExportScreen.h:
--------------------------------------------------------------------------------
1 | //
2 | // ExportScreen.hpp
3 | // Oscilloscope
4 | //
5 | // Created by Hansi on 29.05.18.
6 | //
7 | //
8 |
9 | #ifndef ExportScreen_hpp
10 | #define ExportScreen_hpp
11 |
12 | #include "ofMain.h"
13 | #include "MuiCore.h"
14 |
15 | class ofxAvVideoWriter;
16 |
17 | enum class ExportFormat;
18 |
19 | struct ExportFileInfo{
20 | ofFile file;
21 | bool exists;
22 | std::string error;
23 | int sampleRate;
24 | ExportFormat format;
25 | };
26 |
27 | class ExportScreen : public mui::Container{
28 | public:
29 | ExportScreen();
30 | ~ExportScreen();
31 |
32 | void show(const ofFile & file);
33 | void layout() override;
34 |
35 | void commit();
36 |
37 | const std::filesystem::path getFile();
38 | const ExportFileInfo getFileInfo();
39 | ExportFormat getFormat();
40 | private:
41 |
42 | void buttonPressed(const void * sender, ofTouchEventArgs & args );
43 | void beginExport();
44 |
45 | mui::Container * view;
46 |
47 | mui::Label * filePickerLabel;
48 | mui::Label * formatSelectLabel;
49 | mui::Label * sizeLabel;
50 | mui::Label * sizeXLabel;
51 | mui::Label * sizeAtLabel;
52 | mui::Label * sizeFpsLabel;
53 |
54 | mui::TextArea * widthText;
55 | mui::TextArea * heightText;
56 | mui::TextArea * fpsText;
57 |
58 | mui::SegmentedSelect * formatSelect;
59 |
60 | shared_ptr writer;
61 | mui::FilePicker * filePicker;
62 | mui::Button * exportButton;
63 | mui::Button * cancelButton;
64 | mui::Button * resetButton;
65 |
66 | string defaultName;
67 | };
68 |
69 |
70 |
71 | #endif /* ExportScreen_hpp */
72 |
--------------------------------------------------------------------------------
/src/ui/ConfigView.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | #include "ofxMightyUI.h"
4 | #include "FMenu.h"
5 |
6 | class ConfigView : public mui::Container{
7 | public:
8 | ConfigView();
9 |
10 | void update() override;
11 | void draw() override;
12 | void layout() override;
13 |
14 | void touchDown( ofTouchEventArgs &touch ) override;
15 | void touchMoved( ofTouchEventArgs &touch ) override;
16 | void touchUp( ofTouchEventArgs &touch ) override;
17 | void touchDoubleTap( ofTouchEventArgs &touch ) override;
18 |
19 |
20 | FDropdown * outDevicePicker;
21 | mui::Label * emulationLabel;
22 | mui::SegmentedSelect * emulationMode;
23 |
24 | mui::Label* laserConnectLabel;
25 | mui::Button* laserConnect;
26 | mui::Label* laserSizeLabel;
27 | mui::SliderWithLabel* laserSize;
28 | mui::Label* laserIntensityLabel;
29 | mui::SliderWithLabel* laserIntensity;
30 | mui::Label* laserOffsetLabel;
31 | mui::SliderWithLabel* laserOffsetX;
32 | mui::SliderWithLabel* laserOffsetY;
33 | mui::Label* laserKeystoneLabel;
34 | mui::SliderWithLabel* laserKeystoneX;
35 | mui::SliderWithLabel* laserKeystoneY;
36 |
37 | void fromGlobals();
38 | void toGlobals();
39 |
40 | void buttonPressed( const void * sender, ofTouchEventArgs & args );
41 | void emulationModeChanged(const void * sender, int & value);
42 |
43 | private:
44 | void pushLabel( string text );
45 | void outDevicePickerChanged(const void * sender, string & value);
46 | void gotMessage(const void * sender, ofMessage & msg);
47 | void addDeviceOptions();
48 |
49 | bool showLaserConfig{ false };
50 | vector hiddenLaserUi;
51 | };
52 |
--------------------------------------------------------------------------------
/assets/Images.xcassets/AppIcon.appiconset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "size" : "16x16",
5 | "idiom" : "mac",
6 | "filename" : "appicon-16.png",
7 | "scale" : "1x"
8 | },
9 | {
10 | "size" : "16x16",
11 | "idiom" : "mac",
12 | "filename" : "appicon-32.png",
13 | "scale" : "2x"
14 | },
15 | {
16 | "size" : "32x32",
17 | "idiom" : "mac",
18 | "filename" : "appicon-32.png",
19 | "scale" : "1x"
20 | },
21 | {
22 | "size" : "32x32",
23 | "idiom" : "mac",
24 | "filename" : "appicon-64.png",
25 | "scale" : "2x"
26 | },
27 | {
28 | "size" : "128x128",
29 | "idiom" : "mac",
30 | "filename" : "appicon-128.png",
31 | "scale" : "1x"
32 | },
33 | {
34 | "size" : "128x128",
35 | "idiom" : "mac",
36 | "filename" : "appicon-256.png",
37 | "scale" : "2x"
38 | },
39 | {
40 | "size" : "256x256",
41 | "idiom" : "mac",
42 | "filename" : "appicon-256.png",
43 | "scale" : "1x"
44 | },
45 | {
46 | "size" : "256x256",
47 | "idiom" : "mac",
48 | "filename" : "appicon-512.png",
49 | "scale" : "2x"
50 | },
51 | {
52 | "size" : "512x512",
53 | "idiom" : "mac",
54 | "filename" : "appicon-512.png",
55 | "scale" : "1x"
56 | },
57 | {
58 | "size" : "512x512",
59 | "idiom" : "mac",
60 | "filename" : "appicon-1024.png",
61 | "scale" : "2x"
62 | }
63 | ],
64 | "info" : {
65 | "version" : 1,
66 | "author" : "xcode"
67 | }
68 | }
--------------------------------------------------------------------------------
/src/util/OsciVideoWriter.hpp:
--------------------------------------------------------------------------------
1 | //
2 | // OsciVideoWriter.hpp
3 | // Oscilloscope
4 | //
5 | // Created by Hansi on 06.06.18.
6 | //
7 | //
8 | //
9 |
10 | /// \brief Class to write video (in sync, so it's very slow!)
11 |
12 | #ifndef OsciVideoWriter_hpp
13 | #define OsciVideoWriter_hpp
14 |
15 | #include
16 | #include "ofPixels.h"
17 |
18 | struct AVFormatContext;
19 | struct AVOutputFormat;
20 | struct AVStream;
21 | struct AVFrame;
22 | struct AVPacket;
23 | struct SwsContext;
24 |
25 | class OsciVideoWriter{
26 | public:
27 |
28 | struct WorkData{
29 |
30 | AVFormatContext* out_ctx = nullptr;
31 | AVOutputFormat* out_fmt = nullptr;
32 | AVStream* out_video_st = nullptr;
33 | AVStream* out_audio_st = nullptr;
34 |
35 | // temp audio buffers
36 | uint8_t out_audio_buffer[32 * 2048 * 8] = { 0 };
37 | size_t out_audio_buffer_offset = 0;
38 |
39 | // number of written audio frames
40 | int64_t audio_pts = 0;
41 | int64_t audio_pts_pkt = 0;
42 |
43 | // temp video buffers
44 | SwsContext* sws_ctx;
45 | AVFrame* in_frame = nullptr;
46 | AVFrame* out_frame = nullptr;
47 |
48 | // number of written video frames
49 | int64_t video_frame_num = 0;
50 | };
51 |
52 | struct OutputConfig{
53 | int video_framerate;
54 | int video_width;
55 | int video_height;
56 |
57 | int audio_sample_rate;
58 | int audio_n_channels;
59 | };
60 |
61 | OsciVideoWriter();
62 | ~OsciVideoWriter();
63 |
64 | /// \brief Adds the video file. Returns true on success
65 | bool open(std::string outputFile, const OutputConfig & config);
66 |
67 | /// \brief Adds a video frame from pixels. If the pixel size doesn't match, it fails.
68 | void addVideoFrame(const ofPixels & pixels);
69 |
70 | /// \brief Adds interleaved samples
71 | void addAudioFrame(float * samples, int numSamples);
72 |
73 | /// \brief Closes the file. Always call this, lots of file info must be written at the end.
74 | void close();
75 |
76 | bool isOpen();
77 |
78 |
79 | private:
80 | OutputConfig config;
81 | bool is_open = false;
82 |
83 | WorkData wd;
84 | };
85 |
86 | #endif /* OsciVideoWriter_hpp */
87 |
--------------------------------------------------------------------------------
/Oscilloscope.sln:
--------------------------------------------------------------------------------
1 | Microsoft Visual Studio Solution File, Format Version 12.00
2 | # Visual Studio 15
3 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Oscilloscope", "Oscilloscope.vcxproj", "{7FD42DF7-442E-479A-BA76-D0022F99702A}"
4 | EndProject
5 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "openframeworksLib", "..\..\..\libs\openFrameworksCompiled\project\vs\openframeworksLib.vcxproj", "{5837595D-ACA9-485C-8E76-729040CE4B0B}"
6 | EndProject
7 | Global
8 | GlobalSection(SolutionConfigurationPlatforms) = preSolution
9 | Debug|Win32 = Debug|Win32
10 | Debug|x64 = Debug|x64
11 | Release|Win32 = Release|Win32
12 | Release|x64 = Release|x64
13 | EndGlobalSection
14 | GlobalSection(ProjectConfigurationPlatforms) = postSolution
15 | {7FD42DF7-442E-479A-BA76-D0022F99702A}.Debug|Win32.ActiveCfg = Debug|Win32
16 | {7FD42DF7-442E-479A-BA76-D0022F99702A}.Debug|Win32.Build.0 = Debug|Win32
17 | {7FD42DF7-442E-479A-BA76-D0022F99702A}.Debug|x64.ActiveCfg = Debug|x64
18 | {7FD42DF7-442E-479A-BA76-D0022F99702A}.Debug|x64.Build.0 = Debug|x64
19 | {7FD42DF7-442E-479A-BA76-D0022F99702A}.Release|Win32.ActiveCfg = Release|Win32
20 | {7FD42DF7-442E-479A-BA76-D0022F99702A}.Release|Win32.Build.0 = Release|Win32
21 | {7FD42DF7-442E-479A-BA76-D0022F99702A}.Release|x64.ActiveCfg = Release|x64
22 | {7FD42DF7-442E-479A-BA76-D0022F99702A}.Release|x64.Build.0 = Release|x64
23 | {5837595D-ACA9-485C-8E76-729040CE4B0B}.Debug|Win32.ActiveCfg = Debug|Win32
24 | {5837595D-ACA9-485C-8E76-729040CE4B0B}.Debug|Win32.Build.0 = Debug|Win32
25 | {5837595D-ACA9-485C-8E76-729040CE4B0B}.Debug|x64.ActiveCfg = Debug|x64
26 | {5837595D-ACA9-485C-8E76-729040CE4B0B}.Debug|x64.Build.0 = Debug|x64
27 | {5837595D-ACA9-485C-8E76-729040CE4B0B}.Release|Win32.ActiveCfg = Release|Win32
28 | {5837595D-ACA9-485C-8E76-729040CE4B0B}.Release|Win32.Build.0 = Release|Win32
29 | {5837595D-ACA9-485C-8E76-729040CE4B0B}.Release|x64.ActiveCfg = Release|x64
30 | {5837595D-ACA9-485C-8E76-729040CE4B0B}.Release|x64.Build.0 = Release|x64
31 | EndGlobalSection
32 | GlobalSection(SolutionProperties) = preSolution
33 | HideSolutionNode = FALSE
34 | EndGlobalSection
35 | EndGlobal
36 |
--------------------------------------------------------------------------------
/scripts/prepare.sh:
--------------------------------------------------------------------------------
1 | #! /bin/bash
2 | # copies required libs/files to the bin/data folder.
3 | # it is suggested that you clean up first!
4 |
5 | pushd `dirname $0`
6 | echo "----------------------------"
7 | cd ..
8 | platform=$1
9 |
10 | if [ "$platform" == "" ]; then
11 | echo "Usage: scripts/prepare.sh "
12 | echo ""
13 | echo "Platform: One of the following: "
14 | echo " linux, linux64, win32, win64"
15 | elif [[ "$platform" == "osx" ]]; then
16 | echo XCode-build manages it all. Done!
17 | echo "----------------------------"
18 | elif [[ "$platform" == "linux" ]]; then
19 | echo "Linux (32bit)"
20 | echo "----------------------------"
21 | mkdir bin/libs
22 | echo Copying avcodec libs ...
23 | cp -R addons/ofxAvCodec/libs/avcodec/lib/linux/* bin/libs/
24 | echo Copying mightyUI data ...
25 | cp -R addons/ofxMightyUI/bin/data/* bin/data/
26 | echo Copying fontawsome data ...
27 | cp -R addons/ofxFontAwesome/bin/data/* bin/data/
28 | elif [[ "$platform" == "linux64" ]]; then
29 | echo "Linux (64 bit)"
30 | echo "----------------------------"
31 | echo Copying avcodec libs ...
32 | mkdir bin/libs
33 | cp -R addons/ofxAvCodec/libs/avcodec/lib/linux64/* bin/libs/
34 | echo Copying mightyUI data ...
35 | cp -R addons/ofxMightyUI/bin/data/* bin/data/
36 | echo Copying fontawsome data ...
37 | cp -R addons/ofxFontAwesome/bin/data/* bin/data/
38 | elif [[ "$platform" == "win32" ]]; then
39 | echo "Windows (32bit)"
40 | echo "----------------------------"
41 | echo Copying avcodec libs ...
42 | cp -R addons/ofxAvCodec/libs/avcodec/lib/vs/Win32/*.dll bin/
43 | echo Copying mightyUI data ...
44 | cp -R addons/ofxMightyUI/bin/data/* bin/data/
45 | echo Copying fontawsome data ...
46 | cp -R addons/ofxFontAwesome/bin/data/* bin/data/
47 | elif [[ "$platform" == "win64" ]]; then
48 | echo "Windows (64bit)"
49 | echo "----------------------------"
50 | echo Copying avcodec libs ...
51 | cp -R addons/ofxAvCodec/libs/avcodec/lib/vs/x64/*.dll bin/
52 | echo Copying mightyUI data ...
53 | cp -R addons/ofxMightyUI/bin/data/* bin/data/
54 | echo Copying fontawsome data ...
55 | cp -R addons/ofxFontAwesome/bin/data/* bin/data/
56 | else
57 | echo Unsupported platform: $platform
58 | fi
59 |
60 | popd
--------------------------------------------------------------------------------
/scripts/osx-notarize.sh:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 | # notarizes and zip a signed app
3 | # run this in the folder where your app sits!
4 | # otherwise you end up with things in weird places
5 | appFolder="$1"
6 | bundleId="$2"
7 | teamId="$3"
8 | ascProvider="$4"
9 | username="$5"
10 | password="$6"
11 | zipDest="$7"
12 |
13 | if [[ -z "$appFolder" || -z "$bundleId" || -z "$username" || -z "$password" || -z "$zipDest" || -z "$teamId" ]]
14 | then
15 | echo "Usage: $0 "
16 | exit
17 | fi
18 |
19 | appFolderName=$(basename "$appFolder")
20 | appDest="$distDir/$appFolderName"
21 | appName=${appFolderName%.app}
22 | me="$(dirname $0)"
23 |
24 | echo "Zipping it up..."
25 | if [ -f "$zipDest" ]
26 | then
27 | rm "$zipDest"
28 | fi
29 | ditto -c -k --keepParent "$appName.app" "$zipDest"
30 |
31 | echo "Uploading for notarization..."
32 | echo xcrun altool -asc-provider $ascProvider --team-id $teamId --notarize-app --primary-bundle-id "$bundleId" --username "$username" --password "$password" --file "$zipDest"
33 | uuid="$(xcrun altool -asc-provider $ascProvider --team-id $teamId --notarize-app --primary-bundle-id "$bundleId" --username "$username" --password "$password" --file "$zipDest" 2>&1 | grep RequestUUID | cut -d " " -f 3)"
34 |
35 | if [ -z "$uuid" ]
36 | then
37 | echo "Got no uuid ($uuid) as output of altool, exiting"
38 | exit 1
39 | else
40 | echo "Got uuid $uuid from altool"
41 | fi
42 |
43 | while true
44 | do
45 | output="$(xcrun altool --team-id $teamId --notarization-info "$uuid" -u "$username" -p "$password" 2>&1)"
46 | res=$(echo "$output" | grep "Status Message" | xargs | cut -d " " -f 3-99)
47 | if [ -z "$res" ]
48 | then
49 | echo " > waiting for notarization..."
50 | else
51 | if [ "$res" == "Package Approved" ]
52 | then
53 | echo " > Package check ok!"
54 | break
55 | else
56 | url=$(echo "$output" | grep "LogFileURL" | xargs | cut -d " " -f 2-99)
57 | curl $url
58 | echo " > Package not ok, got \"$output\""
59 | exit 1
60 | fi
61 | fi
62 | done
63 |
64 | echo "Deleting zip"
65 | rm "$zipDest"
66 | echo "Running stapler on the app"
67 | xcrun stapler staple "$appName.app"
68 | echo "Recreating final zip"
69 | ditto -c -k --keepParent "$appName.app" "$zipDest"
70 |
71 |
72 |
73 |
74 |
--------------------------------------------------------------------------------
/src/util/ShaderLoader.h:
--------------------------------------------------------------------------------
1 | //
2 | // ShaderLoader.h
3 | // Oscilloscope
4 | //
5 | // Created by Hansi on 21.08.15.
6 | //
7 | //
8 |
9 | #ifndef Oscilloscope_ShaderLoader_h
10 | #define Oscilloscope_ShaderLoader_h
11 |
12 | #include
13 | #include
14 | #include
15 | #include
16 | #include
17 |
18 | #include
19 | #include "ofMain.h"
20 | #include "../globals.h"
21 |
22 | class ShaderLoader{
23 | string fragFile;
24 | string vertFile;
25 | string geomFile;
26 | ofShader * shader;
27 |
28 | long fragTime = 0;
29 | long vertTime;
30 | long geomTime;
31 |
32 |
33 | public:
34 |
35 | ShaderLoader(){
36 |
37 | }
38 |
39 | void setup( ofShader * shader, string baseName ){
40 | this->shader = shader;
41 | fragFile = ofxToReadonlyDataPath(baseName + ".frag");
42 | vertFile = ofxToReadonlyDataPath(baseName + ".vert");
43 | geomFile = ofxToReadonlyDataPath(baseName + ".geom");
44 |
45 | ofAddListener( ofEvents().update, this, &ShaderLoader::of_update, OF_EVENT_ORDER_BEFORE_APP );
46 | ofAddListener( ofEvents().draw, this, &ShaderLoader::of_draw, OF_EVENT_ORDER_AFTER_APP );
47 | }
48 |
49 | ~ShaderLoader(){
50 | ofRemoveListener( ofEvents().update, this, &ShaderLoader::of_update, OF_EVENT_ORDER_BEFORE_APP );
51 | ofRemoveListener( ofEvents().draw, this, &ShaderLoader::of_draw, OF_EVENT_ORDER_AFTER_APP );
52 | }
53 |
54 | void of_update( ofEventArgs &args ){
55 | if( ofGetFrameNum() % 50 == 0 || fragTime == 0){
56 | time_t fragTimeNow = mtime(fragFile);
57 | time_t vertTimeNow = mtime(vertFile);
58 | time_t geomTimeNow = mtime(geomFile);
59 | if( fragTimeNow != fragTime || vertTimeNow != vertTime || geomTimeNow != geomTime ){
60 | cout << "Reload ... " << endl;
61 | if( shader->isLoaded() ) shader->unload();
62 | shader->load(vertFile, fragFile/*, geomFile*/); // don't use geometry shaders because intelhd3000?
63 | }
64 |
65 | fragTime = fragTimeNow;
66 | vertTime = vertTimeNow;
67 | geomTime = geomTimeNow;
68 | }
69 | }
70 |
71 |
72 | void of_draw( ofEventArgs &args ){
73 | // TODO:
74 | // draw in case of compilation error!
75 | }
76 |
77 |
78 |
79 |
80 |
81 | // http://stackoverflow.com/a/10446821/347508
82 | static time_t mtime(string path) {
83 | struct stat attr;
84 | stat(path.c_str(), &attr);
85 | time_t res = attr.st_mtime;
86 | return res;
87 | }
88 | };
89 |
90 |
91 | #endif
92 |
--------------------------------------------------------------------------------
/src/ui/Playlist.h:
--------------------------------------------------------------------------------
1 | //
2 | // Playlist.hpp
3 | // Oscilloscope
4 | //
5 | // Created by Hansi on 05.08.17.
6 | //
7 | //
8 |
9 | #ifndef Playlist_hpp
10 | #define Playlist_hpp
11 |
12 | #include "ofxMightyUI.h"
13 |
14 | class PlaylistItem;
15 | class FaButton;
16 | class FaToggleButton;
17 |
18 | struct PlaylistItemRef{
19 | PlaylistItemRef(){}
20 | PlaylistItemRef(size_t id, string filename) : id(id), filename(filename){}
21 | size_t id{0};
22 | string filename{""};
23 | };
24 |
25 | class Playlist : public mui::Container{
26 | public:
27 | Playlist();
28 | ~Playlist();
29 |
30 | void draw() override;
31 | void update() override;
32 | void layout() override;
33 | bool fileDragged(ofDragInfo & args) override;
34 | bool keyPressed(ofKeyEventArgs & args) override;
35 |
36 | PlaylistItemRef addFile(ofFile file, double duration = -2 );
37 | void removeAllFiles();
38 |
39 | void save(ostream & out);
40 | void load(istream & in);
41 |
42 |
43 | // finds the next item in the playlist
44 | // if id=0, the first item is returned.
45 | // returns: {0,""} if there is no further item, otherwise returns the thing you want.
46 | PlaylistItemRef getNextItemInPlaylist(size_t id);
47 | string getItemPath(size_t id);
48 |
49 | enum class LoopMode { all_once, all_repeat, one_repeat };
50 |
51 | private:
52 | PlaylistItemRef getNextItem(size_t id);
53 |
54 | void setLoopMode(LoopMode mode);
55 | void buttonPressed(const void * sender, ofTouchEventArgs & args);
56 |
57 | mui::ScrollPane * scroller;
58 | bool checkNewFiles = false;
59 | size_t nextItemId = 1;
60 | map filenames;
61 |
62 | FaButton * loopModeButton;
63 | FaToggleButton * shuffleToggle;
64 | FaToggleButton * onlyOneButton;
65 |
66 | FaButton * clearButton;
67 | FaButton * addFileButton;
68 | };
69 |
70 |
71 | class PlaylistItem : public mui::Label{
72 | public:
73 | PlaylistItem(size_t itemId, ofFile file, double duration = -2);
74 |
75 | void touchDown(ofTouchEventArgs & args) override;
76 | void touchUp(ofTouchEventArgs & args) override;
77 | void touchUpOutside(ofTouchEventArgs & args) override;
78 | void mouseEnter(ofMouseEventArgs &args) override;
79 | void mouseExit(ofMouseEventArgs &args) override;
80 | void drawBackground() override;
81 |
82 |
83 | void updateDuration(bool & alreadyScanned, bool & shouldRemove );
84 |
85 | size_t itemId;
86 | bool selected = false;
87 | bool hovering = false;
88 | ofFile file;
89 | double duration = -2; // -2 = didn't look, -1 = error, > 0 is okay
90 | };
91 |
92 | #endif /* Playlist_hpp */
93 |
--------------------------------------------------------------------------------
/src/ofxIniSettings/ofxIniExtras.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 | #include "ofMain.h"
3 |
4 | // this is basically https://github.com/companje/ofxExtras
5 | // with lots things deleted.
6 | void ofxExit(string error );
7 | bool ofxFileExists(string filename);
8 | bool ofxStringEndsWith(string str, string key);
9 | string ofxFormatString(string format, int number);
10 | string ofxFormatString(string format, string s);
11 | string ofxReplaceString(string input, string replace, string by);
12 | void ofxSaveString(string filename, string str);
13 | void ofxSaveStrings(string filename, vector lines);
14 | string ofxTrimStringRight(string str);
15 | string ofxTrimStringLeft(string str);
16 | string ofxTrimString(string str);
17 | string ofxStringBeforeFirst(string str, string key);
18 | string ofxStringAfterFirst(string str, string key);
19 | string ofxStringAfterLast(string str, string key);
20 | string ofxStringBeforeLast(string str, string key);
21 | bool ofxContains(vector keys, string key);
22 | float ofxDist(float ax, float ay, float az, float bx, float by, float bz);
23 | bool ofxColorMatch(ofColor a, ofColor b, int tolerance);
24 | void ofxScale(float scale);
25 | void ofxSetHexColor(int hexColor, int a); //alpha between 0..255
26 | void ofxSetColor(ofColor c);
27 | void ofxSetColorHSB(int h, int s, int b, int a);
28 | bool ofxToBoolean(string str); //rick 3-1-2008
29 | bool ofxToBoolean(float f);
30 | int ofxToInteger(string str);
31 | string ofxToString(char ch);
32 | string ofxToString(unsigned char ch);
33 | string ofxToString(string str);
34 | string ofxToString(float f);
35 | string ofxToString(bool value);
36 | string ofxToString(int value);
37 | string ofxToString(ofRectangle v);
38 | ofColor ofxToColor(int hexColor);
39 | ofColor ofxToColor(unsigned char r, unsigned char g, unsigned char b);
40 | ofColor ofxToColor(ofVec4f v);
41 | ofColor ofxToColor(ofVec3f v, int alpha);
42 | string ofxToHexString(int value, int digits=6);
43 | int ofxToInteger(ofColor c);
44 | string ofxToString(ofQuaternion q);
45 | ofQuaternion ofxToQuaternion(string str);
46 | string ofxToHex(char c);
47 | void ofxRotate(ofVec3f v);
48 | void ofxRotate(ofQuaternion q);
49 | void ofxRotate(float angle, ofVec3f v);
50 | void ofxTranslate(ofVec3f v);
51 | void ofxScale(ofVec3f v);
52 | ofVec2f ofxToVec2f(string str);
53 | ofVec3f ofxToVec3f(string str);
54 | ofVec3f ofxToVec3f(float *a);
55 | ofVec4f ofxToVec4f(string str);
56 | ofRectangle ofxToRectangle(ofVec4f v);
57 | ofRectangle ofxToRectangle(string str);
58 | string ofxToString(ofVec2f v);
59 | string ofxToString(ofVec3f v, int precision);
60 | string ofxToString(ofVec4f v);
61 | string ofxToString(ofMatrix4x4 m);
62 | ofMatrix4x4 ofxToMatrix4x4(string s);
63 | vector ofxToFloatVector(string s, string delimiter);
64 |
--------------------------------------------------------------------------------
/assets/wix_main.wxs:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
9 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
27 |
28 |
29 |
30 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 | 1
56 | 1
61 |
62 |
63 |
64 |
--------------------------------------------------------------------------------
/icon.rc:
--------------------------------------------------------------------------------
1 | // Microsoft Visual C++ generated resource script.
2 | //
3 | #include
4 | #include "resource.h"
5 | /////////////////////////////////////////////////////////////////////////////
6 | // English (United States) resources
7 |
8 | #if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
9 | LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
10 | #pragma code_page(1252)
11 |
12 | /////////////////////////////////////////////////////////////////////////////
13 | //
14 | // Icon
15 | //
16 |
17 | // Icon with lowest ID value placed first to ensure application icon
18 | // remains consistent on all systems.
19 | MAIN_ICON ICON "icon.ico"
20 |
21 |
22 | #ifdef APSTUDIO_INVOKED
23 | /////////////////////////////////////////////////////////////////////////////
24 | //
25 | // TEXTINCLUDE
26 | //
27 |
28 | 1 TEXTINCLUDE
29 | BEGIN
30 | "resource.h\0"
31 | END
32 |
33 | 2 TEXTINCLUDE
34 | BEGIN
35 | "\0"
36 | END
37 |
38 | 3 TEXTINCLUDE
39 | BEGIN
40 | "\r\n"
41 | "\0"
42 | END
43 |
44 | #endif // APSTUDIO_INVOKED
45 |
46 |
47 | /////////////////////////////////////////////////////////////////////////////
48 | //
49 | // Version
50 | //
51 |
52 | VS_VERSION_INFO VERSIONINFO
53 | FILEVERSION 1,1,0,0
54 | PRODUCTVERSION 1,1,0,0
55 | FILEFLAGSMASK 0x3fL
56 | #ifdef _DEBUG
57 | FILEFLAGS 0x1L
58 | #else
59 | FILEFLAGS 0x0L
60 | #endif
61 | FILEOS 0x40004L
62 | FILETYPE 0x1L
63 | FILESUBTYPE 0x0L
64 | BEGIN
65 | BLOCK "StringFileInfo"
66 | BEGIN
67 | BLOCK "000904b0"
68 | BEGIN
69 | VALUE "CompanyName", "Hansi Raber"
70 | VALUE "FileDescription", "Oscilloscope"
71 | VALUE "FileVersion", "1.1.0"
72 | VALUE "InternalName", "Oscilloscope.exe"
73 | VALUE "LegalCopyright", "Copyleft 2020, https://github.com/kritzikratzi/Oscilloscope"
74 | VALUE "OriginalFilename", "Oscilloscope.exe"
75 | VALUE "ProductName", "Oscilloscope"
76 | VALUE "ProductVersion", "1.1.0"
77 | END
78 | END
79 | BLOCK "VarFileInfo"
80 | BEGIN
81 | VALUE "Translation", 0x9, 1200
82 | END
83 | END
84 |
85 | #endif // English (United States) resources
86 | /////////////////////////////////////////////////////////////////////////////
87 |
88 |
89 |
90 | #ifndef APSTUDIO_INVOKED
91 | /////////////////////////////////////////////////////////////////////////////
92 | //
93 | // Generated from the TEXTINCLUDE 3 resource.
94 | //
95 |
96 |
97 | /////////////////////////////////////////////////////////////////////////////
98 | #endif // not APSTUDIO_INVOKED
99 |
100 |
--------------------------------------------------------------------------------
/src/globals.h:
--------------------------------------------------------------------------------
1 | //
2 | // globals.h
3 | // Oscilloscope
4 | //
5 | // Created by Hansi on 26.07.15.
6 | //
7 | //
8 |
9 | #ifndef __Oscilloscope__globals__
10 | #define __Oscilloscope__globals__
11 |
12 | #include
13 | #include "OsciAvAudioPlayer.h"
14 | #include "ofxIniSettings.h"
15 |
16 | extern string ofxToReadWriteableDataPath( string filename );
17 | extern string ofxToReadonlyDataPath( string filename );
18 | extern void setWindowRepresentedFilename( string filename );
19 |
20 | string ofxFormatTime(double seconds);
21 |
22 | enum class ExportFormat{H264=1,IMAGE_SEQUENCE_PNG=2,IMAGE_SEQUENCE_TIFF=3};
23 | class WickedLasers;
24 | struct ma_context;
25 |
26 | #define globals (Globals::instance)
27 | class Globals{
28 | public:
29 | Globals(){};
30 | void init();
31 |
32 | struct AudioConfig {
33 | string name;
34 | int bufferSize;
35 | int sampleRate;
36 | };
37 |
38 | ma_context * context;
39 |
40 | // audio settings
41 | AudioConfig out_requested{ "",0, 0 };
42 | AudioConfig out_actual{ "",512, 44100 };
43 |
44 | bool micActive{ false };
45 | AudioConfig in_requested{ "",0, 0 };
46 | AudioConfig in_actual{ "",512, 44100 };
47 |
48 | // display settings
49 | float scale{1.0};
50 | bool invertX{false};
51 | bool invertY{false};
52 | bool flipXY{false};
53 | bool zModulation{true};
54 |
55 | float strokeWeight{10}; // 1...20
56 | float timeStretch{1}; // 0.1-2.0
57 | float blur{30}; // 0...255
58 | float intensity{0.4f}; // 0...1
59 | float afterglow{0.5f}; // 0...1
60 | int analogMode{0}; // 0=digital, 1=analog, 2=superanalog
61 |
62 | int numPts{20}; // 1...+inf?
63 | float hue{50}; // 0...360
64 |
65 | float outputVolume{1};
66 | float inputVolume{1};
67 |
68 | int exportWidth{1920};
69 | int exportHeight{1080};
70 | int exportFrameRate{60};
71 | int exportSampleRate{96000};
72 | ExportFormat exportFormat{ExportFormat::IMAGE_SEQUENCE_PNG};
73 |
74 | float secondsBeforeHidingMenu{0.5};
75 |
76 | bool alwaysOnTop{false};
77 |
78 | // laser stuff. none of this is ever stored!
79 | shared_ptr laserPtr{nullptr};
80 | bool laserConnected{ false };
81 | float laserSize{ 0.5 };
82 | float laserIntensity{ 0.0 };
83 | float laserKeystoneX{ 0.0 };
84 | float laserKeystoneY{ 0.0 };
85 | float laserOffsetX{ 0.0 };
86 | float laserOffsetY{ 0.0 };
87 |
88 | void loadFromFile(string settingsFile = ofxToReadWriteableDataPath("settings.txt"));
89 | void saveToFile(string settingsFile = ofxToReadWriteableDataPath("settings.txt"));
90 |
91 | // runtime variables (not saved)
92 | OsciAvAudioPlayer player;
93 | size_t currentlyPlayingItem = 0;
94 |
95 | // the singleton thing
96 | static Globals instance;
97 | };
98 |
99 |
100 | #endif /* defined(__Oscilloscope__globals__) */
101 |
--------------------------------------------------------------------------------
/src/OsciMesh.cpp:
--------------------------------------------------------------------------------
1 | //
2 | // OsciMesh.cpp
3 | // Oscilloscope
4 | //
5 | // Created by Hansi on 12.01.17.
6 | //
7 | //
8 |
9 | #define EPS 1E-6
10 |
11 | #include "OsciMesh.h"
12 |
13 | void OsciMesh::init(){
14 | }
15 |
16 | OsciMesh::OsciMesh(){
17 | shaderLoader.setup(&shader, "shaders/osci");
18 | }
19 |
20 | void OsciMesh::addLines( float * left, float * right, float * bright, int N, int stride ){
21 | // no work? go home watch tv or something
22 | if(N==0) return;
23 |
24 | addLine(last,{left[0],right[0]}, bright==nullptr?1:bright[0]);
25 | last = {left[N-stride],right[N-stride]};
26 |
27 | if(bright==nullptr){
28 | for( int i = stride; i < N; i+= stride ){
29 | ofVec2f p0(left[i-stride], right[i-stride]);
30 | ofVec2f p1(left[i ], right[i ]);
31 | addLine(p0,p1, 1);
32 | }
33 | }
34 | else{
35 | for( int i = stride; i < N; i+= stride ){
36 | ofVec2f p0(left[i-stride], right[i-stride]);
37 | ofVec2f p1(left[i ], right[i ]);
38 | addLine(p0,p1, bright[i]);
39 | }
40 | }
41 | }
42 |
43 | inline void OsciMesh::addLine(ofVec2f p0, ofVec2f p1, const float bright_){
44 | float bright = bright_*2-1;
45 | ofVec2f dir = p1 - p0;
46 | float z = dir.length();
47 | if (z > EPS) dir /= z;
48 | else dir = ofVec2f(1.0, 0.0);
49 |
50 | dir *= uSize;
51 | ofVec2f norm(-dir.y, dir.x);
52 | ofVec2f xy(-uSize, -uSize);
53 |
54 | //make vec3 from vec2+float
55 | const auto vec3 = [](const ofVec2f & xy, const float & z){ return ofVec3f(xy.x,xy.y,z); };
56 |
57 | mesh.addVertex(vec3(p0-dir-norm, bright));
58 | mesh.addColor(ofFloatColor(-uSize, -uSize, z));
59 |
60 | mesh.addVertex(vec3(p0-dir+norm, bright));
61 | mesh.addColor(ofFloatColor(-uSize, uSize, z));
62 |
63 | mesh.addVertex(vec3(p1+dir-norm, bright));
64 | mesh.addColor(ofFloatColor(z+uSize, -uSize, z));
65 |
66 |
67 | mesh.addVertex(vec3(p0-dir+norm, bright));
68 | mesh.addColor(ofFloatColor(-uSize, uSize, z));
69 |
70 | mesh.addVertex(vec3(p1+dir-norm, bright));
71 | mesh.addColor(ofFloatColor(z+uSize, -uSize, z));
72 |
73 | mesh.addVertex(vec3(p1+dir+norm, bright));
74 | mesh.addColor(ofFloatColor(z+uSize, +uSize, z));
75 | };
76 |
77 |
78 | void OsciMesh::draw(ofMatrix4x4 & viewMatrix){
79 | glEnable(GL_BLEND);
80 | glBlendFunc(GL_SRC_ALPHA, GL_ONE);
81 | shader.begin();
82 | shader.setUniform3f("uRgb", uRgb);
83 | shader.setUniform1f("uSize", uSize);
84 | shader.setUniform1f("uIntensity", uIntensity);
85 | shader.setUniform1f("uIntensityBase", uIntensityBase);
86 | shader.setUniformMatrix4f("uMatrix", viewMatrix);
87 | shader.setUniform1f("uHue", uHue );
88 | ofSetColor(255);
89 | mesh.draw();
90 | shader.end();
91 | ofEnableAlphaBlending();
92 | }
93 |
94 |
95 | void OsciMesh::clear(){
96 | mesh.clear();
97 | mesh.setMode(OF_PRIMITIVE_TRIANGLES);
98 | mesh.enableColors();
99 | }
100 |
--------------------------------------------------------------------------------
/src/ui/PlayerOverlay.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | #include "ofxMightyUI.h"
4 | #include "../globals.h"
5 | #include "FaButton.h"
6 | #include "FaToggleButton.h"
7 | #include "FMenu.h"
8 | #include "../util/miniaudio.h"
9 |
10 | class PlayerOverlay : public mui::Container{
11 | public:
12 | PlayerOverlay( float x_ = 0, float y_ = 0, float width_ = ofGetWidth()/mui::MuiConfig::scaleFactor, float height_ = ofGetHeight()/mui::MuiConfig::scaleFactor );
13 |
14 | virtual void fromGlobals();
15 |
16 | virtual void update();
17 | virtual void draw();
18 | virtual void layout();
19 |
20 | virtual void touchDown( ofTouchEventArgs &touch );
21 | virtual void touchMoved( ofTouchEventArgs &touch );
22 | virtual void touchUp( ofTouchEventArgs &touch );
23 | virtual void touchDoubleTap( ofTouchEventArgs &touch );
24 |
25 | void populateMicMenu(FMenu * menu);
26 |
27 | FaButton * loadFileButton;
28 | FaToggleButton * useMicButton;
29 |
30 | FaToggleButton * configButton;
31 | mui::SliderWithLabel * scaleSlider;
32 |
33 | mui::Label * filenameLabel;
34 | FaToggleButton * fullscreenToggle; // toggle fs
35 | FaToggleButton * flipXYToggle; // flip x with y axis
36 | FaToggleButton * invertXToggle; // mirror around x axis
37 | FaToggleButton * invertYToggle; // mirror around y axis
38 | FaToggleButton * sideBySideToggle; // for 3d: toggle side by side mode and anagylph3d mode
39 | FaToggleButton * flip3dToggle; // for 3d: swap left and right channels
40 | FaToggleButton * zModulationToggle; // enable variable brightness control in 3 channel files
41 | FaToggleButton * showPlaylistToggle; // show playlist
42 |
43 | FaToggleButton * playButton;
44 | mui::Slider * timeSlider;
45 | mui::Button * timeLabelButton;
46 | int timeLabelMode = 0;
47 |
48 | mui::Label currentTime;
49 | mui::Label * scaleLabel;
50 |
51 | mui::Label * outputVolumeLabel;
52 | mui::SliderWithLabel * outputVolumeSlider;
53 |
54 | mui::SliderWithLabel * strokeWeightSlider;
55 | mui::Label * strokeWeightLabel;
56 |
57 | mui::SliderWithLabel * timeStretchSlider;
58 | mui::Label * timeStretchLabel;
59 |
60 | mui::SliderWithLabel * blurSlider;
61 | mui::Label * blurLabel;
62 |
63 | mui::SliderWithLabel * numPtsSlider;
64 | mui::Label * numPtsLabel;
65 |
66 | mui::SliderWithLabel * hueSlider;
67 | mui::Label * hueLabel;
68 |
69 | mui::SliderWithLabel * intensitySlider;
70 | mui::Label * intensityLabel;
71 |
72 | mui::SliderWithLabel * afterglowSlider;
73 | mui::Label * afterglowLabel;
74 |
75 | mui::Button * updateButton;
76 |
77 | void buttonPressed(const void * sender, ofTouchEventArgs & args);
78 | void inputSelected(const void * sender, FMenu::Option & opt);
79 | void sliderChanged( const void * sender, float & value );
80 |
81 | struct mic_info{
82 | ma_device_info info;
83 | ma_device_type type;
84 | };
85 | mic_info getSelectedMicDeviceInfo();
86 | private:
87 | mui::Label * addLabel( string text );
88 | mic_info selectedMicDeviceInfo;
89 | };
90 |
--------------------------------------------------------------------------------
/src/ofApp.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | #include "util/miniaudio.h"
4 |
5 | #include "ofMain.h"
6 | #include "util/ShaderLoader.h"
7 | #include "ofxMightyUI.h"
8 |
9 | #include "ui/ConfigView.h"
10 | #include "ui/PlayerOverlay.h"
11 | #include "ui/Playlist.h"
12 | #include "util/Audio.h"
13 | #include "ofxAvAudioPlayer.h"
14 | #include "OsciMesh.h"
15 | #include "util/TexShare.h"
16 | #include "util/OsciVideoWriter.hpp"
17 |
18 | class ExportScreen;
19 | enum class ExportFormat;
20 |
21 |
22 | class ofApp : public ofBaseApp{
23 |
24 | public:
25 |
26 | void setup();
27 | void startApplication();
28 | void stopApplication();
29 | void update();
30 | void draw();
31 | void drawAbove();
32 | void exit();
33 |
34 | void keyPressed (int key);
35 | void keyReleased(int key);
36 | void mouseMoved(int x, int y );
37 | void mouseDragged(int x, int y, int button);
38 | void mousePressed(int x, int y, int button);
39 | void mouseReleased(int x, int y, int button);
40 | void windowResized(int w, int h);
41 | void dragEvent(ofDragInfo dragInfo);
42 | void gotMessage(ofMessage msg);
43 |
44 | void audioIn(float * input, int bufferSize, int nChannels);
45 | void audioOut( float * output, int bufferSize, int nChannels );
46 |
47 | void beginExport(const ofFile & file);
48 | void playlistItemEnded();
49 | void updateSampleRate();
50 |
51 | void startMic();
52 | void stopMic();
53 | ofMatrix4x4 getViewMatrix(int i, bool isQuad);
54 |
55 | void urlResponse(ofHttpResponse & response);
56 |
57 |
58 | mui::Root * root;
59 | ConfigView * configView;
60 | ExportScreen * exportScreen;
61 |
62 | PlayerOverlay * playerOverlay;
63 | Playlist * playlist;
64 | bool playlistEnable = false;
65 | OsciMesh mesh;
66 | OsciMesh mesh2; // for stereoscopic viewing
67 |
68 | ofFbo fbo;
69 | TexShare texSender;
70 |
71 | // storage for mic buffers
72 | int micChannels = 2;
73 | MonoSample micLeft;
74 | MonoSample micRight;
75 | MonoSample micZMod;
76 |
77 | ma_device_config playDeviceConfig;
78 | ma_device playDevice;
79 |
80 | ma_device_config micDeviceConfig;
81 | ma_device micDevice;
82 |
83 | bool changed;
84 | bool clearFbos;
85 | int dropped;
86 | bool showInfo;
87 |
88 | int exporting;
89 | int exportFrameNum;
90 | ExportFormat exportFormat;
91 | int exportSampleRate;
92 | string exportExt;
93 | string exportDir;
94 |
95 | uint64_t lastMouseMoved{0};
96 | uint64_t lastUpdateTime{0};
97 | ofVec2f mousePosBeforeHiding;
98 | bool forceHidden = false;
99 | string fileToLoad;
100 | string currentFilename{"Oscilloscope"};
101 | string nextWindowTitle;
102 |
103 | ofVec2f last;
104 | bool hadWindowFocus = true;
105 | bool applicationRunning = false;
106 | bool initComplete = false;
107 | ofxFontStashStyle tooltipStyle;
108 |
109 | mutex mainThreadMutex;
110 | queue> mainThreadTasks;
111 |
112 | OsciVideoWriter video_writer;
113 | };
114 |
--------------------------------------------------------------------------------
/scripts/osx-sign.sh:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 | realpath() {
3 | OURPWD=$PWD
4 | cd "$(dirname "$1")"
5 | LINK=$(readlink "$(basename "$1")")
6 | while [ "$LINK" ]; do
7 | cd "$(dirname "$LINK")"
8 | LINK=$(readlink "$(basename "$1")")
9 | done
10 | REALPATH="$PWD/$(basename "$1")"
11 | cd "$OURPWD"
12 | echo "$REALPATH"
13 | }
14 |
15 |
16 | app="$1"
17 | signingIdentity="$2"
18 | entitlements="$3"
19 |
20 | if [[ -z "$1" || -z "$2" || -z "$3" ]]
21 | then
22 | echo "Usage: $0 "
23 | exit
24 | fi
25 |
26 | app="$1"
27 | signingIdentity="$2"
28 | entitlements="$3"
29 | me=$(dirname $0)
30 |
31 | # you might want extra_options="--options=runtime"
32 | # to sign an older binary which needs to be notarized
33 | #extra_options="--options=runtime --entitlements $entitlements "
34 | extra_options="--options=runtime --entitlements $entitlements "
35 |
36 |
37 | echo "Clearing strange file attributes"
38 | xattr -cr "$app"
39 |
40 | signdir() {
41 | pluginName=$1
42 | echo "Signing $app/$pluginName"
43 | # sign bundled jre
44 | find "$app/$pluginName" -type f -print | sort -r \
45 | | ( while read FOO; do
46 | codesign -d "$FOO"
47 | if [ $? != 0 ]; then
48 | sudo codesign $extra_options -f -s "$signingIdentity" -vvvv "$FOO"
49 | fi
50 | done)
51 | # Sign most other files
52 | find "$app" -type f -print | sort -r \
53 | | grep -v '_CodeSignature' \
54 | | (while read FOO; do
55 | codesign -d "$FOO"
56 | if [ $? != 0 ]; then
57 | echo "Signing: $FOO"
58 | sudo codesign $extra_options -f -s "$signingIdentity" -vvvv "$FOO" 2>&1
59 | fi
60 | done)
61 | # Sanity check, this doesn't sign anything, because everything is signed
62 | find "$app/$pluginName" -type f -print | sort -r \
63 | | ( while read FOO; do
64 | codesign -v "$FOO"
65 | if [ $? != 0 ]; then
66 | echo "Checking: $FOO"
67 | sudo codesign $extra_options -f -s "$signingIdentity" -vvvv "$FOO" 2>&1
68 | fi
69 | done)
70 | # Test sig
71 | codesign -dvvv "$app/$pluginName"
72 | # Next sign Java directory (must not use --force, as plist is modified)
73 | # This creates $app/Contents/Plugins/Java/Contents/_CodeSignature/{CodeDirectory,CodeRequirements,CodeResources,CodeSignature}
74 | sudo codesign -f -s "$signingIdentity" -vvvv "$app/$pluginName" 2>&1
75 | sudo codesign -f -s "$signingIdentity" "$app/$pluginName/Contents/_CodeSignature/CodeResources"
76 | # sign the new files
77 | find "$app/$pluginName" -type f -print | sort -r \
78 | | ( while read FOO; do
79 | codesign -v "$FOO"
80 | if [ $? != 0 ]; then
81 | sudo codesign $extra_options -s "$signingIdentity" -vvvv "$FOO" 2>&1
82 | fi
83 | done)
84 | }
85 |
86 | find "$app" -name "*.dylib" -type f -print | sort -r \
87 | | ( while read FOO; do
88 | echo "sign dylib: $FOO"
89 | sudo codesign $extra_options -f -s "$signingIdentity" -vvvv "$FOO"
90 | done)
91 |
92 | # finally sign $app
93 | sudo codesign $extra_options -s "$signingIdentity" -vvvv --force "$app"
94 | # Now the verification works
95 | codesign -vvvv --deep "$app"
--------------------------------------------------------------------------------
/Oscilloscope.qbs:
--------------------------------------------------------------------------------
1 | import qbs
2 | import qbs.Process
3 | import qbs.File
4 | import qbs.FileInfo
5 | import qbs.TextFile
6 | import "../../../libs/openFrameworksCompiled/project/qtcreator/ofApp.qbs" as ofApp
7 |
8 | Project{
9 | property string of_root: '../../..'
10 |
11 | ofApp {
12 | name: { return FileInfo.baseName(sourceDirectory) }
13 |
14 | files: [
15 | 'src/**',
16 | ]
17 |
18 | // This project is using addons.make to include the addons
19 | // since it was imported from old code. To change it to include
20 | // the addons from the qbs file change the following lines to
21 | // the list of used addons in array format. eg:
22 | //
23 | of.addons: [
24 | 'addons/ofxAvCodec',
25 | 'addons/ofxFontAwesome',
26 | 'addons/ofxFontStash2',
27 | 'addons/ofxMightyUI',
28 | 'addons/ofxNative',
29 | 'addons/ofxSyphon',
30 | 'addons/ofxSpout',
31 | 'addons/ofxLibsamplerate',
32 | ]
33 |
34 | // additional flags for the project. the of module sets some
35 | // flags by default to add the core libraries, search paths...
36 | // this flags can be augmented through the following properties:
37 | of.pkgConfigs: [] // list of additional system pkgs to include
38 | of.includePaths: [] // include search paths
39 | of.cFlags: [] // flags passed to the c compiler
40 | of.cxxFlags: [] // flags passed to the c++ compiler
41 | of.linkerFlags: [] // flags passed to the linker
42 | of.defines: [] // defines are passed as -D to the compiler
43 | // and can be checked with #ifdef or #if in the code
44 | of.frameworks: [] // osx only, additional frameworks to link with the project
45 | of.staticLibraries: [] // static libraries
46 | of.dynamicLibraries: [] // dynamic libraries
47 |
48 | // create a console window when the application start
49 | consoleApplication: false
50 |
51 | // other flags can be set through the cpp module: http://doc.qt.io/qbs/cpp-module.html
52 | // eg: this will enable ccache when compiling
53 | //
54 | // cpp.compilerWrapper: 'ccache'
55 |
56 | Depends{
57 | name: "cpp"
58 | }
59 |
60 | // common rules that parse the include search paths, core libraries...
61 | Depends{
62 | name: "of"
63 | }
64 |
65 | // dependency with the OF library
66 | Depends{
67 | name: "openFrameworks"
68 | }
69 | }
70 |
71 | property bool makeOF: true // use makfiles to compile the OF library
72 | // will compile OF only once for all your projects
73 | // otherwise compiled per project with qbs
74 |
75 | property bool precompileOfMain: false // precompile ofMain.h
76 | // faster to recompile when including ofMain.h
77 | // but might use a lot of space per project
78 |
79 | references: [FileInfo.joinPaths(of_root, "/libs/openFrameworksCompiled/project/qtcreator/openFrameworks.qbs")]
80 | }
81 |
--------------------------------------------------------------------------------
/src/ui/Dialogs.cpp:
--------------------------------------------------------------------------------
1 | #include "ofxMightyUI.h"
2 | #include "Dialogs.h"
3 | #include "MuiL.h"
4 |
5 | Dialog::Dialog() : mui::Container(0,0,400,100){
6 | blocker = new mui::Container();
7 | blocker->onLayout.add([&](){
8 | blocker->x = 0;
9 | blocker->y = 0;
10 | blocker->width = blocker->parent->width;
11 | blocker->height = blocker->parent->height;
12 | });
13 | blocker->bg = ofColor(0,200);
14 | blocker->opaque = true;
15 |
16 | bg = ofColor(0);
17 | opaque = true;
18 | }
19 |
20 | Dialog::~Dialog(){
21 | if(blocker) MUI_ROOT->safeRemoveAndDelete(blocker);
22 |
23 | for(mui::Container * btn : buttons){
24 | delete btn;
25 | }
26 | for(mui::Container * lbl : labels){
27 | delete lbl;
28 | }
29 |
30 | buttons.clear();
31 | labels.clear();
32 |
33 | children.clear();
34 | }
35 |
36 | void Dialog::layout(){
37 | mui::L(labels).rows({10,10}).stretchToRightEdgeOfParent(10);
38 |
39 | float btn_y0 = 20 + (labels.size() == 0? 0:labels.back()->getBounds().getBottom());
40 |
41 | mui::L(buttons).columns({10,btn_y0});
42 |
43 | height = getChildBounds().getBottom() + 10;
44 |
45 | if(parent){
46 | x = (parent->width - width)/2;
47 | y = (parent->height - height)/2;
48 | }
49 | }
50 |
51 | void Dialog::draw(){
52 | ofNoFill();
53 | ofDrawRectangle(0,0,width-1,height-1);
54 | ofFill();
55 | }
56 |
57 | void Dialog::show(){
58 | MUI_ROOT->add(blocker);
59 | blocker->handleLayout();
60 |
61 | MUI_ROOT->add(this);
62 | layout();
63 | }
64 |
65 | void Dialog::close(){
66 | blocker->visible = false;
67 | MUI_ROOT->safeRemoveAndDelete(blocker);
68 | blocker = nullptr;
69 |
70 | visible = false;
71 | MUI_ROOT->safeRemoveAndDelete(this);
72 | }
73 |
74 | mui::Label * Dialog::addLabel(const std::string & text){
75 | mui::Label * label = new mui::Label(text,0,0,380,20);
76 | add(label);
77 | labels.push_back(label);
78 | return label;
79 | }
80 |
81 | mui::Button * Dialog::addButton(const std::string & text, const std::function & on_choice){
82 | mui::Button * button = new mui::Button(text,0,0,90,30);
83 | button->setProperty("on_choice", on_choice);
84 | ofAddListener(button->onPress, this, &Dialog::buttonPressed);
85 | add(button);
86 | buttons.push_back(button);
87 | return button;
88 | }
89 |
90 | void Dialog::buttonPressed(const void * sender, ofTouchEventArgs & args){
91 | for(mui::Container * btn : buttons){
92 | if(btn == sender){
93 | std::function * func = btn->getProperty>("on_choice");
94 | close();
95 | if(func && *func) (*func)();
96 | }
97 | }
98 | }
99 |
100 |
101 | Dialog * show_yes_no_dialog(const std::string & message, const std::function& on_choice){
102 | Dialog * d = new Dialog();
103 | d->addLabel(message);
104 | d->addButton("Yes", [on_choice](){ on_choice(true); });
105 | d->addButton("No", [on_choice](){ on_choice(false); });
106 | d->show();
107 | return d;
108 | }
109 |
110 | Dialog * show_ok_dialog(const std::string & message, const std::function& on_choice){
111 | Dialog * d = new Dialog();
112 | d->addLabel(message);
113 | d->addButton("Ok", [on_choice](){ on_choice(); });
114 | d->show();
115 | return d;
116 | }
117 |
--------------------------------------------------------------------------------
/oscilloscope.xcodeproj/xcshareddata/xcschemes/oscilloscope Debug.xcscheme:
--------------------------------------------------------------------------------
1 |
2 |
5 |
8 |
9 |
15 |
21 |
22 |
23 |
24 |
25 |
30 |
31 |
32 |
33 |
39 |
40 |
41 |
42 |
51 |
52 |
58 |
59 |
60 |
61 |
62 |
63 |
69 |
70 |
76 |
77 |
78 |
79 |
81 |
82 |
85 |
86 |
87 |
--------------------------------------------------------------------------------
/oscilloscope.xcodeproj/xcshareddata/xcschemes/oscilloscope Release.xcscheme:
--------------------------------------------------------------------------------
1 |
2 |
5 |
8 |
9 |
15 |
21 |
22 |
23 |
24 |
25 |
30 |
31 |
32 |
33 |
39 |
40 |
41 |
42 |
51 |
52 |
58 |
59 |
60 |
61 |
62 |
63 |
69 |
70 |
76 |
77 |
78 |
79 |
81 |
82 |
85 |
86 |
87 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | dist/
2 | scripts/osx-config.sh
3 | ._*
4 | .DS_Store
5 | Thumbs.db
6 | .vs/
7 | oscilloscope.VC.db
8 |
9 | # Created by https://www.gitignore.io
10 |
11 | ### Xcode ###
12 | build/
13 | *.pbxuser
14 | !default.pbxuser
15 | *.mode1v3
16 | !default.mode1v3
17 | *.mode2v3
18 | !default.mode2v3
19 | *.perspectivev3
20 | !default.perspectivev3
21 | xcuserdata
22 | *.xccheckout
23 | *.moved-aside
24 | DerivedData
25 | *.xcuserstate
26 |
27 |
28 | ### VisualStudio ###
29 | ## Ignore Visual Studio temporary files, build results, and
30 | ## files generated by popular Visual Studio add-ons.
31 |
32 | # User-specific files
33 | *.suo
34 | *.user
35 | *.sln.docstates
36 |
37 | # Build results
38 | [Dd]ebug/
39 | [Dd]ebugPublic/
40 | [Rr]elease/
41 | [Rr]eleases/
42 | x64/
43 | x86/
44 | build/
45 | bld/
46 | [Bb]in/
47 | [Oo]bj/
48 |
49 | # Roslyn cache directories
50 | *.ide/
51 |
52 | # MSTest test Results
53 | [Tt]est[Rr]esult*/
54 | [Bb]uild[Ll]og.*
55 |
56 | #NUNIT
57 | *.VisualState.xml
58 | TestResult.xml
59 |
60 | # Build Results of an ATL Project
61 | [Dd]ebugPS/
62 | [Rr]eleasePS/
63 | dlldata.c
64 |
65 | *_i.c
66 | *_p.c
67 | *_i.h
68 | *.ilk
69 | *.meta
70 | *.obj
71 | *.pch
72 | *.pdb
73 | *.pgc
74 | *.pgd
75 | *.rsp
76 | *.sbr
77 | *.tlb
78 | *.tli
79 | *.tlh
80 | *.tmp
81 | *.tmp_proj
82 | *.log
83 | *.vspscc
84 | *.vssscc
85 | .builds
86 | *.pidb
87 | *.svclog
88 | *.scc
89 |
90 | # Chutzpah Test files
91 | _Chutzpah*
92 |
93 | # Visual C++ cache files
94 | ipch/
95 | *.aps
96 | *.ncb
97 | *.opensdf
98 | *.sdf
99 | *.cachefile
100 |
101 | # Visual Studio profiler
102 | *.psess
103 | *.vsp
104 | *.vspx
105 |
106 | # TFS 2012 Local Workspace
107 | $tf/
108 |
109 | # Guidance Automation Toolkit
110 | *.gpState
111 |
112 | # ReSharper is a .NET coding add-in
113 | _ReSharper*/
114 | *.[Rr]e[Ss]harper
115 | *.DotSettings.user
116 |
117 | # JustCode is a .NET coding addin-in
118 | .JustCode
119 |
120 | # TeamCity is a build add-in
121 | _TeamCity*
122 |
123 | # DotCover is a Code Coverage Tool
124 | *.dotCover
125 |
126 | # NCrunch
127 | _NCrunch_*
128 | .*crunch*.local.xml
129 |
130 | # MightyMoose
131 | *.mm.*
132 | AutoTest.Net/
133 |
134 | # Web workbench (sass)
135 | .sass-cache/
136 |
137 | # Installshield output folder
138 | [Ee]xpress/
139 |
140 | # DocProject is a documentation generator add-in
141 | DocProject/buildhelp/
142 | DocProject/Help/*.HxT
143 | DocProject/Help/*.HxC
144 | DocProject/Help/*.hhc
145 | DocProject/Help/*.hhk
146 | DocProject/Help/*.hhp
147 | DocProject/Help/Html2
148 | DocProject/Help/html
149 |
150 | # Click-Once directory
151 | publish/
152 |
153 | # Publish Web Output
154 | *.[Pp]ublish.xml
155 | *.azurePubxml
156 | # TODO: Comment the next line if you want to checkin your web deploy settings
157 | # but database connection strings (with potential passwords) will be unencrypted
158 | *.pubxml
159 | *.publishproj
160 |
161 | # NuGet Packages
162 | *.nupkg
163 | # The packages folder can be ignored because of Package Restore
164 | **/packages/*
165 | # except build/, which is used as an MSBuild target.
166 | !**/packages/build/
167 | # If using the old MSBuild-Integrated Package Restore, uncomment this:
168 | #!**/packages/repositories.config
169 |
170 | # Windows Azure Build Output
171 | csx/
172 | *.build.csdef
173 |
174 | # Windows Store app package directory
175 | AppPackages/
176 |
177 | # Others
178 | sql/
179 | *.Cache
180 | ClientBin/
181 | [Ss]tyle[Cc]op.*
182 | ~$*
183 | *~
184 | *.dbmdl
185 | *.dbproj.schemaview
186 | *.pfx
187 | *.publishsettings
188 | node_modules/
189 |
190 | # RIA/Silverlight projects
191 | Generated_Code/
192 |
193 | # Backup & report files from converting an old project file
194 | # to a newer Visual Studio version. Backup files are not needed,
195 | # because we have git ;-)
196 | _UpgradeReport_Files/
197 | Backup*/
198 | UpgradeLog*.XML
199 | UpgradeLog*.htm
200 |
201 | # SQL Server files
202 | *.mdf
203 | *.ldf
204 |
205 | # Business Intelligence projects
206 | *.rdl.data
207 | *.bim.layout
208 | *.bim_*.settings
209 |
210 | # Microsoft Fakes
211 | FakesAssemblies/
212 |
213 | # SubWolf 2015-07-29 Settings Not Needed
214 | bin/data/settings.txt
215 |
--------------------------------------------------------------------------------
/readme.md:
--------------------------------------------------------------------------------
1 | Oscilloscope
2 | ===
3 |
4 | A software oscilloscope attempting to mimic the aesthetic of old school ray oscilloscopes.
5 |
6 |
7 |
8 | # How to use
9 |
10 | After starting the oscilloscope a welcome message is already loaded, press ▶︎ play to make sure your audio setup works. If it doesn't, open ⚙ settings and try to choose another output device.
11 |
12 | To open files you can either click the folder icon, or drag a file from Explorer/Finder/Nautilus/... to the application.
13 |
14 |
15 | |Key |Action|
16 | |------|------|
17 | |Space |Play/Pause|
18 | |f |Fullscreen|
19 | |Tab |Hide interface|
20 | |e |Export to image sequence|
21 |
22 |
23 |
24 | For more information
25 |
26 | * either visit the user page at oscilloscopemusic.com/osci.php
27 | * [download the latest version](https://github.com/kritzikratzi/Oscilloscope/releases)
28 |
29 |
30 | # Programmer Documentation
31 |
32 | ## Project setup
33 |
34 | Things are moving around a bit sometimes.
35 | Make sure to read these instructions before each build.
36 |
37 | 1. Download and unzip Openframeworks 0.10.1
38 | 1. Open the folder apps/myApps/ (in the OpenFrameworks folder)
39 | 1. Clone the repository with submodules: `git clone --recursive https://github.com/kritzikratzi/Oscilloscope.git`
40 | 1. Download the binary release for ofxAvCodec from [https://github.com/kritzikratzi/ofxAvCodec/releases/tag/0.2](https://github.com/kritzikratzi/ofxAvCodec/releases/tag/0.2)
41 | 1. Replace the addons/ofxAvCodec/libs with the libs folder from the download
42 |
43 |
44 | ### Compiling with XCode (OSX11.5+)
45 |
46 | 1. Add the `--deep` value to the `Other Code Signing Flags` key in the Build Settings tab
47 | 1. Open apps/myApps/oscilloscope/Oscilloscope.xcodeproject and then Build&Run
48 | 1. (Optional) Sign&Notarize with apple: Copy `scripts/osx-config-template.sh` to `osx-config.sh`, then run `scripts/dist.sh osx 1.1.0`
49 |
50 |
51 | You can also build with `make && make run` on the command line. The resulting build will have no icon/no proper name/no retina support.
52 |
53 | ### Compiling with Visual studio 2017
54 |
55 | The shell commands can be run from a git bash, cygwin, msys, or any other shell emulator.
56 |
57 | 1. run `scripts/clean.sh`
58 | 1. run `scripts/prepare.sh win64`
59 | 1. Open oscilloscope.sln and Build&Run
60 |
61 | ### Compiling with make in Linux
62 |
63 | This is a full install including OF (thx rrolison68!)
64 |
65 | cd
66 | wget -c https://openframeworks.cc/versions/v0.10.1/of_v0.10.1_linux64gcc6_release.tar.gz
67 | tar -zxvf of_v0.10.1_linux64gcc6_release.tar.gz
68 | mv of_v0.10.1_linux64gcc6_release OF
69 | cd OF/scripts/linux/ubuntu
70 | sudo ./install_dependencies.sh
71 | cd
72 | cd OF/apps/myApps
73 | git clone --recursive https://github.com/kritzikratzi/Oscilloscope.git
74 | cd Oscilloscope
75 | scripts/clean.sh
76 | cp -R addons/ofxMightyUI/bin/data/* bin/data/
77 | cp -R addons/ofxFontAwesome/bin/data/* bin/data/
78 | make -j2
79 | bin/Oscilloscope
80 | See scripts/readme.md for the full distribution process.
81 |
82 | ### Package the software
83 |
84 | * for osx run `scripts/dist.sh $platform $version`
85 | * platform is one of `osx linux linux64 win64`
86 | * version is whatever version you want, e.g. `1.0.6`
87 |
88 | ### Contributors
89 |
90 | * [https://github.com/subwolf/](subwolf) Linux support
91 | * [https://github.com/s-ol/](s-ol) Linux support
92 |
93 |
94 | ## License/Source code
95 |
96 | * [Openframeworks](http://openframeworks.cc). A creative coding library. The larger part of it is licensed as MIT/BSD.
97 | * [FFmpeg](http://www.ffmpeg.org/) and [ofxAvCodec](https://github.com/kritzikratzi/ofxAvCodec). FFmpeg is _the_ encoder/decoder library and licensed under the gpl/lgpl 2.1. The binaries included here were compiled to comply with the lgpl. A copy of the LGPL together with instructions how the library was compiled for each platform can be found in the `legal` folder.
98 | * The sourcecode for this application is freely available on [github](https://github.com/kritzikratzi/Oscilloscope).
99 |
--------------------------------------------------------------------------------
/src/main.cpp:
--------------------------------------------------------------------------------
1 | #include "ofMain.h"
2 | #include "ofApp.h"
3 | #include "ofxMightyUI.h"
4 |
5 | #if defined(TARGET_OSX)
6 | #import
7 | #elif defined(TARGET_WIN32)
8 | #include "../resource.h"
9 | #endif
10 | #include "version.h"
11 |
12 | #include "ofAppGLFWWindow.h"
13 | #include "ofxNative.h"
14 | #include
15 |
16 |
17 | //========================================================================
18 | int main(){
19 | globals.loadFromFile();
20 | ofSetEscapeQuitsApp(false);
21 |
22 | ofAppGLFWWindow window;
23 |
24 | cout << "LAUNCH DESKTOP" << endl;
25 | ofSetupOpenGL(&window, 1024, 700, OF_WINDOW);
26 | window.setWindowTitle("Oscilloscope " + app_version);
27 |
28 | // go fullscreen in mac osx
29 | ofxNative::maximizeWindow(window);
30 |
31 | #if defined(TARGET_OSX)
32 | NSWindow * cocoaWindow = (NSWindow*)window.getCocoaWindow();
33 | // [cocoaWindow setFrame:[[NSScreen mainScreen] visibleFrame] display:YES];
34 | NSString * ver = [NSString stringWithUTF8String:app_version.c_str()];
35 | NSString * title = [NSString stringWithFormat:@"Oscilloscope %@", ver];
36 | [cocoaWindow setTitle:title];
37 | if(globals.alwaysOnTop){
38 | [cocoaWindow setLevel: NSFloatingWindowLevel];
39 | }
40 | #endif
41 |
42 | #if defined(TARGET_WIN32)
43 | HWND hwnd = ofGetWin32Window();
44 | HICON hMyIcon = LoadIcon(GetModuleHandle(NULL), MAKEINTRESOURCE(MAIN_ICON));
45 | SendMessage(hwnd, WM_SETICON, ICON_BIG, (LPARAM)hMyIcon);
46 | #endif
47 |
48 | mui_init();
49 | mui::MuiConfig::font = "mui/fonts/Lato-Regular.ttf";
50 | ofRunApp(new ofApp);
51 | }
52 |
53 | #ifdef _WIN32
54 | // handle windows startup
55 | INT WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
56 | PSTR lpCmdLine, INT nCmdShow)
57 | {
58 | return main();
59 | }
60 | #endif
61 |
62 |
63 | void setWindowRepresentedFilename( string filename ){
64 | #if defined(TARGET_OSX)
65 | NSWindow * cocoaWindow = (NSWindow*)(ofGetWindowPtr()->getCocoaWindow());
66 | if(filename == ""){
67 | [cocoaWindow setRepresentedFilename:@""];
68 | NSString * ver = [NSString stringWithUTF8String:app_version.c_str()];
69 | NSString * title = [NSString stringWithFormat:@"Oscilloscope %@", ver];
70 | [cocoaWindow setTitle:title];
71 | }
72 | else if(filename[0] != '/'){
73 | [cocoaWindow setRepresentedFilename:@""];
74 | [cocoaWindow setTitle:[NSString stringWithUTF8String:filename.c_str()]];
75 | }
76 | else{
77 | NSString * file = [NSString stringWithUTF8String:filename.c_str()];
78 | NSString * filename = [file pathComponents].lastObject;
79 | [cocoaWindow setTitle:filename];
80 | [cocoaWindow setRepresentedFilename:file];
81 | }
82 | #else
83 | if(filename==""){
84 | ofGetWindowPtr()->setWindowTitle("Oscilloscope " + app_version);
85 | }
86 | else{
87 | ofGetWindowPtr()->setWindowTitle(filename);
88 | }
89 | #endif
90 |
91 | }
92 |
93 |
94 | // returns a path where the application can only read.
95 | // for osx this is the "resources" folder residing inside the application bundle,
96 | // for windows it is still the data folder.
97 | // if the file does not exist in the application bundle, the data folder is returned.
98 | string ofxToReadonlyDataPath( string filename ){
99 | #ifdef TARGET_OSX
100 | // http://www.cocoabuilder.com/archive/cocoa/193451-finding-out-executable-location-from-c-program.html
101 | CFBundleRef bundle = CFBundleGetMainBundle();
102 | CFURLRef url = CFBundleCopyResourcesDirectoryURL(bundle);
103 | CFURLRef absolute = CFURLCopyAbsoluteURL(url);
104 | Boolean abs;
105 | CFStringRef path = CFURLCopyFileSystemPath(absolute,kCFURLPOSIXPathStyle);
106 | CFIndex maxLength = CFStringGetMaximumSizeOfFileSystemRepresentation(path);
107 | char *result = (char*)malloc(maxLength);
108 |
109 | if(result) {
110 | if(!CFStringGetFileSystemRepresentation(path,result, maxLength)) {
111 | free(result);
112 | result = NULL;
113 | }
114 | }
115 |
116 | string realResult = string([[NSString stringWithUTF8String:result] stringByAppendingPathComponent:[NSString stringWithUTF8String:filename.c_str()]].UTF8String );
117 |
118 | CFRelease(path);
119 | CFRelease(url);
120 | CFRelease(absolute);
121 |
122 | if( ofFile(realResult, ofFile::Reference).exists() ){
123 | return realResult;
124 | }
125 | else{
126 | return ofToDataPath(filename,true);
127 | }
128 | #else
129 | return ofToDataPath(filename,true);
130 | #endif
131 | }
132 |
133 |
134 | // returns a path where the application can safely read+write data.
135 | // this is great for settings files and the like.
136 | // for osx this is the application support directory (without sandboxing)
137 | // or ~/Library/Containers//
138 | // for windows this is in %APPDATA%
139 | string ofxToReadWriteableDataPath( string filename ){
140 | return ofxNative::getSystemDataFolder() + "/" + filename;
141 | }
142 |
--------------------------------------------------------------------------------
/src/globals.cpp:
--------------------------------------------------------------------------------
1 | //
2 | // globals.cpp
3 | // Oscilloscope
4 | //
5 | // Created by Hansi on 26.07.15.
6 | //
7 | //
8 |
9 | #include "globals.h"
10 | #include "util/WickedLasers.h"
11 | #include "util/miniaudio.h"
12 |
13 | Globals Globals::instance;
14 |
15 | void Globals::init() {
16 | laserPtr = make_shared();
17 | context = new ma_context();
18 | if (ma_context_init(NULL, 0, NULL, context) != MA_SUCCESS) {
19 | ofSystemAlertDialog("Failed to initialize audio context :(");
20 |
21 | }
22 | }
23 |
24 | string ofxFormatTime(double seconds) {
25 | int total = seconds;
26 | int s = total % 60;
27 |
28 | total = total / 60;
29 | int m = total % 60;
30 |
31 | total = total / 60;
32 | int h = total;
33 |
34 | return ofToString(h, 2, '0') + ":" + ofToString(m, 2, '0') + ":" + ofToString(s, 2, '0');
35 | }
36 |
37 |
38 | void Globals::loadFromFile(string settingsFile) {
39 | ofxIniSettings settings = ofxIniSettings(settingsFile);
40 | out_requested.bufferSize = settings.get("out_bufferSize", out_requested.bufferSize);
41 | out_requested.sampleRate = settings.get("out_sampleRate", out_requested.sampleRate);
42 | out_requested.name = settings.get("out_deviceName", out_requested.name);
43 | in_requested.bufferSize = settings.get("in_bufferSize", in_requested.sampleRate);
44 | in_requested.sampleRate = settings.get("in_sampleRate", in_requested.sampleRate);
45 | in_requested.name = settings.get("in_deviceName", in_requested.name);
46 |
47 | scale = settings.get("scale", scale);
48 | flipXY = settings.get("flipXY", flipXY);
49 | zModulation = settings.get("zModulation", zModulation);
50 | invertX = settings.get("invertX", invertX);
51 | invertY = settings.get("invertY", invertY);
52 | outputVolume = settings.get("outputVolume", outputVolume);
53 | inputVolume = settings.get("inputVolume", inputVolume);
54 | strokeWeight = settings.get("strokeWeight", strokeWeight);
55 | //timeStretch = settings.get( "timeStretch", timeStretch ); // never load timestretch!
56 | blur = settings.get("blur", blur);
57 | numPts = settings.get("numPts", numPts);
58 | hue = settings.get("hue", hue);
59 | intensity = settings.get("intensity", intensity);
60 | afterglow = settings.get("afterglow", afterglow);
61 | analogMode = settings.get("analogMode", analogMode);
62 | exportFrameRate = settings.get("exportFrameRate", exportFrameRate);
63 | exportWidth = settings.get("exportWidth", exportWidth);
64 | exportHeight = settings.get("exportHeight", exportHeight);
65 | exportFormat = (ExportFormat)settings.get("exportFormat", (int)exportFormat);
66 | exportSampleRate = settings.get("exportSampleRate", (int)exportSampleRate);
67 |
68 | laserOffsetX = settings.get("laserOffsetX", laserOffsetX);
69 | laserOffsetY = settings.get("laserOffsetY", laserOffsetY);
70 | laserKeystoneX = settings.get("laserKeystoneX", laserKeystoneX);
71 | laserKeystoneY = settings.get("laserKeystoneY", laserKeystoneY);
72 |
73 | //secondsBeforeHidingMenu = settings.get( "secondsBeforeHidingMenu", secondsBeforeHidingMenu );
74 | }
75 |
76 |
77 | void Globals::saveToFile(string settingsFile) {
78 | if (!ofFile(settingsFile, ofFile::Reference).exists()) {
79 | ofFile file(settingsFile, ofFile::WriteOnly);
80 | file << endl;
81 | file.close();
82 | }
83 |
84 | ofxIniSettings settings = ofxIniSettings(settingsFile);
85 |
86 | //settings.set("out_bufferSize", out_requested.bufferSize);
87 | //settings.set("out_sampleRate", out_requested.sampleRate);
88 | settings.set("out_deviceName", out_requested.name);
89 | //settings.set("in_bufferSize", in_requested.bufferSize);
90 | //settings.set("in_sampleRate", in_requested.sampleRate);
91 | settings.set("in_deviceName", in_requested.name);
92 | settings.set("scale", scale);
93 | settings.set("flipXY", flipXY);
94 | settings.set("zModulation", zModulation);
95 | settings.set("invertX", invertX);
96 | settings.set("invertY", invertY);
97 | settings.set("outputVolume", outputVolume);
98 | settings.set("inputVolume", inputVolume);
99 | settings.set("strokeWeight", strokeWeight);
100 | // settings.set( "timeStretch", timeStretch ); // never save timestretch!
101 | settings.set("blur", blur);
102 | settings.set("numPts", numPts);
103 | settings.set("hue", hue);
104 | settings.set("intensity", intensity);
105 | settings.set("afterglow", afterglow);
106 | settings.set("analogMode", analogMode);
107 | settings.set("exportFrameRate", exportFrameRate);
108 | settings.set("exportWidth", exportWidth);
109 | settings.set("exportHeight", exportHeight);
110 | settings.set("exportFormat", (int)exportFormat);
111 | settings.set("exportSampleRate", (int)exportSampleRate);
112 |
113 | settings.set("laserOffsetX", laserOffsetX);
114 | settings.set("laserOffsetY", laserOffsetY);
115 | settings.set("laserKeystoneX", laserKeystoneX);
116 | settings.set("laserKeystoneY", laserKeystoneY);
117 |
118 | // settings.set( "secondsBeforeHidingMenu", secondsBeforeHidingMenu );
119 | }
120 |
--------------------------------------------------------------------------------
/scripts/readme.md:
--------------------------------------------------------------------------------
1 | #Oscilloscope - Packaging notes
2 |
3 | ===
4 |
5 | These are my own notes how to bundle up the app for each platform so that i don't forget.
6 |
7 | # OSX
8 |
9 |
10 | 1. Open apps/myApps/oscilloscope/Oscilloscope.xcodeproject
11 | 1. Select the binary target and update the version info
12 | 1. Delete oscilloscope.app in finder, to make sure you have a fresh build
13 | 1. Build&Run
14 | 1. Code sign: `scripts/sign-mac.sh bin/Oscilloscope.app "Developer ID Application: Name of your certificate"` (run `security find-identity -v -p codesigning` to get a list of installed certs)
15 | 1. Create a zip in finder (don't use terminal, that creates a different zip i think)
16 |
17 | You can also build with `make && make run` on the command line. The resulting build will have no icon/no proper name/no retina support.
18 |
19 | First patch OF to get rid of glut and fmodex: https://forum.openframeworks.cc/t/bundling-osx-app-without-glut-and-without-fmodex-nasty/23503
20 |
21 | ## Windows (Visual studio 2015)
22 |
23 | 1. run `scripts/clean.sh`
24 | 1. run `scripts/prepare.sh win32`
25 | 1. Open oscilloscope.sln
26 | 1. Open icon.rc, update the version info section
27 | 1. build
28 | 1. Run scripts/dist.sh win32 1.0.x
29 |
30 | At this point audio should play through Asio (first choice), or Wasapi. You can follow these instructions to patch OF so you can pick at startup: http://pastebin.com/ZZLZ3jUm
31 |
32 |
33 | ### VS Project file
34 |
35 | #### Delay Load DLLs
36 |
37 | Configuration: Win32 / Release
38 | Go to `Linker>All Options>Delay Load Dlls` and enter:
39 |
40 |
41 | assimp.dll
42 | glut32.dll
43 | libeay32.dll
44 | ssleay32.dll
45 | swscale-3.dll
46 | Zlib.dll
47 | FreeType.dll
48 | fmodex.dll
49 | fmodexL.dll
50 |
51 | None of these are actually used, ever. Specifying them as delay loaded allows you to just delete them.
52 |
53 |
54 |
55 | ### Compiling with make in Linux
56 |
57 | 1. run `scripts/clean.sh`
58 | 1. run `scripts/prepare.sh linux64`
59 | 1. run `make && make run` ? [subwolf knows, i haven't done this in ages!]
60 |
61 | See scripts/readme.md for the full distribution process.
62 |
63 | ### Package the software
64 |
65 | * for osx run `scripts/dist.sh $platform $version`
66 | * platform is one of `osx linux linux64 win32 win64`
67 | * version is whatever version you want, e.g. `1.0.6`
68 |
69 |
70 | Helper Scripts
71 | ===
72 |
73 |
74 | These scripts help manage the build process.
75 | You'll need a bash shell to run the scripts.
76 |
77 | The scripts should all figure out the correct paths themselves. There's no need to worry about the working directory.
78 |
79 |
80 | clean.sh
81 | ---
82 |
83 | Cleans out the bin/ folder and removes files not in the repository.
84 | Changed files will not be reset.
85 |
86 | prepare.sh
87 | ---
88 | Prepares the bin folder for a platform. This also fixes some problems with the build process that (i believe) I'm currently too dumb to fix directly in the make files.
89 |
90 | The script requires one argument, the operating system. Possible options are:
91 |
92 | * osx
93 | * linux
94 | * linux64
95 | * win32
96 | * win64
97 |
98 | Depending on the parameter some dll files and other resources are copied to the bin folder.
99 | Use `clean.sh` to get rid of the mess again.
100 |
101 |
102 | dist.sh
103 | ---
104 | Assembles a zip file ready for binary distribution. This adds the ffmpeg license files, compilation instructions, and does a whole lot of other things. It takes two parameters, one for the version, the other for the platform.
105 |
106 | A typical distribution workflow looks like this:
107 |
108 | cd apps/myApps/Oscilloscope
109 |
110 | platform=osx
111 | version=1.0.3
112 |
113 | scripts/clean.sh
114 | scripts/prepare.sh $platform
115 |
116 | # now build & test (use xcode on mac, visual studio on windows, run make release on linux)
117 |
118 | scripts/dist.sh $platform $version
119 |
120 |
121 |
122 | # OSX: Getting rid of GLUT and Fmodex (optional)
123 |
124 | Those two libraries aren't needed. Removing them is done all at once, like this:
125 |
126 |
127 | Remove the setting `FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_1 = "\"$(SRCROOT)/../../../libs/glut/lib/osx\""` (you can find it through xcode cmd+shift+f search)
128 |
129 | Then, in `CoreOF.xcconfig`, redefine LIB_FMODEX and change LIB_FMODEX:
130 |
131 | // disable fmodex!
132 | LIB_FMODEX = -Wl,-U,_FMOD_System_Close
133 | REMOVED_DEPS = yes
134 |
135 | OF_CORE_FRAMEWORKS = -framework Accelerate -framework AGL -framework AppKit -framework ApplicationServices -framework AudioToolbox -framework AVFoundation -framework Cocoa -framework CoreAudio -framework CoreFoundation -framework CoreMedia -framework CoreServices -framework CoreVideo -framework IOKit -framework OpenGL -framework QuartzCore -framework QuickTime -framework QTKit //-framework GLUT
136 |
137 |
138 | Now go into the project config, build phases, run scripts, and wrap the glut and fmodex entries in an if:
139 |
140 | if [ REMOVED_DEPS -ne "yes"]
141 | then
142 | # Copy libfmod and change install directory for fmod to run
143 | rsync -aved ../../../libs/fmodex/lib/osx/libfmodex.dylib "$TARGET_BUILD_DIR/$PRODUCT_NAME.app/Contents/Frameworks/";
144 | install_name_tool -change @executable_path/libfmodex.dylib @executable_path/../Frameworks/libfmodex.dylib "$TARGET_BUILD_DIR/$PRODUCT_NAME.app/Contents/MacOS/$PRODUCT_NAME";
145 | # Copy GLUT framework (must remove for AppStore submissions)
146 | rsync -aved ../../../libs/glut/lib/osx/GLUT.framework "$TARGET_BUILD_DIR/$PRODUCT_NAME.app/Contents/Frameworks/"
147 | fi
148 |
149 | This way the build should still work if someone hasn't tweaked their OF installation.
--------------------------------------------------------------------------------
/src/ui/FMenu.h:
--------------------------------------------------------------------------------
1 | /*
2 | * FMenu.h
3 | * ofxMightyUI
4 | *
5 | * v1.14, add button with custom callback
6 | * v1.13, set minWidth on init
7 | * v1.12, removed highlightSelected option from dropdown
8 | * v1.11, add removeAllOptionsAndNotify()
9 | * v1.10, renamed dropdown::getOptionByName to dropdown::getOptionByValue (which is what was meant in the first place)
10 | * v1.9, added getOptionByValue(...), cleaned up a tiny bit
11 | * v1.8, undocumented.... minWidth, fixed layout issues, fontsize back to normal
12 | * v1.7, fdropdown: triangle scale, data display function, use mui_root->popup functions for dropdown
13 | * v1.6, merged 1.3a-1.5 from AL, merged 1.3-1.5 from OS
14 | * v1.5, allow multicolumn, rewrite layouting
15 | * v1.4, mouse over effect for buttons
16 | * v1.3a, add remove all options method
17 | * v1.5, 21.11.2016, removed funny dependency to soundythingie
18 | * v1.4, dropdown class now has a "datadelegate"
19 | * v1.3, added a dropdown button class with embedded menu
20 | * v1.2, it actually sortof works a bit, with the options.
21 | * v1.1, ability to attach data to an option
22 | * v1.0, 29.01.11. initial version
23 | *
24 | */
25 |
26 | #pragma once
27 |
28 | #include "ofxMightyUI.h"
29 |
30 | enum class FMenuNotify{
31 | always, if_changed, never
32 | };
33 |
34 | template
35 | class FMenu : public mui::Container {
36 | public:
37 | struct Option {
38 | Option(mui::Button * b, const T & v, mui::EventHandler