Go Back   Cockos Incorporated Forums > REAPER Forums > MIDI Hardware, Control Surfaces, and OSC

Reply
 
Thread Tools Display Modes
Old 12-04-2017, 11:04 AM   #281
Geoff Waddington
Human being with feelings
 
Geoff Waddington's Avatar
 
Join Date: Mar 2009
Location: Dartmouth, Nova Scotia
Posts: 11,183
Default

Quote:
Originally Posted by fundorin View Post
Just copy/paste? How many plugins do you have in your system, Geoff?


P.S. It seems like I need to get back to oscii-bot scripting now. According to the manual, oscii-bot can also read from external files, so, after finishing the main script, it should be possible to get fx parameter's names and values from external files.
Hmmm... the way this mapping system works, you need the Widget name and the FX Param name on the same line in the same file, so there is no easy way to auto generate FX maps, seems like you are expecting a completely different outcome than this project will provide.

Some of your posts hint at auto generating files, that would be a very different approach than this project provides, the idea is to NOT have the params automatically laid out, but rather to tightly control widget/FX Param association, in order to customize the workflow to your particular needs.

Maybe you could explain the workflow you are attempting to facilitate, that might help me understand what you need ?
__________________
To install you need the CSI Software and Support Files
For installation instructions and documentation see the Wiki
Donate -- via PayPal to waddingtongeoff@gmail.com
Geoff Waddington is offline   Reply With Quote
Old 12-04-2017, 11:36 AM   #282
TonE
Human being with feelings
 
Join Date: Feb 2009
Location: Reaper HAS send control via midi !!!
Posts: 4,031
Default

Every system design needs some diagrams, are there any diagrams showing an overview of systems, components, interfaces? The purpose and goal of everything? If those are wrong from the beginning it makes no sense to think further. This is usually what various companies do, putting some nonsense together, then trying to sell it.
TonE is offline   Reply With Quote
Old 12-04-2017, 02:18 PM   #283
Geoff Waddington
Human being with feelings
 
Geoff Waddington's Avatar
 
Join Date: Mar 2009
Location: Dartmouth, Nova Scotia
Posts: 11,183
Default

Quote:
Originally Posted by TonE View Post
Every system design needs some diagrams, are there any diagrams showing an overview of systems, components, interfaces? The purpose and goal of everything? If those are wrong from the beginning it makes no sense to think further. This is usually what various companies do, putting some nonsense together, then trying to sell it.
Hell yeah !!

Diagrams ? Diagrams ? We don't need no stinkin' diagrams !!

Seriously, thanks very much for asking, I've got 30 years of OO in languages such as Smalltalk, Object1, Actor, Eiffel, C++, Java, C#, and probably a few more I've forgotten. I also have solid assembly skills, and skills in procedural languages as well, too many languages to try and recall at my advanced age

As far as control surfaces, I wrote the original support for the Presonus Faderport back in 2006, it was Cubase, DP, and Sonar only at that time, IIRC.

Also did an MCU version for Reaper.

A few years back wrote the EuCon support for Reaper.

So with all that said here is the current state of the project, subject, of course, to the inevitable change that is guaranteed to happen.

Overall architecture:

Provide the ability to have an arbitrary surface control (midi/OSC/Web) cause an arbitrary action in Reaper.

Language: C++ Dll/dylib.

High level goals include:

NO UI initially:
Typically, UI's are hell and cross platform UI's are hell squared as far as human resource drain. I would estimate conservatively that this will cut the project time by 2/3.
So we can deliver in 1/3 time.

That means the files must be in a format that can be reasonably edited in a text editor by a human.
This leads to a simplified approach that yields other advantages, including things like tighter network packets for better performing remote operations.

So no binary, XML etc., just a simple text file format, leaning STRONGLY right now towards the Reaper .rpp format, nice and clean.

Most of the code is in the navigation from Control Surface Widget to Reaper Action, the actual Widgets and Actions are quite simple.

One of the most important things to get right in OO is the containment so here is a OO/DB entity/relationship view from a containment perspective where the symbol -> means "contains"

ControlSurfaceIntegrator->CSurfManager->LogicalCSurfs

LogicalCSurfs->RealCSurfs->CSurfChannels->CSurfWidgets

LogicalCSurfs->Interactors->Actions

So now for a simplified use case / UML sequence diagram combo:

User presses Mute button
CSurfWidget handles midi message
CSurfWidget calls up to CSurfChannel with widget name "Mute" and value 1.
CSurfChannel calls up to RealCSurf with it's trackGUID added to the name "Mute" and value 1.
RealCSurf calls up to LogicalCSurf with RealCSurf name added to trackGUID, name "Mute" and value 1.

LogicalCSurf iterates over interactors looking for an interactor with corresponding trackGUID.
Interactor iterates over Actions looking for one named "Mute".
Action named Mute gets value 1.

That's the easy one
Here's the other direction:

ControlSurfaceIntegrator receives an update request frequently (user adjustable, usually 15-60 Hz range) from Reaper.
ControlSurfaceIntegrator tells CSurfManager to update.
CSurfManager tells LogicalCSurf to update,

Now it is very tempting right here to take the easy way out and ask all the interactors to update, but that is a scalability problem just waiting to happen, and it can be easily avoided.
There is no sense asking for interactors that are not visible on the surface(s) to update, it is at best wasted energy, and at worst a severe performance killer.

So......

LogicalCSurf tells RealCSurf to update.
RealCSurf tells CSurfChannel to update.
CSurfChannel tells CSurfWidget to update
CSurfWidget calls up to CSurfChannel with widget name "Mute".
CSurfChannel calls up to RealCSurf with it's trackGUID added to the name "Mute".
RealCSurf calls up to LogicalCSurf with RealCSurf name added to trackGUID, and name "Mute".
LogicalCSurf iterates over interactors looking for an interaction with corresponding trackGUID.
Interactor iterates over Actions looking for one named "Mute".
Interactor tells Action to update
Action checks current Reaper value (in this case the value for "Mute" ), compares it to the value it has from the last update request and if it is different..
Action calls Interactor with surface name, Action name, and new value.
Interactor calls LogicalCSurf with trackGUID, surface name, Action name, and new value.
LogicalCSurf iterates over RealCSurfs looking for one with corresponding surface name.
RealCSurf iterates over CSurfChannels looking for a CSurfChannel with corresponding trackGUID.
CSurfChannel iterates over CSurfWidgets looking for one with corresponding Action name.
CSurfWidget sets new value, which in this case means sending a midi message to the "Mute" button on the physical surface.

