diff --git a/message/ack.h b/message/ack.h index f61ed57f..14a2adf4 100644 --- a/message/ack.h +++ b/message/ack.h @@ -47,7 +47,7 @@ public: stream.read(&message[0], size); } - virtual uint32_t getSize() + virtual uint32_t getSize() const { return sizeof(int16_t) + message.size(); } @@ -55,10 +55,10 @@ public: std::string message; protected: - virtual void doserialize(std::ostream& stream) + virtual void doserialize(std::ostream& stream) const { int16_t size(message.size()); - stream.write(reinterpret_cast(&size), sizeof(int16_t)); + stream.write(reinterpret_cast(&size), sizeof(int16_t)); stream.write(message.c_str(), size); } }; diff --git a/message/command.h b/message/command.h index 365bc77b..ef4595b4 100644 --- a/message/command.h +++ b/message/command.h @@ -49,7 +49,7 @@ public: stream.read(&command[0], size); } - virtual uint32_t getSize() + virtual uint32_t getSize() const { return sizeof(int16_t) + command.size(); } @@ -57,10 +57,10 @@ public: std::string command; protected: - virtual void doserialize(std::ostream& stream) + virtual void doserialize(std::ostream& stream) const { int16_t size(command.size()); - stream.write(reinterpret_cast(&size), sizeof(int16_t)); + stream.write(reinterpret_cast(&size), sizeof(int16_t)); stream.write(command.c_str(), size); } }; diff --git a/message/header.h b/message/header.h index 4ae169b5..ab25a4f4 100644 --- a/message/header.h +++ b/message/header.h @@ -24,6 +24,9 @@ namespace msg { +/** + * Codec dependend header of encoded data stream + */ class Header : public BaseMessage { public: @@ -49,7 +52,7 @@ public: stream.read(payload, payloadSize); } - virtual uint32_t getSize() + virtual uint32_t getSize() const { return sizeof(int16_t) + codec.size() + sizeof(uint32_t) + payloadSize; } @@ -59,12 +62,12 @@ public: std::string codec; protected: - virtual void doserialize(std::ostream& stream) + virtual void doserialize(std::ostream& stream) const { int16_t size(codec.size()); - stream.write(reinterpret_cast(&size), sizeof(int16_t)); + stream.write(reinterpret_cast(&size), sizeof(int16_t)); stream.write(codec.c_str(), size); - stream.write(reinterpret_cast(&payloadSize), sizeof(uint32_t)); + stream.write(reinterpret_cast(&payloadSize), sizeof(uint32_t)); stream.write(payload, payloadSize); } }; diff --git a/message/message.h b/message/message.h index 8b8d0b08..24a64142 100644 --- a/message/message.h +++ b/message/message.h @@ -75,16 +75,20 @@ struct tv int32_t sec; int32_t usec; - /* - 5.3 - 6.2 = -0.9 - -1 - 0.1 - 5.3 - 6.4 = -1.1 - -1 - -0.1 - */ -//(timeMsg.received.sec - timeMsg.sent.sec) * 1000000 + (timeMsg.received.usec - timeMsg.sent.usec) + tv operator+(const tv& other) + { + tv result(*this); + result.sec += other.sec; + result.usec += other.usec; + if (result.usec > 1000000) + { + result.sec += result.usec / 1000000; + result.usec %= 1000000; + } + return result; + } + tv operator-(const tv& other) { tv result(*this); @@ -130,10 +134,10 @@ struct BaseMessage stream.read(reinterpret_cast(&type), sizeof(uint16_t)); stream.read(reinterpret_cast(&id), sizeof(uint16_t)); stream.read(reinterpret_cast(&refersTo), sizeof(uint16_t)); - stream.read(reinterpret_cast(&sent.sec), sizeof(int32_t)); - stream.read(reinterpret_cast(&sent.usec), sizeof(int32_t)); - stream.read(reinterpret_cast(&received.sec), sizeof(int32_t)); - stream.read(reinterpret_cast(&received.usec), sizeof(int32_t)); + stream.read(reinterpret_cast(&sent.sec), sizeof(int32_t)); + stream.read(reinterpret_cast(&sent.usec), sizeof(int32_t)); + stream.read(reinterpret_cast(&received.sec), sizeof(int32_t)); + stream.read(reinterpret_cast(&received.usec), sizeof(int32_t)); stream.read(reinterpret_cast(&size), sizeof(uint32_t)); } @@ -157,34 +161,34 @@ struct BaseMessage read(is); } - virtual void serialize(std::ostream& stream) + virtual void serialize(std::ostream& stream) const { - stream.write(reinterpret_cast(&type), sizeof(uint16_t)); - stream.write(reinterpret_cast(&id), sizeof(uint16_t)); - stream.write(reinterpret_cast(&refersTo), sizeof(uint16_t)); - stream.write(reinterpret_cast(&sent.sec), sizeof(int32_t)); - stream.write(reinterpret_cast(&sent.usec), sizeof(int32_t)); - stream.write(reinterpret_cast(&received.sec), sizeof(int32_t)); - stream.write(reinterpret_cast(&received.usec), sizeof(int32_t)); + stream.write(reinterpret_cast(&type), sizeof(uint16_t)); + stream.write(reinterpret_cast(&id), sizeof(uint16_t)); + stream.write(reinterpret_cast(&refersTo), sizeof(uint16_t)); + stream.write(reinterpret_cast(&sent.sec), sizeof(int32_t)); + stream.write(reinterpret_cast(&sent.usec), sizeof(int32_t)); + stream.write(reinterpret_cast(&received.sec), sizeof(int32_t)); + stream.write(reinterpret_cast(&received.usec), sizeof(int32_t)); size = getSize(); - stream.write(reinterpret_cast(&size), sizeof(uint32_t)); + stream.write(reinterpret_cast(&size), sizeof(uint32_t)); doserialize(stream); } - virtual uint32_t getSize() + virtual uint32_t getSize() const { return 3*sizeof(uint16_t) + 2*sizeof(tv) + sizeof(uint32_t); }; uint16_t type; - uint16_t id; + mutable uint16_t id; uint16_t refersTo; - tv sent; tv received; - uint32_t size; + mutable tv sent; + mutable uint32_t size; protected: - virtual void doserialize(std::ostream& stream) + virtual void doserialize(std::ostream& stream) const { }; }; diff --git a/message/pcmChunk.cpp b/message/pcmChunk.cpp index af5f8211..ec8ffc70 100644 --- a/message/pcmChunk.cpp +++ b/message/pcmChunk.cpp @@ -32,6 +32,11 @@ PcmChunk::PcmChunk(const SampleFormat& sampleFormat, size_t ms) : WireChunk(samp } +PcmChunk::PcmChunk(const PcmChunk& pcmChunk) : WireChunk(pcmChunk), format(pcmChunk.format), idx(0) +{ +} + + PcmChunk::PcmChunk() : WireChunk(), idx(0) { } diff --git a/message/pcmChunk.h b/message/pcmChunk.h index ca157043..70e2037a 100644 --- a/message/pcmChunk.h +++ b/message/pcmChunk.h @@ -29,12 +29,18 @@ namespace msg { +/** + * Piece of PCM data with SampleFormat information + * Has information about "when" recorded (start) and duration + * frames can be read with "readFrames", which will also change the start time + */ class PcmChunk : public WireChunk { public: PcmChunk(const SampleFormat& sampleFormat, size_t ms); + PcmChunk(const PcmChunk& pcmChunk); PcmChunk(); - ~PcmChunk(); + virtual ~PcmChunk(); int readFrames(void* outputBuffer, size_t frameCount); int seek(int frames); @@ -42,8 +48,8 @@ public: inline chronos::time_point_hrc start() const { return chronos::time_point_hrc( - chronos::sec(timestamp.sec) + - chronos::usec(timestamp.usec) + + chronos::sec(timestamp.sec) + + chronos::usec(timestamp.usec) + chronos::usec((chronos::usec::rep)(1000000. * ((double)idx / (double)format.rate))) ); } @@ -52,7 +58,7 @@ public: { return start() + durationLeft(); } - + template inline T duration() const { @@ -83,7 +89,6 @@ public: SampleFormat format; private: -// SampleFormat format_; uint32_t idx; }; diff --git a/message/request.h b/message/request.h index 18133441..04e7a7c4 100644 --- a/message/request.h +++ b/message/request.h @@ -25,6 +25,9 @@ namespace msg { +/** + * Request is sent from client to server. The answer is identified by a request id + */ class Request : public BaseMessage { public: @@ -45,7 +48,7 @@ public: stream.read(reinterpret_cast(&request), sizeof(int16_t)); } - virtual uint32_t getSize() + virtual uint32_t getSize() const { return sizeof(int16_t); } @@ -53,9 +56,9 @@ public: message_type request; protected: - virtual void doserialize(std::ostream& stream) + virtual void doserialize(std::ostream& stream) const { - stream.write(reinterpret_cast(&request), sizeof(int16_t)); + stream.write(reinterpret_cast(&request), sizeof(int16_t)); } }; diff --git a/message/sampleFormat.h b/message/sampleFormat.h index 5062dd83..81330489 100644 --- a/message/sampleFormat.h +++ b/message/sampleFormat.h @@ -25,16 +25,17 @@ namespace msg { -// sample and frame as defined in alsa: -// http://www.alsa-project.org/main/index.php/FramesPeriods -// Say we want to work with a stereo, 16-bit, 44.1 KHz stream, one-way (meaning, either in playback or in capture direction). Then we have: -// 'stereo' = number of channels: 2 -// 1 analog sample is represented with 16 bits = 2 bytes -// 1 frame represents 1 analog sample from all channels; here we have 2 channels, and so: -// 1 frame = (num_channels) * (1 sample in bytes) = (2 channels) * (2 bytes (16 bits) per sample) = 4 bytes (32 bits) -// To sustain 2x 44.1 KHz analog rate - the system must be capable of data transfer rate, in Bytes/sec: -// Bps_rate = (num_channels) * (1 sample in bytes) * (analog_rate) = (1 frame) * (analog_rate) = ( 2 channels ) * (2 bytes/sample) * (44100 samples/sec) = 2*2*44100 = 176400 Bytes/sec (link to formula img) - +/** + * sample and frame as defined in alsa: + * http://www.alsa-project.org/main/index.php/FramesPeriods + * Say we want to work with a stereo, 16-bit, 44.1 KHz stream, one-way (meaning, either in playback or in capture direction). Then we have: + * 'stereo' = number of channels: 2 + * 1 analog sample is represented with 16 bits = 2 bytes + * 1 frame represents 1 analog sample from all channels; here we have 2 channels, and so: + * 1 frame = (num_channels) * (1 sample in bytes) = (2 channels) * (2 bytes (16 bits) per sample) = 4 bytes (32 bits) + * To sustain 2x 44.1 KHz analog rate - the system must be capable of data transfer rate, in Bytes/sec: + * Bps_rate = (num_channels) * (1 sample in bytes) * (analog_rate) = (1 frame) * (analog_rate) = ( 2 channels ) * (2 bytes/sample) * (44100 samples/sec) = 2*2*44100 = 176400 Bytes/sec (link to formula img) + */ class SampleFormat : public BaseMessage { public: @@ -79,19 +80,19 @@ public: stream.read(reinterpret_cast(&frameSize), sizeof(uint16_t)); } - virtual uint32_t getSize() + virtual uint32_t getSize() const { return sizeof(int32_t) + 4*sizeof(int16_t); } protected: - virtual void doserialize(std::ostream& stream) + virtual void doserialize(std::ostream& stream) const { - stream.write(reinterpret_cast(&rate), sizeof(uint32_t)); - stream.write(reinterpret_cast(&bits), sizeof(uint16_t)); - stream.write(reinterpret_cast(&channels), sizeof(uint16_t)); - stream.write(reinterpret_cast(&sampleSize), sizeof(uint16_t)); - stream.write(reinterpret_cast(&frameSize), sizeof(uint16_t)); + stream.write(reinterpret_cast(&rate), sizeof(uint32_t)); + stream.write(reinterpret_cast(&bits), sizeof(uint16_t)); + stream.write(reinterpret_cast(&channels), sizeof(uint16_t)); + stream.write(reinterpret_cast(&sampleSize), sizeof(uint16_t)); + stream.write(reinterpret_cast(&frameSize), sizeof(uint16_t)); } }; diff --git a/message/serverSettings.h b/message/serverSettings.h index 95ca069d..ae950f31 100644 --- a/message/serverSettings.h +++ b/message/serverSettings.h @@ -41,7 +41,7 @@ public: stream.read(reinterpret_cast(&bufferMs), sizeof(int32_t)); } - virtual uint32_t getSize() + virtual uint32_t getSize() const { return sizeof(int32_t); } @@ -49,9 +49,9 @@ public: int32_t bufferMs; protected: - virtual void doserialize(std::ostream& stream) + virtual void doserialize(std::ostream& stream) const { - stream.write(reinterpret_cast(&bufferMs), sizeof(int32_t)); + stream.write(reinterpret_cast(&bufferMs), sizeof(int32_t)); } }; diff --git a/message/time.h b/message/time.h index 4b5442c5..4d9e2705 100644 --- a/message/time.h +++ b/message/time.h @@ -40,7 +40,7 @@ public: stream.read(reinterpret_cast(&latency), sizeof(double)); } - virtual uint32_t getSize() + virtual uint32_t getSize() const { return sizeof(double); } @@ -48,9 +48,9 @@ public: double latency; protected: - virtual void doserialize(std::ostream& stream) + virtual void doserialize(std::ostream& stream) const { - stream.write(reinterpret_cast(&latency), sizeof(double)); + stream.write(reinterpret_cast(&latency), sizeof(double)); } }; diff --git a/message/wireChunk.h b/message/wireChunk.h index 3c923ff9..0b508efa 100644 --- a/message/wireChunk.h +++ b/message/wireChunk.h @@ -31,6 +31,10 @@ namespace msg { +/** + * Piece of raw data + * Has information about "when" captured (timestamp) + */ class WireChunk : public BaseMessage { public: @@ -39,6 +43,12 @@ public: payload = (char*)malloc(size); } + WireChunk(const WireChunk& wireChunk) : BaseMessage(message_type::kWireChunk), timestamp(wireChunk.timestamp), payloadSize(wireChunk.payloadSize) + { + payload = (char*)malloc(payloadSize); + memcpy(payload, wireChunk.payload, payloadSize); + } + virtual ~WireChunk() { free(payload); @@ -53,7 +63,7 @@ public: stream.read(payload, payloadSize); } - virtual uint32_t getSize() + virtual uint32_t getSize() const { return sizeof(int32_t) + sizeof(int32_t) + sizeof(uint32_t) + payloadSize; } @@ -63,11 +73,11 @@ public: char* payload; protected: - virtual void doserialize(std::ostream& stream) + virtual void doserialize(std::ostream& stream) const { - stream.write(reinterpret_cast(×tamp.sec), sizeof(int32_t)); - stream.write(reinterpret_cast(×tamp.usec), sizeof(int32_t)); - stream.write(reinterpret_cast(&payloadSize), sizeof(uint32_t)); + stream.write(reinterpret_cast(×tamp.sec), sizeof(int32_t)); + stream.write(reinterpret_cast(×tamp.usec), sizeof(int32_t)); + stream.write(reinterpret_cast(&payloadSize), sizeof(uint32_t)); stream.write(payload, payloadSize); } };