I am currently working on my final degree Project and have developed a GUI with Projucer to remotely control an audio DSP platform.
In fact, I’d like to implement TCP/IP protocol in my GUI, but unfortunately I am a newbie in programming windows sockets.
The first thing I tried was including WinSock2.h in my MainComponent.h file but new compile errors arosed (related with Juce Rectangle class) in Visual Studio 2017, so I searched in Juce’s Forum for a possible solution.
Then, I found a topic titled “Problems with winsock2 functions in a big JUCEy project”, and tried to apply the solutions that were proposed, but without succeed. In fact, I tried to reorder my header files both in my MainComponent.h and in JuceHeader.h file, but in both cases did not work.
I can’t help with the compilation issue, but I wanted to check if your project requires you to use the socket layer directly? Otherwise you may want to use the JUCE StreamingSocket class.
The audio DSP platform have to be remotely controled via WiFi, i.e. the router is plugged into the platform and the GUI have to receive from and transmit data to platform (signal level and the parameters’ value of the different audio interfaces - EQ, Dynamics and Reverb) through a wireless connection.
Sorry by my newbie condition, but Is that possible with the Juce’s StreamingSocket class? How can I add the sockaddr_in struct into the connect function?
StreamingSocket is a TCP socket, so it will serve the purpose for any code that needs a TCP socket, and will handle many of the details that you would otherwise need to concern yourself with if you were writing directly to the sockets API. You won’t ‘add’ the sockaddr_in struct, but instead use the StreamingSocket API to setup the same data. You would start by calling: StreamingSocket::connect(const String& remoteHostname, int remotePortNumber, int timeOutMillisecs);
If you go to the link I put in my first response you can see all of the functions that StreamingSocket supplies.
Even easier is to use InterprocessConnection and InterprocessConnectionServer classes, they are just ready to go. Everything you described can be done using these classes.
@MBO My interpretation of the OP’s request was that they needed to connect to something outside of JUCE, to remotely control an audio DSP platform. But if not, your suggestion will make the job even easier.
I’ve just taken a look to StreamingSocket and InterprocessConnections classes, but I still have a doubt… The hostName input variable of connect() and connectToSocket() functions corresponds to the IP adrress of the DSP platform?
For example, is it right if i call connect() from the GUI in that way:
xavo, what class is this final project for? what is your experience with c++? what is your experience with network programming?
and yes, your call to connect is correct. But, obviously that is just attempting to establish a connection, but you will still need to read and write the data as should be specified by the dsp platform you are connecting to.
I am newbie in almost everything, but I still working on it to change this condition!
This days I’ve been reading plenty of docs about TCP sockets programming and I am aware of the code that I have to implement in the GUI and in the platform.
I have finally opted to use the StreamingSocket class. I asked to both of you for some tutorial or example, because I’ll like to properly implement this protocol in my GUI’s code, and not to directly do it in the MainCompoment constructor of my code. In fact, I’ve create a TCPConnection class of my own, and I’m using a Thread to establish the connection with the platform. What I’m not sure about is if I have to execute another Thread in my MainComponent constructor, because both of them are acceeding to the same data struct (which is the buffer where I store the audio data), and if I have to declare the members of the data struct as atomic. Well, as you can see I am not a C++ or multithread’s master programmer, and I am still searching for a guideline template like the ones that most of Juce examples provide.
Sounds like you are on the right track, which means you can’t be as newbie as you said you are. You’ve already moved in the correct directions, and are talking about relevant things that most newbies wouldn’t yet understand they need to consider.
The correct solution requires understanding the problem some more. one solution is to use a mutex (juce::CriticalSection) to control which thread has access to a given piece of data. One thread will lock the mutex when accessing the data. If the other thread attempts to lock the mutex, it will be blocked until the first thread unlocks it. This blocking could have implications to a given thread, and so ideally we lock mutex’s for the shortest possible time.
Atomics provide a different solution, that only protect a given variable from being accessed simultaneously by multiple threads. So, if there is only one POD variable that you want to give thread safety access to, then an atomic will be useful. But if you are dealing with more than one POD that should be updated/read all at the same time, either individual POD’s, or a struct/class, then you will need to use a mutex.