Phew

It really is worth it, the performance varies little from 20 tracks to 1000+ tracks.


There are lots if other details like the fact that every value transmitted is in the normalized floating point range of 0.0 - 1.0, that means controls are interchangeable from a values perspective. Stuff like that, mostly internal details.
__________________
To install you need the CSI Software and Support Files
For installation instructions and documentation see the Wiki
Donate -- via PayPal to waddingtongeoff@gmail.com
Geoff Waddington is offline   Reply With Quote
Old 12-04-2017, 10:09 PM   #284
fundorin
Banned
 
Join Date: Feb 2014
Location: Moscow, Russia
Posts: 554
Default

Quote:
Originally Posted by Geoff Waddington View Post
Maybe you could explain the workflow you are attempting to facilitate, that might help me understand what you need ?
I just remembered that Automap software had kinda similar approach.
The button in settings generated wrapped versions of all installed plugins, so that user could rearrange the parameters of the plugin in the Automap GUI itself.
This worked, but plugin folder was flooded with wrapped versions.
For example:

Original structure:
PlugFolder\Plug1.dll <- original plugin
PlugFolder\Plug2.dll <- original plugin
PlugFolder\Plug3.dll <- original plugin

After automap generator:
PlugFolder\Plug1.dll <- automap wrapper
PlugFolder\Plug1 (automap).dll <- original plugin
PlugFolder\Plug2.dll <- automap wrapper
PlugFolder\Plug2 (automap).dll <- original plugin
PlugFolder\Plug3.dll <- automap wrapper
PlugFolder\Plug3 (automap).dll <- original plugin

There were several problems with this approach:
1. FX browser showed every plugin twice
2. One should manually replace all plugins in the existing projects with wrapped versions
3. After plugin updates, wrapping should be done again
4. Automap didn't have full HUI implementation and no option to remap mixer mode mappings.

It driven me mad, all those flaws in the working process, so I got rid of the Automap software as quickly as I could and ended up without midi feedback from Reaper for years.
If only Automap could generate external keymaps for each plugin and store them at some other place then plugins folders, without touching the original .dlls, that would be great.
And, of cause, HUI/MCU support with feedback/free controls mapping.

Wrapper GUI:


Automap floating GUI. Called and toggled with physical "View" button on the surface. Paired with "Learn" button, so it's works similarly to the Reaper's own learn function, but also allows to set up several parameters of the mapped controller, like toggle/momentary for buttons, absolute/relative for encoders, range for pots and some other important stuff that I've already forgot after years of not using Automap:


Another screenshot (Korg M1) with preset names in header):


