mirror of
https://github.com/badaix/snapcast.git
synced 2025-05-17 19:16:14 +02:00
new messaging
git-svn-id: svn://elaine/murooma/trunk@230 d8a302eb-03bc-478d-80e4-98257eca68ef
This commit is contained in:
parent
a519d0f0dd
commit
04e872e036
15 changed files with 107 additions and 104 deletions
|
@ -3,7 +3,7 @@ CC = /usr/bin/g++
|
||||||
CFLAGS = -std=gnu++0x -Wall -Wno-unused-function -O3 -D_REENTRANT -DVERSION=\"$(VERSION)\" -I..
|
CFLAGS = -std=gnu++0x -Wall -Wno-unused-function -O3 -D_REENTRANT -DVERSION=\"$(VERSION)\" -I..
|
||||||
LDFLAGS = -lrt -lpthread -lboost_system -lboost_program_options -lasound -logg -lvorbis -lvorbisenc
|
LDFLAGS = -lrt -lpthread -lboost_system -lboost_program_options -lasound -logg -lvorbis -lvorbisenc
|
||||||
|
|
||||||
OBJ = snapClient.o stream.o player.o receiver.o pcmDecoder.o oggDecoder.o ../common/chunk.o ../common/log.o ../common/sampleFormat.o
|
OBJ = snapClient.o stream.o player.o receiver.o ../common/message.o ../common/log.o ../common/sampleFormat.o
|
||||||
BIN = snapclient
|
BIN = snapclient
|
||||||
|
|
||||||
all: client
|
all: client
|
||||||
|
|
|
@ -1,12 +1,12 @@
|
||||||
#ifndef DECODER_H
|
#ifndef DECODER_H
|
||||||
#define DECODER_H
|
#define DECODER_H
|
||||||
#include "common/chunk.h"
|
#include "common/message.h"
|
||||||
|
|
||||||
class Decoder
|
class Decoder
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
Decoder();
|
Decoder();
|
||||||
virtual bool decode(Chunk* chunk) = 0;
|
virtual bool decode(PcmChunk* chunk) = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -23,17 +23,20 @@ OggDecoder::~OggDecoder()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool OggDecoder::decodePayload(Chunk* chunk)
|
bool OggDecoder::decodePayload(PcmChunk* chunk)
|
||||||
{
|
{
|
||||||
WireChunk* wireChunk = chunk->wireChunk;
|
|
||||||
|
|
||||||
/* grab some data at the head of the stream. We want the first page
|
/* grab some data at the head of the stream. We want the first page
|
||||||
(which is guaranteed to be small and only contain the Vorbis
|
(which is guaranteed to be small and only contain the Vorbis
|
||||||
stream initial header) We need the first page to get the stream
|
stream initial header) We need the first page to get the stream
|
||||||
serialno. */
|
serialno. */
|
||||||
|
bytes = chunk->payloadSize;
|
||||||
|
buffer=ogg_sync_buffer(&oy, bytes);
|
||||||
|
memcpy(buffer, chunk->payload, bytes);
|
||||||
|
ogg_sync_wrote(&oy,bytes);
|
||||||
|
|
||||||
|
|
||||||
wireChunk->length = 0;
|
chunk->payloadSize = 0;
|
||||||
convsize=4096;//bytes/vi.channels;
|
convsize=4096;//bytes/vi.channels;
|
||||||
/* The rest is just a straight decode loop until end of stream */
|
/* The rest is just a straight decode loop until end of stream */
|
||||||
// while(!eos){
|
// while(!eos){
|
||||||
|
@ -95,11 +98,11 @@ bool OggDecoder::decodePayload(Chunk* chunk)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t oldSize = wireChunk->length;
|
size_t oldSize = chunk->payloadSize;
|
||||||
size_t size = 2*vi.channels * bout;
|
size_t size = 2*vi.channels * bout;
|
||||||
wireChunk->length += size;
|
chunk->payloadSize += size;
|
||||||
wireChunk->payload = (char*)realloc(wireChunk->payload, wireChunk->length);
|
chunk->payload = (char*)realloc(chunk->payload, chunk->payloadSize);
|
||||||
memcpy(wireChunk->payload + oldSize, convbuffer, size);
|
memcpy(chunk->payload + oldSize, convbuffer, size);
|
||||||
/* tell libvorbis how many samples we actually consumed */
|
/* tell libvorbis how many samples we actually consumed */
|
||||||
vorbis_synthesis_read(&vd,bout);
|
vorbis_synthesis_read(&vd,bout);
|
||||||
}
|
}
|
||||||
|
@ -113,8 +116,13 @@ bool OggDecoder::decodePayload(Chunk* chunk)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool OggDecoder::decodeHeader(Chunk* chunk)
|
bool OggDecoder::decodeHeader(HeaderMessage* chunk)
|
||||||
{
|
{
|
||||||
|
bytes = chunk->payloadSize;
|
||||||
|
buffer=ogg_sync_buffer(&oy, bytes);
|
||||||
|
memcpy(buffer, chunk->payload, bytes);
|
||||||
|
ogg_sync_wrote(&oy,bytes);
|
||||||
|
|
||||||
cout << "Decode header\n";
|
cout << "Decode header\n";
|
||||||
if(ogg_sync_pageout(&oy,&og)!=1)
|
if(ogg_sync_pageout(&oy,&og)!=1)
|
||||||
{
|
{
|
||||||
|
@ -220,13 +228,8 @@ cout << "6" << endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool OggDecoder::decode(Chunk* chunk)
|
bool OggDecoder::decode(BaseMessage* chunk)
|
||||||
{
|
{
|
||||||
WireChunk* wireChunk = chunk->wireChunk;
|
|
||||||
bytes = wireChunk->length;
|
|
||||||
buffer=ogg_sync_buffer(&oy, bytes);
|
|
||||||
memcpy(buffer, wireChunk->payload, bytes);
|
|
||||||
ogg_sync_wrote(&oy,bytes);
|
|
||||||
if (chunk->getType() == chunk_type::payload)
|
if (chunk->getType() == chunk_type::payload)
|
||||||
return decodePayload(chunk);
|
return decodePayload(chunk);
|
||||||
else if (chunk->getType() == chunk_type::header)
|
else if (chunk->getType() == chunk_type::header)
|
||||||
|
|
|
@ -9,11 +9,11 @@ class OggDecoder
|
||||||
public:
|
public:
|
||||||
OggDecoder();
|
OggDecoder();
|
||||||
virtual ~OggDecoder();
|
virtual ~OggDecoder();
|
||||||
virtual bool decode(Chunk* chunk);
|
virtual bool decode(BaseMessage* chunk);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
bool decodePayload(Chunk* chunk);
|
bool decodePayload(PcmChunk* chunk);
|
||||||
bool decodeHeader(Chunk* chunk);
|
bool decodeHeader(HeaderMessage* chunk);
|
||||||
|
|
||||||
ogg_sync_state oy; /* sync and verify incoming physical bitstream */
|
ogg_sync_state oy; /* sync and verify incoming physical bitstream */
|
||||||
ogg_stream_state os; /* take physical pages, weld into a logical
|
ogg_stream_state os; /* take physical pages, weld into a logical
|
||||||
|
|
|
@ -5,7 +5,7 @@ PcmDecoder::PcmDecoder()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool PcmDecoder::decode(Chunk* chunk)
|
bool PcmDecoder::decode(BaseMessage* chunk)
|
||||||
{
|
{
|
||||||
/* WireChunk* wireChunk = chunk->wireChunk;
|
/* WireChunk* wireChunk = chunk->wireChunk;
|
||||||
for (size_t n=0; n<wireChunk->length; ++n)
|
for (size_t n=0; n<wireChunk->length; ++n)
|
||||||
|
|
|
@ -7,7 +7,7 @@ class PcmDecoder
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
PcmDecoder();
|
PcmDecoder();
|
||||||
virtual bool decode(Chunk* chunk);
|
virtual bool decode(BaseMessage* chunk);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -2,8 +2,8 @@
|
||||||
#include <boost/lexical_cast.hpp>
|
#include <boost/lexical_cast.hpp>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include "common/log.h"
|
#include "common/log.h"
|
||||||
#include "oggDecoder.h"
|
//#include "oggDecoder.h"
|
||||||
#include "pcmDecoder.h"
|
//#include "pcmDecoder.h"
|
||||||
|
|
||||||
|
|
||||||
#define PCM_DEVICE "default"
|
#define PCM_DEVICE "default"
|
||||||
|
@ -47,7 +47,7 @@ void Receiver::stop()
|
||||||
void Receiver::worker()
|
void Receiver::worker()
|
||||||
{
|
{
|
||||||
active_ = true;
|
active_ = true;
|
||||||
OggDecoder decoder;
|
// OggDecoder decoder;
|
||||||
while (active_)
|
while (active_)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
|
@ -62,18 +62,43 @@ void Receiver::worker()
|
||||||
// std::clog << kLogNotice << "connected to " << ip << ":" << port << std::endl;
|
// std::clog << kLogNotice << "connected to " << ip << ":" << port << std::endl;
|
||||||
while (true)
|
while (true)
|
||||||
{
|
{
|
||||||
WireChunk* wireChunk = new WireChunk();
|
BaseMessage baseMessage;
|
||||||
socketRead(&s, wireChunk, Chunk::getHeaderSize());
|
boost::asio::streambuf b;
|
||||||
wireChunk->payload = (char*)malloc(wireChunk->length);
|
// reserve 512 bytes in output sequence
|
||||||
socketRead(&s, wireChunk->payload, wireChunk->length);
|
boost::asio::streambuf::mutable_buffers_type bufs = b.prepare(baseMessage.getSize());
|
||||||
Chunk* chunk = new Chunk(stream_->format, wireChunk);
|
size_t read = s.receive(bufs);
|
||||||
|
//cout << "read: " << read << "\n";
|
||||||
|
// received data is "committed" from output sequence to input sequence
|
||||||
|
b.commit(baseMessage.getSize());
|
||||||
|
std::istream is(&b);
|
||||||
|
baseMessage.read(is);
|
||||||
|
// cout << "type: " << baseMessage.type << ", size: " << baseMessage.size << "\n";
|
||||||
|
|
||||||
|
read = 0;
|
||||||
|
bufs = b.prepare(baseMessage.size);
|
||||||
|
while (read < baseMessage.size)
|
||||||
|
{
|
||||||
|
size_t n = s.receive(bufs);
|
||||||
|
b.commit(n);
|
||||||
|
read += n;
|
||||||
|
}
|
||||||
|
// received data is "committed" from output sequence to input sequence
|
||||||
|
// std::istream is(&b);
|
||||||
|
if (baseMessage.type == message_type::payload)
|
||||||
|
{
|
||||||
|
PcmChunk* chunk = new PcmChunk(stream_->format, 0);
|
||||||
|
chunk->read(is);
|
||||||
|
//cout << "WireChunk length: " << chunk->payloadSize << ", Duration: " << chunk->getDuration() << ", sec: " << chunk->tv_sec << ", usec: " << chunk->tv_usec/1000 << ", type: " << chunk->type << "\n";
|
||||||
|
stream_->addChunk(chunk);
|
||||||
|
}
|
||||||
|
|
||||||
//cout << "WireChunk length: " << wireChunk->length << ", Duration: " << chunk->getDuration() << ", sec: " << wireChunk->tv_sec << ", usec: " << wireChunk->tv_usec/1000 << ", type: " << wireChunk->type << "\n";
|
//cout << "WireChunk length: " << wireChunk->length << ", Duration: " << chunk->getDuration() << ", sec: " << wireChunk->tv_sec << ", usec: " << wireChunk->tv_usec/1000 << ", type: " << wireChunk->type << "\n";
|
||||||
if (decoder.decode(chunk))
|
/* if (decoder.decode(chunk))
|
||||||
{
|
{
|
||||||
//cout << "Duration: " << chunk->getDuration() << "\n";
|
//cout << "Duration: " << chunk->getDuration() << "\n";
|
||||||
stream_->addChunk(chunk);
|
stream_->addChunk(chunk);
|
||||||
}
|
}
|
||||||
}
|
*/ }
|
||||||
}
|
}
|
||||||
catch (const std::exception& e)
|
catch (const std::exception& e)
|
||||||
{
|
{
|
||||||
|
|
|
@ -10,7 +10,6 @@
|
||||||
#include <boost/program_options.hpp>
|
#include <boost/program_options.hpp>
|
||||||
|
|
||||||
#include "common/sampleFormat.h"
|
#include "common/sampleFormat.h"
|
||||||
#include "common/chunk.h"
|
|
||||||
#include "common/utils.h"
|
#include "common/utils.h"
|
||||||
#include "common/log.h"
|
#include "common/log.h"
|
||||||
#include "stream.h"
|
#include "stream.h"
|
||||||
|
|
|
@ -31,11 +31,11 @@ void Stream::clearChunks()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void Stream::addChunk(Chunk* chunk)
|
void Stream::addChunk(PcmChunk* chunk)
|
||||||
{
|
{
|
||||||
while (chunks.size() * chunk->getDuration() > 10000)
|
while (chunks.size() * chunk->getDuration() > 10000)
|
||||||
chunks.pop();
|
chunks.pop();
|
||||||
chunks.push(shared_ptr<Chunk>(chunk));
|
chunks.push(shared_ptr<PcmChunk>(chunk));
|
||||||
// cout << "new chunk: " << chunk->getDuration() << ", Chunks: " << chunks.size() << "\n";
|
// cout << "new chunk: " << chunk->getDuration() << ", Chunks: " << chunks.size() << "\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -110,7 +110,7 @@ time_point_ms Stream::getNextPlayerChunk(void* outputBuffer, unsigned long frame
|
||||||
|
|
||||||
while (read < toRead)
|
while (read < toRead)
|
||||||
{
|
{
|
||||||
read += chunk->read(buffer + read*format.frameSize, toRead - read);
|
read += chunk->readFrames(buffer + read*format.frameSize, toRead - read);
|
||||||
if (chunk->isEndOfChunk())
|
if (chunk->isEndOfChunk())
|
||||||
chunk = chunks.pop();
|
chunk = chunks.pop();
|
||||||
}
|
}
|
||||||
|
@ -175,7 +175,7 @@ int msBuffer = framesPerBuffer / format_.msRate();
|
||||||
if (sleep < -msBuffer/2)
|
if (sleep < -msBuffer/2)
|
||||||
{
|
{
|
||||||
cout << "Sleep " << sleep;
|
cout << "Sleep " << sleep;
|
||||||
sleep = Chunk::getAge(getSilentPlayerChunk(outputBuffer, framesPerBuffer)) - bufferMs + outputBufferDacTime;
|
sleep = PcmChunk::getAge(getSilentPlayerChunk(outputBuffer, framesPerBuffer)) - bufferMs + outputBufferDacTime;
|
||||||
std::cerr << " after: " << sleep << ", chunks: " << chunks.size() << "\n";
|
std::cerr << " after: " << sleep << ", chunks: " << chunks.size() << "\n";
|
||||||
// std::clog << kLogNotice << "sleep: " << sleep << std::endl;
|
// std::clog << kLogNotice << "sleep: " << sleep << std::endl;
|
||||||
// if (sleep > -msBuffer/2)
|
// if (sleep > -msBuffer/2)
|
||||||
|
@ -201,7 +201,7 @@ cout << "\nms: " << Chunk::getAge(ms) << "\t chunk: " << chunk->getAge() << "\n"
|
||||||
// cout << "chunk->getAge() > chunk->getDuration(): " << chunk->getAge() - bufferMs + outputBufferDacTime << " > " << chunk->getDuration() << ", chunks: " << chunks.size() << ", out: " << outputBufferDacTime << ", needed: " << msBuffer << ", sleep: " << sleep << "\n";
|
// cout << "chunk->getAge() > chunk->getDuration(): " << chunk->getAge() - bufferMs + outputBufferDacTime << " > " << chunk->getDuration() << ", chunks: " << chunks.size() << ", out: " << outputBufferDacTime << ", needed: " << msBuffer << ", sleep: " << sleep << "\n";
|
||||||
usleep(1000);
|
usleep(1000);
|
||||||
}
|
}
|
||||||
cout << "seek: " << Chunk::getAge(seek(sleep)) - bufferMs + outputBufferDacTime << "\n";
|
cout << "seek: " << PcmChunk::getAge(seek(sleep)) - bufferMs + outputBufferDacTime << "\n";
|
||||||
sleep = 0;
|
sleep = 0;
|
||||||
}
|
}
|
||||||
else if (sleep < 0)
|
else if (sleep < 0)
|
||||||
|
@ -218,7 +218,7 @@ cout << "\nms: " << Chunk::getAge(ms) << "\t chunk: " << chunk->getAge() << "\n"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
int age = Chunk::getAge(getNextPlayerChunk(outputBuffer, framesPerBuffer, correction)) - bufferMs + outputBufferDacTime;
|
int age = PcmChunk::getAge(getNextPlayerChunk(outputBuffer, framesPerBuffer, correction)) - bufferMs + outputBufferDacTime;
|
||||||
|
|
||||||
|
|
||||||
// if (pCardBuffer->full())
|
// if (pCardBuffer->full())
|
||||||
|
|
|
@ -8,7 +8,7 @@
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include "doubleBuffer.h"
|
#include "doubleBuffer.h"
|
||||||
#include "common/chunk.h"
|
#include "common/message.h"
|
||||||
#include "common/timeUtils.h"
|
#include "common/timeUtils.h"
|
||||||
#include "common/queue.h"
|
#include "common/queue.h"
|
||||||
#include "common/sampleFormat.h"
|
#include "common/sampleFormat.h"
|
||||||
|
@ -18,7 +18,7 @@ class Stream
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
Stream(const SampleFormat& format);
|
Stream(const SampleFormat& format);
|
||||||
void addChunk(Chunk* chunk);
|
void addChunk(PcmChunk* chunk);
|
||||||
void clearChunks();
|
void clearChunks();
|
||||||
void getPlayerChunk(void* outputBuffer, double outputBufferDacTime, unsigned long framesPerBuffer);
|
void getPlayerChunk(void* outputBuffer, double outputBufferDacTime, unsigned long framesPerBuffer);
|
||||||
void setBufferLen(size_t bufferLenMs);
|
void setBufferLen(size_t bufferLenMs);
|
||||||
|
@ -37,12 +37,12 @@ private:
|
||||||
long lastTick;
|
long lastTick;
|
||||||
int sleep;
|
int sleep;
|
||||||
|
|
||||||
Queue<std::shared_ptr<Chunk>> chunks;
|
Queue<std::shared_ptr<PcmChunk>> chunks;
|
||||||
DoubleBuffer<int>* pCardBuffer;
|
DoubleBuffer<int>* pCardBuffer;
|
||||||
DoubleBuffer<int>* pMiniBuffer;
|
DoubleBuffer<int>* pMiniBuffer;
|
||||||
DoubleBuffer<int>* pBuffer;
|
DoubleBuffer<int>* pBuffer;
|
||||||
DoubleBuffer<int>* pShortBuffer;
|
DoubleBuffer<int>* pShortBuffer;
|
||||||
std::shared_ptr<Chunk> chunk;
|
std::shared_ptr<PcmChunk> chunk;
|
||||||
|
|
||||||
int median;
|
int median;
|
||||||
int shortMedian;
|
int shortMedian;
|
||||||
|
|
|
@ -54,7 +54,7 @@ int PcmChunk::seek(int frames)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int PcmChunk::read(void* outputBuffer, size_t frameCount)
|
int PcmChunk::readFrames(void* outputBuffer, size_t frameCount)
|
||||||
{
|
{
|
||||||
//logd << "read: " << frameCount << ", total: " << (wireChunk->length / format.frameSize) << ", idx: " << idx;// << std::endl;
|
//logd << "read: " << frameCount << ", total: " << (wireChunk->length / format.frameSize) << ", idx: " << idx;// << std::endl;
|
||||||
int result = frameCount;
|
int result = frameCount;
|
||||||
|
|
|
@ -28,15 +28,23 @@ struct BaseMessage
|
||||||
|
|
||||||
BaseMessage(message_type type_)
|
BaseMessage(message_type type_)
|
||||||
{
|
{
|
||||||
type = type;
|
type = type_;
|
||||||
};
|
};
|
||||||
|
|
||||||
virtual void read(istream& stream)
|
virtual void read(istream& stream)
|
||||||
{
|
{
|
||||||
stream.read(reinterpret_cast<char*>(&type), sizeof(uint16_t));
|
stream.read(reinterpret_cast<char*>(&type), sizeof(uint16_t));
|
||||||
cout << type << "\n";
|
// cout << type << "\n";
|
||||||
stream.read(reinterpret_cast<char*>(&size), sizeof(uint32_t));
|
stream.read(reinterpret_cast<char*>(&size), sizeof(uint32_t));
|
||||||
cout << size << "\n";
|
// cout << size << "\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
void read(char* stream)
|
||||||
|
{
|
||||||
|
memcpy(reinterpret_cast<char*>(&type), stream, sizeof(uint16_t));
|
||||||
|
// cout << "type: " << type << "\n";
|
||||||
|
memcpy(reinterpret_cast<char*>(&size), stream + sizeof(uint16_t), sizeof(uint32_t));
|
||||||
|
// cout << "size: " << size << "\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void serialize(ostream& stream)
|
virtual void serialize(ostream& stream)
|
||||||
|
@ -107,8 +115,9 @@ protected:
|
||||||
class WireChunk : public BaseMessage
|
class WireChunk : public BaseMessage
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
WireChunk() : BaseMessage(message_type::payload)
|
WireChunk(size_t size = 0) : BaseMessage(message_type::payload), payloadSize(size)
|
||||||
{
|
{
|
||||||
|
payload = (char*)malloc(size);
|
||||||
}
|
}
|
||||||
|
|
||||||
// WireChunk(int8_t logLevel_, char* text_) : BaseMessage(message_type::payload), logLevel(logLevel_), length(sizeof(text_)), text(text_)
|
// WireChunk(int8_t logLevel_, char* text_) : BaseMessage(message_type::payload), logLevel(logLevel_), length(sizeof(text_)), text(text_)
|
||||||
|
@ -117,6 +126,7 @@ public:
|
||||||
|
|
||||||
virtual ~WireChunk()
|
virtual ~WireChunk()
|
||||||
{
|
{
|
||||||
|
free(payload);
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void read(istream& stream)
|
virtual void read(istream& stream)
|
||||||
|
@ -124,7 +134,7 @@ public:
|
||||||
stream.read(reinterpret_cast<char *>(&tv_sec), sizeof(int32_t));
|
stream.read(reinterpret_cast<char *>(&tv_sec), sizeof(int32_t));
|
||||||
stream.read(reinterpret_cast<char *>(&tv_usec), sizeof(int32_t));
|
stream.read(reinterpret_cast<char *>(&tv_usec), sizeof(int32_t));
|
||||||
stream.read(reinterpret_cast<char *>(&payloadSize), sizeof(uint32_t));
|
stream.read(reinterpret_cast<char *>(&payloadSize), sizeof(uint32_t));
|
||||||
payload = (char*)malloc(payloadSize);
|
payload = (char*)realloc(payload, payloadSize);
|
||||||
stream.read(payload, payloadSize);
|
stream.read(payload, payloadSize);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -153,19 +163,20 @@ protected:
|
||||||
class HeaderMessage : public BaseMessage
|
class HeaderMessage : public BaseMessage
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
HeaderMessage(size_t size = 0) : BaseMessage(message_type::payload), payloadSize(size)
|
HeaderMessage(size_t size = 0) : BaseMessage(message_type::header), payloadSize(size)
|
||||||
{
|
{
|
||||||
payload = (char*)malloc(size);
|
payload = (char*)malloc(size);
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual ~HeaderMessage()
|
virtual ~HeaderMessage()
|
||||||
{
|
{
|
||||||
|
free(payload);
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void read(istream& stream)
|
virtual void read(istream& stream)
|
||||||
{
|
{
|
||||||
stream.read(reinterpret_cast<char *>(&payloadSize), sizeof(uint32_t));
|
stream.read(reinterpret_cast<char *>(&payloadSize), sizeof(uint32_t));
|
||||||
payload = (char*)malloc(payloadSize);
|
payload = (char*)realloc(payload, payloadSize);
|
||||||
stream.read(payload, payloadSize);
|
stream.read(payload, payloadSize);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -292,7 +303,7 @@ public:
|
||||||
PcmChunk(const SampleFormat& sampleFormat, size_t ms);
|
PcmChunk(const SampleFormat& sampleFormat, size_t ms);
|
||||||
~PcmChunk();
|
~PcmChunk();
|
||||||
|
|
||||||
int read(void* outputBuffer, size_t frameCount);
|
int readFrames(void* outputBuffer, size_t frameCount);
|
||||||
bool isEndOfChunk() const;
|
bool isEndOfChunk() const;
|
||||||
|
|
||||||
inline time_point_ms timePoint() const
|
inline time_point_ms timePoint() const
|
||||||
|
|
|
@ -60,45 +60,6 @@ using namespace std::chrono;
|
||||||
|
|
||||||
bool g_terminated = false;
|
bool g_terminated = false;
|
||||||
|
|
||||||
/*
|
|
||||||
int main(int argc, char* argv[])
|
|
||||||
{
|
|
||||||
TestMessage* chunk = new TestMessage(1, (char*)"Hallo");
|
|
||||||
stringstream ss;
|
|
||||||
chunk->serialize(ss);
|
|
||||||
|
|
||||||
BaseMessage header;
|
|
||||||
ss.seekg(0, ss.beg);
|
|
||||||
header.read(ss);
|
|
||||||
// cout << ss.str() << "\n";
|
|
||||||
// ss.read(reinterpret_cast<char*>(&header), sizeof(MessageHeader));
|
|
||||||
cout << "Header: " << header.type << ", " << header.size << "\n";
|
|
||||||
delete chunk;
|
|
||||||
chunk = new TestMessage();
|
|
||||||
chunk->read(ss);
|
|
||||||
cout << "Header: " << chunk->type << ", " << chunk->size << ", " << (int)chunk->logLevel << ", " << chunk->text << "\n";
|
|
||||||
|
|
||||||
|
|
||||||
chunk->tv_sec = 21;
|
|
||||||
chunk->tv_usec = 2;
|
|
||||||
chunk->payloadSize = 5;
|
|
||||||
chunk->payload = (char*)malloc(5);
|
|
||||||
chunk->payload[0] = 99;
|
|
||||||
char* stream = chunk->serialize();
|
|
||||||
cout << "1\n";
|
|
||||||
for (size_t n=0; n<24; ++n)
|
|
||||||
cout << (int)stream[n] << " ";
|
|
||||||
delete chunk;
|
|
||||||
cout << "\n3\n";
|
|
||||||
chunk = new WireChunk();
|
|
||||||
cout << "4\n";
|
|
||||||
chunk->deserialize(stream);
|
|
||||||
cout << "5\n";
|
|
||||||
cout << chunk->tv_sec << ", " << chunk->tv_usec << ", " << chunk->payloadSize << ", " << chunk->payload << "\n";
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
class Session
|
class Session
|
||||||
|
@ -112,15 +73,18 @@ public:
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
boost::asio::streambuf streambuf;
|
||||||
|
std::ostream stream(&streambuf);
|
||||||
for (;;)
|
for (;;)
|
||||||
{
|
{
|
||||||
shared_ptr<BaseMessage> message(messages.pop());
|
shared_ptr<BaseMessage> message(messages.pop());
|
||||||
/* char* stream = chunk->serialize();
|
message->serialize(stream);
|
||||||
size_t written(0);
|
boost::asio::write(*socket_, streambuf);
|
||||||
size_t toWrite = sizeof(stream);
|
/* size_t written(0);
|
||||||
|
size_t toWrite = message->getSize();
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
written += boost::asio::write(*socket_, boost::asio::buffer(stream + written, toWrite - written));//, error);
|
written += boost::asio::write(*socket_, streambuf);//, error);
|
||||||
}
|
}
|
||||||
while (written < toWrite);
|
while (written < toWrite);
|
||||||
*/ }
|
*/ }
|
||||||
|
@ -176,9 +140,10 @@ public:
|
||||||
{
|
{
|
||||||
socket_ptr sock(new tcp::socket(io_service_));
|
socket_ptr sock(new tcp::socket(io_service_));
|
||||||
a.accept(*sock);
|
a.accept(*sock);
|
||||||
// cout << "New connection: " << sock->remote_endpoint().address().to_string() << "\n";
|
cout << "New connection: " << sock->remote_endpoint().address().to_string() << "\n";
|
||||||
Session* session = new Session(sock);
|
Session* session = new Session(sock);
|
||||||
cout << "Sending header: " << headerChunk->payloadSize << "\n";
|
if (headerChunk)
|
||||||
|
cout << "Sending header: " << headerChunk->payloadSize << endl;
|
||||||
session->send(headerChunk);
|
session->send(headerChunk);
|
||||||
session->start();
|
session->start();
|
||||||
sessions.insert(shared_ptr<Session>(session));
|
sessions.insert(shared_ptr<Session>(session));
|
||||||
|
@ -297,9 +262,9 @@ int main(int argc, char* argv[])
|
||||||
long nextTick = getTickCount();
|
long nextTick = getTickCount();
|
||||||
|
|
||||||
mkfifo(fifoName.c_str(), 0777);
|
mkfifo(fifoName.c_str(), 0777);
|
||||||
size_t duration = 50;
|
|
||||||
|
|
||||||
SampleFormat format(sampleFormat);
|
SampleFormat format(sampleFormat);
|
||||||
|
size_t duration = 50;
|
||||||
|
//size_t chunkSize = duration*format.rate*format.frameSize / 1000;
|
||||||
std::auto_ptr<Encoder> encoder;
|
std::auto_ptr<Encoder> encoder;
|
||||||
if (codec == "ogg")
|
if (codec == "ogg")
|
||||||
encoder.reset(new OggEncoder(sampleFormat));
|
encoder.reset(new OggEncoder(sampleFormat));
|
||||||
|
@ -311,8 +276,8 @@ size_t duration = 50;
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// shared_ptr<HeaderMessage> header(encoder->getHeader());
|
shared_ptr<HeaderMessage> header(encoder->getHeader());
|
||||||
// server->setHeader(header);
|
server->setHeader(header);
|
||||||
|
|
||||||
while (!g_terminated)
|
while (!g_terminated)
|
||||||
{
|
{
|
||||||
|
@ -322,7 +287,7 @@ size_t duration = 50;
|
||||||
shared_ptr<PcmChunk> chunk;//(new WireChunk());
|
shared_ptr<PcmChunk> chunk;//(new WireChunk());
|
||||||
while (true)//cin.good())
|
while (true)//cin.good())
|
||||||
{
|
{
|
||||||
chunk.reset(new PcmChunk(format, duration));//2*WIRE_CHUNK_SIZE));
|
chunk.reset(new PcmChunk(sampleFormat, duration));//2*WIRE_CHUNK_SIZE));
|
||||||
int toRead = chunk->payloadSize;
|
int toRead = chunk->payloadSize;
|
||||||
int len = 0;
|
int len = 0;
|
||||||
do
|
do
|
||||||
|
@ -337,10 +302,10 @@ size_t duration = 50;
|
||||||
|
|
||||||
chunk->tv_sec = tvChunk.tv_sec;
|
chunk->tv_sec = tvChunk.tv_sec;
|
||||||
chunk->tv_usec = tvChunk.tv_usec;
|
chunk->tv_usec = tvChunk.tv_usec;
|
||||||
double chunkDuration = 50;//encoder->encode(chunk.get());
|
double chunkDuration = encoder->encode(chunk.get());
|
||||||
if (chunkDuration > 0)
|
if (chunkDuration > 0)
|
||||||
server->send(chunk);
|
server->send(chunk);
|
||||||
cout << chunk->tv_sec << ", " << chunk->tv_usec / 1000 << "\n";
|
//cout << chunk->tv_sec << ", " << chunk->tv_usec / 1000 << "\n";
|
||||||
// addUs(tvChunk, 1000*chunk->getDuration());
|
// addUs(tvChunk, 1000*chunk->getDuration());
|
||||||
addUs(tvChunk, chunkDuration * 1000);
|
addUs(tvChunk, chunkDuration * 1000);
|
||||||
nextTick += duration;
|
nextTick += duration;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue