andrewm@71: //scope.cpp
giuliomoro@217: #ifndef SCOPE_H_
giuliomoro@217: #define SCOPE_H_
giuliomoro@217: 
giuliomoro@217: #ifdef USE_JUCE
giuliomoro@217: #include <JuceHeader.h>
giuliomoro@217: #else
giuliomoro@301: #include <Bela.h> 
andrewm@71: #include <rtdk.h>
andrewm@71: #include <cmath>
andrewm@71: #include <UdpClient.h>
giuliomoro@217: #include <vector>
giuliomoro@217: #include <string>
giuliomoro@233: extern int gShouldStop;
giuliomoro@217: #endif /* USE_JUCE */
andrewm@71: 
giuliomoro@107: #define NETWORK_AUDIO_BUFFER_SIZE 302
giuliomoro@217: #define UDP_BUFFER_HEADER_CHANNEL_INDEX 0
giuliomoro@217: #define UDP_BUFFER_HEADER_TIMESTAMP_INDEX 1
giuliomoro@217: #define UDP_BUFFER_HEADER_LENGTH 2
giuliomoro@217: 
giuliomoro@217: struct NetworkBuffer{
giuliomoro@217: 	int channelNumber;
giuliomoro@217: 	int numBuffers;
giuliomoro@217: 	int writeBuffer;
giuliomoro@217: 	int readBuffer;
giuliomoro@217: 	int writePointer;
giuliomoro@217: 	float** buffers;
giuliomoro@217: 	bool* doneOnTime;
giuliomoro@217: 	bool* readyToBeSent;
giuliomoro@217: 	bool enabled;
giuliomoro@217: 	int sampleCount;
giuliomoro@217: 	static const int bufferLength=NETWORK_AUDIO_BUFFER_SIZE;
giuliomoro@217: 	static const int headerLength=UDP_BUFFER_HEADER_LENGTH;
giuliomoro@217: 	static const int headerChannelIndex=UDP_BUFFER_HEADER_CHANNEL_INDEX;
giuliomoro@217: 	static const int headerTimestampIndex=UDP_BUFFER_HEADER_TIMESTAMP_INDEX;
andrewm@71: };
andrewm@71: 
giuliomoro@217: #ifdef USE_JUCE
giuliomoro@217: class NetworkSend: public Thread {
giuliomoro@107: #else
giuliomoro@217: class NetworkSend {
giuliomoro@217: #endif /* USE_JUCE */
giuliomoro@217: 	float sampleRate;
giuliomoro@217: #ifdef USE_JUCE
giuliomoro@217: 	DatagramSocket udpClient;
giuliomoro@217: 	int sleepTimeMs;
giuliomoro@217: 	String remoteHostname;
giuliomoro@217: 	int remotePortNumber;
giuliomoro@93: #else
giuliomoro@217: 	UdpClient udpClient;
giuliomoro@217: 	bool isThreadRunning();
giuliomoro@217: 	static int sleepTimeMs;
giuliomoro@217: 	static bool threadShouldExit();
giuliomoro@217: 	static bool threadIsExiting;
giuliomoro@217: 	static bool threadRunning;
giuliomoro@217: 	static bool staticConstructed;
giuliomoro@217: 	static void staticConstructor();
giuliomoro@217: 	static AuxiliaryTask sendDataTask; //TODO: allow different AuxiliaryTasks for different priorities (e.g.: audio vs scope)
giuliomoro@217: 	static std::vector<NetworkSend *> objAddrs;
giuliomoro@217: #endif /* USE_JUCE */
giuliomoro@217: 	void dealloc();
giuliomoro@217: public:
giuliomoro@217: 	NetworkBuffer channel;
giuliomoro@217: #ifdef USE_JUCE
giuliomoro@217: 	NetworkSend(const String &threadName);
giuliomoro@217: #else
giuliomoro@217: 	NetworkSend();
giuliomoro@217: #endif
giuliomoro@217: 	~NetworkSend();
giuliomoro@217: 	void setup(float aSampleRate, int blockSize, int aChannelNumber, int aPort, const char *aServer);
giuliomoro@217: 	void cleanup();
giuliomoro@217: 	void sendData();
giuliomoro@217: 	void log(float value);
giuliomoro@217: 	void setPort(int aPort);
giuliomoro@217: 	void setServer(const char* aServer);
giuliomoro@217: 	void setChannelNumber(int aChannelNumber);
giuliomoro@217: 	int getChannelNumber();
giuliomoro@217: 	int getTimestamp();
giuliomoro@217: #ifdef USE_JUCE
giuliomoro@217: 	void run();
giuliomoro@217: #else
giuliomoro@217: 	static int getNumInstances();
giuliomoro@217: 	static void sendAllData();
giuliomoro@217:     static void startThread();
giuliomoro@217:     static void stopThread();
giuliomoro@217: 	static void run();
giuliomoro@217: #endif /* USE_JUCE */
andrewm@71: };
andrewm@71: 
giuliomoro@217: #ifdef USE_JUCE
giuliomoro@217: #else
giuliomoro@217: /**
giuliomoro@217:  * An array of NetworkSend objects with some default parameters
giuliomoro@217:  *
giuliomoro@217:  * All sending on the same port (defaults to 9999)
giuliomoro@217:  * All sending to the same server (defaults to 127.0.0.1)
giuliomoro@217: */
giuliomoro@217: class Scope {
giuliomoro@217: 	std::vector<NetworkSend> channels;
giuliomoro@217: 	void deallocate();
giuliomoro@217: public:
giuliomoro@217: 	Scope(int aNumChannels);
giuliomoro@217: 	~Scope();
giuliomoro@217: 	void log(int channel, float value);
giuliomoro@217:     void setup();
giuliomoro@217:     void setup(float sampleRate, int aPort, const char* aServer);
giuliomoro@217:     void sendData();
giuliomoro@217:     void setPort(int port);
giuliomoro@217:     void setPort(int channel, int port);
giuliomoro@217:     int getNumChannels();
giuliomoro@217: };
giuliomoro@217: #endif /* USE_JUCE */
andrewm@71: 
giuliomoro@217: #endif /* SCOPE_H */