Some differences in Automap GUI, while used with other controllers (sorry for big resolution. Our forum doesn't support spoiler tag):

Novation Nocturn:
https://global.novationmusic.com/sit...eset/step1.jpg

Novation Launchpad with advanced mappings (no feedback). CC type, qwerty assign, range of the controller:

Last edited by fundorin; 12-05-2017 at 04:19 AM. Reason: removed big image
fundorin is offline   Reply With Quote
Old 12-05-2017, 03:03 AM   #285
Geoff Waddington
Human being with feelings
 
Geoff Waddington's Avatar
 
Join Date: Mar 2009
Location: Dartmouth, Nova Scotia
Posts: 11,183
Default

Quote:
Originally Posted by fundorin View Post
I just remembered that Automap software had kinda similar approach.
The button in settings generated wrapped versions of all installed plugins, so that user could rearrange the parameters of the plugin in the Automap GUI itself.
This worked, but plugin folder was flooded with wrapped versions.
For example:

Original structure:
PlugFolder\Plug1.dll <- original plugin
PlugFolder\Plug2.dll <- original plugin
PlugFolder\Plug3.dll <- original plugin

After automap generator:
PlugFolder\Plug1.dll <- automap wrapper
PlugFolder\Plug1 (automap).dll <- original plugin
PlugFolder\Plug2.dll <- automap wrapper
PlugFolder\Plug2 (automap).dll <- original plugin
PlugFolder\Plug3.dll <- automap wrapper
PlugFolder\Plug3 (automap).dll <- original plugin

There were several problems with this approach:
1. FX browser showed every plugin twice
2. One should manually replace all plugins in the existing projects with wrapped versions
3. After plugin updates, wrapping should be done again
4. Automap didn't have full HUI implementation and no option to remap mixer mode mappings.
Right, thought as much.

You are interested in auto mapping, this project is the polar opposite of that.

This project is all about custom mapping, not auto mapping.

It is much more manual by nature, that's the whole idea.

Please see the post just before your last post and notice that any arbitrary widget can be connected with any arbitrary Reaper Action (not just actions from the Action List, it is much broader than that).


So to use a ridiculously extravagant example on s huge scale, think Skywalker Sound.

Ok, they're going to set up for a mix.

Now, if this is a subcontract, the client will bring in reems of configuration stuff, including tech setup and customization of control surfaces.

Now, pare this down to a more modest setup, and you will see that this config will not change very often.


Still, perhaps there are pieces in this project that might help you, not sure.
__________________
To install you need the CSI Software and Support Files
For installation instructions and documentation see the Wiki
Donate -- via PayPal to waddingtongeoff@gmail.com

Last edited by Geoff Waddington; 12-05-2017 at 03:09 AM.
Geoff Waddington is offline   Reply With Quote
Old 12-05-2017, 03:30 AM   #286
fundorin
Banned
 
Join Date: Feb 2014
Location: Moscow, Russia
Posts: 554
Default

Quote:
Originally Posted by Geoff Waddington View Post
Right, thought as much.

You are interested in auto mapping, this project is the polar opposite of that.
Not quite true. Automap generated the default map, similar to how plugin parameters are displayed in Lemur, for example:
(if it's ok, I'll post future images as link, so they won't ruin the forum layout)
http://www.delchambre.be/images/Lemu...Studio-One.png

After having the initial map, one can always remap parameters to his liking, adjust them or completely delete unneded ones, though it's better to move them to the last pages of the map, actually.

Quote:
Originally Posted by Geoff Waddington View Post
This project is all about custom mapping, not auto mapping.
Yep. Im fully aware of it, but having the surface display names/value of the parameters even without manual work is always good thing, even if they'll be mapped not as you'd like. I think that it's easier to edit something that is already working, instead of writing it from the scratch.
For general users, at least.

Quote:
Originally Posted by Geoff Waddington View Post
It is much more manual by nature, that's the whole idea.
Depends of what do you mean by "manual". I see it as a set of "widgets" that can be mapped to physical controls, at one side and plugin parameters/actions in Reaper from the other side.
Like Pot1<>CC8<>Widget1<>PlugCutoff, where user can change the pool Widget1-8 mapping from Pot1-8 to Encoder1-8 or Button 9-16 in the main script.
He can also change mappings for widgets in plugin maps to get Parameters in the desired order and change range/curve/toggle properties of the widgets.

Quote:
Originally Posted by Geoff Waddington View Post
Please see the post just before your last post and notice that any arbitrary widget can be connected with any arbitrary Reaper Action (not just actions from the Action List, it is much broader than that).
I think that I understand your concept. If not, correct me, please.

Quote:
Originally Posted by Geoff Waddington View Post
So to use a ridiculously extravagant example on s huge scale, think Skywalker Sound.

Ok, they're going to set up for a mix.

Now, if this is a subcontract, the client will bring in reems of configuration stuff, including tech setup and customization of control surfaces.

Now, pare this down to a more modest setup, and you will see that this config will not change very often.
I didn't get that reference, at first, but, googled Skywalker Sound.
But I don't get your example, tbt.

Last edited by fundorin; 12-05-2017 at 03:50 AM.
fundorin is offline   Reply With Quote
Old 12-05-2017, 04:04 AM   #287
Geoff Waddington
Human being with feelings
 
Geoff Waddington's Avatar
 
Join Date: Mar 2009
Location: Dartmouth, Nova Scotia
Posts: 11,183
Default

Quote:
Originally Posted by fundorin View Post
Not quite true. Automap generated the default map, similar to how plugin parameters are displayed in Lemur, for example:
(if it's ok, I'll post future images as link, so they won't ruin the forum layout)
http://www.delchambre.be/images/Lemu...Studio-One.png

After having the initial map, one can always remap parameters to his liking, adjust them or completely delete unneded ones, though it's better to move them to the last pages of the map, actually.


Yep. Im fully aware of it, but having the surface display names/value of the parameters even without manual work is always good thing, even if they'll be mapped not as you'd like. I think that it's easier to edit something that is already working, instead of writing it from the scratch.
For general users, at least.


Depends of what do you mean by "manual". I see it as a set of "widgets" that can be mapped to physical controls, at one side and plugin parameters/actions in Reaper from the other side.
Like Pot1<>CC8<>Widget1<>PlugCutoff, where user can change the pool Widget1-8 mapping from Pot1-8 to Encoder1-8 or Button 9-16 in the main script.
He can also change mappings for widgets in plugin maps to get Parameters in the desired order and change range/curve/toggle properties of the widgets.


I think that I understand your concept. If not, correct me, please.


I didn't get that reference, at first, but, googled Skywalker Sound.
But I don't get your example, tbt.
AHA, I think I finally get what you are driving at, thanks for your patience, I can be slow at times

You are talkin' UI.

There will be no UI in the first version so that we can cut the development time to about 1/3 as stated in the architecture post a few back.

This allows us to get something out there to the good folks a lot faster.

Now as to a discussion about the UI....

Have been thinking about this for a LONG time.

All theses endless configuration windows, your post a few back beautifully illustrates the clutter and confusion I'm trying to eliminate.

So what is the actual use case here ?

User wants to connect a widget to an action.

OK, seems simple, let's eliminate all this intermediary garbage and just do this:

User presses button on surface
Dialog pops up with list of actions
User selects action
DONE - now widget on surface is associated with Reaper action.

Under the hood the file format remains the same, it is just populated by a
(hopefully) VERY simple UI.
__________________
To install you need the CSI Software and Support Files
For installation instructions and documentation see the Wiki
Donate -- via PayPal to waddingtongeoff@gmail.com
Geoff Waddington is offline   Reply With Quote
Old 12-05-2017, 04:38 AM   #288
fundorin
Banned
 
Join Date: Feb 2014
Location: Moscow, Russia
Posts: 554
Default

Quote:
Originally Posted by Geoff Waddington View Post
AHA, I think I finally get what you are driving at, thanks for your patience, I can be slow at times

You are talkin' UI.

There will be no UI in the first version so that we can cut the development time to about 1/3 as stated in the architecture post a few back.
Again, I wasn't talking about UI. Not about GUI at the computer screen, at least. Definitely about LCD screen on the surface, though.

Quote:
Originally Posted by Geoff Waddington View Post
This allows us to get something out there to the good folks a lot faster.

Now as to a discussion about the UI....

Have been thinking about this for a LONG time.
I get it. The faster the prototype can reach the end user to start testing, the better.

Quote:
Originally Posted by Geoff Waddington View Post
All theses endless configuration windows, your post a few back beautifully illustrates the clutter and confusion I'm trying to eliminate.
In fact, that floating red-black window in automap is called by a special key, so that user can not only see the parameter's names on LCD, with only 7 parameters at the time, but all of them, at once. For one page of controls, at least. I find this approach very convenient, actually. You just need to press one button to see more then 48 mapping in one window. This is handy when switching between different FXs, cause I don't think that anybody can remember all those mapping.

Quote:
Originally Posted by Geoff Waddington View Post
So what is the actual use case here ?

User wants to connect a widget to an action.

OK, seems simple, let's eliminate all this intermediary garbage and just do this:
Yep.

Quote:
Originally Posted by Geoff Waddington View Post
User presses button on surface
Dialog pops up with list of actions
User selects action
DONE - now widget on surface is associated with Reaper action.
I don't get this part. What actions would be displayed in the list? What if one action is meant to be toggle and the other one is value range? Can user define this for the control?

Can't we just use Reaper's own learn function that would trigger new lines for mappings in the map file for the selected plugin?

This is Battery 4 parameters list. Do you suggest this to be displayed when the learn button is pressed? https://i.imgur.com/tegsKPr.png
Mapping all of them mapping can drive mad anyone. But, having pregereated mapping file can help. Or, while "learn" mode is enable, pressing parameter on the screen and then desired control on the surfaces, in pairs, can speed up the mapping process a lot.
Where the name (both short and long) of the plugin could be changed, during the learn process?
Why not use Reaper's method of "last touched parameter" together with "last touched widget", for example?

Quote:
Originally Posted by Geoff Waddington View Post
Under the hood the file format remains the same, it is just populated by a
(hopefully) VERY simple UI.
To be honest, I don't see anything terrible in good UI. The plugin itself would have options, like this - https://i.imgur.com/LB9TlGc.png
It can also have GUI (I actually don't know if it's possible with CSurf SDK), so the consoles that don't have LCD, like BCF2000 could display mapped parameters names and values, like some other software does, if I'm not mistaken.

Last edited by fundorin; 12-05-2017 at 04:46 AM.
fundorin is offline   Reply With Quote
Old 12-05-2017, 05:07 AM   #289
Geoff Waddington
Human being with feelings
 
Geoff Waddington's Avatar
 
Join Date: Mar 2009
Location: Dartmouth, Nova Scotia
Posts: 11,183
Default

Quote:
Originally Posted by fundorin View Post
I don't get this part. What actions would be displayed in the list? What if one action is meant to be toggle and the other one is value range? Can user define this for the control?
That's exactly why values are normalized in the range 0.0 - 1.0.
Any control can be substituted for any other control.

Quote:
Originally Posted by fundorin View Post
This is Battery 4 parameters list. Do you suggest this to be displayed when the learn button is pressed? https://i.imgur.com/tegsKPr.png
Mapping all of them mapping can drive mad anyone. But, having pregereated mapping file can help. Or, while "learn" mode is enable, pressing parameter on the screen and then desired control on the surfaces, in pairs, can speed up the mapping process a lot.
Where the name (both short and long) of the plugin could be changed, during the learn process?
Yeah, that NI stuff is a bear.

Quote:
Originally Posted by fundorin View Post
Or, while "learn" mode is enable, pressing parameter on the screen and then desired control on the surfaces, in pairs, can speed up the mapping process a lot.
Where the name (both short and long) of the plugin could be changed, during the learn process?
That's more or less what I'm thinkin' for the UI.

Quote:
Originally Posted by fundorin View Post
To be honest, I don't see anything terrible in good UI
Of course, I agree 100% !

But a good UI is the simplest UI that gets the job done in a comfortable way for the user.
__________________
To install you need the CSI Software and Support Files
For installation instructions and documentation see the Wiki
Donate -- via PayPal to waddingtongeoff@gmail.com
Geoff Waddington is offline   Reply With Quote
Old 12-05-2017, 11:14 AM   #290
fundorin
Banned
 
Join Date: Feb 2014
Location: Moscow, Russia
Posts: 554
Default

I envy the users of the Bitwig and the Ableton with their controller scripts.
https://www.bitwig.com/en/community/...l_scripts.html
https://forum.ableton.com/viewtopic.php?f=1&t=192290
fundorin is offline   Reply With Quote
Old 12-05-2017, 03:39 PM   #291
airon
Human being with feelings
 
airon's Avatar
 
Join Date: Aug 2006
Location: Berlin
Posts: 11,817
Default

Cutting to the chase for connecting control resources to target functions can work in two directions. Actions and plugin parameters is all we're after iirc.

You start with the control resources, or you start with the action/parameter.

On the Avid Icon D-Control/Command custom fader maps you can start with the fader. You pick that with the select button, and then TOUCH the parameter it's supposed to control. (see this little 3 minute video by Brent Heber for details)

In Reaper I'm used to touching the parameter, and then assigning a control resource. I don't really care. I just want to get things setup quickly.

Btw, the GUI for this can be a LUA script. We have lots of talented GUI folks with great libraries.

It would only need to generate a text file after all.
__________________
Using Latch Preview (Video) - Faderport 16 setup for CSI 1.1 , CSI 3.10
Website
"My ego comes pre-shrunk" - Randy Thom
airon is offline   Reply With Quote
Old 12-05-2017, 03:51 PM   #292
TonE
Human being with feelings
 
Join Date: Feb 2009
Location: Reaper HAS send control via midi !!!
Posts: 4,031
Default

Did you all try ReaLearn?
https://www.helgoboss.org/projects/realearn/
Just try now, add 100 mappings, do your mappings, save as track template. Do as many as you want. Then switch among those templates whenever you want. This single track can control all other tracks. For each of your devices you could create hundreds of templates, which you could switch all independently. So your devices stay fixed, but the mapping templates change, so the behaviour in Reaper will change, still same device. Magic of track templates applied to control.

Last edited by TonE; 12-05-2017 at 04:03 PM.
TonE is offline   Reply With Quote
Old 12-05-2017, 04:16 PM   #293
Geoff Waddington
Human being with feelings
 
Geoff Waddington's Avatar
 
Join Date: Mar 2009
Location: Dartmouth, Nova Scotia
Posts: 11,183
Default

Ok folks, I know there will be a number of hurdles, but my idea of making the mapping as simple as possible goes like this:

First you must have a context, so let's say you have an FX window opened and with focus.

Press/turn/whatever, the midi widget that you want to map.
Click mouse on FX knob/switch/whatever in the FX GUI on the parameter you want the widget to control.
DONE.

I'm pretty sure it can't be made quite this easy, but the goal is to get as close to that as possible.
__________________
To install you need the CSI Software and Support Files
For installation instructions and documentation see the Wiki
Donate -- via PayPal to waddingtongeoff@gmail.com
Geoff Waddington is offline   Reply With Quote
Old 12-05-2017, 05:03 PM   #294
TonE
Human being with feelings
 
Join Date: Feb 2009
Location: Reaper HAS send control via midi !!!
Posts: 4,031
Default

Why not trying ReaLearn? The perfect solution is there waiting for you.
TonE is offline   Reply With Quote
Old 12-05-2017, 05:14 PM   #295
Geoff Waddington
Human being with feelings
 
Geoff Waddington's Avatar
 
Join Date: Mar 2009
Location: Dartmouth, Nova Scotia
Posts: 11,183
Default

Quote:
Originally Posted by TonE View Post
Why not trying ReaLearn? The perfect solution is there waiting for you.
I would love it if ReaLearn was the perfect solution waiting for us, but I had a quick look at it and it doesn't look like it is the perfect solution, what about mapping things like stereo pan or dual pan, etc.

Everyone seems to be concentrating on plugin mapping, but there is much more to this than just plugin mapping.

Perhaps I am missing something, how does ReaLearn help here ?

Also you were enquiring about diagrams, goals, overview, etc. Did you read the simplified architecture post ? What did you think ?
__________________
To install you need the CSI Software and Support Files
For installation instructions and documentation see the Wiki
Donate -- via PayPal to waddingtongeoff@gmail.com
Geoff Waddington is offline   Reply With Quote
Old 12-05-2017, 06:03 PM   #296
TonE
Human being with feelings
 
Join Date: Feb 2009
Location: Reaper HAS send control via midi !!!
Posts: 4,031
Default

I thought this is not a diagram. Plus art of overcomplication.
TonE is offline   Reply With Quote
Old 12-05-2017, 06:18 PM   #297
Geoff Waddington
Human being with feelings
 
Geoff Waddington's Avatar
 
Join Date: Mar 2009
Location: Dartmouth, Nova Scotia
Posts: 11,183
Default

Quote:
Originally Posted by TonE View Post
I thought this is not a diagram. Plus art of overcomplication.
Yeah, a diagram would be superior, I should do one at some point, perhaps after things are more stable.

As far as over complication, I would push back and say it's the simplest solution I have come up with so far that gives us everyting we need.

How would you simplify it ?
__________________
To install you need the CSI Software and Support Files
For installation instructions and documentation see the Wiki
Donate -- via PayPal to waddingtongeoff@gmail.com
Geoff Waddington is offline   Reply With Quote
Old 12-05-2017, 10:19 PM   #298
fundorin
Banned
 
Join Date: Feb 2014
Location: Moscow, Russia
Posts: 554
Default

Quote:
Originally Posted by Geoff Waddington View Post
Everyone seems to be concentrating on plugin mapping, but there is much more to this than just plugin mapping.
It's all because I know how to get midi feedback from Reaper via oscii-bot.
The plugin maps part is the most interesting now, since it's already present in both MCU plugins and, apart from the controllers mappings, can be universal across different consoles.

Last edited by fundorin; 12-05-2017 at 11:28 PM.
fundorin is offline   Reply With Quote
Old 12-06-2017, 02:24 AM   #299
TonE
Human being with feelings
 
Join Date: Feb 2009
Location: Reaper HAS send control via midi !!!
Posts: 4,031
Default

Quote:
Originally Posted by Geoff Waddington View Post
I would love it if ReaLearn was the perfect solution waiting for us, but I had a quick look at it and it doesn't look like it is the perfect solution, what about mapping things like stereo pan or dual pan, etc.
Maybe you are not aware of the fact that pan can be an fx parameter as well, sends also, so no problem for ReaLearn. And still, if that would NOT be the case, still it would the perfect solution in 97% of the cases.
TonE is offline   Reply With Quote
Old 12-06-2017, 02:34 AM   #300
TonE
Human being with feelings
 
Join Date: Feb 2009
Location: Reaper HAS send control via midi !!!
Posts: 4,031
Default

Quote:
Originally Posted by fundorin View Post
It's all because I know how to get midi feedback from Reaper via oscii-bot.
For getting midi feedback there is also this:
Script: tack_Sync MIDI CCs on Track Select.lua
append 'Track Output' text to the alias.

Last edited by TonE; 12-06-2017 at 09:32 AM.
TonE is offline   Reply With Quote
Old 12-06-2017, 02:48 AM   #301
fundorin
Banned
 
Join Date: Feb 2014
Location: Moscow, Russia
Posts: 554
Default

Quote:
Originally Posted by TonE View Post
For getting midi feedback there is also this:
Script: tack_Sync MIDI CCs on Track Select.lua
append 'Track Output' text to the alias.
https://www.youtube.com/watch?v=ZO6eQt6L1KI
Oh, please, stop. Too much bustle with all those "insert jsfx on each track first to get it working".
Until Reascript API will allow users to access midi devices directly (not via virtual keyboard) the only two options, for now, are : OSC via oscii-bot (weird approach, because of EEL2, but working) and csurf plugins (hard to build, seamless integration). That's it.
Every other option is a crutch and can't be considered as a reiliable option for everyday work process.

Last edited by fundorin; 12-06-2017 at 02:56 AM.
fundorin is offline   Reply With Quote
Old 12-06-2017, 02:50 AM   #302
Geoff Waddington
Human being with feelings
 
Geoff Waddington's Avatar
 
Join Date: Mar 2009
Location: Dartmouth, Nova Scotia
Posts: 11,183
Default

Quote:
Originally Posted by fundorin View Post
It's all because I know how to get midi feedback from Reaper via oscii-bot.
The plugin maps part is the most interesting now, since it's already present in both MCU plugins and, apart from the controllers mappings, can be universal across different consoles.
Cool.

I think this is a great approach in your context and probably deserves attention in this project, but further down the road.

The first version of this software is biased towards Control Surfaces like MCU, Faderport, etc., and not Musical Control Surfaces like midi keyboards, Maschine, etc.
__________________
To install you need the CSI Software and Support Files
For installation instructions and documentation see the Wiki
Donate -- via PayPal to waddingtongeoff@gmail.com
Geoff Waddington is offline   Reply With Quote
Old 12-06-2017, 02:52 AM   #303
Geoff Waddington
Human being with feelings
 
Geoff Waddington's Avatar
 
Join Date: Mar 2009
Location: Dartmouth, Nova Scotia
Posts: 11,183
Default

Quote:
Originally Posted by TonE View Post
Maybe you are not aware of the fact that pan can be an fx parameter as well, sends also, so no problem for ReaLearn. And still, if that would NOT be the case, still it would the perfect solution in 97% of the cases.
Yeah, from what I understand of your use case ReaLearn looks like the perfect tool for you.

The first version of this software is biased towards Control Surfaces like MCU, Faderport, etc., and not Musical Control Surfaces like midi keyboards, Maschine, etc.
__________________
To install you need the CSI Software and Support Files
For installation instructions and documentation see the Wiki
Donate -- via PayPal to waddingtongeoff@gmail.com
Geoff Waddington is offline   Reply With Quote
Old 12-06-2017, 03:37 AM   #304
TonE
Human being with feelings
 
Join Date: Feb 2009
Location: Reaper HAS send control via midi !!!
Posts: 4,031
Default

Yes, and for your use case we have no diagram, we can not know what you want to achieve? What is the goal? Assuming those goals can not be reached by other means, how your solution does, in the diagram. Plus more importantly, which cases your solution does not care about? Now, and in 5 years, for the next 100000 new Reaper users?
TonE is offline   Reply With Quote
Old 12-06-2017, 03:44 AM   #305
TonE
Human being with feelings
 
Join Date: Feb 2009
Location: Reaper HAS send control via midi !!!
Posts: 4,031
Default

Quote:
Originally Posted by Geoff Waddington View Post
The first version of this software is biased towards Control Surfaces like MCU, Faderport, etc., and not Musical Control Surfaces like midi keyboards, Maschine, etc.
Why making all this differentiation between the different brands and devices? Does it really matter? Should it not work with any device and any combination of devices. Not only single devices. Let us assume in the world exist only devices A,B,C,D...Z. Some user has A, another C, another G, another has A+D+L. Now should it not work with any combination? How to use those combinations, in complementary, orthogonal, or overlapping (non-orthogonal) way, meaning duplicating certain functionality in multiple surfaces? How does your solution address such scenarios?

How does the solution use snapshots? Snapshots for sounds, patterns, mutes, tempo, to name a few? Saving snapshots, recalling snapshots? Or is this totally out of the story, does nobody need this?
TonE is offline   Reply With Quote
Old 12-06-2017, 05:14 AM   #306
Geoff Waddington
Human being with feelings
 
Geoff Waddington's Avatar
 
Join Date: Mar 2009
Location: Dartmouth, Nova Scotia
Posts: 11,183
Default

Quote:
Originally Posted by TonE View Post
Yes, and for your use case we have no diagram, we can not know what you want to achieve? What is the goal? Assuming those goals can not be reached by other means, how your solution does, in the diagram. Plus more importantly, which cases your solution does not care about? Now, and in 5 years, for the next 100000 new Reaper users?
Oh, now I get it.

You want a formal specification stretching out 5 years ?

Ok, no prob.

I'm presuming you would like a UML presentation.

What the hell, let's make it a bit more formal, what are the exact deliverables you expect and on what timeline ?

I am fully equipped and prepared to do something like this, but it ain't cheap.

I would suggest you get ready to donate about $100,000 or so every six months to keep this going.

Oh, and speaking of going, I'm a one man shop, so you should be prepared for a formal spec around the end of 2018

Or we could just go with stated goal: provide users the ability to map an arbitrary control surface widget to an arbitrary Reaper action, a lot simpler and a lot more Reaperry don't you think ?
__________________
To install you need the CSI Software and Support Files
For installation instructions and documentation see the Wiki
Donate -- via PayPal to waddingtongeoff@gmail.com
Geoff Waddington is offline   Reply With Quote
Old 12-06-2017, 05:21 AM   #307
Geoff Waddington
Human being with feelings
 
Geoff Waddington's Avatar
 
Join Date: Mar 2009
Location: Dartmouth, Nova Scotia
Posts: 11,183
Default

Quote:
Originally Posted by TonE View Post
Why making all this differentiation between the different brands and devices? Does it really matter? Should it not work with any device and any combination of devices. Not only single devices. Let us assume in the world exist only devices A,B,C,D...Z. Some user has A, another C, another G, another has A+D+L. Now should it not work with any combination? How to use those combinations, in complementary, orthogonal, or overlapping (non-orthogonal) way, meaning duplicating certain functionality in multiple surfaces? How does your solution address such scenarios?
Well, it matters in a practical sense, in terms of work prioritization.

If you read carefully you'll see I used the word "initially", so I'm not saying these things won't be done, just not in the first version.

As far as orthogonality, I agree 100%, that's exactly why the design is the way it is, orthogonality.

Quote:
Originally Posted by TonE View Post
How does the solution use snapshots? Snapshots for sounds, patterns, mutes, tempo, to name a few? Saving snapshots, recalling snapshots? Or is this totally out of the story, does nobody need this?
First time I've heard snapshots mentioned, have you read the previous discussion in this thread about the ability to switch logical surface maps at the touch of a button ?

Is this what you mean by snapshots ?
__________________
To install you need the CSI Software and Support Files
For installation instructions and documentation see the Wiki
Donate -- via PayPal to waddingtongeoff@gmail.com
Geoff Waddington is offline   Reply With Quote
Old 12-06-2017, 06:18 AM   #308
TonE
Human being with feelings
 
Join Date: Feb 2009
Location: Reaper HAS send control via midi !!!
Posts: 4,031
Default

What you mean with control surface widget? Why you need any widget anywhere? ReaLearn can already do all the mapping we need. What is the problem with it.
TonE is offline   Reply With Quote
Old 12-06-2017, 06:21 AM   #309
TonE
Human being with feelings
 
Join Date: Feb 2009
Location: Reaper HAS send control via midi !!!
Posts: 4,031
Default

I do not need any uml or oop, as you seem to dream about. We do not know even why you started with all of this? What should be its purpose, nobody knows, except you maybe. Or why caring of mackie control, at all, for example? Are you a slave of mackie?
TonE is offline   Reply With Quote
Old 12-06-2017, 07:06 AM   #310
fundorin
Banned
 
Join Date: Feb 2014
Location: Moscow, Russia
Posts: 554
Default

Quote:
Originally Posted by TonE View Post
We do not know even why you started with all of this?
Just wow. Don't say "we" if you don't know something.

WE know, what Geoff's project is about. There are couple of other threads, where we discussed it's purpose. There even was an iOS prototype, if I remember correctly.
fundorin is offline   Reply With Quote
Old 12-06-2017, 07:18 AM   #311
TonE
Human being with feelings
 
Join Date: Feb 2009
Location: Reaper HAS send control via midi !!!
Posts: 4,031
Default

If you know, why can you not explain its purpose? Nobody needs oop or uml diagrams. Just a black box, input, output, purpose of the whole story? Noone can tell? At least not the developer it seems.
TonE is offline   Reply With Quote
Old 12-06-2017, 08:05 AM   #312
fundorin
Banned
 
Join Date: Feb 2014
Location: Moscow, Russia
Posts: 554
Default

Quote:
Originally Posted by TonE View Post
If you know, why can you not explain its purpose? Nobody needs oop or uml diagrams. Just a black box, input, output, purpose of the whole story? Noone can tell? At least not the developer it seems.
You know csurf plugins, like MCU or Eucon?
You know oscii-bot scripts?
This will be a mixture of both, so that end users could install the plugin and custom mapping file to use their devices with Reaper and feedback. That simple. That's enough knowledge for now. Any further info is only inside Geoff's head.

My last reply to you, by the way.
fundorin is offline   Reply With Quote
Old 12-06-2017, 09:34 AM   #313
TonE
Human being with feelings
 
Join Date: Feb 2009
Location: Reaper HAS send control via midi !!!
Posts: 4,031
Default

Quote:
Originally Posted by fundorin View Post
Oh, please, stop. Too much bustle with all those "insert jsfx on each track first to get it working".
Why stop, this makes the solution even more flexible, functionality can be saved into track templates. When you load your template everything will be ready.
TonE is offline   Reply With Quote
Old 12-06-2017, 11:16 AM   #314
Geoff Waddington
Human being with feelings
 
Geoff Waddington's Avatar
 
Join Date: Mar 2009
Location: Dartmouth, Nova Scotia
Posts: 11,183
Default

Quote:
Originally Posted by fundorin View Post
You know csurf plugins, like MCU or Eucon?
You know oscii-bot scripts?
This will be a mixture of both, so that end users could install the plugin and custom mapping file to use their devices with Reaper and feedback. That simple. That's enough knowledge for now. Any further info is only inside Geoff's head.
Thanks for chiming in, the only thing I would correct is, it's mostly inside my head, but some stuff isn't even inside my head yet

Oh, and there is a lot of code already operational, so it's not just inside my head
__________________
To install you need the CSI Software and Support Files
For installation instructions and documentation see the Wiki
Donate -- via PayPal to waddingtongeoff@gmail.com
Geoff Waddington is offline   Reply With Quote
Old 12-06-2017, 12:17 PM   #315
fundorin
Banned
 
Join Date: Feb 2014
Location: Moscow, Russia
Posts: 554
Default

Quote:
Originally Posted by Geoff Waddington View Post
Thanks for chiming in, the only thing I would correct is, it's mostly inside my head, but some stuff isn't even inside my head yet
True. I'm currently writing my oscii-bot script and just adding feature by feature, without even knowing, what will be added tomorrow.
For now, I'm doing encoders part, trying to make Reaper respond to the rotation acceleration.
Quote:
Originally Posted by Geoff Waddington View Post
Oh, and there is a lot of code already operational, so it's not just inside my head
Same again. Have some templates ready for modes changing, but currently working on mixer part only.

In the past, I did some diagrams, excel tables and lists, but now I'm to lazy doing them again and just writing the code instead.
fundorin is offline   Reply With Quote
Old 12-07-2017, 06:02 PM   #316
_Stevie_
Human being with feelings
 
_Stevie_'s Avatar
 
Join Date: Oct 2017
Location: Black Forest
Posts: 5,054
Default

Quote:
Originally Posted by Geoff Waddington View Post
Thank you!
_Stevie_ is offline   Reply With Quote
Old 12-09-2017, 04:32 AM   #317
azslow3
Human being with feelings
 
Join Date: Nov 2017
Location: Heidelberg, Germany
Posts: 797
Default

Some comments from experience with Cakewalk ACT. NOT as a proposal to do the same. I will go my own way, as I have done with ACT, probably again alone. But that has helped many people and so I am going to continue at my "new home" (that is not related to this thread).

General problematic for Control Surfaces and why "MIDI Learn", implemented in all DAWS, in not perfect: the number of physical controls in N, the number of controllable parameters is M. M is 10-1000 bigger then N, even in a simple project. Some surfaces support several layouts in firmware, effectively making N*2 ... N*5 distinguishable controls from the DAW perspective. For controlling fixed subset of parameters, f.e. for live performance, that is sufficient. But from general project perspective, that is a drop of water into the ocean (and has side effects for knobs and sliders, so works well for buttons and encoders only).

In a project without plug-ins, so for bare DAW recording/mixing, the set of parameters is always the same: O(10) per track (Volume, mute, etc.), O(10) for transport (play, loop, etc.), plus O(10) actions (ala toolbox). Since the only variable component is the track number, making the Surface control one track (f.e. Faderport) or a group of tracks (MCU) and providing a way to switch the track/group takes the number of parameter under control. The result can be "hard-coded" then, as done in binary plug-ins for particular surfaces in all DAWs.

With plug-ins the situation is worse. Many of them have O(1000) parameters and the number of plug-ins in power user collection is also O(1000). So unlike with controlling DAW, where O(10) physical controls should be mapped to O(100) parameters, we have O(10) to O(1000000) mapping problem.

I have observed several approaches:
1) fix plug-ins as a part of the DAW (as fixed "channel strips"), f.e. EQ/Comp in old Sonar, MixBus. Than controller can take the approach used for the DAW, with (semi)hardcoded mapping.
2) "prepare" plug-ins for outside controlling by internal mapping (preset dependent) to some reasonable number of extra exposed controls (like 8 knobs + some buttons). Most heavy softsynth use that.
3*) organize X banks with Y modifiers, to bring the order of available controls up to the order of parameters and let the user select what they really need. F.e (8 knobs + 8 sliders + 8 buttons) x 4 banks lean toward O(100). Covers most not aggregated FXes completely and allow only factor 10 reduction for power synth.

