Go Back   Cockos Incorporated Forums > REAPER Forums > REAPER Developer Forum

Reply
 
Thread Tools Display Modes
Old 11-19-2015, 01:51 PM   #1
Argitoth
Human being with feelings
 
Argitoth's Avatar
 
Join Date: Feb 2008
Location: Phoenix, AZ
Posts: 2,037
Default HOWTO: Create a multi-platform reaper plugin

WARNING: GUI stuff is currently a work in progress by Xenakios, will remove this message when it becomes nicely packaged and I have written a nice tutorial.

Special thanks to:
  • COCKOS for existing
  • SWS for trailblazing
  • Xenakios for all his persistence in helping me and the community in getting example Xcode and Visual Studio projects. The MyReaperPlugin example project is 99% Xenakios original code.
  • Breeder for helping me get a virtual mac running on my windows machine and answering all my REAPER API questions.
  • Etienne Laurin for answering a million C++ questions.


These instructions will be a collection of things I wish I had known when starting out. BTW mac regex implementation has a bug where infinite loop is caused if the regex expressions ends in a .*. I'd recommend using boost regex or other multiplatform regex library. Also, these instructions may be very noobie... take it or leave! Learning how to create reascript API functions is on my todo list.

KEY
fill in the blank, specific to you
exactly the text you must type

DOWNLOAD TEMPLATE PROJECTS
  • https://github.com/elanhickler/MyReaperPlugin.git
  • To ensure the plugin is compatible with your version of REAPER, or to ensure you have access to the latest API, generate a reaper_plugin_functions.h
    • Open REAPER and search for header in the actions list, run and overwrite the reaper_plugin_functions.h file in MyReaperPlugin\library\reaper_plugin
    • You may also check the "Write functions exported by third party extensions" to get access to SWS reascript API functions, for example. The example project comes with REAPER 5.1 header file.

FOLDER STRUCTURE
  • NameOfProject
    • binary (holds the final output, the dll/dylib files)
      • Release (added to .gitignore, holds the final dll/dylib release version)
      • Debug (added to .gitignore, holds the final dll/dylib debug version)
    • header (hpp files)
    • library (files from libraries you want to be responsible for managing and keeping up to date, otherwise do not put files here)
      • WDL (this library sits here nicely)
    • source (cpp files)
    • Visual Studio
      • NameOfProject.sln (solution file holds the project and the configuration/platform build options)
      • NameOfProject.vcxproj (the actual project file)
      • NameOfProject.vcxproj.filters (keeps track of project file organization)
      • NameOfProject.vcxproj.user (keeps track of debugger command arguments e.g. running reaper.exe when debugging)
      • NameOfProject.sdf (added to .gitignore)
      • NameOfProject.rc_mac_dlg (Windows GUI resource for Mac generated by swell/mac_resgen.php)
      • NameOfProject.rc_mac_menu (same as above)
    • Xcode
      • NameOfProject.xcodeproj (the actual project, right click and Show Package Contents to see contents, xcuserdata is added to .gitignore)
    • .gitignore (git file using special syntax which tells git clients what files should not be uploaded to repository)
    • main.cpp (code for implementing actions and building the reaper plugin)
    • main.hpp (included in main.cpp, define your actions here)

NAME YOUR PROJECT
* IMPORTANT: The the final dll or dylib file must have reaper_ as a prefix.
WIN:
  • In Solution Explorer right-click on MyReaperPlugin project (not the solution) --> Properties --> Configuration Properties --> General --> change Target Name
  • Make sure you are changing for all configurations and platforms by using the Configuration and Platform dropdown menu to edit all.
  • (Optional) Rename solution (.sln file)
  • (Optional) Rename project and re-add the project to the solution
MAC:
  • Folder icon --> Click on project --> Click on project under Project --> Build Settings --> Have All and Combined highlighted --> Search for Dynamic Library Install Name --> double click on the resulting field to rename
  • Folder icon --> Click on project --> Targets --> Single-click on a target to rename
  • Product --> Scheme --> Manage Schemes --> Click on a scheme --> Edit --> Build tab --> Remove old targets with - symbol, Re-add targets with the + symbol, do this for both schemes.
  • (optional) Rename project (.xcodeproj file)

SETUP DEBUGGING
WIN:
  • My Computer --> Advanced --> Environmental Variables
  • Under "System variables" click NEW, type REAPER64_DIR and/or REAPER32_DIR and path to reaper root in the respective fields.
  • Configuration manager dropdown menu, switch to Debug.
  • Solution platform dropdown menu, switch to x32 or x64.
  • Debug --> Start Debugging
MAC:
  • If you are using REAPER 32-bit you will have to change your executable destination. Product --> Scheme --> Manage schemes --> Click on debug --> Edit --> Run tab --> Executable
  • Scheme dropdown menu, navigate to Debug
  • Click the play button

BUILD RELEASE
WIN:
  • Solution configuration dropdown menu, switch to Release.
  • Solution platform dropdown menu, switch to x32 or x64.
  • Build --> Build Solution
MAC:
  • Scheme dropdown menu, navigate to Release
  • Click the play button
__________________
Soundemote - Home of the chaosfly and pretty oscilloscope.
MyReaperPlugin - Easy-to-use cross-platform C++ REAPER extension template

Last edited by Argitoth; 12-15-2015 at 11:43 AM.
Argitoth is offline   Reply With Quote
Old 11-24-2015, 04:18 PM   #2
Argitoth
Human being with feelings
 
