diff --git a/client/decoder/flacDecoder.cpp b/client/decoder/flacDecoder.cpp
index 937bbfd3..c267b3b4 100644
--- a/client/decoder/flacDecoder.cpp
+++ b/client/decoder/flacDecoder.cpp
@@ -16,13 +16,14 @@
along with this program. If not, see .
***/
-#include "flacDecoder.h"
#include
#include
#include
#include
+#include "flacDecoder.h"
#include "common/log.h"
+
using namespace std;
@@ -53,18 +54,26 @@ FlacDecoder::~FlacDecoder()
bool FlacDecoder::decode(msg::PcmChunk* chunk)
{
+ cacheInfo_.reset();
pcmChunk = chunk;
-//logO << "Decode start: " << chunk->payloadSize << endl;
flacChunk->payload = (char*)realloc(flacChunk->payload, chunk->payloadSize);
memcpy(flacChunk->payload, chunk->payload, chunk->payloadSize);
flacChunk->payloadSize = chunk->payloadSize;
pcmChunk->payload = (char*)realloc(pcmChunk->payload, 0);
pcmChunk->payloadSize = 0;
- FLAC__stream_decoder_process_single(decoder);
- if (flacChunk->payloadSize > 0)
+ while (flacChunk->payloadSize > 0)
FLAC__stream_decoder_process_single(decoder);
-//logO << "Decode end\n" << endl;
+
+ if ((cacheInfo_.cachedBlocks_ > 0) && (cacheInfo_.sampleRate_ != 0))
+ {
+ double diffMs = cacheInfo_.cachedBlocks_ / ((double)cacheInfo_.sampleRate_ / 1000.);
+ int32_t s = (diffMs / 1000);
+ int32_t us = (diffMs * 1000);
+ us %= 1000000;
+ logD << "Cached: " << cacheInfo_.cachedBlocks_ << ", " << diffMs << "ms, " << s << "s, " << us << "us\n";
+ chunk->timestamp = chunk->timestamp - tv(s, us);
+ }
return true;
}
@@ -75,21 +84,19 @@ bool FlacDecoder::setHeader(msg::Header* chunk)
FLAC__bool ok = true;
FLAC__StreamDecoderInitStatus init_status;
- if((decoder = FLAC__stream_decoder_new()) == NULL) {
- fprintf(stderr, "ERROR: allocating decoder\n");
- return 1;
+ if ((decoder = FLAC__stream_decoder_new()) == NULL)
+ {
+ logS(kLogErr) << "ERROR: allocating decoder\n";
+ return false;
}
// (void)FLAC__stream_decoder_set_md5_checking(decoder, true);
-
init_status = FLAC__stream_decoder_init_stream(decoder, read_callback, NULL, NULL, NULL, NULL, write_callback, metadata_callback, error_callback, this);
-
-// init_status = FLAC__stream_decoder_init_file(decoder, argv[1], write_callback, metadata_callback, error_callback, fout);
- if(init_status != FLAC__STREAM_DECODER_INIT_STATUS_OK) {
- fprintf(stderr, "ERROR: initializing decoder: %s\n", FLAC__StreamDecoderInitStatusString[init_status]);
+ if(init_status != FLAC__STREAM_DECODER_INIT_STATUS_OK)
+ {
+ logS(kLogErr) << "ERROR: initializing decoder: " << FLAC__StreamDecoderInitStatusString[init_status] << "\n";
ok = false;
}
-// FLAC__stream_decoder_process_until_end_of_stream(decoder);
FLAC__stream_decoder_process_until_end_of_metadata(decoder);
return ok;
@@ -106,23 +113,14 @@ FLAC__StreamDecoderReadStatus read_callback(const FLAC__StreamDecoder *decoder,
}
else if (flacChunk != NULL)
{
-//logO << "Read: " << *bytes << "\t" << flacChunk->payloadSize << "\n";
- FLAC__StreamDecoderReadStatus result = FLAC__STREAM_DECODER_READ_STATUS_CONTINUE;
+ ((FlacDecoder*)client_data)->cacheInfo_.isCachedChunk_ = false;
if (*bytes > flacChunk->payloadSize)
*bytes = flacChunk->payloadSize;
-// else
-// result = FLAC__STREAM_DECODER_READ_STATUS_END_OF_STREAM;
-
-// if (flacChunk->payloadSize == 0)
-// return FLAC__STREAM_DECODER_READ_STATUS_END_OF_STREAM;
memcpy(buffer, flacChunk->payload, *bytes);
memmove(flacChunk->payload, flacChunk->payload + *bytes, flacChunk->payloadSize - *bytes);
flacChunk->payloadSize = flacChunk->payloadSize - *bytes;
flacChunk->payload = (char*)realloc(flacChunk->payload, flacChunk->payloadSize);
-//logO << "Read end\n";
-// return FLAC__STREAM_DECODER_READ_STATUS_END_OF_STREAM;
- return result;
}
return FLAC__STREAM_DECODER_READ_STATUS_CONTINUE;
}
@@ -130,7 +128,6 @@ FLAC__StreamDecoderReadStatus read_callback(const FLAC__StreamDecoder *decoder,
FLAC__StreamDecoderWriteStatus write_callback(const FLAC__StreamDecoder *decoder, const FLAC__Frame *frame, const FLAC__int32 * const buffer[], void *client_data)
{
-//logO << "Write start\n";
(void)decoder;
/* if(channels != 2 || bps != 16) {
@@ -141,30 +138,34 @@ FLAC__StreamDecoderWriteStatus write_callback(const FLAC__StreamDecoder *decoder
fprintf(stderr, "ERROR: This frame contains %d channels (should be 2)\n", frame->header.channels);
return FLAC__STREAM_DECODER_WRITE_STATUS_ABORT;
}
-*/ if(buffer [0] == NULL) {
- fprintf(stderr, "ERROR: buffer [0] is NULL\n");
+*/ if (buffer[0] == NULL)
+ {
+ logS(kLogErr) << "ERROR: buffer [0] is NULL\n";
return FLAC__STREAM_DECODER_WRITE_STATUS_ABORT;
}
- if(buffer [1] == NULL) {
- fprintf(stderr, "ERROR: buffer [1] is NULL\n");
+
+ if (buffer[1] == NULL)
+ {
+ logS(kLogErr) << "ERROR: buffer [1] is NULL\n";
return FLAC__STREAM_DECODER_WRITE_STATUS_ABORT;
}
if (pcmChunk != NULL)
{
+//TODO: hard coded to 2 channels, 16 bit
size_t bytes = frame->header.blocksize * 4;
-//logO << "blocksize: " << frame->header.blocksize << "\tframe_number: " << frame->header.number.frame_number << "\tsample_number: " << frame->header.number.sample_number << "\n";
-//logO << "Write: " << bytes << "\tpayloadSize: " << pcmChunk->payloadSize + bytes << "\n";
-//flacChunk->payloadSize = 0;
+
+ if (((FlacDecoder*)client_data)->cacheInfo_.isCachedChunk_)
+ ((FlacDecoder*)client_data)->cacheInfo_.cachedBlocks_ += frame->header.blocksize;
+
pcmChunk->payload = (char*)realloc(pcmChunk->payload, pcmChunk->payloadSize + bytes);
- for(size_t i = 0; i < frame->header.blocksize; i++)
+ for(size_t i = 0; i < frame->header.blocksize; i++)
{
memcpy(pcmChunk->payload + pcmChunk->payloadSize + 4*i, (char*)(buffer[0] + i), 2);
memcpy(pcmChunk->payload + pcmChunk->payloadSize + 4*i+2, (char*)(buffer[1] + i), 2);
}
pcmChunk->payloadSize += bytes;
-//logO << "Write end: " << flacChunk->payloadSize << "\n";
}
return FLAC__STREAM_DECODER_WRITE_STATUS_CONTINUE;
@@ -173,11 +174,11 @@ FLAC__StreamDecoderWriteStatus write_callback(const FLAC__StreamDecoder *decoder
void metadata_callback(const FLAC__StreamDecoder *decoder, const FLAC__StreamMetadata *metadata, void *client_data)
{
- (void)decoder, (void)client_data;
-
+ (void)decoder;
/* print some stats */
- if(metadata->type == FLAC__METADATA_TYPE_STREAMINFO)
+ if(metadata->type == FLAC__METADATA_TYPE_STREAMINFO)
{
+ ((FlacDecoder*)client_data)->cacheInfo_.sampleRate_ = metadata->data.stream_info.sample_rate;
logO << "sample rate : " << metadata->data.stream_info.sample_rate << "Hz\n";
logO << "channels : " << metadata->data.stream_info.channels << "\n";
logO << "bits per sample: " << metadata->data.stream_info.bits_per_sample << "\n";
@@ -188,7 +189,7 @@ void metadata_callback(const FLAC__StreamDecoder *decoder, const FLAC__StreamMet
void error_callback(const FLAC__StreamDecoder *decoder, FLAC__StreamDecoderErrorStatus status, void *client_data)
{
(void)decoder, (void)client_data;
- fprintf(stderr, "Got error callback: %s\n", FLAC__StreamDecoderErrorStatusString[status]);
+ logS(kLogErr) << "Got error callback: " << FLAC__StreamDecoderErrorStatusString[status] << "\n";
}
diff --git a/client/decoder/flacDecoder.h b/client/decoder/flacDecoder.h
index 4e7b0849..fef88bac 100644
--- a/client/decoder/flacDecoder.h
+++ b/client/decoder/flacDecoder.h
@@ -18,8 +18,27 @@
#ifndef FLAC_DECODER_H
#define FLAC_DECODER_H
+
#include "decoder.h"
+struct CacheInfo
+{
+ CacheInfo() : sampleRate_(0)
+ {
+ reset();
+ }
+
+ void reset()
+ {
+ isCachedChunk_ = true;
+ cachedBlocks_ = 0;
+ }
+
+ bool isCachedChunk_;
+ size_t cachedBlocks_;
+ size_t sampleRate_;
+};
+
class FlacDecoder : public Decoder
{
@@ -28,6 +47,8 @@ public:
virtual ~FlacDecoder();
virtual bool decode(msg::PcmChunk* chunk);
virtual bool setHeader(msg::Header* chunk);
+
+ CacheInfo cacheInfo_;
};
diff --git a/message/message.h b/message/message.h
index 2ad84873..5eec0046 100644
--- a/message/message.h
+++ b/message/message.h
@@ -97,21 +97,12 @@ struct tv
tv result(*this);
result.sec -= other.sec;
result.usec -= other.usec;
- if (result.usec > 0)
+ while (result.usec < 0)
{
- result.sec += 1;
- result.usec = 1000000 - result.usec;
+ result.sec -= 1;
+ result.usec += 1000000;
}
- else if (result.usec < 0)
- {
- result.usec *= -1;
- }
- /* else if (result.usec >= 1000000)
- {
- result.usec -= 1000000;
- result.sec += 1;
- }
- */ return result;
+ return result;
}
};
diff --git a/server/controlServer.cpp b/server/controlServer.cpp
index 574d550a..2f8a05a7 100644
--- a/server/controlServer.cpp
+++ b/server/controlServer.cpp
@@ -104,6 +104,7 @@ void ControlServer::handleAccept(socket_ptr socket)
tv.tv_usec = 0;
setsockopt(socket->native(), SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof(tv));
setsockopt(socket->native(), SOL_SOCKET, SO_SNDTIMEO, &tv, sizeof(tv));
+// socket->set_option(boost::asio::ip::tcp::no_delay(false));
logS(kLogNotice) << "ControlServer::NewConnection: " << socket->remote_endpoint().address().to_string() << endl;
shared_ptr session = make_shared(this, socket);
{