3 is still not solved perfectly, asking the user to map up to 100000 parameters manually. Here is the ACT attempt to solve that:
a) prepare a generic list of all parameters. Plug-in provide its own order. Unfortunately, most plug-ins have to sorted it by "usability" and so:
b) try to put known by name parameters at the top of the list (f.e. power -> first button, gain -> first knob, etc.). By analyzing representative set of plug-ins, the result of such automatic ordering can be usable. Unfortunately, only primitive searching was implemented in ACT. Categorized searching can have better result (f.e. "detect" the plug-in is EQ and use EQ specific priority list).
c) distribute constructed list to available list of controls. Some surface has 8 knobs, some 3, some 24. ACT put at least some logic in mapping, it takes parameters one by one giving already re-mapped by user parameters the priority, up to "ignoring" proposed control type (so if user has manually mapped 8 knobs and now there are 4 knobs and 4 sliders, 4 knobs are shifted to sliders). While the idea looks nice, in practice, the result is horribly. If user has decided to give one more physical control for plug-ins, the whole mapping can be shifted.
4) finally, user can map everything manually. So the mapping is Per plugin x Per surface.

I was thinking a lot how to improve (b) and (c), but without reasonable proposals so far.
But may be someone else, looking at the problematic, will find a good solution
azslow3 is offline   Reply With Quote
Old 12-09-2017, 06:02 AM   #318
fundorin
Banned
 
Join Date: Feb 2014
Location: Moscow, Russia
Posts: 554
Default

Quote:
Originally Posted by azslow3 View Post
But from general project perspective, that is a drop of water into the ocean (and has side effects for knobs and sliders, so works well for buttons and encoders only).
Reaper has 50 125 actions for now. The number of SWS actions is close to it. So, ~100 000 action in total.

I've made a mode in my controller that exceeds this number greatly.
You know, 8 different types of 8 controls available. Plus 2 buttons to switch pages. Another 2 buttons to switch banks. Also 7 shift button, that could be used in combo with controls and with each other. I've set number of pages and banks to 16. This gives:

Number of available controls: 64
Combination of 8 shifts (7 shift buttons plus no shift at all). 2 to the power of 8: 256
That gives 16 384 controls at one page.
Number of pages (can be changed by liking): 16
That gives 262 144 controls at 16 pages.
There are 16 banks of pages.
That gives 4 194 304 unique controls.

I agree that pressing 7 different shift buttons at the time, while turning the pot should be considered as nonsense, as well navigating from bank 1 to bank 16, but it's possible to cover each available Reaper action with external controls.
Of cause, this is possible, using OSC. But, if you'll look at this thread's name, you'll see "includes OSC".

Speaking of FX parameters, Reaper banks them, according to this settings:

