-
-
Notifications
You must be signed in to change notification settings - Fork 1.3k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Osc in Mixxx + ARM64/2.6 (20241104) #13835
base: main
Are you sure you want to change the base?
Conversation
Still crashes. Relevant line?:
I did try making sure the port numbers matched TouchOSC.
|
@Eve00000
|
I 'm sure thread #9 is from osc but I'm not that sure about #6 |
Yes, that's why I mentioned the vcpkg config on CI last time. I will try to find some differences between my local build and the one from GitHub Actions. |
Yes, YDUC. And I can do better (worse) then you @ronso0 : I am not familiar with vcpkg at all :-( |
Regarding vcpkg, this is (still) based on oscpack. You put here a oscpack into the lib folder which will be likely ripped of by the distro maintainers anyway. So let's move that also to vcpkg. It is part of Ubuntu already. I will have a look. Or do we want liblo anyway. Do whe have a view what pros and cons are. Do you? |
This is what chat-gpt recommends: Both liblo and oscpack are libraries for implementing the Open Sound Control (OSC) protocol, but they have key differences that might influence your decision on which to use for adding OSC support to Mixxx. 1. General Overviewliblo (Lightweight OSC)
oscpack
2. Comparison for Adding OSC to MixxxEase of Integration
Language and Compatibility
Performance
Networking Requirements
3. RecommendationFor a standard OSC implementation with minimal effort:
For more flexibility or if Mixxx requires deep integration with C++ features or custom networking:
If you need specific features like multicast, or need deeper examples, I can provide guidance or snippets for both libraries. Let me know! |
Wow, I think @daschuer has a direct connection with chatgpt or maybe shares in OpenAI 😃 As I've written earlier: I have made the choice for OSCPack as I can understand the code in it, I understand the flow and the reason for the different procedures (so you will certainly understand it). I have major problems with liblo.
As I mentioned before I would take a deeper look at liblo again, but this would be when I have lots of time (and motivation, courage and nothing better to do). On my wish- and workinglist are: smarties/ grouped crates / preparation crates + pannel It's nice to have a comparison, but the comparison is made at the stage there isn't yet one of them both implemented. So this is what ChatGPT answers on the question 'Can you make a comparison between OSCPACK and liblo to integrate osc in mixxx, with the knowledge that there is already a working implementation of oscpack in mixxx.' Here’s a comparison of oscpack and liblo for integrating OSC (Open Sound Control) in Mixxx, considering that Mixxx already has a working implementation using oscpack:
liblo Pros
If the current implementation in Mixxx meets functional and performance needs, there’s little advantage in switching to liblo, as the effort required for migration and potential licensing implications could outweigh the benefits. @ronso0 @daschuer @ArthurVimond |
I have prepared a vcpkg for oscpack here: |
Thank you, but honestly I have no idea what this exactly means. |
We should contribute the changes upstream. |
Sure, but I don't know if the changes match the original idea. |
src/engine/enginebuffer.cpp
Outdated
if (m_pConfig->getValue<bool>(ConfigKey("[OSC]", "OscEnabled"))) { | ||
OscTrackLoadedInGroup(m_pConfig, | ||
getGroup(), | ||
pTrack->getArtist().toLatin1(), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Latin-1 does not support Ιωάννα "Νάνα" Μούσχουρη for instance.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
too bad for Nana Mouskouri, she'll need new glasses because OSC only supports ASCII characters :-)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
How about using OSC-blob for it?
An alternative would be to use base64 or escape special characters Json \uXXXX or
Bas364 zpzOv8+Nz4PPh86/z4XPgc63
URL %CE%9C%CE%BF%CF%8D%CF%83%CF%87%CE%BF%CF%85%CF%81%CE%B7
Html Μούσχουρη
Tiësto
Ti\u00EBsto
Ti%C3%ABsto
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
src/engine/enginebuffer.cpp
Outdated
getGroup(), | ||
pTrack->getArtist().toLatin1(), | ||
pTrack->getTitle().toLatin1(), | ||
(float)1, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
(float)1, | |
1f, |
we do not used C-Style casts in Mixxx
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Now all of a sudden I'm feeling old :-)
src/engine/enginebuffer.cpp
Outdated
@@ -563,6 +574,18 @@ void EngineBuffer::slotTrackLoaded(TrackPointer pTrack, | |||
m_pTrackSampleRate->set(trackSampleRate.toDouble()); | |||
m_pTrackLoaded->forceSet(1); | |||
|
|||
// EveOSC begin | |||
if (m_pConfig->getValue<bool>(ConfigKey("[OSC]", "OscEnabled"))) { | |||
OscTrackLoadedInGroup(m_pConfig, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Functions shout be named as a imperative. This way you are able to guess form the name what it does and not when it should be called like here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do you mean the functions should be named something like
OscLetsSendInformationToTheClientsBecauseATrackWasLoaded()
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, somhow.
OscFunctionsSendPtrType(m_pConfig, | ||
OscGroup, | ||
"TrackArtist", | ||
DefOscBodyType::STRINGBODY, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It would be ned to have wapper funtions like OscFunctionsSendStringBody
or such.
Using a common prefix for functions like OscFunctions
should become a class or namespace.
In this case a class that holds the OSC instance is probably the way to go.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't understand this remark
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Isn't that just code-makeup?
IIUCWYM than there should be a function called OscFunctionsSendStringBody() that is just accepting the vars and passing them through to the OscFunctionsSendStringBody(), but in this way you can write an 'imperative procedurename' that should explain in it's name what the function needs to do? Makeup for the reader 😄
src/osc/oscfunctions.h
Outdated
p << osc::EndBundle; | ||
|
||
// Retrieve output port | ||
int CKOscPortOutInt = m_pConfig->getValue(ConfigKey("[OSC]", "OscPortOut")).toInt(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This string lokup is not fast, because of allocating memory. I think it would helpt to cache this in a member variable.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
owkee, can you point me an example?
I am arfaid the proposed nameng scheme looks a bit foreign among other solutions. We have: See: https://opensoundcontrol.stanford.edu/spec-1_0.html OSC Address Patterns An OSC Server’s OSC Methods are arranged in a tree strcuture called an OSC Address Space. An OSC Method’s OSC Address begins with the character ‘/’ (forward slash), followed by the names of all the containers, in order, along the path from the root of the tree to the OSC Method, separated by forward slash characters, followed by the name of the OSC Method. The syntax of OSC Addresses was chosen to match the syntax of URLs |
Here the Ableton example: It is also interesting that everyone seems to use lower case urls. I think we ca treat out COs as a huge dictionary of float falues. I think: For the parameter value wa may use What do you think? Dies this work with TouchOSC? |
Indeed the original 1.0 agreement (20 tears ago) was the tree-logic, later there was no more agreement anymore so the 1.1 died. Meanwhile the all software working with OSC made their own syntax (evolution in 20years) So that was the logic I started with, and as I mentioned I had to make a translation for the CO's that was easy for was easy enough (read: not too complicated) for people who want to create an OSC-interface. And so I choose for a general syntax with the combination of the @-symbol. A kind if Mixxx-interpretation over the OSC-transport-protocol.
Are you very keen on having the original OSC-logic? The setter could be the address with a value, but I would like to keep the GetV# / GetP# / GetT# for TouchOSC it would be OK, fo me ir's a lot of work adapting my complete interface + implementing the whole logic 😃 |
On one hand it is very recommendet to follow established standards, to be future prove. On the other hand we also don't want to complicate things or put extra work on you without a reason. My strong demand here is to look left and right and pick an informed descision. The exact result is secondary. So let's start. Tree structure: I have found this: A proposal for self documenting the OSC interface. I think one confirmation is that we can use the ppropsed json format to document our interafce. There are also some other proposals link which all assume OSC is implemnted in a certain way. The resultin Json responds is a tree like document following the OSC path. Pattern Matching The other thing is the wild card capability to do more than one commant at once using ? * and []. How does your propasl integrate with it? |
It looks like I have not yet found a good description how queries should be implemented in OSC. I can also imagine to subcribe a certain value. This will than be almost like a mapping. dis you consider this? |
OscQuerry has it:
|
In order to make Mixxx ready for the future, in particular when url-instructions get a wider use (e.g. Internet of Things) we 'd like to step up to a /tree/branch/leaf structure. The goal is to also broadcast the complete Mixxx-CO-structure through a query to the environment where the developer is building an interface. In this way the developer does not need to know all CO's, CO's and their characteristics would be 'shared' from within Mixxx. As a base for this logic we will start with converting the OSC-logic. In PR's #14229 and #14238 will be worked on this evolution, this PR wil remain working and the MixxxInTouchOSC will be maintained until further notice. |
***** This PR is created after crash reports on ARM64 of PR #13714 *******
***** If tests are all ok, this PR can replace the old one ******
Now with rebase from 2.6 + ARM64 problem should be solved
OSC working in Mixxx (also Epic, my first real PR )
Q1: now 5 clients can be configured in settings, should I make it 10?
Open for feedback
Test with MixxxInTouchOSCv50.tosc.txt -> rename: drop the .txt
corrected in #49 : jog channels (deckswitch was lost in updates)
added: slowstart & brake
added in #50 : unescape TrackArtist & TrackTitle json \uXXXX
MixxxInTouchOSCv50.tosc.txt
OSC in Mixxx
Why?
There are different user cases where OSC-functionality in Mixxx is an added value:
The example enclosed has the functionality of a combination of an extra controller, an info screen and a remote controller.
Environment
Different to hardware controllers that are in general connected to the Mixxx-machine through USB (Midi / HID) OSC works over the network (LAN). Networkconnections can be wired or wireless. Keep in mind that the user needs to provide a LAN connection between the Mixxx-machine and the OSC-Receivers. There are many reasons why a DJ doesn't want to connect it's Mixxx-machine to a public network. Preferable the DJ sets up a private LAN: a hardware or software wireless accesspoint, to connect tablets or smartphones, a small switch to connect machines with a LAN-connector or in case only one other machine needs to be connected to Mixxx a crossed-cable can be used. (all tested).
Mixxx Ecosystem
The integration of OSC in Mixxx needed to respect Mixxx's Ecosystem, OSC had to work by analogy to the hardware controllers Midi/Hid integration. Some remarks:
Remark: as TouchOSC is seen as the 'standard' OSC-editor, all following OSC functions, scripts ... are created and tested in TouchOSC.
The OSC - object.
OSC is a protocol to send/receive small commands and informationspackages over a network.
That package is constructed of severl parts:
The address and port of the machine to which the package is addressed is configured in the connections.
The path starts always with a slash, followed with a 1st address-part, a slash, a 2nd adress-part .... a slash, a x-th address-part, a slash and the name of the object.
(in Mixxx we don't use all the address-parts, just a slash and the name of the object: /name)
A value can be a String, Int, Boolean or Float.
(in Mixxx we'll use only the float)
There a different types of OSC-Controls
General:
A control has a type, shape, value, orientation, color... and can contain a script form.
A control can send information when touched/pressed/released or with a script.
with Momentary (on the moment of the action) if 'press' and 'release' are selected touching the control will send information and releasing the button will send information as well.
With 'Toggle Press' you only send information on the moment that you press the button (with Toggle Realease on the moment that you release the button)
A control has also a value, this can be a text (in case of a label) or a key. The key can be x or touch.
Touch is a Boolean: you touch the control or you don't. fi in case you touch the button you want to change the color of the button.
The value of x can be defined in the scale of the OSC-message or can be given in a script.
Main Types used to control Mixxx:
a Label: can be the descriving text overlay on a button or a 'standalone field' used to give some information, or even an 'receiving control' (to receive text =string information)
a Button: serves to send an instruction (information) when touched or to activate a script.
*when the information is send can be defined: Momentary (on the moment of the action): if 'press' and 'release' are selected touching the button will send information and releasing the button will send information as well.
If you're defining a 'play-button' you don't want this because in the same action (press-release) you start (send 1) and pause (send 0) the track.
With 'Toggle Press' you only send information on the moment that you press the button (with Toggle Realease on the moment that you release the button)
a Radial: can be used to control an encoder fi high / mid / low eq, gain. The information send is the value on the scale where the control is last touched (can be through a script), a Radial has a minimum and maximum value.
a Fader: can be used to control a fader (rate / volume / crossfader), The information send is the value on the scale where the control is last touched (can be through a script), a Fader has a minimum and maximum value.
an Encoder: can be used to control a jogwheel, to browse, in the library.. The information send is calulated relative to the previous position of the control.
A control has different properties:
name, tag, size, color, shape.
These properties can be changed through scripting.
Fi change the color of a playbutton when it's pressed to start the plaing.
Fi the play-button '(Channel2)@play' can be changed to '(Channel4)@play' when a 'deckswitchbutton' to switch to deck 4 is activated. When pressing the 'deckswitchbutton' again to return to deck 2 the name of the control can be changed back to
'(Channel2)@play'.
Remark:
In the duration that the button is renamed to '(Channel4)@play' the controller can't receive messages for '(Channel2)@play',
if the deck 2 player is started meanwhile the OSC controller does not know. You'lll need to cover this issue with scripting after changing the deck fi;
A OSC-Controller can be devided in parts to create more space or to devide controls in groups.
This can be done with a 'pager'. A pager contains different 'pages'.
Properties of controls on another 'page' can be called using the 'parent' and 'children' instructions.
fi: if you want to use the value of a 'Shift-button' that is located on another page, you can start from the 'root' of the document:
Remark: both lines are valid and call the value of the same 'Shift-Button'
To change the name of a control that is located in a 'sub-pager' on the same main 'page':
Remark: you can see both addressing methods can be used.
Controls on different pages can have the same name (OSC uses an internal ID system to identify the controls),
so you can have the same control in different forms or on diferent 'pages'.
If the 'naming' and 'path' rules are respected all controls will receive the same information.
fi: If you have a 1st 'page' called 'Stems' on which you created controls for stems in [Channel1] (Mixxx CO group is between [ ] ):
name: (Channel1Stem1)@mute
path: /name
and on a 2nd 'page' you created a virtual controller on which you want to control the stems of [Channel1] as well, you just create a new control with the same name and path.
if you send a scripted instruction like
both controls will be receive the information and will be updated.
OSC integration in Mixxx
In OSC the terms OSC Server and Client are used, the machine sending information is the server, the machine receiving information is the client. In a system where both machines send and receive information I prefer to talk about Receivers (the OSC Controllers and the Mixxx-Machine)
'/name' (so NOT as '/page/subpage/whatever/name'
Simple mapping of Control Object in TouchOSC:
when you press again an OSC message is sent with the value 0.
OSC functions on Mixxx Machine
Scripting
Used as: 'sendOSC('/GetP#(Master)@crossfader', 1)', 'sendOSC('/GetV#(EqualizerRack1_(Channel1)Effect1)@Parameter3', 1)' ...
When Mixxx receives these requests, Mixxx will send the values of these CO's instantly to all Active Receivers. These values will be received in the configured objects fi '(Master)@crossfader' and '(EqualizerRack1(Channel1)_Effect1)@Parameter3' if these are configured, else they'll be ignored.
fi function to select the behaviour of key depending on the chosen deck to control (value of Ch2_Deckswitch- and the value of the Shift button.
You can define an object with this name or a global 'onReceiveOSC'function for the correspondinf path ' if path == '/Osc@OscSync' then' ... in which you can list all objects for which you want to request an update:
fi:
Remark: in TouchOSC you can also create a (global) periodical function, fi to update a control like playposition. Herefor you need to call the 'time'-element of the device:
In the next example we swant to receive the actual playpostion to calculate the elapsed and remain time of the track in Deck 1. If the Deck is not playing the interval between the updates can be longer than when the track is playing.
In the same example you can see the conversion of a string to a number 'tonumber())', the conversion of a number to a string 'tostring()', and the concatenate function ( .. ) as well as marking text as comment '--'
This script can be stored in a (Channel1)@playposition ' label coontrol.
Example: combination of print (to view received values in script window combined with a loo:
Remark: in Mixxx we only send one argument in each OSC message (package), in other words: we send a new package for each value. So the example above will have only 1 argument in Mixxx - OSC.