Commit 7fa3d0ff authored by jcacerec's avatar jcacerec
Browse files

portest4 to test binding to same socket

parent 1ff65215
/*
JackTrip: A Multimachine System for High-Quality Audio
Network Performance over the Internet
Copyright (c) 2008 Chris Chafe, Juan-Pablo Caceres,
SoundWIRE group at CCRMA.
Permission is hereby granted, free of charge, to any person
obtaining a copy of this software and associated documentation
files (the "Software"), to deal in the Software without
restriction, including without limitation the rights to use,
copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following
conditions:
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
OTHER DEALINGS IN THE SOFTWARE.
*/
/*
* stream.h
*/
#ifndef _STREAM_H
#define _STREAM_H
#include "circularbuffer.h"
#include "InputStreamPlugin.h"
#include "OutputStreamPlugin.h"
#include "process_plugin.h"
#include "audioInfo.h"
#include "networkInfo.h"
#include <QThread>
//#include "q3ptrvector.h"
#include <QVector>
/**
* @brief Connects an InputStreamPlugin to an OutputStreamPlugin with
* optional ProcessStreamPlugins processing the signal.
*/
/**
* Stream uses a CircularBuffer (a queue of audio buffers) under the hood. \n
* <img src="stream.jpg">
*/
class Stream
{
long lastPluckTime;
bool harp;
protected:
// Vector inputs;
//Q3PtrVector < InputStreamPlugin > ins;
QVector < InputStreamPlugin* > ins; //QT4 port
// Vector outputs;
//Q3PtrVector < OutputStreamPlugin > outs;
QVector < OutputStreamPlugin* > outs; //QT4 port
// Vector processes;
//Q3PtrVector < ProcessStreamPlugin > procs;
QVector < ProcessStreamPlugin* > procs; //QT4 port
// Vector circularBuffers;
//Q3PtrVector < CircularBuffer > bufs;
QVector < CircularBuffer* > bufs; //QT4 port
// Vector outputLocks;
//Q3PtrVector < QSemaphore >locks;
QVector < QSemaphore* >locks; //QT4 port
int insCount;
int procsCount;
int outsCount;
int locksCount;
int bufsCount;
int processesPerChan;
/** @brief Controls read access. No output is allowed
to read until the master output has read (set with
synchronizeOutputsTo.
*/
int outputSynchKey;
AudioInfoT audioInfo;
void addCircularBuffer();
public:
Stream(AudioInfo * info, NetworkInfo * netInfo, int numBuffers, bool block);
~Stream();
void addInput(InputStreamPlugin *newin);
void addOutput(OutputStreamPlugin *newout);
void synchronizeOutputsTo(OutputStreamPlugin *synchControlOutput);
void addProcess(ProcessStreamPlugin *newproc);
int read(void *buf, int key);
int tapRead(void *buf);
int write(const void *buf, int key);
int
writeRedundant (const void *buf, int key, int z, int seq);
void clear();
void startThreads();
void stopThreads();
bool threadsRunning;
};
#endif
/*
JackTrip: A Multimachine System for High-Quality Audio
Network Performance over the Internet
Copyright (c) 2008 Chris Chafe, Juan-Pablo Caceres,
SoundWIRE group at CCRMA.
Permission is hereby granted, free of charge, to any person
obtaining a copy of this software and associated documentation
files (the "Software"), to deal in the Software without
restriction, including without limitation the rights to use,
copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following
conditions:
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
OTHER DEALINGS IN THE SOFTWARE.
*/
/*
* StreamPlugin.cpp
*/
#include "StreamPlugin.h"
unsigned long StreamPlugin::usecTime ()
{
struct timeval tv;
gettimeofday (&tv, NULL);
return ((tv.tv_sec * 1000000) + (tv.tv_usec));
// was sec*1000 and usec/1000 for msec
}
char* StreamPlugin::getName ()
{
return name;
}
char* StreamPlugin::setName (const char *newName)
{
strncpy (name, newName, 23);
name[23] = '\0';
return name;
}
/*
JackTrip: A Multimachine System for High-Quality Audio
Network Performance over the Internet
Copyright (c) 2008 Chris Chafe, Juan-Pablo Caceres,
SoundWIRE group at CCRMA.
Permission is hereby granted, free of charge, to any person
obtaining a copy of this software and associated documentation
files (the "Software"), to deal in the Software without
restriction, including without limitation the rights to use,
copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following
conditions:
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
OTHER DEALINGS IN THE SOFTWARE.
*/
/*
* StreamPlugin.h
*
* @brief Basic properties of an audio plugin
*/
#ifndef _PLUGIN_H
#define _PLUGIN_H
#include <QThread>
// for plotting
#include <sys/time.h>
#include <QApplication>
class StreamPlugin : public QThread
{
public:
bool dontRun;
// for plotting
unsigned long usecTime (); // in usec
QObject * _rcvr;
//void setGUI(QObject * rcvr){_rcvr = rcvr;};
//virtual void plotVal (double v) = 0;
char* getName ();
char *setName (const char *newName);
protected:
char name[24]; //TODO: Make this better
};
#endif
/*
JackTrip: A Multimachine System for High-Quality Audio
Network Performance over the Internet
Copyright (c) 2008 Chris Chafe, Juan-Pablo Caceres,
SoundWIRE group at CCRMA.
Permission is hereby granted, free of charge, to any person
obtaining a copy of this software and associated documentation
files (the "Software"), to deal in the Software without
restriction, including without limitation the rights to use,
copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following
conditions:
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
OTHER DEALINGS IN THE SOFTWARE.
*/
/*
* audioConsts.h
*/
#ifndef _AUDIOCONSTS_H
#define _AUDIOCONSTS_H
#include <stdint.h>
typedef signed short INT16; /**< @brief Audio sample type. */
#endif
/*
JackTrip: A Multimachine System for High-Quality Audio
Network Performance over the Internet
Copyright (c) 2008 Chris Chafe, Juan-Pablo Caceres,
SoundWIRE group at CCRMA.
Permission is hereby granted, free of charge, to any person
obtaining a copy of this software and associated documentation
files (the "Software"), to deal in the Software without
restriction, including without limitation the rights to use,
copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following
conditions:
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
OTHER DEALINGS IN THE SOFTWARE.
*/
/*
* audioInfo.cpp
*/
#include "audioInfo.h"
#include <iostream>
AudioInfo::AudioInfo (int sampleRate, int bytesPerSample, int framesPerBuffer,
int numChans, int netChans, int secondsBetweenPlucks,
bool jack, clock_t * lastTick,
int jack_alsa_readable_offset ):
sampleRate (sampleRate),
bytesPerSample (bytesPerSample),
numChans (numChans),
netHarpStrings (netChans),
framesPerBuffer (framesPerBuffer),
secondsBetweenPlucks (secondsBetweenPlucks),
jack (jack),
jack_alsa_readable_offset (jack_alsa_readable_offset),
lastTickTime (lastTick)
{
}
AudioInfo::~AudioInfo ()
{
}
int
AudioInfo::getSampleRate ()
{
return (sampleRate);
}
int
AudioInfo::getBytesPerSample ()
{
return (bytesPerSample);
}
int
AudioInfo::getNumChans ()
{
if (getNumNetHarpStrings () > 0)
{
return (getNumNetHarpStrings ());
}
else
{
return (numChans);
}
}
int
AudioInfo::getFramesPerBuffer ()
{
return (framesPerBuffer);
}
void
AudioInfo::setFramesPerBuffer (int newFramesPerBuffer)
{
framesPerBuffer = newFramesPerBuffer;
}
int
AudioInfo::getBytesPerBuffer ()
{
return (getFramesPerBuffer () * getBytesPerSample () *
getNumChans ());
}
int
AudioInfo::getNumNetHarpStrings ()
{
return (netHarpStrings);
}
int
AudioInfo::getNumAudioChans ()
{
return (numChans);
}
int
AudioInfo::getSecondsBetweenPlucks ()
{
return (secondsBetweenPlucks);
}
int
AudioInfo::getJack_alsa_readable_offset()
{
return (jack_alsa_readable_offset);
}
bool AudioInfo::isJack ()
{
return (jack);
}
/*
JackTrip: A Multimachine System for High-Quality Audio
Network Performance over the Internet
Copyright (c) 2008 Chris Chafe, Juan-Pablo Caceres,
SoundWIRE group at CCRMA.
Permission is hereby granted, free of charge, to any person
obtaining a copy of this software and associated documentation
files (the "Software"), to deal in the Software without
restriction, including without limitation the rights to use,
copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following
conditions:
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
OTHER DEALINGS IN THE SOFTWARE.
*/
/*
* audioInfo.h
*/
#ifndef _AUDIO_INFO_H
#define _AUDIO_INFO_H
#include <ctime>
/**
* @brief Contains all information relevant to audio buffers.
*/
typedef class AudioInfo
{
private:
int sampleRate; //!< Audio sample rate (e.g. 44100).
int bytesPerSample; //!< Number of bytes per sample (e.g. INT16 = 2 bytes).
int numChans; //!< Number of audio channels.
int netHarpStrings; //!< Number of network channels (NetHarp strings).
int framesPerBuffer;//!< One frame is one sample from every channel.
int secondsBetweenPlucks; //!< Seconds to wait between plucks of the NetHarp.
public:
bool jack; //!< jack audio subsystem, otherwise RtAudio
int jack_alsa_readable_offset; //!< offset to alsa input lowest channel number.
/**
* @brief Constructor.
*
* @param sampleRate - Audio sample rate.
* @param bytesPerSample - sample byte depth.
* @param numChans - number of audio channels.
* @param netHarpStrings - number of strings for NetHarp.
* @param framesPerBuffer - number of audio frames per audio buffer.
* @param jack - using jack audio subsystem, otherwise RtAudio.
* @param jack_alsa_readable_offset - offset to alsa input lowest channel number.
*/
AudioInfo( int sampleRate, int bytesPerSample, int framesPerBuffer,
int numChans, int netHarpStrings, int secondsBetweenPlucks,
bool jack, clock_t *lastTick,
int jack_alsa_readable_offset );
~AudioInfo();
int getSampleRate();
int getBytesPerSample();
/**
* @brief Returns the number of channels in the audio buffers for streams: Mas( numAudioChannels, numNetHarpChannels).
*/
int getNumChans();
int getFramesPerBuffer();
void setFramesPerBuffer(int newFramesPerBuffer);
int getBytesPerBuffer();
int getNumNetHarpStrings();
int getNumAudioChans();
int getSecondsBetweenPlucks();
bool isJack();
clock_t *lastTickTime;
int getJack_alsa_readable_offset();
} *AudioInfoT;
#endif
/*
JackTrip: A Multimachine System for High-Quality Audio
Network Performance over the Internet
Copyright (c) 2008 Chris Chafe, Juan-Pablo Caceres,
SoundWIRE group at CCRMA.
Permission is hereby granted, free of charge, to any person
obtaining a copy of this software and associated documentation
files (the "Software"), to deal in the Software without
restriction, including without limitation the rights to use,
copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following
conditions:
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
OTHER DEALINGS IN THE SOFTWARE.
*/
/*
* circularbuffer.cpp
*
* The CircularBuffer provides numChunks of buffering.
* When created, it has (numChunks / 2) chunks of 0s.
* This provides tolerance for an offset of numChunks/2
* between the number of reads and writes.
*
* FIXME - It might be an idea to let the open threshold vary
* (asymmetric tolerance.) I don't really know...
*
* If read is called on an empty CircularBuffer, it is reset
* to its original state.
*
* If write is called on a full CircularBuffer, the readPosition is
* moved forward (numChunks / 2) and the write proceeds (the
* oldest numChunks/2 chunks are skipped).
*/
#include "circularbuffer.h"
#include <iostream>
#include <ctime>
using namespace std;
CircularBuffer::CircularBuffer (int chunkSize, int numChunks,
bool blockOnEmpty, int maxSeq):
writePosition (0),
readPosition (0),
blockOnEmpty (blockOnEmpty),
numBufChunks (numChunks),
numChunksFree (numChunks - 1),
chunkSize (chunkSize),
maxSeq (maxSeq)
{
cbBuffer = (void *) new char[chunkSize * numChunks];
seqBuffer = new int[numChunks];
for (int i = 0; i < numChunks; i++) seqBuffer[i] = -1;
lastSeq = -1;
if (cbBuffer == NULL)
cerr << "CircularBuffer Out Of Memory!" << endl;
prepareReaderWriter ();
dataLock = new QSemaphore (1);
//cout << (*dataLock).available() << endl;
secondTry = false;
}
CircularBuffer::CircularBuffer (CircularBuffer * copyMe):
writePosition (0), readPosition (0), isOpen (false)
{
chunkSize = copyMe->chunkSize;
numBufChunks = copyMe->numBufChunks;
numChunksFree = numBufChunks - 1;
blockOnEmpty = copyMe->blockOnEmpty;
cbBuffer = (void *) new char[chunkSize * numBufChunks];
if (cbBuffer == NULL)
cerr << "CircularBuffer Out Of Memory!" << endl;
prepareReaderWriter ();
dataLock = new QSemaphore (1);
}
CircularBuffer::~CircularBuffer ()
{
delete readSemaphore;
delete dataLock;
}
void
CircularBuffer::debugDump ()
{
cerr << "========================================" << endl;
cerr << "chunkSize=" << chunkSize << endl;
cerr << "numChunks=" << numBufChunks << endl;
cerr << "cbBuffer=" << cbBuffer << endl;
cerr << "readPosition=" << readPosition << endl;
cerr << "writePosition=" << writePosition << endl << endl;
}
int
CircularBuffer::write (const void *writeChunk)
{
if (isFull () == false)
{
memcpy ((void *) ((char *) cbBuffer +
writePosition * chunkSize), writeChunk,
chunkSize);
writePosition = ++writePosition % numBufChunks;
}
else