DEVICE_FX_COUNT 8
DEVICE_FX_PARAM_COUNT 16
DEVICE_FX_INST_PARAM_COUNT 16

DEVICE_FX_COUNT i/device/fx/count
DEVICE_FX_PARAM_COUNT i/device/fxparam/count
DEVICE_FX_INST_PARAM_COUNT i/device/fxinstparam/count

So, one can change those numbers to better suit his physical device.
Just like you switch between individual tracks with faderport, you also switch between FX instances on selected track and FX params for selected FX.

Using plugin maps one can sort fx params, so that most useful one would always be on the first page.

Some developers already sorted them by default, while others present them alphabetically/by appearance in GUI/by numbers and without proper names.

So, as I said before, there should be custom plugin maps on reaper stash, so that we could exchange our custom maps with each other.

If each user will create maps for at least one developer plugins bundle, we will soon get convenient way to control our plugins, using a small amount of controls.

Maps could be hosted via Gdrive folder with a couple of people having access to modify it's contents.
Them, later, it might be possible to get ReaPack analog, but for maps instead of scripts.
fundorin is offline   Reply With Quote
Old 12-09-2017, 06:53 AM   #319
azslow3
Human being with feelings
 
Join Date: Nov 2017
Location: Heidelberg, Germany
Posts: 797
Default

