diff --git a/client/Makefile b/client/Makefile index 1864ebc0..8e6a59f1 100644 --- a/client/Makefile +++ b/client/Makefile @@ -3,7 +3,7 @@ CC = /usr/bin/g++ CFLAGS = -std=gnu++0x -Wall -Wno-unused-function -O3 -D_REENTRANT -DVERSION=\"$(VERSION)\" -I.. LDFLAGS = -lrt -lpthread -lportaudio -lboost_system -lboost_program_options -lasound -OBJ = snapClient.o stream.o ../common/chunk.o ../common/log.o ../common/sampleFormat.o +OBJ = snapClient.o stream.o player.o receiver.o ../common/chunk.o ../common/log.o ../common/sampleFormat.o BIN = snapclient all: client diff --git a/client/player.cpp b/client/player.cpp new file mode 100644 index 00000000..669baf64 --- /dev/null +++ b/client/player.cpp @@ -0,0 +1,122 @@ +#include "player.h" +#include +#include + +#define PCM_DEVICE "default" + +using namespace std; + + +Player::Player(Stream* stream) : active_(false), stream_(stream) +{ +} + + +void Player::start() +{ + unsigned int pcm, tmp, rate; + int channels; + snd_pcm_hw_params_t *params; + int buff_size; + + rate = stream_->format.rate; + channels = stream_->format.channels; + + + /* Open the PCM device in playback mode */ + if ((pcm = snd_pcm_open(&pcm_handle, PCM_DEVICE, SND_PCM_STREAM_PLAYBACK, 0)) < 0) + cout << "ERROR: Can't open " << PCM_DEVICE << " PCM device. " << snd_strerror(pcm) << "\n"; + +/* struct snd_pcm_playback_info_t pinfo; + if ( (pcm = snd_pcm_playback_info( pcm_handle, &pinfo )) < 0 ) + fprintf( stderr, "Error: playback info error: %s\n", snd_strerror( err ) ); + printf("buffer: '%d'\n", pinfo.buffer_size); +*/ + /* Allocate parameters object and fill it with default values*/ + snd_pcm_hw_params_alloca(¶ms); + + snd_pcm_hw_params_any(pcm_handle, params); + + /* Set parameters */ + if ((pcm = snd_pcm_hw_params_set_access(pcm_handle, params, SND_PCM_ACCESS_RW_INTERLEAVED)) < 0) + cout << "ERROR: Can't set interleaved mode. " << snd_strerror(pcm) << "\n"; + + if ((pcm = snd_pcm_hw_params_set_format(pcm_handle, params, SND_PCM_FORMAT_S16_LE)) < 0) + cout << "ERROR: Can't set format. " << snd_strerror(pcm) << "\n"; + + if ((pcm = snd_pcm_hw_params_set_channels(pcm_handle, params, channels)) < 0) + cout << "ERROR: Can't set channels number. " << snd_strerror(pcm) << "\n"; + + if ((pcm = snd_pcm_hw_params_set_rate_near(pcm_handle, params, &rate, 0)) < 0) + cout << "ERROR: Can't set rate. " << snd_strerror(pcm) << "\n"; + + long unsigned int periodsize = 2*rate/50; + if ((pcm = snd_pcm_hw_params_set_buffer_size_near(pcm_handle, params, &periodsize)) < 0) + cout << "Unable to set buffer size " << (long int)periodsize << ": " << snd_strerror(pcm) << "\n"; + + /* Write parameters */ + if ((pcm = snd_pcm_hw_params(pcm_handle, params)) < 0) + cout << "ERROR: Can't set harware parameters. " << snd_strerror(pcm) << "\n"; + + /* Resume information */ + cout << "PCM name: " << snd_pcm_name(pcm_handle) << "\n"; + + cout << "PCM state: " << snd_pcm_state_name(snd_pcm_state(pcm_handle)) << "\n"; + + snd_pcm_hw_params_get_channels(params, &tmp); + cout << "channels: " << tmp << "\n"; + + if (tmp == 1) + printf("(mono)\n"); + else if (tmp == 2) + printf("(stereo)\n"); + + snd_pcm_hw_params_get_rate(params, &tmp, 0); + cout << "rate: " << tmp << " bps\n"; + + /* Allocate buffer to hold single period */ + snd_pcm_hw_params_get_period_size(params, &frames, 0); + cout << "frames: " << frames << "\n"; + + buff_size = frames * channels * 2 /* 2 -> sample size */; + buff = (char *) malloc(buff_size); + + snd_pcm_hw_params_get_period_time(params, &tmp, NULL); + cout << "period time: " << tmp << "\n"; + + playerThread = new thread(&Player::worker, this); +} + + +void Player::stop() +{ + active_ = false; +} + + +void Player::worker() +{ + unsigned int pcm; + active_ = true; + while (active_) + { + snd_pcm_sframes_t avail; + snd_pcm_sframes_t delay; + snd_pcm_avail_delay(pcm_handle, &avail, &delay); + + stream_->getPlayerChunk(buff, (float)delay / stream_->format.msRate(), frames); + + if ((pcm = snd_pcm_writei(pcm_handle, buff, frames)) == -EPIPE) { + printf("XRUN.\n"); + snd_pcm_prepare(pcm_handle); + } else if (pcm < 0) { + printf("ERROR. Can't write to PCM device. %s\n", snd_strerror(pcm)); + } + } + + snd_pcm_drain(pcm_handle); + snd_pcm_close(pcm_handle); + free(buff); +} + + diff --git a/client/player.h b/client/player.h new file mode 100644 index 00000000..3db37f51 --- /dev/null +++ b/client/player.h @@ -0,0 +1,30 @@ +#ifndef PLAYER_H +#define PLAYER_H + +#include +#include +#include +#include +#include "stream.h" + + +class Player +{ +public: + Player(Stream* stream); + void start(); + void stop(); + +private: + void worker(); + snd_pcm_t* pcm_handle; + snd_pcm_uframes_t frames; + char *buff; + std::atomic active_; + Stream* stream_; + std::thread* playerThread; +}; + + +#endif + diff --git a/client/receiver.cpp b/client/receiver.cpp new file mode 100644 index 00000000..95c70543 --- /dev/null +++ b/client/receiver.cpp @@ -0,0 +1,81 @@ +#include "receiver.h" +#include +#include +#include "common/log.h" + + +#define PCM_DEVICE "default" + +using namespace std; + + +Receiver::Receiver(Stream* stream) : active_(false), stream_(stream) +{ +} + + +void Receiver::socketRead(tcp::socket* socket, void* to, size_t bytes) +{ + size_t toRead = bytes; + size_t len = 0; + do + { + len += socket->read_some(boost::asio::buffer((char*)to + len, toRead)); + toRead = bytes - len; + } + while (toRead > 0); +} + + +void Receiver::start(const std::string& ip, int port) +{ + tcp::resolver resolver(io_service); + tcp::resolver::query query(tcp::v4(), ip, boost::lexical_cast(port)); + iterator = resolver.resolve(query); + receiverThread = new thread(&Receiver::worker, this); +} + + +void Receiver::stop() +{ + active_ = false; +} + + +void Receiver::worker() +{ + active_ = true; + while (active_) + { + try + { + tcp::socket s(io_service); + s.connect(*iterator); + struct timeval tv; + tv.tv_sec = 5; + tv.tv_usec = 0; + setsockopt(s.native(), SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof(tv)); + +// std::clog << kLogNotice << "connected to " << ip << ":" << port << std::endl; + while (true) + { + WireChunk* wireChunk = new WireChunk(); + socketRead(&s, wireChunk, Chunk::getHeaderSize()); +//cout << "WireChunk length: " << wireChunk->length << ", sec: " << wireChunk->tv_sec << ", usec: " << wireChunk->tv_usec << "\n"; + wireChunk->payload = (char*)malloc(wireChunk->length); + socketRead(&s, wireChunk->payload, wireChunk->length); + + stream_->addChunk(new Chunk(stream_->format, wireChunk)); + } + } + catch (const std::exception& e) + { + cout << kLogNotice << "Exception: " << e.what() << ", trying to reconnect" << std::endl; + stream_->clearChunks(); + usleep(500*1000); + } + } +} + + + diff --git a/client/receiver.h b/client/receiver.h new file mode 100644 index 00000000..36a2dac7 --- /dev/null +++ b/client/receiver.h @@ -0,0 +1,32 @@ +#ifndef RECEIVER_H +#define RECEIVER_H + +#include +#include +#include +#include +#include "stream.h" + +using boost::asio::ip::tcp; + + +class Receiver +{ +public: + Receiver(Stream* stream); + void start(const std::string& ip, int port); + void stop(); + +private: + void socketRead(tcp::socket* socket, void* to, size_t bytes); + void worker(); + boost::asio::io_service io_service; + tcp::resolver::iterator iterator; + std::atomic active_; + Stream* stream_; + std::thread* receiverThread; +}; + + +#endif + diff --git a/client/snapClient.cpp b/client/snapClient.cpp index 6323024c..e5749e23 100644 --- a/client/snapClient.cpp +++ b/client/snapClient.cpp @@ -13,299 +13,28 @@ #include #include #include -#include -#include #include #include -#include #include "common/sampleFormat.h" #include "common/chunk.h" #include "common/utils.h" #include "common/log.h" #include "stream.h" +#include "player.h" +#include "receiver.h" + + -using boost::asio::ip::tcp; using namespace std; namespace po = boost::program_options; -int deviceIdx; -Stream* stream; - -#define PCM_DEVICE "default" - - -void socketRead(tcp::socket* socket, void* to, size_t bytes) -{ - size_t toRead = bytes; - size_t len = 0; - do - { - len += socket->read_some(boost::asio::buffer((char*)to + len, toRead)); - toRead = bytes - len; - } - while (toRead > 0); -} - - - -void receiver(const SampleFormat& format, const std::string& ip, int port) -{ - try - { - boost::asio::io_service io_service; - tcp::resolver resolver(io_service); - tcp::resolver::query query(tcp::v4(), ip, boost::lexical_cast(port)); - tcp::resolver::iterator iterator = resolver.resolve(query); - - while (true) - { - try - { - tcp::socket s(io_service); - s.connect(*iterator); - struct timeval tv; - tv.tv_sec = 5; - tv.tv_usec = 0; - setsockopt(s.native(), SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof(tv)); - - std::clog << kLogNotice << "connected to " << ip << ":" << port << std::endl; - while (true) - { - WireChunk* wireChunk = new WireChunk(); - socketRead(&s, wireChunk, Chunk::getHeaderSize()); -// cout << "WireChunk length: " << wireChunk->length << ", sec: " << wireChunk->tv_sec << ", usec: " << wireChunk->tv_usec << "\n"; - wireChunk->payload = (char*)malloc(wireChunk->length); - socketRead(&s, wireChunk->payload, wireChunk->length); - - stream->addChunk(new Chunk(format, wireChunk)); - } - } - catch (const std::exception& e) - { - std::clog << kLogNotice << "Exception: " << e.what() << ", trying to reconnect" << std::endl; - stream->clearChunks(); - usleep(500*1000); - } - } - } - catch (const std::exception& e) - { - std::clog << kLogNotice << "Exception: " << e.what() << std::endl; - } -} - - -void player(Stream* stream) -{ - unsigned int pcm, tmp, rate; - int channels; - snd_pcm_t *pcm_handle; - snd_pcm_hw_params_t *params; - snd_pcm_uframes_t frames; - char *buff; - int buff_size; - - rate = stream->format.rate; - channels = stream->format.channels; - - - /* Open the PCM device in playback mode */ - if ((pcm = snd_pcm_open(&pcm_handle, PCM_DEVICE, SND_PCM_STREAM_PLAYBACK, 0)) < 0) - cout << "ERROR: Can't open " << PCM_DEVICE << " PCM device. " << snd_strerror(pcm) << "\n"; - -/* struct snd_pcm_playback_info_t pinfo; - if ( (pcm = snd_pcm_playback_info( pcm_handle, &pinfo )) < 0 ) - fprintf( stderr, "Error: playback info error: %s\n", snd_strerror( err ) ); - printf("buffer: '%d'\n", pinfo.buffer_size); -*/ - /* Allocate parameters object and fill it with default values*/ - snd_pcm_hw_params_alloca(¶ms); - - snd_pcm_hw_params_any(pcm_handle, params); - - /* Set parameters */ - if ((pcm = snd_pcm_hw_params_set_access(pcm_handle, params, SND_PCM_ACCESS_RW_INTERLEAVED)) < 0) - cout << "ERROR: Can't set interleaved mode. " << snd_strerror(pcm) << "\n"; - - if ((pcm = snd_pcm_hw_params_set_format(pcm_handle, params, SND_PCM_FORMAT_S16_LE)) < 0) - cout << "ERROR: Can't set format. " << snd_strerror(pcm) << "\n"; - - if ((pcm = snd_pcm_hw_params_set_channels(pcm_handle, params, channels)) < 0) - cout << "ERROR: Can't set channels number. " << snd_strerror(pcm) << "\n"; - - if ((pcm = snd_pcm_hw_params_set_rate_near(pcm_handle, params, &rate, 0)) < 0) - cout << "ERROR: Can't set rate. " << snd_strerror(pcm) << "\n"; - - long unsigned int periodsize = 2*rate / 50; - if ((pcm = snd_pcm_hw_params_set_buffer_size_near(pcm_handle, params, &periodsize)) < 0) - cout << "Unable to set buffer size " << (long int)periodsize << ": " << snd_strerror(pcm) << "\n"; - - /* Write parameters */ - if ((pcm = snd_pcm_hw_params(pcm_handle, params)) < 0) - cout << "ERROR: Can't set harware parameters. " << snd_strerror(pcm) << "\n"; - - /* Resume information */ - cout << "PCM name: " << snd_pcm_name(pcm_handle) << "\n"; - - cout << "PCM state: " << snd_pcm_state_name(snd_pcm_state(pcm_handle)) << "\n"; - - snd_pcm_hw_params_get_channels(params, &tmp); - cout << "channels: " << tmp << "\n"; - - if (tmp == 1) - printf("(mono)\n"); - else if (tmp == 2) - printf("(stereo)\n"); - - snd_pcm_hw_params_get_rate(params, &tmp, 0); - cout << "rate: " << tmp << " bps\n"; - - /* Allocate buffer to hold single period */ - snd_pcm_hw_params_get_period_size(params, &frames, 0); - cout << "frames: " << frames << "\n"; - - buff_size = frames * channels * 2 /* 2 -> sample size */; - buff = (char *) malloc(buff_size); - - snd_pcm_hw_params_get_period_time(params, &tmp, NULL); - cout << "period time: " << tmp << "\n"; - - while (true) - { -/* if (pcm = read(0, buff, buff_size) == 0) { - printf("Early end of file.\n"); - return 0; - } -*/ - snd_pcm_sframes_t avail; - snd_pcm_sframes_t delay; - snd_pcm_avail_delay(pcm_handle, &avail, &delay); - - stream->getPlayerChunk(buff, (float)delay / stream->format.msRate(), frames); - - if ((pcm = snd_pcm_writei(pcm_handle, buff, frames)) == -EPIPE) { - printf("XRUN.\n"); - snd_pcm_prepare(pcm_handle); - } else if (pcm < 0) { - printf("ERROR. Can't write to PCM device. %s\n", snd_strerror(pcm)); - } - } - - snd_pcm_drain(pcm_handle); - snd_pcm_close(pcm_handle); - free(buff); -} - - -/* This routine will be called by the PortAudio engine when audio is needed. -** It may called at interrupt level on some machines so don't do anything -** that could mess up the system like calling malloc() or free(). -*/ -static int paStreamCallback( const void *inputBuffer, void *outputBuffer, - unsigned long framesPerBuffer, - const PaStreamCallbackTimeInfo* timeInfo, - PaStreamCallbackFlags statusFlags, - void *userData ) -{ -//cout << "paStreamCallback: " << statusFlags << ", currentTime: " << timeInfo->currentTime << ", out: " << timeInfo->outputBufferDacTime << "\n"; - Stream* stream = (Stream*)userData; - short* out = (short*)outputBuffer; - - (void) timeInfo; /* Prevent unused variable warnings. */ - (void) statusFlags; - (void) inputBuffer; - - stream->getPlayerChunk(out, timeInfo->outputBufferDacTime, framesPerBuffer); - return paContinue; -} - - - -PaStream* initAudio(PaError& err, uint16_t sampleRate, short channels, uint16_t bps) -{ - PaStreamParameters outputParameters; - PaStream *paStream = NULL; -// printf("PortAudio Test: output sine wave. SR = %d, BufSize = %d\n", SAMPLE_RATE, FRAMES_PER_BUFFER); - - err = Pa_Initialize(); - if( err != paNoError ) goto error; - - int numDevices; - numDevices = Pa_GetDeviceCount(); - if( numDevices < 0 ) - { - printf( "ERROR: Pa_CountDevices returned 0x%x\n", numDevices ); - err = numDevices; - goto error; - } - const PaDeviceInfo *deviceInfo; - for(int i=0; iname << "\n"; - } - - outputParameters.device = deviceIdx==-1?Pa_GetDefaultOutputDevice():deviceIdx; /* default output device */ - std::cerr << "Using Device: " << outputParameters.device << "\n"; - if (outputParameters.device == paNoDevice) - { - fprintf(stderr,"Error: No default output device.\n"); - goto error; - } - outputParameters.channelCount = channels; /* stereo output */ - if (bps == 16) - outputParameters.sampleFormat = paInt16; /* 32 bit floating point output */ - else if (bps == 8) - outputParameters.sampleFormat = paUInt8; /* 32 bit floating point output */ - else if (bps == 32) - outputParameters.sampleFormat = paInt32; /* 32 bit floating point output */ - else if (bps == 24) - outputParameters.sampleFormat = paInt24; /* 32 bit floating point output */ - - outputParameters.suggestedLatency = Pa_GetDeviceInfo( outputParameters.device )->defaultHighOutputLatency; - outputParameters.hostApiSpecificStreamInfo = NULL; - std::cerr << "HighLatency: " << outputParameters.suggestedLatency << "\t LowLatency: " << Pa_GetDeviceInfo( outputParameters.device )->defaultLowOutputLatency << "\n"; - err = Pa_OpenStream( - &paStream, - NULL, /* no input */ - &outputParameters, - sampleRate, - paFramesPerBufferUnspecified, //FRAMES_PER_BUFFER, - paClipOff, /* we won't output out of range samples so don't bother clipping them */ - paStreamCallback, - stream ); - if( err != paNoError ) goto error; - - - err = Pa_StartStream( paStream ); - cout << "Latency: " << Pa_GetStreamInfo(paStream)->outputLatency << "\n"; - if( err != paNoError ) goto error; - -// err = Pa_StopStream( paStream ); -// if( err != paNoError ) goto error; - -// err = Pa_CloseStream( paStream ); -// if( err != paNoError ) goto error; - -// Pa_Terminate(); -// printf("Test finished.\n"); - - return paStream; -error: - Pa_Terminate(); - fprintf( stderr, "An error occured while using the portaudio stream\n" ); - fprintf( stderr, "Error number: %d\n", err ); - fprintf( stderr, "Error message: %s\n", Pa_GetErrorText( err ) ); - return paStream; -} - - - int main (int argc, char *argv[]) { + int deviceIdx; + Stream* stream; string ip; int bufferMs; size_t port; @@ -341,15 +70,15 @@ int main (int argc, char *argv[]) stream = new Stream(SampleFormat(sampleFormat)); stream->setBufferLen(bufferMs); -// PaError paError; -// PaStream* paStream = initAudio(paError, sampleRate, channels, bps); -// stream->setLatency(1000*Pa_GetStreamInfo(paStream)->outputLatency); - std::thread receiverThread(receiver, stream->format, ip, port); - std::thread playerThread(player, stream); + Player player(stream); + player.start(); + Receiver receiver(stream); + receiver.start(ip, port); + + while(true) + usleep(1000); - playerThread.join(); - return 0; } diff --git a/client/stream.cpp b/client/stream.cpp index cc2760d5..3e36c2bd 100644 --- a/client/stream.cpp +++ b/client/stream.cpp @@ -35,8 +35,8 @@ void Stream::addChunk(Chunk* chunk) { while (chunks.size() * chunk->getDuration() > 10000) chunks.pop(); -// cout << "new chunk: " << chunk->getDuration() << ", Chunks: " << chunks.size() << "\n"; chunks.push(shared_ptr(chunk)); +// cout << "new chunk: " << chunk->getDuration() << ", Chunks: " << chunks.size() << "\n"; } @@ -118,7 +118,7 @@ void Stream::getPlayerChunk(void* outputBuffer, double outputBufferDacTime, unsi { //cout << "framesPerBuffer: " << framesPerBuffer << "\tms: " << framesPerBuffer*2 / PLAYER_CHUNK_MS_SIZE << "\t" << PLAYER_CHUNK_SIZE << "\n"; //int msBuffer = framesPerBuffer / (format_.rate/1000); -//cout << msBuffer << " ms, " << framesPerBuffer << "\t" << hz_/1000 << "\n"; +//cout << msBuffer << " ms, " << framesPerBuffer << "\t" << format_.rate/1000 << "\n"; int ticks = 0; long currentTick = getTickCount(); if (lastTick == 0) diff --git a/common/chunk.cpp b/common/chunk.cpp index 32952c14..de31c13d 100644 --- a/common/chunk.cpp +++ b/common/chunk.cpp @@ -4,13 +4,14 @@ #include "common/log.h" -Chunk::Chunk(const SampleFormat& sampleFormat, WireChunk* _wireChunk) : wireChunk(_wireChunk), format(format_), format_(sampleFormat), idx(0) +Chunk::Chunk(const SampleFormat& sampleFormat, WireChunk* _wireChunk) : wireChunk(_wireChunk), format(sampleFormat), idx(0) { } -Chunk::Chunk(const SampleFormat& sampleFormat, size_t ms) : format(format_), format_(sampleFormat), idx(0) +Chunk::Chunk(const SampleFormat& sampleFormat, size_t ms) : format(sampleFormat), idx(0) { +// format = sampleFormat; wireChunk = new WireChunk; wireChunk->length = format.rate*format.frameSize*ms / 1000; wireChunk->payload = (char*)malloc(wireChunk->length); @@ -33,6 +34,7 @@ bool Chunk::isEndOfChunk() const double Chunk::getDuration() const { +// std::cout << wireChunk->length << "\t" << format.frameSize << "\t" << (wireChunk->length / format.frameSize) << "\t" << ((double)format.rate / 1000.) << "\n"; return (wireChunk->length / format.frameSize) / ((double)format.rate / 1000.); } diff --git a/common/chunk.h b/common/chunk.h index 68ec7611..28f727c2 100644 --- a/common/chunk.h +++ b/common/chunk.h @@ -70,10 +70,10 @@ public: double getDuration() const; WireChunk* wireChunk; - const SampleFormat& format; + SampleFormat format; private: - SampleFormat format_; +// SampleFormat format_; uint32_t idx; }; diff --git a/common/sampleFormat.cpp b/common/sampleFormat.cpp index a4c28eeb..9c1cbe89 100644 --- a/common/sampleFormat.cpp +++ b/common/sampleFormat.cpp @@ -5,13 +5,13 @@ #include -SampleFormat::SampleFormat(const std::string& format) : rate(rate_), bits(bits_), channels(channels_), sampleSize(bytes_), frameSize(frameSize_) +SampleFormat::SampleFormat(const std::string& format) //: rate(rate_), bits(bits_), channels(channels_), sampleSize(bytes_), frameSize(frameSize_) { setFormat(format); } -SampleFormat::SampleFormat(uint16_t sampleRate, uint16_t bitsPerSample, uint16_t channelCount) : rate(rate_), bits(bits_), channels(channels_), sampleSize(bytes_), frameSize(frameSize_) +SampleFormat::SampleFormat(uint16_t sampleRate, uint16_t bitsPerSample, uint16_t channelCount) //: rate(rate_), bits(bits_), channels(channels_), sampleSize(bytes_), frameSize(frameSize_) { setFormat(sampleRate, bitsPerSample, channelCount); } @@ -31,13 +31,13 @@ void SampleFormat::setFormat(const std::string& format) void SampleFormat::setFormat(uint16_t rate, uint16_t bits, uint16_t channels) { - rate_ = rate; - bits_ = bits; - bytes_ = bits / 8; - channels_ = channels; - if (bits_ == 24) - bytes_ = 4; - frameSize_ = channels_*bytes_; + this->rate = rate; + this->bits = bits; + this->channels = channels; + sampleSize = bits / 8; + if (bits == 24) + sampleSize = 4; + frameSize = channels*sampleSize; } diff --git a/common/sampleFormat.h b/common/sampleFormat.h index 184909d7..01cfc146 100644 --- a/common/sampleFormat.h +++ b/common/sampleFormat.h @@ -1,5 +1,5 @@ -#ifndef SAMPLE_FORMAT -#define SAMPLE_FORMAT +#ifndef SAMPLE_FORMAT_H +#define SAMPLE_FORMAT_H #include @@ -9,26 +9,27 @@ class SampleFormat public: SampleFormat(); SampleFormat(const std::string& format); - SampleFormat(uint16_t rate = 48000, uint16_t bits = 16, uint16_t channels = 2); + SampleFormat(uint16_t rate, uint16_t bits, uint16_t channels); void setFormat(const std::string& format); void setFormat(uint16_t rate, uint16_t bits, uint16_t channels); - const uint16_t& rate; - const uint16_t& bits; - const uint16_t& channels; + uint16_t rate; + uint16_t bits; + uint16_t channels; - const uint16_t& sampleSize; - const uint16_t& frameSize; + uint16_t sampleSize; + uint16_t frameSize; float msRate() const { return (float)rate/1000.f; } -private: +/*private: uint16_t rate_; uint16_t bits_; uint16_t channels_; uint16_t bytes_; uint16_t frameSize_; +*/ }; diff --git a/common/utils.h b/common/utils.h index de5a3f40..4a8f3366 100644 --- a/common/utils.h +++ b/common/utils.h @@ -9,6 +9,7 @@ #include #include #include +#include // trim from start