Argitoth's Avatar
 
Join Date: Feb 2008
Location: Phoenix, AZ
Posts: 2,037
Default

Create your first include files (hpp and cpp)
C++:
  • I'm not sure of the fastest way to do this, but I just create txt files by hand and and rename them to .hpp and cpp, throw them into the correct folders and drag them into the projects.
  • Some quick things to note, copying memory is wasteful when you are sure you don't need to copy memory.
    PHP Code:
    // new memory is allocated, a copy of the given variable value is sent
    // to the memory location, this is how functions are usually written.
    int myfunc(int myparam
    {     
        
    myparam 2//myparam is now 2, 
    }

    // myparam references the given variable. myparam becomes an alias of the
    // given variable, efficient use of cpu and memory.
    int myfunc(intmyparam
    {     
        
    myparam 2//myparam changes the input variable
    }

    // myparam references the given variable but it cannot be changed
    // use should use const as it makes it clear you don't intend to 
    // make changes to input variable, but you also don't need a whole
    // new variable.
    int myfunc(const intmyparam
    {   
        
    int myequation 3*myparam //good
        
    myparam 2//illegal 

  • To create a class, define all functions and members in the hpp as well as default values (unless you want to define default values upon construction of an object version of the class).
    PHP Code:
    /*************/
    /*MyClass.hpp*/
    /*************/
    #prama once // always do this at the top of each header, allows
                // you to include the .hpp in multiple places without
                // getting redefinition errors.

    class MyClass {
        public: 
    // public is assumed if not written
        
    MyClass(intb// no return type because it's t
                        // the class constructor function
        
    int dostuff(int x = -1); // x = 4 makes x default to x, you
                                // cannot use this for int& b
        
    private: // use private to hide a bunch of functions and variables 
        
    int a;   // that are only needed for the object to do stuff,
        
    intb;  // makes autocomplete easier to use as well.

    }

    /*************/
    /*MyClass.cpp*/
    /*************/
    #include MyClass.hpp // always do this

    // the stuff after : is called a "class initializer list"
    // incase you want to google it for more info
    MyClass(intneeded_for_b) : b(needed_for_b) {
       
    // do other stuff here when creating the object
    }

    // if you didn't have a reference member class:
    MyClass() {}

    // or if you wanted int a as a parameter
    MyClass(int a) {}

    // do not specify the defaults of parameters here!
    int dostuff(int x) {
        if (
    == -10// oh look, we did not give 
                            // a variable since x is still
                            // -1
        
    return b;

  • Using a class:
    PHP Code:
    /**********/
    /*main.cpp*/
    /**********/
    void main {
        
    int some_kinda_int;

        
    int another_int 2;

        
    MyClass mc(some_kinda_int); // make an object

        
    mc.dostuff(another_int); // use an object's function

        
    MyClass::dostuff(some_kinda_int
                           
    // this is how you use a class function
                           // without having to make an object first
                           // google c++ static class function
                           // to learn how.

  • Do not use if statements when switch/case is more appropriate.
    PHP Code:
    //Google "c++ enum" for more info. Also learn struct and namespace!
    enum {stateAstateBstateC// unnamed enumeration, will
    int myvar stateB;           // clutter your namespace

    enum MyStates {stateAstateBstateC// now it is named
    int myvar MyStates::stateB // that's how you access it
                                 // very good for autocomplete

    enum class MyStates {stateAstateBstateC}
    int myvar MyStates::stateB // illegal because int is not MyStates
    MyStates myvar MyStates::// good if you want to ensure you are
                                 // using the right enum
    switch (myvar) {
        
    //when you don't name the enum
        
    case stateA:
            break; 
    //very important to break
                   // or the code will continue
                   // to stateB

        //when you name the enum
        
    case MyStates::stateB:
            
    myvar MyStates::stateC
            
    continue; // this is a neat trick when
                      // the switch is inside a loop

        
    case MyStates::stateC:
            if (
    myvar !=  MyStates::stateA)
                return 
    0// combine if and switch when appropriate
            
    return // return a value or...
            
    return myvar // return the state
                         // useful for when
                         // inside a sub-function
        // default case.
        
    default: {     
            
    int x 3// use brackets here or you will get
         
    }             // error because x needs initialization
        
        // you can do more stuff here




Dealing with include file errors
WIN AND MAC:
  • Symbols not found: Most likely due to not having the cpp somewhere in Visual Studio or Xcode file list, or a .a or .lib file is not in the library search path. Also caused by incorrect use of "static" class members or not defining in the cpp declared in the hpp.
  • Duplicate symbols: In Xcode it is easy to add a cpp file twice to the compile list. Under the folder icon click on project --> Click on a target --> Go to Build Phases, open Compile Sources dropdown menu.
  • Redefinitions: Caused by a mismatch between the hpp and cpp version of a function or variable. Define default function parameters in the hpp only.
  • Header not found: The path to the file was not included in header search path or the #include definition is incorrect.
  • Still having trouble?: Sometimes libraries/include files require very specific search paths due to how include files are including other include files. Know what those very specific include paths are.

Debugger not hitting breakpoints
WIN AND MAC:
  • Put a breakpoint somewhere in the extern C function and continue form there.
  • hpp not found, symbols not found: Caused by the latest dll not being used by REAPER possibly due to plugin failing to be copied to the folder. Try Copying the plugin to the correct place by hand or rebuild from scratch.
  • still nothing?: Ensure that your plugin folder for the wrong architecture(32 or 64 bit)
  • Still having trouble?: Other things you can try: Check that you are launching the right REAPER exe. Delete dll, do not rebuild, check your actions list for your plugin actions (there should be none). Make sure you don't have multiple copies of the plugin in different places in your REAPER directory.

Still having trouble?:
Online IDE for quick tests (you should make a test version of your project for anything more complex rather than use online IDE):
Final tips
  • Do not repeat yourself (DRY): If you write something 3 times, it may be time to create a function.
  • Write nice code: Do not micro-optimize. Write code that looks nice. If you have speed problems, only then should you do something differently, do not go down the optimization rabbit hole without a reason!
  • Avoid using macros: It clutters the namespace. Use sparingly! They definitely have their uses.
  • Avoid using unsigned int or various versions of int unless you absolutely have to (do use size_t when appropriate)
  • Avoid using float unless you have to. Otherwise use double.
__________________
Soundemote - Home of the chaosfly and pretty oscilloscope.
MyReaperPlugin - Easy-to-use cross-platform C++ REAPER extension template

Last edited by Argitoth; 12-09-2015 at 07:34 AM.
Argitoth is offline   Reply With Quote
Old 11-24-2015, 04:19 PM   #3
Argitoth
Human being with feelings
 
Argitoth's Avatar
 
Join Date: Feb 2008
Location: Phoenix, AZ
Posts: 2,037
Default

(optional) Use a Git client
  • Download: Sourcetree, really awesome git client IMO, and I've tried a handful.
  • Commit: save changes to local files
  • Push: save changes to remote files (the online repository)
  • Pull: get changes from remote files (you must do this before pushing)
  • Discard: Remove changes from local files (be careful with this!)
  • Be careful about not saving you changes in Visual Studio or Xcode and pulling changes from remote, you could lose unsaved changes right then and there.


(optional) How to setup
  • Step 1: Remote setup (Github.com)
  • Step 2: Local setup (using Sourcetree)
    • File --> Clone / New --> Clone
    • in Source URL: paste in HTTPS link
    • Destination path: your intended project folder
    • Name: your intended project name
    • Drag files and folders from inside MyReaperPlugin folder into your project folder
    • Commit and push changes to your repository by clicking Commit tab
    • click Unstaged files check box
    • Fill out a message in the commit text box
    • click Push changes immediately check box
    • click Commit
__________________
Soundemote - Home of the chaosfly and pretty oscilloscope.
MyReaperPlugin - Easy-to-use cross-platform C++ REAPER extension template

Last edited by Argitoth; 12-10-2015 at 02:50 AM.
Argitoth is offline   Reply With Quote
Old 11-25-2015, 03:46 PM   #4
Argitoth
Human being with feelings
 
Argitoth's Avatar
 
Join Date: Feb 2008
Location: Phoenix, AZ
Posts: 2,037
Default

(optional) GET boost
WIN:MAC:
  • Open terminal
  • Get brew by using terminal command: ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"
  • enter xcode-select --install (not sure if this is a required step)
  • enter brew install boost --universal

(optional) SETUP ENVIRONMENTAL VARIABLES for boost
WIN:
  • My Computer --> Advanced --> Environmental Variables
  • Under "System variables" click NEW, type BOOST_ROOT and path to boost root in the respective fields
Xcode:
  • Go to project build settings
  • Click on + to get a dropdown menu and click on Add User-Defined Setting
  • Add BOOST_INCLUDE as /usr/local/Cellar/boost/1.59.0/include
  • Add BOOST_LIBRARY as /usr/local/Cellar/boost/1.59.0/lib

(optional) SETUP PROJECTS for boost
Visual Studio:
  • Project --> Properties --> C/C++ --> General
  • Additional Include Directories add $(BOOST_ROOT)
  • Project --> Properties --> Linker --> General
  • Additional Library Directories add $(BOOST_ROOT)/lib64-msvc-14.0 and $(BOOST_ROOT)/lib32-msvc-14.0
Xcode
  • In project build settings Header Search Paths add $BOOST_INCLUDE
  • In project build settings Library Search Paths add $BOOST_LIBRARY
  • Navigate to your boost lib folder
  • drag libboost_regex-mt.a into Xcode. Have "create groups" and all targets checked and click Finish
  • do the same as above for libboost_filesystem-mt.a and libboost_system-mt.a as filesystem also requires system.
__________________
Soundemote - Home of the chaosfly and pretty oscilloscope.
MyReaperPlugin - Easy-to-use cross-platform C++ REAPER extension template

Last edited by Argitoth; 12-09-2015 at 09:37 PM.
Argitoth is offline   Reply With Quote
Old 12-09-2015, 05:10 AM   #5
Argitoth
Human being with feelings
 
Argitoth's Avatar
 
Join Date: Feb 2008
Location: Phoenix, AZ
Posts: 2,037
Default

Github repository for example reaper plugin project is live! There is still more work to be done, for example the project is for OS X 10.7 and up. If someone has an earlier version of mac I could help them setup for 10.6 and update the repository to include 10.6 support.

This template project could include user interface stuff in the future. (XENAKIOS!! yes I'm looking at you.)

Post here if you need help.
__________________
Soundemote - Home of the chaosfly and pretty oscilloscope.
MyReaperPlugin - Easy-to-use cross-platform C++ REAPER extension template

Last edited by Argitoth; 12-09-2015 at 06:14 AM.
Argitoth is offline   Reply With Quote
Old 12-09-2015, 04:48 PM   #6
cfillion
Human being with feelings
 
cfillion's Avatar
 
Join Date: May 2015
Location: Québec, Canada
Posts: 1,213
Default

Quote:
Originally Posted by Argitoth View Post
  • res.rc_mac_dlg (not sure what it's for)
  • res.rc_mac_menu (not sure what it's for)
These are the SWELL version of Windows's resource (RC) files for OS X. They are generated from the original RC file by the mac_resgen.php script found in SWELL's root (WDL/WDL/swell).

They are not needed unless you use Windows RC files for Win32 dialog templates or menus.

Last edited by cfillion; 12-09-2015 at 07:12 PM.
cfillion is online now   Reply With Quote
Old 12-09-2015, 05:09 PM   #7
Xenakios
Human being with feelings
 
Xenakios's Avatar
 
Join Date: Feb 2007
Location: Oulu, Finland
Posts: 6,562
Default

It's cool you are gathering all this info!

It will also serve as a stark reminder creating C++ extension plugins for Reaper is not a thing to be taken lightly. Anyone considering it should first thoroughly investigate other options such as ReaScript.
__________________
For info on SWS Reaper extension plugin (including Xenakios' previous extension/actions) :
http://www.sws-extension.org/
https://github.com/Jeff0S/sws
--
Xenakios blog (about HourGlass and λ) :
http://xenakios.wordpress.com/
Xenakios is online now   Reply With Quote
Old 12-09-2015, 09:13 PM   #8
Argitoth
Human being with feelings
 
Argitoth's Avatar
 
Join Date: Feb 2008
Location: Phoenix, AZ
Posts: 2,037
Default

Quote:
Originally Posted by cfillion View Post
These are the SWELL version of Windows's resource (RC) files for OS X. They are generated from the original RC file by the mac_resgen.php script found in SWELL's root (WDL/WDL/swell).
thanks!

Quote:
Originally Posted by Xenakios View Post
It's cool you are gathering all this info! It will also serve as a stark reminder creating C++ extension plugins for Reaper is not a thing to be taken lightly...
Oh Xen, this was meant to encourage not discourage! IMO a C++ plugin is trivial once you have your eggs in a basket. I've done my best here to make putting your eggs in a basket as easy as downloading the repository. The struggles I've faced with C++ are only due to the complexity of what I was trying to do. But that's what the community is for, to answer questions and keep you moving. Now that I know a thing or two I can answer questions.
__________________
Soundemote - Home of the chaosfly and pretty oscilloscope.
MyReaperPlugin - Easy-to-use cross-platform C++ REAPER extension template
Argitoth is offline   Reply With Quote
Old 12-10-2015, 05:17 PM   #9
Xenakios
Human being with feelings
 
Xenakios's Avatar
 
Join Date: Feb 2007
Location: Oulu, Finland
Posts: 6,562
Default

I made a very simple win32 GUI example thing for the plugin. Unfortunately it doesn't build/run correctly on OS-X. Does anybody see what the error is? I suspect the .rc file for the dialog isn't correctly parsed and transformed by the php code generation script...The script of course doesn't give any error when it is run.
__________________
For info on SWS Reaper extension plugin (including Xenakios' previous extension/actions) :
http://www.sws-extension.org/
https://github.com/Jeff0S/sws
--
Xenakios blog (about HourGlass and λ) :
http://xenakios.wordpress.com/
Xenakios is online now   Reply With Quote
Old 12-10-2015, 07:02 PM   #10
Argitoth
Human being with feelings
 
Argitoth's Avatar
 
Join Date: Feb 2008
Location: Phoenix, AZ
Posts: 2,037
Default

Just an idea you probably already considered: did you try breakpoints?
__________________
Soundemote - Home of the chaosfly and pretty oscilloscope.
MyReaperPlugin - Easy-to-use cross-platform C++ REAPER extension template
Argitoth is offline   Reply With Quote
Old 12-10-2015, 07:18 PM   #11
Xenakios
Human being with feelings
 
Xenakios's Avatar
 
Join Date: Feb 2007
Location: Oulu, Finland
Posts: 6,562
Default

The problem was in the .rc file encoding. For some reason Visual Studio 2015 saved it in an encoding that the Cockos PHP script could not parse. A similar problem also happened with the resource.h file. XCode/Clang couldn't use the file due to the incompatible text encoding. (The GUI example now runs succesfully in OS-X.)
__________________
For info on SWS Reaper extension plugin (including Xenakios' previous extension/actions) :
http://www.sws-extension.org/
https://github.com/Jeff0S/sws
--
Xenakios blog (about HourGlass and λ) :
http://xenakios.wordpress.com/
Xenakios is online now   Reply With Quote
Old 12-11-2015, 05:10 PM   #12
Argitoth
Human being with feelings
 
Argitoth's Avatar
 
Join Date: Feb 2008
Location: Phoenix, AZ
Posts: 2,037
Default

Xen, thanks for making some great GUI examples. I need to study these and I will eventually make a guide for it.
__________________
Soundemote - Home of the chaosfly and pretty oscilloscope.
MyReaperPlugin - Easy-to-use cross-platform C++ REAPER extension template
Argitoth is offline   Reply With Quote
Old 12-15-2015, 11:49 AM   #13
Argitoth
Human being with feelings
 
Argitoth's Avatar
 
Join Date: Feb 2008
Location: Phoenix, AZ
Posts: 2,037
Default

I'm now satisfied with the implementation of reascript.
__________________
Soundemote - Home of the chaosfly and pretty oscilloscope.
MyReaperPlugin - Easy-to-use cross-platform C++ REAPER extension template
Argitoth is offline   Reply With Quote
Old 12-15-2015, 05:38 PM   #14
Xenakios
Human being with feelings
 
Xenakios's Avatar
 
Join Date: Feb 2007
Location: Oulu, Finland
Posts: 6,562
Default

The GUI stuff is in somewhat of a flux at the moment but I believe it will turn out pretty nice in the end.
__________________
For info on SWS Reaper extension plugin (including Xenakios' previous extension/actions) :
http://www.sws-extension.org/
https://github.com/Jeff0S/sws
--
Xenakios blog (about HourGlass and λ) :
http://xenakios.wordpress.com/
Xenakios is online now   Reply With Quote
Old 12-16-2015, 05:25 AM   #15
Argitoth
Human being with feelings
 
Argitoth's Avatar
 
Join Date: Feb 2008
Location: Phoenix, AZ
Posts: 2,037
Default

Code:
            DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
                    Version 2, December 2004

 Copyright (C) 2004 Sam Hocevar <sam@hocevar.net>

 Everyone is permitted to copy and distribute verbatim or modified
 copies of this license document, and changing it is allowed as long
 as the name is changed.

            DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
   TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION

  0. You just DO WHAT THE FUCK YOU WANT TO.
I think I want this license for MRP. Yes I'm calling it MRP now. my reaper plugin.

Edit: Oh unless, Xen, you want to get credited for your GUI stuff then we can use something stronger.
__________________
Soundemote - Home of the chaosfly and pretty oscilloscope.
MyReaperPlugin - Easy-to-use cross-platform C++ REAPER extension template

Last edited by Argitoth; 12-16-2015 at 05:38 AM.
Argitoth is offline   Reply With Quote
Old 03-11-2016, 05:42 PM   #16
jamesd256
Human being with feelings
 
jamesd256's Avatar
 
Join Date: Dec 2015
Location: Chelmsford
Posts: 107
Default

Quote:
Originally Posted by Argitoth View Post
Code:
            DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
                    Version 2, December 2004

 Copyright (C) 2004 Sam Hocevar <sam@hocevar.net>

 Everyone is permitted to copy and distribute verbatim or modified
 copies of this license document, and changing it is allowed as long
 as the name is changed.

            DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
   TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION

  0. You just DO WHAT THE FUCK YOU WANT TO.
I think I want this license for MRP. Yes I'm calling it MRP now. my reaper plugin.

Edit: Oh unless, Xen, you want to get credited for your GUI stuff then we can use something stronger.
This is awesome work! Thank you so much Argitoth and Xenakios, this has sped up my learning curve. I'm ready to go!

Maybe this thread should be a sticky?
jamesd256 is offline   Reply With Quote
Old 03-12-2016, 11:41 AM   #17
Argitoth
Human being with feelings
 
Argitoth's Avatar
 
Join Date: Feb 2008
Location: Phoenix, AZ
Posts: 2,037
Default

This project is somewhat abandoned due to using an insufficient GUI framework.

I may resurrect this project with details on how to use JUCE for the GUI in the future.

This project is still great for everything else.
__________________
Soundemote - Home of the chaosfly and pretty oscilloscope.
MyReaperPlugin - Easy-to-use cross-platform C++ REAPER extension template
Argitoth is offline   Reply With Quote
Old 03-12-2016, 04:50 PM   #18
WyattRice
Human being with feelings
 
WyattRice's Avatar
 
Join Date: Sep 2009
Location: Virginia
Posts: 1,769
Default

Thanks for putting this together.

As a test, I tried to build using the latest VS2015 community version. I get three of these errors.

Error C4996 'strnicmp': The POSIX name for this item is deprecated. Instead, use the ISO C and C++ conformant name: _strnicmp. See online help for details. MyReaperPlugin C:\Users\Wyatt\Desktop\MyReaperPlugin-master\MyReaperPlugin-master\library\WDL\WDL\jnetlib\httpget.cpp

Will the template project build as it is (Just for a test)?

Sorry for such a noob question.

Thanks, Wyatt
WyattRice is offline   Reply With Quote
Old 03-12-2016, 05:36 PM   #19
jamesd256
Human being with feelings
 
jamesd256's Avatar
 
Join Date: Dec 2015
Location: Chelmsford
Posts: 107
Default

Quote:
Originally Posted by WyattRice View Post
Thanks for putting this together.

As a test, I tried to build using the latest VS2015 community version. I get three of these errors.

Error C4996 'strnicmp': The POSIX name for this item is deprecated. Instead, use the ISO C and C++ conformant name: _strnicmp. See online help for details. MyReaperPlugin C:\Users\Wyatt\Desktop\MyReaperPlugin-master\MyReaperPlugin-master\library\WDL\WDL\jnetlib\httpget.cpp

Will the template project build as it is (Just for a test)?

Sorry for such a noob question.

Thanks, Wyatt
I just had a go at building. Once I fixed the first function name problems, I ran into some linker errors. I was able to work around these build problems with the following:

asyncdns.cpp:

Line 128:

if (!stricmp(m_cache[x].hostname,hostname) && m_cache[x].mode==0)

Change to:

if (!_stricmp(m_cache[x].hostname,hostname) && m_cache[x].mode==0)

httpget.cpp:

Line 298:

if (!strnicmp(headername,p,headername_len) && p[headername_len] == ':')

Change to:

if (!_strnicmp(headername,p,headername_len) && p[headername_len] == ':')

Line 362:

if (!strnicmp(buf,"Location:",9))

Change to:

if (!_strnicmp(buf,"Location:",9))

main.cpp:

Add this pragma:

#pragma comment(lib, "Ws2_32.lib")

Adding this via properties, linker, input, additional dependencies should have worked I think, but didn't for me.
jamesd256 is offline   Reply With Quote
Old 03-12-2016, 05:42 PM   #20
WyattRice
Human being with feelings
 
WyattRice's Avatar
 
Join Date: Sep 2009
Location: Virginia
Posts: 1,769
Default

jamesd256,
Thanks!
WyattRice is offline   Reply With Quote
Old 03-12-2016, 06:05 PM   #21
jamesd256
Human being with feelings
 
jamesd256's Avatar
 
Join Date: Dec 2015
Location: Chelmsford
Posts: 107
Default

Quote:
Originally Posted by Argitoth View Post
This project is somewhat abandoned due to using an insufficient GUI framework.

I may resurrect this project with details on how to use JUCE for the GUI in the future.

This project is still great for everything else.
Klinke's famous csurf extension uses JUCE, and is available on Github.

Unfortunately it's using Juce 1.5, which is 'ancient history'. That's what they told me on the JUCE forum when I asked for help with building against it.
jamesd256 is offline   Reply With Quote
Old 11-07-2016, 02:25 PM   #22
rjlwest
Human being with feelings
 
Join Date: Nov 2016
Posts: 14
Default

strong thread.
rjlwest is offline   Reply With Quote
Old 11-07-2016, 02:45 PM   #23
Xenakios
Human being with feelings
 
Xenakios's Avatar
 
Join Date: Feb 2007
Location: Oulu, Finland
Posts: 6,562
Default

Quote:
Originally Posted by jamesd256 View Post
Klinke's famous csurf extension uses JUCE, and is available on Github.

Unfortunately it's using Juce 1.5, which is 'ancient history'. That's what they told me on the JUCE forum when I asked for help with building against it.
JUCE is at version 4.3 now, so no wonder they are not that eager to support doing anything with such an old version at the JUCE forum.
__________________
For info on SWS Reaper extension plugin (including Xenakios' previous extension/actions) :
http://www.sws-extension.org/
https://github.com/Jeff0S/sws
--
Xenakios blog (about HourGlass and λ) :
http://xenakios.wordpress.com/
Xenakios is online now   Reply With Quote
Old 11-07-2016, 04:10 PM   #24
rjlwest
Human being with feelings
 
Join Date: Nov 2016
Posts: 14
Default

with JUCE you would need a license, you could use openframeworks. I have an interface library but i think it may be the wrong tool for the job, overkill and not good looking.

as for this project, I can build (only after re adding a few files xcode couldnt find), i can deploy to the correct folder, but Reaper won't see anything I built. I did the header thing, my version of SWS is sws-v2.8.3.0
rjlwest is offline   Reply With Quote
Old 11-07-2016, 04:27 PM   #25
Xenakios
Human being with feelings
 
Xenakios's Avatar
 
Join Date: Feb 2007
Location: Oulu, Finland
Posts: 6,562
Default

Quote:
Originally Posted by rjlwest View Post
with JUCE you would need a license, you could use openframeworks. I have an interface library but i think it may be the wrong tool for the job, overkill and not good looking.

as for this project, I can build (only after re adding a few files xcode couldnt find), i can deploy to the correct folder, but Reaper won't see anything I built. I did the header thing, my version of SWS is sws-v2.8.3.0
You need to ensure the CPU architectures match. 32 bit Reaper needs a 32 bit build of the plugin and 64 bit Reaper needs a 64 bit build. Anyway, I haven't been myself working on this plugin thing for a while, so I am not sure how it should be built or what it should be doing in Reaper etc...(It's amazing how quickly one can forget things when not actively working on them, at least at this age...)

Regarding using JUCE, it's just a choice one can make if one is either willing to pay the license price or willing to open source the code of the plugin.
__________________
For info on SWS Reaper extension plugin (including Xenakios' previous extension/actions) :
http://www.sws-extension.org/
https://github.com/Jeff0S/sws
--
Xenakios blog (about HourGlass and λ) :
http://xenakios.wordpress.com/
Xenakios is online now   Reply With Quote
Old 11-07-2016, 04:38 PM   #26
rjlwest
Human being with feelings
 
Join Date: Nov 2016
Posts: 14
Default

Quote:
Originally Posted by Xenakios View Post
You need to ensure the CPU architectures match. 32 bit Reaper needs a 32 bit build of the plugin and 64 bit Reaper needs a 64 bit build. Anyway, I haven't been myself working on this plugin thing for a while, so I am not sure how it should be built or what it should be doing in Reaper etc...(It's amazing how quickly one can forget things when not actively working on them, at least at this age...)

Regarding using JUCE, it's just a choice one can make if one is either willing to pay the license price or willing to open source the code of the plugin.
"2016-11-07 23:33:56.333 reaper_host_i386[1964:105487] Error loading /Applications/REAPER64.app/Contents/Plugins/REAPERReWireDev.bundle/Contents/MacOS/REAPERReWireDev: dlopen(/Applications/REAPER64.app/Contents/Plugins/REAPERReWireDev.bundle/Contents/MacOS/REAPERReWireDev, 262): no suitable image found. Did find:
/Applications/REAPER64.app/Contents/Plugins/REAPERReWireDev.bundle/Contents/MacOS/REAPERReWireDev: mach-o, but wrong architecture"

does look like an architecture issue, I'll have to look at it tomorrow.

I take it it's supposed to show up in the extensions list when it's working?
rjlwest is offline   Reply With Quote
Old 11-07-2016, 04:44 PM   #27
Xenakios
Human being with feelings
 
Xenakios's Avatar
 
Join Date: Feb 2007
Location: Oulu, Finland
Posts: 6,562
Default

Quote:
Originally Posted by rjlwest View Post

I take it it's supposed to show up in the extensions list when it's working?
It just adds actions into the Reaper action list, no menu entries or default keyboard shortcut keys.

By the way, take the win32 based GUI stuff in the code with a very large grain of salt. Lots of it does not work correctly. The GUI stuff should probably be removed from the plugin completely...(The code was not updated to use JUCE in the end.)
__________________
For info on SWS Reaper extension plugin (including Xenakios' previous extension/actions) :
http://www.sws-extension.org/
https://github.com/Jeff0S/sws
--
Xenakios blog (about HourGlass and λ) :
http://xenakios.wordpress.com/
Xenakios is online now   Reply With Quote
Old 11-08-2016, 02:45 AM   #28
rjlwest
Human being with feelings
 
Join Date: Nov 2016
Posts: 14
Default

Quote:
Originally Posted by Xenakios View Post
It just adds actions into the Reaper action list, no menu entries or default keyboard shortcut keys.

By the way, take the win32 based GUI stuff in the code with a very large grain of salt. Lots of it does not work correctly. The GUI stuff should probably be removed from the plugin completely...(The code was not updated to use JUCE in the end.)
what I want to do is so simple, I think it could be done just with 1 button, all I want to do to start with is export all media events through a network port so I can grab it in a standalone program and recreate them.
rjlwest is offline   Reply With Quote
Old 11-08-2016, 03:05 AM   #29
Xenakios
Human being with feelings
 
Xenakios's Avatar
 
Join Date: Feb 2007
Location: Oulu, Finland
Posts: 6,562
Default

Quote:
Originally Posted by rjlwest View Post
what I want to do is so simple, I think it could be done just with 1 button, all I want to do to start with is export all media events through a network port so I can grab it in a standalone program and recreate them.
Well, it doesn't sound like you need any GUI at all, at least at first. Just add an action in the plugin that does your task.
__________________
For info on SWS Reaper extension plugin (including Xenakios' previous extension/actions) :
http://www.sws-extension.org/
https://github.com/Jeff0S/sws
--
Xenakios blog (about HourGlass and λ) :
http://xenakios.wordpress.com/
Xenakios is online now   Reply With Quote
Old 11-08-2016, 12:23 PM   #30
rjlwest
Human being with feelings
 
Join Date: Nov 2016
Posts: 14
Default

what is the default behaviour of the plugin if I don't add anything? I got rid of the console output by removing i386 in the build settings so it just builds for x86_64, but still nothing shows in Reaper. Is it expected to do nothing until I add actions?

edit: never mind, I figured it out. this is amazing and has saved me weeks practically.

Last edited by rjlwest; 11-08-2016 at 02:42 PM.
rjlwest is offline   Reply With Quote
Old 11-09-2016, 07:32 AM   #31
DrFrankencopter
Human being with feelings
 
Join Date: Jan 2011
Location: Ottawa, Canada
Posts: 106
Default

Thanks for putting this together. I'm just getting started with it on Xcode, and have run into issues just building the basic MyReaperPlugin.

Within the Xcode project navigator pane under the library/WDL folder there is:
httpget.cpp
asyncdns.cpp
connection.cpp
util.cpp
listen.cpp

None of these files appear in my library/WDL directory...and I don't see them in the git repository either. I think these are from the jnetlib directory. I'll try pointing them to the right spot.

Also, the compiler is complaining that there are "no input files". This is Xcode 7.3 BTW.

Cheers

Kris
DrFrankencopter is offline   Reply With Quote
Old 11-09-2016, 07:43 AM   #32
DrFrankencopter
Human being with feelings
 
Join Date: Jan 2011
Location: Ottawa, Canada
Posts: 106
Default

Ok, so I pointed Xcode to the right file locations, and it claims that build succeeded (lots of warning, but whatever). It launched Reaper, but I have a message in Xcode's console that "SWELL API NOT FOUND:" . I figure that's a problem on mac, as I understand that's how cross platform support for the API is enabled.

Another strange thing is that while the plugin claims to build it shows up as red in Xcode's project navigator. I wonder if it's trying to build in a directory that doesn't exist... I note in the first post that there is supposed to be a "binary" folder with debug and release sub folders. I don't have these....as they aren't in the zip from git.

I'll try making them and digging around the project file to see where the build products go.

Cheers

Kris
DrFrankencopter is offline   Reply With Quote
Old 11-09-2016, 07:50 AM   #33
DrFrankencopter
Human being with feelings
 
Join Date: Jan 2011
Location: Ottawa, Canada
Posts: 106
Default

Ok, I'm learning more here. The plugin builds in a private derived data folder (like most Xcode projects), but it deploys it to Users/username/Library/Application Support/REAPER/UserPlugins/ and leaves a symlink in the derived data folder.

Now I need to find out if Reaper is actually seeing it. When I experimented with plug-in development earlier this week I was copying my plugin into the REAPER.app bundle under plugins.

How can I check what plug-ins have been loaded?

Cheers

Kris
DrFrankencopter is offline   Reply With Quote
Old 11-09-2016, 08:04 AM   #34
Xenakios
Human being with feelings
 
Xenakios's Avatar
 
Join Date: Feb 2007
Location: Oulu, Finland
Posts: 6,562
Default

Quote:
Originally Posted by DrFrankencopter View Post
How can I check what plug-ins have been loaded?
AFAIK there's no feature or API for that...(You could of course put in a debug print statement or breakpoint in the extension plugin entry point function to see if it is called and if it successfully gets to the end.)
__________________
For info on SWS Reaper extension plugin (including Xenakios' previous extension/actions) :
http://www.sws-extension.org/
https://github.com/Jeff0S/sws
--
Xenakios blog (about HourGlass and λ) :
http://xenakios.wordpress.com/
Xenakios is online now   Reply With Quote
Old 02-07-2017, 02:36 PM   #35
SpiderFox
Human being with feelings
 
Join Date: Jan 2017
Posts: 29
Default

How far have you gone with the GUI stuff?

I'm really interested in creating a reaper extension but the Win32 GUI stuff is really annoying´.
SpiderFox is offline   Reply With Quote
Old 02-07-2017, 02:54 PM   #36
Xenakios
Human being with feelings
 
Xenakios's Avatar
 
Join Date: Feb 2007
Location: Oulu, Finland
Posts: 6,562
Default

Quote:
Originally Posted by SpiderFox View Post
How far have you gone with the GUI stuff?

I'm really interested in creating a reaper extension but the Win32 GUI stuff is really annoying´.
If you mean the JUCE based stuff, it can be made to work "OK", but the integration with the Reaper windowing isn't anywhere near perfect. But that is something I can personally live with, since doing the actual GUI code with the win32 API would be way worse.
__________________
For info on SWS Reaper extension plugin (including Xenakios' previous extension/actions) :
http://www.sws-extension.org/
https://github.com/Jeff0S/sws
--
Xenakios blog (about HourGlass and λ) :
http://xenakios.wordpress.com/
Xenakios is online now   Reply With Quote
Old 02-07-2017, 05:57 PM   #37
SpiderFox
Human being with feelings
 
Join Date: Jan 2017
Posts: 29
Default

Is there a simple sample extension which illustrates the usage of the JUCE library?
SpiderFox is offline   Reply With Quote
Old 02-07-2017, 07:41 PM   #38
Xenakios
Human being with feelings
 
Xenakios's Avatar
 
Join Date: Feb 2007
Location: Oulu, Finland
Posts: 6,562
Default

Quote:
Originally Posted by SpiderFox View Post
Is there a simple sample extension which illustrates the usage of the JUCE library?
At the moment, I don't think so. I could explain the general procedure here but there really is no substitute for a full working project/code example. It is not going to be exactly "simple" because using JUCE complicates the build procedure quite a lot. (It's not a library one can simply include in a project and use.)

Are you sure you can't just get by with using the win32 API? (I know it's extremely annoying and frustrating to use, but sometimes it can be the right choice.)

How about some solution that doesn't require building a Reaper extension plugin at all?
__________________
For info on SWS Reaper extension plugin (including Xenakios' previous extension/actions) :
http://www.sws-extension.org/
https://github.com/Jeff0S/sws
--
Xenakios blog (about HourGlass and λ) :
http://xenakios.wordpress.com/
Xenakios is online now   Reply With Quote
Old 02-09-2017, 11:24 AM   #39
Xenakios
Human being with feelings
 
Xenakios's Avatar
 
Join Date: Feb 2007
Location: Oulu, Finland
Posts: 6,562
Default

edit : moved this to a separate thread in case Argitoth wants to keep this thread dedicated to his stuff.
__________________
For info on SWS Reaper extension plugin (including Xenakios' previous extension/actions) :
http://www.sws-extension.org/
https://github.com/Jeff0S/sws
--
Xenakios blog (about HourGlass and λ) :
http://xenakios.wordpress.com/

Last edited by Xenakios; 02-09-2017 at 11:33 AM.
Xenakios is online now   Reply With Quote
Old 03-09-2017, 04:27 PM   #40
rjlwest
Human being with feelings
 
Join Date: Nov 2016
Posts: 14
Default

I have 2 questions, I notice a JUCE thread, I was wondering where that comes from and if I can turn it off.

Also, the only bits of non library code I still use from the example project are

execute_in_main_thread
start_or_stop_main_thread_executor
mtetimerproc

I was wondering if this code is from Reaper or if I would be ripping off someones hard work? The Reaper plugin I'm making os a very lightweight part of something far deeper and will be comercially available so I'm just investigating whether or not I should take it out.

also one more question

_timer = SetTimer(0, 1000, 333, Proc);

the third parameter is UINT rate, I Was wondering are these milliseconds? I'm having a terrible problem with performance and can't pin it down, I think I investigated this already and found them to be milliseconds and that it sleeps for that time after the function has run until its called again.
rjlwest is offline   Reply With Quote
Reply

Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off

Forum Jump


All times are GMT -7. The time now is 12:26 PM.


Powered by vBulletin® Version 3.8.11
Copyright ©2000 - 2017, vBulletin Solutions Inc.