Quote:
Originally Posted by fundorin View Post
Reaper has 50 125 actions for now. The number of SWS actions is close to it. So, ~100 000 action in total.

I've made a mode in my controller that exceeds this number greatly.
I have experimented a lot with usability of modes, bunks and modifiers (since in my framework there can be arbitrary number of all of them), but that was not the point of my previous post.

So I want to comment on the relevant part only:
Quote:
Using plugin maps one can sort fx params, so that most useful one would always be on the first page.

Some developers already sorted them by default, while others present them alphabetically/by appearance in GUI/by numbers and without proper names.

So, as I said before, there should be custom plugin maps on reaper stash, so that we could exchange our custom maps with each other.

If each user will create maps for at least one developer plugins bundle, we will soon get convenient way to control our plugins, using a small amount of controls.

Maps could be hosted via Gdrive folder with a couple of people having access to modify it's contents.
Them, later, it might be possible to get ReaPack analog, but for maps instead of scripts.
I have mentioned, the evil is in details and there is a problem with "most useful" and "sorting" parameters and "the first page" on surface, so there is a general problem with brute force universal mapping, used everywhere and also just described by you.

I will try to explain by example. Let say we want control a 4 band EQ and we have 2 surfaces: BCR2000 (1x8 + 3x8 encoders) and X-Touch Mini (1x8 encoders).
For BCR, I guess everyone will prefer to have F/G/Q (or some different order) in a column. So you can control the EQ "intuitively", as in the GUI:
LF - 1, LMF - 2, HMF - 3, HF - 4.
That still can be usable on Mini. But for Gain, you would prefer:
LG - 9, LMG - 10, HMG - 11, HG - 12.
Leaving 5,6,7,8 not assigned (in practice, using it for some other FX in the strip, f.e. for compressor).
But Mini owner will disagree - he has only 8 encoders in total, he will prefer Gain on 5,6,7,8.
Note that the problem can not be solved by numbering BCR controls differently, for 4 band EQ we need just 4 "columns", for 8 band EQ - all 8.

I hope the example clarify a bit one of my points.

But independent from where on particular controller a user want to have LG, he/she naturally wants to see LG in a different EQ at the same place. I mean "knob X should control LG in ANY 4 band EQ", but X is controller dependent.

That was my another point.

I have written that I have not tested how that can work in practice, but my current thoughts about a topic is introduction of yet another indirection in mapping. So one map between parameters of particular plug-in to some "generic EQ plug-in", another from "generic EQ plug-in" to particular surface. I already know many problems with this approach as well, but that is worse a long independent discussion...
azslow3 is offline   Reply With Quote
Old 12-09-2017, 08:03 AM   #320
fundorin
Banned
 
Join Date: Feb 2014
Location: Moscow, Russia
Posts: 554
Default

Quote:
Originally Posted by azslow3 View Post
I mean "knob X should control LG in ANY 4 band EQ", but X is controller dependent.
So, I think that that's why Geoff came with an idea of "widgets" in chain
real_knob1<>widget[x]<>fx_param1.
Users doesn't map MIDI CC values to the FX parameters. They map widgets to them. And, inside the main script, CCs are mapped to widgets.

After DLing my map, you can test it with your devices and modify widgets placement to your liking. If the total number of fx parameters exceeds the number of your physical controls, you just change the main script, adding shifts and pages.

To control different FX's at once, you should use assignable mode in your controller, cause having two identical FX's at the same place on each track and in every project seems unlikely to me.

Even if you have prepared track templates with, let's say, ReaEQ and ReaComp loaded, some of your tracks would have them in "slots" 1 and 2 (audio tracks and folders), while others in "slots" 2 and 3, cause "slot" 1 in used for instrument plugin. Or, "slots" 3 and 4, cause "slot" 1 is for midi arpeggiator.

There won't be any standard ever.
fundorin 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 03:33 AM.


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