text:
// ffmpeg_player.cpp
// part of MusicPlayer, https://github.com/albertz/music-player
// Copyright (c) 2012, Albert Zeyer, www.az2000.de
// All rights reserved.
// This code is under the 2-clause BSD license, see License.txt in the root directory of this project.

#include "musicplayer.h"
#include "PyUtils.h"
#include "PythonHelpers.h"
#include "Py3Compat.h"

#include <stdio.h>
#include <string.h>
#include <boost/bind.hpp>

#define SAMPLERATE 44100
#define NUMCHANNELS 2

bool PlayerObject::getNextSong(bool skipped, bool maybeFade) {
	PlayerObject* player = this;

	// We must hold the player lock here.

	if(maybeFade) {
		InStreams::ItemPtr isptr = player->getInStream();
		if(isptr.get()) {
			PlayerInStream* is = &isptr->value;

			if(is->playerStartedPlaying && player->fader.sampleFactor() != 0) {
				// Let it fade out.
				player->fader.change(-1, player->outSamplerate, false);

				// Delay skip. The worker-proc will handle it.
				// This will also fade it in again.
				is->skipMe = true;
				return true;
			}
		}
	}

	if(skipped)
		outOfSync = true;

	while(pyQueueLock) {
		PyScopedUnlock unlock(this->lock);
		usleep(100);
	}
	pyQueueLock = true;

	bool ret = false;
	bool errorOnOpening = false;

	PyObject* oldSong = player->curSong;
	player->curSong = NULL;

	{
		PyScopedGIL gstate;

		if(player->queue == NULL) {
			PyErr_SetString(PyExc_RuntimeError, "player queue is not set");
			goto final;
		}

		// Note: No PyIter_Check because it adds CPython 2.7 ABI dependency when
		// using CPython 2.7 headers. Anyway, just calling PyIter_Next directly
		// is also ok since it will do the check itself.

		PyObject* newSong = PyIter_Next(player->queue);

		if(PyErr_Occurred()) { // pass through any Python errors
			Py_XDECREF(newSong);
			goto final;
		}

		if(!newSong) {
			PyErr_SetString(PyExc_RuntimeError, "player queue does not have more songs");
			goto final;
		}

		assert(newSong);
		player->curSong = newSong;
	}

	{
		if(player->openInStream())
			ret = true;
		else {
			// This is not fatal, so don't make a Python exception.
			// When we are in playing state, we will just skip to the next song.
			// This can happen if we don't support the format or whatever.
			printf("cannot open input stream\n");
			errorOnOpening = true;
		}
	}

	// make callback onSongChange
	if(player->dict) {
		PyScopedGIL gstate;

		PyObject* onSongChange = PyDict_GetItemString(player->dict, "onSongChange");
		if(onSongChange && onSongChange != Py_None) {
			PyObject* kwargs = PyDict_New();
			assert(kwargs);
			if(oldSong)
				PyDict_SetItemString(kwargs, "oldSong", oldSong);
			else
				PyDict_SetItemString(kwargs, "oldSong", Py_None);
			PyDict_SetItemString(kwargs, "newSong", player->curSong);
			PyDict_SetItemString_retain(kwargs, "skipped", PyBool_FromLong(skipped));
			PyDict_SetItemString_retain(kwargs, "errorOnOpening", PyBool_FromLong(errorOnOpening));

			PyObject* retObj = PyEval_CallObjectWithKeywords(onSongChange, NULL, kwargs);
			Py_XDECREF(retObj);

			// errors are not fatal from the callback, so handle it now and go on
			if(PyErr_Occurred()) {
				PyErr_Print(); // prints traceback to stderr, resets error indicator. also handles sys.excepthook if it is set (see pythonrun.c, it's not said explicitely in the docs)
			}

			Py_DECREF(kwargs);
		}
	}

final:
	{
		PyScopedGIL gstate;
		Py_XDECREF(oldSong);
	}

	pyQueueLock = false;

	if(ret && nextSongOnEof)
		openPeekInStreams();
	return ret;
}

static int player_setqueue(PlayerObject* player, PyObject* queue) {
	Py_XDECREF(player->queue);
	Py_INCREF((PyObject*)player);
	Py_BEGIN_ALLOW_THREADS
	{
		PyScopedLock lock(player->lock);
		player->queue = queue;
	}
	Py_END_ALLOW_THREADS
	Py_DECREF((PyObject*)player);
	Py_XINCREF(queue);
	return 0;
}

static int player_setpeekqueue(PlayerObject* player, PyObject* queue) {
	Py_XDECREF(player->peekQueue);
	Py_INCREF((PyObject*)player);
	Py_BEGIN_ALLOW_THREADS
	{
		PyScopedLock lock(player->lock);
		player->peekQueue = queue;
	}
	Py_END_ALLOW_THREADS
	Py_DECREF((PyObject*)player);
	Py_XINCREF(queue);
	return 0;
}

static
PyObject* player_new(PyTypeObject *subtype, PyObject *args, PyObject *kwds) {
	PlayerObject* player = (PlayerObject*) subtype->tp_alloc(subtype, 0);
	//printf("%p new\n", player);
	return (PyObject*)player;
}

static
PyObject* player_alloc(PyTypeObject *type, Py_ssize_t nitems) {
    PyObject *obj;
    const size_t size = _PyObject_VAR_SIZE(type, nitems+1);
    /* note that we need to add one, for the sentinel */

    if (PyType_IS_GC(type))
        obj = _PyObject_GC_Malloc(size);
    else
        obj = (PyObject *)PyObject_MALLOC(size);

    if (obj == NULL)
        return PyErr_NoMemory();

	// This is why we need this custom alloc: To call the C++ constructor.
    memset(obj, '\0', size);
	new ((PlayerObject*) obj) PlayerObject();

    if (type->tp_flags & Py_TPFLAGS_HEAPTYPE)
        Py_INCREF(type);

    if (type->tp_itemsize == 0)
        PyObject_INIT(obj, type);
    else
        (void) PyObject_INIT_VAR((PyVarObject *)obj, type, nitems);

    if (PyType_IS_GC(type))
        PyObject_GC_Track(obj); // _PyObject_GC_TRACK macro is not to be used for external modules
    return obj;
}

static
int player_init(PyObject* self, PyObject* args, PyObject* kwds) {
	PlayerObject* player = (PlayerObject*) self;
	//printf("%p player init\n", player);

	mlock(player, sizeof(*player));
	player->nextSongOnEof = 1;
	player->skipPyExceptions = 1;
	player->volumeAdjustEnabled = true;
	player->volume = 0.9f;
	player->volumeSmoothClip.setX(0.95f, 10.0f);
	player->soundcardOutputEnabled = true;
	player->outOfSync = true;

	player->openStreamLock = player->pyQueueLock = false;

	{
		// We have the Python GIL here. For setAudioTgt, we need the Player lock.
		// For performance reasons, just disable the lock and do it without locking.
		// This is safe because we have the only reference here.
		player->lock.enabled = false;
		player->setAudioTgt(SAMPLERATE, NUMCHANNELS);
		player->lock.enabled = true;
	}

	player->workerThread.func = boost::bind(&PlayerObject::workerProc, player, _1);

	return 0;
}

static
void player_dealloc(PyObject* obj) {
	PlayerObject* player = (PlayerObject*)obj;
	//printf("%p dealloc\n", player);

	// first, destroy any non-python threads
	Py_BEGIN_ALLOW_THREADS
	{
		player->workerThread.stop();
		player->outStream.reset();
	}
	Py_END_ALLOW_THREADS

	{
		// we don't need a lock because in dealloc, we have the only ref to this PlayerObject.
		// also, we must not lock it here because we cannot free inStream otherwise.

		player->inStreams.clear();

		Py_XDECREF(player->dict);
		player->dict = NULL;

		Py_XDECREF(player->curSong);
		player->curSong = NULL;

		Py_XDECREF(player->queue);
		player->queue = NULL;

		Py_XDECREF(player->peekQueue);
		player->peekQueue = NULL;
	}

	player->~PlayerObject();
	Py_TYPE(obj)->tp_free(obj);
}

void PlayerObject::setAudioTgt(int samplerate, int numchannels) {
	if(this->playing) return;

	// TODO: error checkking for samplerate or numchannels?
	// No idea how to check what libswresample supports.

	// see also player_setplaying where we init the PaStream (with same params)
	this->outSamplerate = samplerate;
	this->outNumChannels = numchannels;

	// reset the outstream (PortAudio). we must force a reopen.
	this->outStream.reset();

	// We must refill the buffers. The samplerate conversion will
	// happen on-the-fly in audio_decode_frame().
	this->resetBuffers();
}

static
PyObject* player_method_seekAbs(PyObject* self, PyObject* arg) {
	PlayerObject* player = (PlayerObject*) self;
	double argDouble = PyFloat_AsDouble(arg);
	if(PyErr_Occurred()) return NULL;
	Py_INCREF(self);
	Py_BEGIN_ALLOW_THREADS
	{
		PyScopedLock lock(player->lock);
		player->seekSong(argDouble, false);
	}
	Py_END_ALLOW_THREADS
	Py_DECREF(self);
	Py_INCREF(Py_None);
	return Py_None;
}

static PyMethodDef md_seekAbs = {
	"seekAbs",
	player_method_seekAbs,
	METH_O,
	NULL
};

static
PyObject* player_method_seekRel(PyObject* self, PyObject* arg) {
	PlayerObject* player = (PlayerObject*) self;
	double argDouble = PyFloat_AsDouble(arg);
	if(PyErr_Occurred()) return NULL;
	Py_INCREF(self);
	Py_BEGIN_ALLOW_THREADS
	{
		PyScopedLock lock(player->lock);
		player->seekSong(argDouble, true);
	}
	Py_END_ALLOW_THREADS
	Py_DECREF(self);
	Py_INCREF(Py_None);
	return Py_None;
}

static PyMethodDef md_seekRel = {
	"seekRel",
	player_method_seekRel,
	METH_O,
	NULL
};

static
PyObject* player_method_nextSong(PyObject* self, PyObject* _unused_arg) {
	PlayerObject* player = (PlayerObject*) self;
	bool ret = false;
	Py_INCREF(self);
	Py_BEGIN_ALLOW_THREADS
	{
		PyScopedLock lock(player->lock);
		ret = player->getNextSong(true, true);
	}
	Py_END_ALLOW_THREADS
	Py_DECREF(self);
	if(PyErr_Occurred()) return NULL;
	return PyBool_FromLong(ret);
}

static PyMethodDef md_nextSong = {
	"nextSong",
	player_method_nextSong,
	METH_NOARGS,
	NULL
};

static
PyObject* player_method_reloadPeekStreams(PyObject* self, PyObject* _unused_arg) {
	PlayerObject* player = (PlayerObject*) self;
	Py_INCREF(self);
	Py_BEGIN_ALLOW_THREADS
	{
		PyScopedLock lock(player->lock);
		player->openPeekInStreams();
	}
	Py_END_ALLOW_THREADS
	Py_DECREF(self);
	if(PyErr_Occurred())
		// we will consume and handle any error here.
		// player.reloadPeekStreams should not raise any exceptions.
		PyErr_Print();
	Py_INCREF(Py_None);
	return Py_None;
}

static PyMethodDef md_reloadPeekStreams = {
	"reloadPeekStreams",
	player_method_reloadPeekStreams,
	METH_NOARGS,
	NULL
};

static
PyObject* player_method_startWorkerThread(PyObject* self, PyObject* _unused_arg) {
	PlayerObject* player = (PlayerObject*) self;
	Py_INCREF(self);
	Py_BEGIN_ALLOW_THREADS
	{
		PyScopedLock lock(player->lock);
		player->startWorkerThread();
	}
	Py_END_ALLOW_THREADS
	Py_DECREF(self);
	Py_INCREF(Py_None);
	return Py_None;
}

static PyMethodDef md_startWorkerThread = {
	"startWorkerThread",
	player_method_startWorkerThread,
	METH_NOARGS,
	NULL
};

static
PyObject* player_method_readOutStream(PyObject* self, PyObject* args, PyObject* kws) {
	PlayerObject* player = (PlayerObject*) self;

	long num = player->outSamplerate * player->outNumChannels; // buffer for one second
	static const char *kwlist[] = {"num", NULL};
	if(!PyArg_ParseTupleAndKeywords(args, kws, "|i:readOutStream", (char**)kwlist, &num))
		return NULL;

	if(player->soundcardOutputEnabled) {
		PyErr_SetString(PyExc_RuntimeError, "cannot use readOutStream with soundcardOutputEnabled");
		return NULL;
	}

	if(!player->playing) {
		PyErr_SetString(PyExc_RuntimeError, "cannot use readOutStream while not playing");
		return NULL;
	}

	size_t size = num * OUTSAMPLEBYTELEN;
	PyObject* buffer = PyBytes_FromStringAndSize(NULL, size);
	if(!buffer) return NULL;
	memset(PyBytes_AS_STRING(buffer), 0, size);
	size_t sampleOutNum = 0;

	Py_INCREF(self);
	Py_BEGIN_ALLOW_THREADS
	{
		PyScopedLock lock(player->lock);
		player->readOutStream((OUTSAMPLE_t*)PyBytes_AS_STRING(buffer), num, &sampleOutNum);
	}
	Py_END_ALLOW_THREADS
	Py_DECREF(self);

	// if _PyString_Resize fails, it sets buffer=NULL, so we have the correct error behavior
	_PyBytes_Resize(&buffer, sampleOutNum * OUTSAMPLEBYTELEN);
	return buffer;
}

static PyMethodDef md_readOutStream = {
	"readOutStream",
	(PyCFunction) player_method_readOutStream,
	METH_VARARGS|METH_KEYWORDS,
	NULL
};

static
PyObject* player_method_resetPlaying(PyObject* self, PyObject* _unused_arg) {
	PlayerObject* player = (PlayerObject*) self;
	if(PyErr_Occurred()) return NULL;
	Py_INCREF(self);
	Py_BEGIN_ALLOW_THREADS
	{
		PyScopedLock lock(player->lock);
		player->resetPlaying();
	}
	Py_END_ALLOW_THREADS
	Py_DECREF(self);
	Py_INCREF(Py_None);
	return Py_None;
}

static PyMethodDef md_resetPlaying = {
	"resetPlaying",
	player_method_resetPlaying,
	METH_NOARGS,
	NULL
};

static
PyObject* player_getdict(PlayerObject* player) {
	if(!player->dict) {
		player->dict = PyDict_New();
		if(!player->dict) return NULL;
		// This function is called when we want to ensure that we have a dict,
		// i.e. we requested for it.
		// This is most likely from IPython or so, thus give the developer
		// a list of possible entries.
		PyDict_SetItemString(player->dict, "onSongChange", Py_None);
		PyDict_SetItemString(player->dict, "onSongFinished", Py_None);
		PyDict_SetItemString(player->dict, "onPlayingStateChange", Py_None);
		// The following entries are just there for code completion and inspection.
		const char* attribs[] = {
			"queue", "peekQueue",
			"playing", "resetPlaying",
			"curSong", "curSongPos", "curSongLen", "curSongMetadata", "curSongGainFactor",
			"seekAbs", "seekRel",
			"nextSong",
			"reloadPeekStreams",
			"startWorkerThread",
			"readOutStream",
			"volume",
			"volumeSmoothClip",
			"volumeAdjustEnabled",
			"outSampleFormat", "outSamplerate", "outNumChannels",
			"preferredSoundDevice", "actualSoundDevice",
			"soundcardOutputEnabled",
			"nextSongOnEof"
		};
		for(const char* attr : attribs)
			PyDict_SetItemString(player->dict, attr, Py_None);
	}
	return player->dict;
}

static
PyObject* player_getattr(PyObject* obj, char* key) {
	PlayerObject* player = (PlayerObject*)obj;
	//printf("%p getattr %s\n", player, key);

	if(strcmp(key, "__dict__") == 0) {
		PyObject* dict = player_getdict(player);
		Py_XINCREF(dict);
		return dict;
	}

	if(strcmp(key, "queue") == 0) {
		if(player->queue) {
			Py_INCREF(player->queue);
			return player->queue;
		}
		goto returnNone;
	}

	if(strcmp(key, "peekQueue") == 0) {
		if(player->peekQueue) {
			Py_INCREF(player->peekQueue);
			return player->peekQueue;
		}
		goto returnNone;
	}

	if(strcmp(key, "playing") == 0) {
		return PyBool_FromLong(player->playing);
	}

	if(strcmp(key, "resetPlaying") == 0) {
		return PyCFunction_New(&md_resetPlaying, (PyObject*) player);
	}

	if(strcmp(key, "curSong") == 0) {
		// Note: if we simply check for curSong, we need an additional curSongOpened or so because from the outside, we often want to know if we correctly loaded the current song
		if(!player->curSong) goto returnNone;
		PlayerObject::InStreams::ItemPtr is = player->getInStream();
		if(!is) goto returnNone;
		if(!is->value.song) goto returnNone;
		if(PyObject_RichCompareBool(player->curSong, is->value.song, Py_EQ) == 1) {
			Py_INCREF(is->value.song);
			return is->value.song;
		}
		goto returnNone;
	}

	if(strcmp(key, "curSongPos") == 0) {
		if(player->isInStreamOpened())
			return PyFloat_FromDouble(player->curSongPos());
		goto returnNone;
	}

	if(strcmp(key, "curSongLen") == 0) {
		if(player->isInStreamOpened() && player->curSongLen() > 0)
			return PyFloat_FromDouble(player->curSongLen());
		goto returnNone;
	}

	if(strcmp(key, "curSongMetadata") == 0) {
		if(player->curSongMetadata()) {
			Py_INCREF(player->curSongMetadata());
			return player->curSongMetadata();
		}
		goto returnNone;
	}

	if(strcmp(key, "curSongGainFactor") == 0) {
		if(player->isInStreamOpened())
			return PyFloat_FromDouble(player->curSongGainFactor());
		goto returnNone;
	}

	if(strcmp(key, "seekAbs") == 0) {
		return PyCFunction_New(&md_seekAbs, (PyObject*) player);
	}

	if(strcmp(key, "seekRel") == 0) {
		return PyCFunction_New(&md_seekRel, (PyObject*) player);
	}

	if(strcmp(key, "nextSong") == 0) {
		return PyCFunction_New(&md_nextSong, (PyObject*) player);
	}

	if(strcmp(key, "reloadPeekStreams") == 0) {
		return PyCFunction_New(&md_reloadPeekStreams, (PyObject*) player);
	}

	if(strcmp(key, "startWorkerThread") == 0) {
		return PyCFunction_New(&md_startWorkerThread, (PyObject*) player);
	}

	if(strcmp(key, "readOutStream") == 0) {
		return PyCFunction_New(&md_readOutStream, (PyObject*) player);
	}

	if(strcmp(key, "volume") == 0) {
		return PyFloat_FromDouble(player->volume);
	}

	if(strcmp(key, "volumeSmoothClip") == 0) {
		PyObject* t = PyTuple_New(2);
		PyTuple_SetItem(t, 0, PyFloat_FromDouble(player->volumeSmoothClip.x1));
		PyTuple_SetItem(t, 1, PyFloat_FromDouble(player->volumeSmoothClip.x2));
		return t;
	}

	if(strcmp(key, "volumeAdjustEnabled") == 0) {
		return PyBool_FromLong(player->volumeAdjustEnabled);
	}

	if(strcmp(key, "outSampleFormat") == 0) {
		PyObject* t = PyTuple_New(2);
		PyTuple_SetItem(t, 0, PyString_FromString(OUTSAMPLEFORMATSTR));
		PyTuple_SetItem(t, 1, PyInt_FromLong(OUTSAMPLEBITLEN));
		return t;
	}

	if(strcmp(key, "outSamplerate") == 0) {
		return PyInt_FromLong(player->outSamplerate);
	}

	if(strcmp(key, "outNumChannels") == 0) {
		return PyInt_FromLong(player->outNumChannels);
	}

	if(strcmp(key, "preferredSoundDevice") == 0) {
		return PyString_FromString(player->preferredSoundDevice.c_str());
	}

	if(strcmp(key, "actualSoundDevice") == 0) {
		return PyString_FromString(player->getSoundDevice().c_str());
	}

	if(strcmp(key, "soundcardOutputEnabled") == 0) {
		return PyBool_FromLong(player->soundcardOutputEnabled);
	}

	if(strcmp(key, "nextSongOnEof") == 0) {
		return PyBool_FromLong(player->nextSongOnEof);
	}

	{
		PyObject* dict = player_getdict(player);
		if(dict) { // should always be true...
			Py_INCREF(dict);
			PyObject* res = PyDict_GetItemString(dict, key);
			if (res != NULL) {
				Py_INCREF(res);
				Py_DECREF(dict);
				return res;
			}
			Py_DECREF(dict);
		}
	}

	PyErr_Format(PyExc_AttributeError, "PlayerObject has no attribute '%.400s'", key);
	return NULL;

returnNone:
	Py_INCREF(Py_None);
	return Py_None;
}

static
int player_setattr(PyObject* obj, char* key, PyObject* value) {
	PlayerObject* player = (PlayerObject*)obj;
	//printf("%p setattr %s %p\n", player, key, value);

	if(strcmp(key, "queue") == 0) {
		return player_setqueue(player, value);
	}

	if(strcmp(key, "peekQueue") == 0) {
		return player_setpeekqueue(player, value);
	}

	if(strcmp(key, "playing") == 0) {
		PyScopedGIUnlock gunlock;
		PyScopedLock lock(player->lock);
		return player->setPlaying(PyObject_IsTrue(value));
	}

	if(strcmp(key, "volume") == 0) {
		if(!PyArg_Parse(value, "f", &player->volume))
			return -1;
		if(player->volume < 0) player->volume = 0;
		if(player->volume > 5) player->volume = 5; // Well, this limit is made up. But it makes sense to have a limit somewhere...
		return 0;
	}

	if(strcmp(key, "volumeSmoothClip") == 0) {
		float x1, x2;
		if(!PyArg_ParseTuple(value, "ff", &x1, &x2))
			return -1;
		player->volumeSmoothClip.setX(x1, x2);
		return 0;
	}

	if(strcmp(key, "volumeAdjustEnabled") == 0) {
		player->volumeAdjustEnabled = PyObject_IsTrue(value);
		return 0;
	}

	if(strcmp(key, "outSampleFormat") == 0) {
		PyErr_SetString(PyExc_AttributeError, "outSampleFormat is readonly (hardcoded) for now");
		return -1;
	}

	if(strcmp(key, "outSamplerate") == 0) {
		if(player->playing) {
			PyErr_SetString(PyExc_RuntimeError, "cannot set outSamplerate while playing");
			return -1;
		}
		int freq = SAMPLERATE;
		if(!PyArg_Parse(value, "i", &freq))
			return -1;
		{
			PyScopedGIUnlock gunlock;
			PyScopedLock lock(player->lock);
			player->setAudioTgt(freq, player->outNumChannels);
		}
		return 0;
	}

	if(strcmp(key, "outNumChannels") == 0) {
		if(player->playing) {
			PyErr_SetString(PyExc_RuntimeError, "cannot set outNumChannels while playing");
			return -1;
		}
		int numchannels = NUMCHANNELS;
		if(!PyArg_Parse(value, "i", &numchannels))
			return -1;
		{
			PyScopedGIUnlock gunlock;
			PyScopedLock lock(player->lock);
			player->setAudioTgt(player->outSamplerate, numchannels);
		}
		return 0;
	}

	if(strcmp(key, "preferredSoundDevice") == 0) {
		std::string dev;
		if(!pyStr(value, dev)) {
			PyErr_SetString(PyExc_ValueError, "preferredSoundDevice must be a string");
			return -1;
		}
		{
			PyScopedGIUnlock gunlock;
			PyScopedLock lock(player->lock);
			player->preferredSoundDevice = dev;
		}
		return 0;
	}

	if(strcmp(key, "actualSoundDevice") == 0) {
		PyErr_SetString(PyExc_AttributeError, "actualSoundDevice is readonly");
		return -1;
	}

	if(strcmp(key, "soundcardOutputEnabled") == 0) {
		if(player->playing) {
			PyErr_SetString(PyExc_RuntimeError, "cannot set soundcardOutputEnabled while playing");
			return -1;
		}
		player->soundcardOutputEnabled = PyObject_IsTrue(value);
		return 0;
	}

	if(strcmp(key, "nextSongOnEof") == 0) {
		player->nextSongOnEof = PyObject_IsTrue(value);
		return 0;
	}

	PyObject* s = PyString_FromString(key);
	if(!s) return -1;
	int ret = PyObject_GenericSetAttr(obj, s, value);
	Py_XDECREF(s);
	return ret;
}

PyTypeObject Player_Type = {
	PyVarObject_HEAD_INIT(&PyType_Type, 0)
	"PlayerType",
	sizeof(PlayerObject),	// basicsize
	0,	// itemsize
	player_dealloc,		/*tp_dealloc*/
	0,                  /*tp_print*/
	player_getattr,		/*tp_getattr*/
	player_setattr,		/*tp_setattr*/
	0,                  /*tp_compare*/
	0,					/*tp_repr*/
	0,                  /*tp_as_number*/
	0,                  /*tp_as_sequence*/
	0,                  /*tp_as_mapping*/
	0,					/*tp_hash */
	0, // tp_call
	0, // tp_str
	0, // tp_getattro
	0, // tp_setattro
	0, // tp_as_buffer
	Py_TPFLAGS_HAVE_CLASS, // flags
	"Player type", // doc
	0, // tp_traverse
	0, // tp_clear
	0, // tp_richcompare
	0, // weaklistoffset
	0, // iter
	0, // iternext
	0, // methods
	0, //PlayerMembers, // members
	0, // getset
	0, // base
	0, // dict
	0, // descr_get
	0, // descr_set
	offsetof(PlayerObject, dict), // dictoffset
	player_init, // tp_init
	player_alloc, // alloc
	player_new, // new
};

PyObject *
pyCreatePlayer(PyObject* self) {
	PyTypeObject* type = &Player_Type;
	PyObject *obj = NULL, *args = NULL, *kwds = NULL;
	args = PyTuple_Pack(0);

	obj = type->tp_new(type, args, kwds);
	if(obj == NULL) goto final;

	if(type->tp_init && type->tp_init(obj, args, kwds) < 0) {
		Py_DECREF(obj);
		obj = NULL;
	}

final:
	Py_XDECREF(args);
	Py_XDECREF(kwds);
	return obj;
}

max_stars_repo_name: albertz/music-player-core

max_issues_repo_name: albertz/music-player-core

max_forks_repo_name: albertz/music-player-core


text:
//
// Copyright (c) 2019 Vinnie Falco (vinnie.falco@gmail.com)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//
// Official repository: https://github.com/cppalliance/json
//

#ifndef BOOST_JSON_DETAIL_IMPL_DEFAULT_RESOURCE_IPP
#define BOOST_JSON_DETAIL_IMPL_DEFAULT_RESOURCE_IPP

#include <boost/json/detail/default_resource.hpp>

BOOST_JSON_NS_BEGIN
namespace detail {

// these are here so that ~memory_resource
// is emitted in the library instead of
// the user's TU.

default_resource::
~default_resource()
{
}

} // detail
BOOST_JSON_NS_END

#endif

ext: ipp

max_stars_repo_name: cppalliance-bot/json

max_issues_repo_name: cppalliance-bot/json

max_forks_repo_name: cppalliance-bot/json


text:
#ifndef _MAP_HPP
#define _MAP_HPP

/////////////////////////////////////////////////////////////////////////////
// Name:        src/lev/map.hpp
// Purpose:     header for image mapping class
// Author:      Akiva Miura <akiva.miura@gmail.com>
// Modified by:
// Created:     02/01/2012
// Copyright:   (C) 2010-2012 Akiva Miura
// Licence:     MIT License
/////////////////////////////////////////////////////////////////////////////

#include "base.hpp"
#include "draw.hpp"
#include <boost/shared_ptr.hpp>
#include <luabind/luabind.hpp>

extern "C" {
  int luaopen_lev_map(lua_State *L);
}

namespace lev
{

  class map : public clickable
  {
    public:
      typedef boost::shared_ptr<map> ptr;
    protected:
      map() : clickable() { }
    public:
      virtual ~map() { }
      virtual bool clear() = 0;
      static boost::shared_ptr<map> create();
      virtual type_id get_type_id() const { return LEV_TMAP; }
      virtual bool map_image(drawable::ptr img, int x, int y, unsigned char alpha = 255) = 0;
      virtual bool map_link(drawable::ptr img, drawable::ptr hover_img,
                            int x, int y, luabind::object on_lsingle, luabind::object on_hover,
                            unsigned char alpha = 255) = 0;
      virtual bool pop_back() = 0;
  };

}

#endif // _MAP_HPP

ext: hpp

max_stars_repo_name: akivajp/lev

max_issues_repo_name: akivajp/lev

max_forks_repo_name: akivajp/lev


text:
// -*- C++ -*-
//
// Copyright Sylvain Bougerel 2009 - 2012.
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file COPYING or copy at
// http://www.boost.org/LICENSE_1_0.txt)

#define BOOST_TEST_DYN_LINK
#define SPATIAL_ENABLE_ASSERT // detect interal issues that should not occur

#include <boost/test/unit_test.hpp>
#include <utility> // std::make_pair
#include "../../src/idle_box_multimap.hpp"
#include "spatial_test_types.hpp"

using namespace spatial;

BOOST_AUTO_TEST_CASE( test_idle_box_map_constructors )
{
  idle_box_multimap<2, int2, int> idle_boxes;
  idle_box_multimap<0, int2, int> runtime_idle_boxes;
}

BOOST_AUTO_TEST_CASE( test_idle_box_map_copy_assignment )
{
  idle_box_multimap<2, int2, int> idle_boxes;
  idle_boxes.insert(std::make_pair(zeros, 0));
  idle_boxes.insert(std::make_pair(ones, 1));
  idle_boxes.insert(std::make_pair(twos, 2));
  idle_box_multimap<2, int2, int> copy(idle_boxes);
  BOOST_CHECK_EQUAL(idle_boxes.size(), copy.size());
  BOOST_CHECK(*idle_boxes.begin() == *copy.begin());
  idle_boxes = copy;
  BOOST_CHECK_EQUAL(idle_boxes.size(), copy.size());
  BOOST_CHECK(*idle_boxes.begin() == *copy.begin());
}

BOOST_AUTO_TEST_CASE( test_zero_idle_box_map_copy_assignment )
{
  idle_box_multimap<0, int2, int> idle_boxes;
  idle_boxes.insert(std::make_pair(zeros, 0));
  idle_boxes.insert(std::make_pair(ones, 1));
  idle_boxes.insert(std::make_pair(twos, 2));
  idle_box_multimap<0, int2, int> copy(idle_boxes);
  BOOST_CHECK_EQUAL(idle_boxes.size(), copy.size());
  BOOST_CHECK(*idle_boxes.begin() == *copy.begin());
  idle_boxes = copy;
  BOOST_CHECK_EQUAL(idle_boxes.size(), copy.size());
  BOOST_CHECK(*idle_boxes.begin() == *copy.begin());
}

ext: cpp

max_stars_repo_name: Roboauto/spatial

max_issues_repo_name: Roboauto/spatial

max_forks_repo_name: Roboauto/spatial


text:
#include "stdafx.h"
#include "HardwareKeyGetter.h"
#include <boost/scoped_ptr.hpp>
#include <winsock2.h>
#include <iphlpapi.h>
#include <iomanip>
#pragma comment(lib, "IPHLPAPI.lib")
using namespace ETLicense;
// https://msdn.microsoft.com/en-us/library/windows/desktop/aa365917(v=vs.85).aspx for mac address

HardwareKeyGetter::HardwareKeyGetter()
{}

HardwareKeyGetter::~HardwareKeyGetter()
{}

HardwareKeys HardwareKeyGetter::operator()() const
{
    HardwareKeys keys;
    ULONG outbufferLength = sizeof(IP_ADAPTER_INFO);
    PIP_ADAPTER_INFO adapterInfo = (IP_ADAPTER_INFO*)malloc(sizeof(IP_ADAPTER_INFO));

    if (ERROR_BUFFER_OVERFLOW == GetAdaptersInfo(adapterInfo, &outbufferLength))
    {
        free(adapterInfo);
        adapterInfo = (IP_ADAPTER_INFO *)malloc(outbufferLength);
        if (!adapterInfo)
        {
            return keys;
        }
    }

    DWORD dwRetVal;
    if (NO_ERROR != (dwRetVal = GetAdaptersInfo(adapterInfo, &outbufferLength)))
    {
        return keys;
    }
    boost::scoped_ptr<IP_ADAPTER_INFO> sptrAdapterInfo(adapterInfo);

    PIP_ADAPTER_INFO pAdapter = adapterInfo;
    int indexCount = 0;
    while (pAdapter)
    {
        std::stringstream physicalAddress;
        physicalAddress << std::hex << std::uppercase;
        for (UINT i = 0; i < pAdapter->AddressLength; i++)
        {
            physicalAddress << std::setw(2) << std::setfill('0');   // every loop needs this statement for all tokens
            if (i == (pAdapter->AddressLength - 1))
            {
                physicalAddress << (int)pAdapter->Address[i];
            }
            else
            {
                physicalAddress << (int)pAdapter->Address[i] << "-";
            }
        }
        HardwareKey key;
        key.key = physicalAddress.str();
        keys.push_back(key);

        pAdapter = pAdapter->Next;
        ++indexCount;
    }
    return keys;
}

max_stars_repo_name: lantaoxu/lickey

max_issues_repo_name: lantaoxu/lickey

max_forks_repo_name: lantaoxu/lickey


text:
#include <boost/mpl11/detail/left_folds/variadic.hpp>
#include <boost/mpl11/integer.hpp>

template <typename x, typename y>
using plus = boost::mpl11::integer_c<
    decltype(x::type::value + y::type::value),
    x::type::value + y::type::value
>;

template <typename ...xs>
using sum = boost::mpl11::detail::left_folds::variadic<
    plus, boost::mpl11::int_<0>, xs...
>;

<%= render('_main.erb') %>

max_stars_repo_name: ldionne/benchcc

max_issues_repo_name: ldionne/benchcc

max_forks_repo_name: ldionne/benchcc


text:
/* -*- c-basic-offset: 4 indent-tabs-mode: nil -*-  vi:set ts=8 sts=4 sw=4: */

/*
    MiniBPM
    A fixed-tempo BPM estimator for music audio
    Copyright 2012 Particular Programs Ltd.

    This program is free software; you can redistribute it and/or
    modify it under the terms of the GNU General Public License as
    published by the Free Software Foundation; either version 2 of the
    License, or (at your option) any later version.  See the file
    COPYING included with this distribution for more information.

    Alternatively, if you have a valid commercial licence for MiniBPM
    obtained by agreement with the copyright holders, you may
    redistribute and/or modify it under the terms described in that
    licence.

    If you wish to distribute code using MiniBPM under terms other
    than those of the GNU General Public License, you must obtain a
    valid commercial licence before doing so.
*/

#include "../src/MiniBpm.cpp"

using breakfastquay::FourierFilterbank;
using breakfastquay::Autocorrelation;
using breakfastquay::ACFCombFilter;
using breakfastquay::MiniBPM;

#define BOOST_TEST_DYN_LINK
#define BOOST_TEST_MAIN

#include <boost/test/unit_test.hpp>

BOOST_AUTO_TEST_SUITE(TestFourierFilterbank)

#define FFT(n) FourierFilterbank(n, 2, 0, 1, false)
#define COMPARE_ZERO(x) BOOST_CHECK_SMALL(x, 1e-10)
#define COMPARE_ALL_ZERO(a) \
    for (int cmp_i = 0; cmp_i < (int)(sizeof(a)/sizeof(a[0])); ++cmp_i) { \
        COMPARE_ZERO(a[cmp_i]); \
    }

BOOST_AUTO_TEST_CASE(outputSize)
{
    int size = FFT(4).getOutputSize();
    BOOST_CHECK_EQUAL(size, 3);
    size = FourierFilterbank(4, 4, 1, 1, false).getOutputSize();
    BOOST_CHECK_EQUAL(size, 1);
    size = FourierFilterbank(4, 4, 1, 2, false).getOutputSize();
    BOOST_CHECK_EQUAL(size, 2);
    size = FourierFilterbank(512, 44100, 0, 440, true).getOutputSize();
    BOOST_CHECK_EQUAL(size, 6);
}

BOOST_AUTO_TEST_CASE(dc)
{
    double in[] = { 1, 1, 1, 1 };
    double mag[3];
    FFT(4).forwardMagnitude(in, mag);
    BOOST_CHECK_EQUAL(mag[0], 4.0);
    COMPARE_ZERO(mag[1]);
    COMPARE_ZERO(mag[2]);
}

BOOST_AUTO_TEST_CASE(sine)
{
    double in[] = { 0, 1, 0, -1 };
    double mag[3];
    FFT(4).forwardMagnitude(in, mag);
    COMPARE_ZERO(mag[0]);
    BOOST_CHECK_EQUAL(mag[1], 2.0);
    COMPARE_ZERO(mag[2]);
}

BOOST_AUTO_TEST_CASE(sineSubset)
{
    double in[] = { 0, 1, 0, -1 };
    double mag[1];
    FourierFilterbank(4, 4, 1, 1, false).forwardMagnitude(in, mag);
    BOOST_CHECK_EQUAL(mag[0], 2.0);
}

BOOST_AUTO_TEST_CASE(cosine)
{
    double in[] = { 1, 0, -1, 0 };
    double mag[3];
    FFT(4).forwardMagnitude(in, mag);
    COMPARE_ZERO(mag[0]);
    BOOST_CHECK_EQUAL(mag[1], 2.0);
    COMPARE_ZERO(mag[2]);
}

BOOST_AUTO_TEST_CASE(sineCosine)
{
    double in[] = { 0.5, 1, -0.5, -1 };
    double mag[3];
    FFT(4).forwardMagnitude(in, mag);
    COMPARE_ZERO(mag[0]);
    BOOST_CHECK_CLOSE(mag[1], sqrt(5.0), 1e-10);
    COMPARE_ZERO(mag[2]);
}

BOOST_AUTO_TEST_CASE(nyquist)
{
    double in[] = { 1, -1, 1, -1 };
    double mag[3];
    FFT(4).forwardMagnitude(in, mag);
    COMPARE_ZERO(mag[0]);
    COMPARE_ZERO(mag[1]);
    BOOST_CHECK_EQUAL(mag[2], 4.0);
}

BOOST_AUTO_TEST_CASE(dirac)
{
    double in[] = { 1, 0, 0, 0 };
    double mag[3];
    FFT(4).forwardMagnitude(in, mag);
    BOOST_CHECK_EQUAL(mag[0], 1.0);
    BOOST_CHECK_EQUAL(mag[1], 1.0);
    BOOST_CHECK_EQUAL(mag[2], 1.0);
}

BOOST_AUTO_TEST_CASE(forwardArrayBounds)
{
    double in[] = { 1, 1, -1, -1 };
    double mag[] = { 999, 999, 999, 999, 999 };
    FFT(4).forwardMagnitude(in, mag + 1);
    BOOST_CHECK_EQUAL(mag[0], 999.0);
    BOOST_CHECK_EQUAL(mag[4], 999.0);
}

BOOST_AUTO_TEST_SUITE_END()

BOOST_AUTO_TEST_SUITE(TestAutocorrelation)

BOOST_AUTO_TEST_CASE(unnormalised)
{
    double in[] = { 1,0,0, 1,0,0, 1,0,0, 1,0,0 };
    double out[] = { 0,0,0, 0,0,0, 0,0,0, 0,0,0 };
    Autocorrelation(12, 12).acf(in, out);
    BOOST_CHECK_EQUAL(out[0], 4.0);
    BOOST_CHECK_EQUAL(out[1], 0.0);
    BOOST_CHECK_EQUAL(out[2], 0.0);
    BOOST_CHECK_EQUAL(out[3], 3.0);
    BOOST_CHECK_EQUAL(out[4], 0.0);
    BOOST_CHECK_EQUAL(out[5], 0.0);
    BOOST_CHECK_EQUAL(out[6], 2.0);
    BOOST_CHECK_EQUAL(out[7], 0.0);
    BOOST_CHECK_EQUAL(out[8], 0.0);
    BOOST_CHECK_EQUAL(out[9], 1.0);
    BOOST_CHECK_EQUAL(out[10], 0.0);
    BOOST_CHECK_EQUAL(out[11], 0.0);
}

BOOST_AUTO_TEST_CASE(normalisedUnity)
{
    double in[] = { 1,0,0, 1,0,0, 1,0,0, 1,0,0 };
    double out[] = { 0,0,0, 0,0,0, 0,0,0, };
    Autocorrelation(12, 9).acfUnityNormalised(in, out);
    BOOST_CHECK_EQUAL(out[0], 1.0);
    BOOST_CHECK_EQUAL(out[1], 0.0);
    BOOST_CHECK_EQUAL(out[2], 0.0);
    BOOST_CHECK_EQUAL(out[3], 1.0);
    BOOST_CHECK_EQUAL(out[4], 0.0);
    BOOST_CHECK_EQUAL(out[5], 0.0);
    BOOST_CHECK_EQUAL(out[6], 1.0);
    BOOST_CHECK_EQUAL(out[7], 0.0);
    BOOST_CHECK_EQUAL(out[8], 0.0);
}

BOOST_AUTO_TEST_CASE(bpmLagConversion)
{
    int lag = Autocorrelation::bpmToLag(120.0, 2.0);
    BOOST_CHECK_EQUAL(lag, 1);
    lag = Autocorrelation::bpmToLag(130.0, 2.0);
    BOOST_CHECK_EQUAL(lag, 1);
    lag = Autocorrelation::bpmToLag(130.0, 100.0);
    BOOST_CHECK_EQUAL(lag, 46);

    double bpm = Autocorrelation::lagToBpm(1, 2.0);
    BOOST_CHECK_EQUAL(bpm, 120.0);
    bpm = Autocorrelation::lagToBpm(50, 100.0);
    BOOST_CHECK_EQUAL(bpm, 120.0);
    bpm = Autocorrelation::lagToBpm(46, 100.0);
    BOOST_CHECK_CLOSE(bpm, 130.0, 0.5);
    bpm = Autocorrelation::lagToBpm(0.5, 1.0);
    BOOST_CHECK_CLOSE(bpm, 120.0, 0.1);

    bpm = Autocorrelation::lagToBpm(1, 1.0);
    BOOST_CHECK_EQUAL(bpm, 60.0);
    bpm = Autocorrelation::lagToBpm(2, 1.0);
    BOOST_CHECK_EQUAL(bpm, 30.0);
    bpm = Autocorrelation::lagToBpm(3, 1.0);
    BOOST_CHECK_EQUAL(bpm, 20.0);
    bpm = Autocorrelation::lagToBpm(4, 1.0);
    BOOST_CHECK_EQUAL(bpm, 15.0);
}

BOOST_AUTO_TEST_SUITE_END()

BOOST_AUTO_TEST_SUITE(TestACFCombFilter)

BOOST_AUTO_TEST_CASE(contributingRange)
{
    int base, count;
    ACFCombFilter::getContributingRange(1, 1, base, count);
    BOOST_CHECK_EQUAL(base, 1);
    BOOST_CHECK_EQUAL(count, 1);
    ACFCombFilter::getContributingRange(1, 2, base, count);
    BOOST_CHECK_EQUAL(base, 2);
    BOOST_CHECK_EQUAL(count, 1);
    ACFCombFilter::getContributingRange(1, 4, base, count);
    BOOST_CHECK_EQUAL(base, 3);
    BOOST_CHECK_EQUAL(count, 3);
    ACFCombFilter::getContributingRange(1, 8, base, count);
    BOOST_CHECK_EQUAL(base, 6);
    BOOST_CHECK_EQUAL(count, 6);
}

BOOST_AUTO_TEST_CASE(contributingRangeCoverage)
{
    const int n = 64;
    const int maxMultiple = 16;
    int *target = new int[n];

    // Need to ensure that each lag contributes to no more than one
    // target lag, at each multiple
    for (int multiple = 1; multiple <= maxMultiple; multiple = multiple * 2) {
	for (int i = 1; i < n; ++i) {
	    target[i] = -1;
	}
	for (int i = 1; i < n; ++i) {
	    int base, count;
	    ACFCombFilter::getContributingRange(i, multiple, base, count);
	    for (int j = base; j < base + count; ++j) {
		BOOST_CHECK_GE(j, i);
		if (j >= 0 && j < n) {
		    if (target[j] != -1) {
			BOOST_CHECK_EQUAL(target[j], i);
		    }
		    target[j] = i;
		}
	    }
	}
    }

    // and that each lag is a source for only one multiple, for a
    // given target
    for (int i = 1; i < n; ++i) {
	for (int j = 1; j < n; ++j) {
	    target[j] = -1;
	}
	for (int multiple = 1; multiple <= maxMultiple; multiple = multiple * 2) {
	    int base, count;
	    ACFCombFilter::getContributingRange(i, multiple, base, count);
	    for (int j = base; j < base + count; ++j) {
		BOOST_CHECK_GE(j, i);
		if (j >= 0 && j < n) {
		    if (target[j] != -1) {
			BOOST_CHECK_EQUAL(target[j], multiple);
		    }
		    target[j] = multiple;
		}
	    }
	}
    }

    delete[] target;
}

#define REFINER(n) ACFCombFilter(4, 10, 20, n)

BOOST_AUTO_TEST_CASE(refineSingleElement)
{
    double acf[] = { 0.0, 1.0 };
    double bpm = REFINER(1).refine(1, acf, 2);
    BOOST_CHECK_EQUAL(bpm, 60);
}

BOOST_AUTO_TEST_CASE(refineEmpty)
{
    double acf[] = { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 };
    double bpm = REFINER(1).refine(1, acf, 8);
    BOOST_CHECK_EQUAL(bpm, 60);
}

BOOST_AUTO_TEST_CASE(refineTrivial)
{
    double acf[] = { 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 };
    double bpm = REFINER(1).refine(1, acf, 8);
    BOOST_CHECK_EQUAL(bpm, 60);
}

BOOST_AUTO_TEST_CASE(refineConsistent)
{
    double acf[] = { 0.0, 1.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0 };
    double bpm = REFINER(1).refine(1, acf, 8);
    BOOST_CHECK_EQUAL(bpm, 60);
}

BOOST_AUTO_TEST_CASE(refineAdjusting)
{
    double acf[] = { 0.0, 1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0 };
    double bpm = REFINER(1).refine(1, acf, 8);
    BOOST_CHECK_LT(bpm, 60);
    BOOST_CHECK_GT(bpm, 50);
}

BOOST_AUTO_TEST_SUITE_END()

static float *tap(double duration, double rate, double bpm, int &len)
{
    double bps = bpm / 60.0;
    len = int(duration * rate + 0.5);
    float *data = new float[len];
    for (int i = 0; i < len; ++i) {
	data[i] = 0.f;
    }
    int beats = int(bps * duration + 0.5);
    for (int i = 0; i < beats; ++i) {
	int ix = (i / bps) * rate;
	if (ix < len) data[ix] = 1.f;
    }
    return data;
}

BOOST_AUTO_TEST_SUITE(TestMiniBpm)

BOOST_AUTO_TEST_CASE(tapper)
{
    // Testing our test harness
    int len = 0;
    float *data = tap(2.0, 20.0, 240.0, len);
    BOOST_CHECK_EQUAL(len, 40);
    for (int i = 0; i < 8; ++i) {
	BOOST_CHECK_EQUAL(data[i * 5], 1.f);
	for (int j = 1; j < 5; ++j) {
	    BOOST_CHECK_EQUAL(data[i * 5 + j], 0.f);
	}
    }
    delete[] data;
}

BOOST_AUTO_TEST_CASE(complete_120bpm_8000)
{
    float rate = 8000.f;
    int len;
    float *data = tap(6.0, rate, 120.0, len);
    double bpm = MiniBPM(rate).estimateTempoOfSamples(data, len);
    delete[] data;
    BOOST_CHECK_CLOSE(bpm, 120.0, 0.25);
}

BOOST_AUTO_TEST_CASE(complete_120bpm_44100)
{
    float rate = 44100.f;
    int len;
    float *data = tap(6.0, rate, 120.0, len);
    double bpm = MiniBPM(rate).estimateTempoOfSamples(data, len);
    delete[] data;
    BOOST_CHECK_CLOSE(bpm, 120.0, 0.25);
}

BOOST_AUTO_TEST_CASE(complete_120bpm_48000)
{
    float rate = 48000.f;
    int len;
    float *data = tap(6.0, rate, 120.0, len);
    double bpm = MiniBPM(rate).estimateTempoOfSamples(data, len);
    delete[] data;
    BOOST_CHECK_CLOSE(bpm, 120.0, 0.25);
}

BOOST_AUTO_TEST_CASE(buffered_120bpm_44100)
{
    float rate = 44100.f;
    int len;
    float *data = tap(6.0, rate, 120.0, len);
    MiniBPM mbpm(rate);
    int blockSize = 1000;
    for (int i = 0; i < len/blockSize; ++i) {
	int thisBlock = blockSize;
	if (i * blockSize + thisBlock > len) {
	    thisBlock = len - i * blockSize;
	}
	mbpm.process(data + i * blockSize, thisBlock);
    }
    delete[] data;
    double bpm = mbpm.estimateTempo();
    BOOST_CHECK_CLOSE(bpm, 120.0, 0.25);
}

BOOST_AUTO_TEST_CASE(minmax)
{
    MiniBPM mbpm(44100);
    double min = 0.0, max = 0.0;
    mbpm.getBPMRange(min, max);
    BOOST_CHECK_NE(min, 0.0);
    BOOST_CHECK_NE(max, 0.0);
    BOOST_CHECK_GT(max, min);
    BOOST_CHECK_GT(min, 30.0);
    BOOST_CHECK_GT(max, 30.0);
    BOOST_CHECK_LT(min, 240.0);
    BOOST_CHECK_LT(max, 240.0);
    mbpm.setBPMRange(70, 140);
    mbpm.getBPMRange(min, max);
    BOOST_CHECK_EQUAL(min, 70);
    BOOST_CHECK_EQUAL(max, 140);
}

BOOST_AUTO_TEST_CASE(complete_240bpm_outOfRange)
{
    // 240bpm is too fast for default range; should return 120
    float rate = 44100.f;
    int len;
    float *data = tap(6.0, rate, 240.0, len);
    double bpm = MiniBPM(rate).estimateTempoOfSamples(data, len);
    delete[] data;
    BOOST_CHECK_CLOSE(bpm, 120.0, 0.25);
}

BOOST_AUTO_TEST_CASE(complete_120bpm_outOfRange)
{
    // adjust range to make 120bpm also too fast; should return 60
    float rate = 44100.f;
    int len;
    float *data = tap(6.0, rate, 120.0, len);
    MiniBPM mbpm(rate);
    mbpm.setBPMRange(30, 90);
    double bpm = mbpm.estimateTempoOfSamples(data, len);
    delete[] data;
    BOOST_CHECK_CLOSE(bpm, 60.0, 0.25);
}

BOOST_AUTO_TEST_CASE(candidates)
{
    float rate = 44100.f;
    int len;
    float *data = tap(6.0, rate, 120.0, len);
    MiniBPM mbpm(rate);
    double bpm = mbpm.estimateTempoOfSamples(data, len);
    double min, max;
    mbpm.getBPMRange(min, max);
    std::vector<double> candidates = mbpm.getTempoCandidates();
    delete[] data;
    BOOST_CHECK_CLOSE(bpm, 120.0, 0.25);
    BOOST_CHECK(candidates.size() > 1);
    BOOST_CHECK_CLOSE(candidates[0], 120.0, 0.25);
    BOOST_CHECK_CLOSE(candidates[1], 60.0, 0.25);
    for (int i = 0; i < candidates.size(); ++i) {
	BOOST_CHECK_GE(candidates[i], min);
	BOOST_CHECK_LE(candidates[i], max);
    }
}

BOOST_AUTO_TEST_SUITE_END()


text:
//  Copyright John Maddock 2008.
//  Use, modification and distribution are subject to the
//  Boost Software License, Version 1.0.  (See accompanying file
//  LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//
#define BOOST_MATH_TR1_SOURCE
#include <boost/math/tr1.hpp>
#include <boost/math/special_functions/fpclassify.hpp>
#include <boost/math/special_functions/sign.hpp>
#include "c_policy.hpp"

namespace boost{ namespace math{ namespace tr1{

template<> bool BOOST_MATH_TR1_DECL signbit<long double> BOOST_PREVENT_MACRO_SUBSTITUTION(long double x)
{
   return static_cast<bool>((boost::math::signbit)(x));
}

template<> int BOOST_MATH_TR1_DECL fpclassify<long double> BOOST_PREVENT_MACRO_SUBSTITUTION(long double x)
{
   return (boost::math::fpclassify)(x);
}

template<> bool BOOST_MATH_TR1_DECL isfinite<long double> BOOST_PREVENT_MACRO_SUBSTITUTION(long double x)
{
   return (boost::math::isfinite)(x);
}

template<> bool BOOST_MATH_TR1_DECL isinf<long double> BOOST_PREVENT_MACRO_SUBSTITUTION(long double x)
{
   return (boost::math::isinf)(x);
}

template<> bool BOOST_MATH_TR1_DECL isnan<long double> BOOST_PREVENT_MACRO_SUBSTITUTION(long double x)
{
   return (boost::math::isnan)(x);
}

template<> bool BOOST_MATH_TR1_DECL isnormal<long double> BOOST_PREVENT_MACRO_SUBSTITUTION(long double x)
{
   return (boost::math::isnormal)(x);
}

}}}

max_issues_repo_name: mrfarhadi/BinClone

max_forks_repo_name: mrfarhadi/BinClone


text:
#define DEBUG 1
/**
 * File    : D.cpp
 * Author  : Kazune Takahashi
 * Created : 2020/1/18 21:28:34
 * Powered by Visual Studio Code
 */
#include <algorithm>
#include <bitset>
#include <cassert>
#include <cctype>
#include <chrono>
#include <cmath>
#include <complex>
#include <cstdint>
#include <cstdio>
#include <cstdlib>
#include <functional>
#include <iomanip>
#include <iostream>
#include <map>
#include <queue>
#include <random>
#include <set>
#include <stack>
#include <string>
#include <tuple>
#include <unordered_map>
#include <unordered_set>
#include <vector>
// ----- boost -----
#include <boost/rational.hpp>
#include <boost/multiprecision/cpp_int.hpp>
// ----- using directives and manipulations -----
using namespace std;
using boost::rational;
using boost::multiprecision::cpp_int;
using ll = long long;
// ----- constexpr for Mint and Combination -----
constexpr ll MOD{1000000007LL};
// constexpr ll MOD{998244353LL}; // be careful
constexpr ll MAX_SIZE{3000010LL};
// constexpr ll MAX_SIZE{30000010LL}; // if 10^7 is needed
// ----- ch_max and ch_min -----
template <typename T>
void ch_max(T &left, T right)
{
  if (left < right)
  {
    left = right;
  }
}
template <typename T>
void ch_min(T &left, T right)
{
  if (left > right)
  {
    left = right;
  }
}
// ----- Mint -----
template <ll MOD = MOD>
class Mint
{
public:
  ll x;
  Mint() : x{0LL} {}
  Mint(ll x) : x{(x % MOD + MOD) % MOD} {}
  Mint operator-() const { return x ? MOD - x : 0; }
  Mint &operator+=(const Mint &a)
  {
    if ((x += a.x) >= MOD)
    {
      x -= MOD;
    }
    return *this;
  }
  Mint &operator-=(const Mint &a) { return *this += -a; }
  Mint &operator*=(const Mint &a)
  {
    (x *= a.x) %= MOD;
    return *this;
  }
  Mint &operator/=(const Mint &a)
  {
    Mint b{a};
    return *this *= b.power(MOD - 2);
  }
  Mint operator+(const Mint &a) const { return Mint(*this) += a; }
  Mint operator-(const Mint &a) const { return Mint(*this) -= a; }
  Mint operator*(const Mint &a) const { return Mint(*this) *= a; }
  Mint operator/(const Mint &a) const { return Mint(*this) /= a; }
  bool operator<(const Mint &a) const { return x < a.x; }
  bool operator<=(const Mint &a) const { return x <= a.x; }
  bool operator>(const Mint &a) const { return x > a.x; }
  bool operator>=(const Mint &a) const { return x >= a.x; }
  bool operator==(const Mint &a) const { return x == a.x; }
  bool operator!=(const Mint &a) const { return !(*this == a); }
  const Mint power(ll N)
  {
    if (N == 0)
    {
      return 1;
    }
    else if (N % 2 == 1)
    {
      return *this * power(N - 1);
    }
    else
    {
      Mint half = power(N / 2);
      return half * half;
    }
  }
};
template <ll MOD>
Mint<MOD> operator+(ll lhs, const Mint<MOD> &rhs)
{
  return rhs + lhs;
}
template <ll MOD>
Mint<MOD> operator-(ll lhs, const Mint<MOD> &rhs)
{
  return -rhs + lhs;
}
template <ll MOD>
Mint<MOD> operator*(ll lhs, const Mint<MOD> &rhs)
{
  return rhs * lhs;
}
template <ll MOD>
Mint<MOD> operator/(ll lhs, const Mint<MOD> &rhs)
{
  return Mint<MOD>{lhs} / rhs;
}
template <ll MOD>
istream &operator>>(istream &stream, Mint<MOD> &a)
{
  return stream >> a.x;
}
template <ll MOD>
ostream &operator<<(ostream &stream, const Mint<MOD> &a)
{
  return stream << a.x;
}
// ----- Combination -----
template <ll MOD = MOD, ll MAX_SIZE = MAX_SIZE>
class Combination
{
public:
  vector<Mint<MOD>> inv, fact, factinv;
  Combination() : inv(MAX_SIZE), fact(MAX_SIZE), factinv(MAX_SIZE)
  {
    inv[1] = 1;
    for (auto i = 2LL; i < MAX_SIZE; i++)
    {
      inv[i] = (-inv[MOD % i]) * (MOD / i);
    }
    fact[0] = factinv[0] = 1;
    for (auto i = 1LL; i < MAX_SIZE; i++)
    {
      fact[i] = Mint<MOD>(i) * fact[i - 1];
      factinv[i] = inv[i] * factinv[i - 1];
    }
  }
  Mint<MOD> operator()(int n, int k)
  {
    if (n >= 0 && k >= 0 && n - k >= 0)
    {
      return fact[n] * factinv[k] * factinv[n - k];
    }
    return 0;
  }
  Mint<MOD> catalan(int x, int y)
  {
    return (*this)(x + y, y) - (*this)(x + y, y - 1);
  }
};
// ----- for C++14 -----
using mint = Mint<MOD>;
using combination = Combination<MOD, MAX_SIZE>;
ll gcd(ll x, ll y) { return y ? gcd(y, x % y) : x; }
ll lcm(ll x, ll y) { return x / gcd(x, y) * y; }
// ----- frequently used constexpr -----
// constexpr double epsilon{1e-10};
constexpr int infty{100000};
// constexpr int dx[4] = {1, 0, -1, 0};
// constexpr int dy[4] = {0, 1, 0, -1};
// ----- Yes() and No() -----
void Yes()
{
  cout << "Yes" << endl;
  exit(0);
}
void No()
{
  cout << "No" << endl;
  exit(0);
}

// ----- SegTree -----

template <typename T>
class SegTree
{ // 0-indexed, [0, N).
private:
  int N;
  vector<T> dat;
  T unit;  // モノイドの単位元
  T(*func) // モノイドの演算
  (T, T);
  T(*_update) // update で値をどうするか書く
  (T, T);

public:
  SegTree() {}

  SegTree(int n, T unit, T (*func)(T, T), T (*_update)(T, T)) : N{1}, unit{unit}, func{func}, _update{_update}
  {
    while (N < n)
    {
      N *= 2;
    }
    dat = vector<T>(2 * N - 1, unit);
  }

  void update(int k, T a)
  {
    k += N - 1;
    dat[k] = _update(dat[k], a);
    while (k > 0)
    {
      k = (k - 1) / 2;
      dat[k] = func(dat[k * 2 + 1], dat[k * 2 + 2]);
    }
  }

private:
  T find(int a, int b, int k, int l, int r)
  {
    if (r <= a || b <= l)
    {
      return unit;
    }
    if (a <= l && r <= b)
    {
      return dat[k];
    }
    T vl = find(a, b, k * 2 + 1, l, (l + r) / 2);
    T vr = find(a, b, k * 2 + 2, (l + r) / 2, r);
    return func(vl, vr);
  }

public:
  T find(int a, int b)
  { // [a, b) の find をする。
    return find(a, b, 0, 0, N);
  }
};

// ----- frequently used examples -----

// for +
auto func2 = [](auto x, auto y) {
  return x + y;
};
auto _update2 = [](auto x, auto y) {
  return y;
};
constexpr ll unit2{0LL};

// ----- main() -----

struct Card
{
  int A, B;
};

using Info = tuple<int, int>;

int main()
{
  int N;
  cin >> N;
  vector<Card> V(N);
  for (auto i = 0; i < N; ++i)
  {
    cin >> V[i].A;
  }
  for (auto i = 0; i < N; ++i)
  {
    cin >> V[i].B;
  }
  for (auto i = 1; i < N; i += 2)
  {
    swap(V[i].A, V[i].B);
  }
  if (N == 1)
  {
    cout << 0 << endl;
    return 0;
  }
  int ans{infty};
  for (auto k = 0; k < (1 << N); ++k)
  {
    int cnt{0};
    for (auto i = 0; i < N; ++i)
    {
      cnt += (k >> i) & 1;
    }
    if (cnt == N - N / 2)
    {
      vector<Info> X, Y;
      for (auto i = 0; i < N; ++i)
      {
        if ((k >> i) & 1)
        {
          X.push_back(Info(V[i].A, i));
        }
        else
        {
          Y.push_back(Info(V[i].B, i));
        }
      }
      sort(X.begin(), X.end());
      sort(Y.begin(), Y.end());
      vector<Info> Z;
      int x = 0, y = 0;
      while (x < static_cast<int>(X.size()))
      {
        Z.push_back(X[x]);
        ++x;
        if (y < static_cast<int>(Y.size()))
        {
          Z.push_back(Y[y]);
          ++y;
        }
      }
      assert(static_cast<int>(Z.size()) == N);
      bool ok{true};
      for (auto i = 0; i < N - 1; ++i)
      {
        if (get<0>(Z[i]) > get<0>(Z[i + 1]))
        {
          ok = false;
          break;
        }
      }
      if (!ok)
      {
        continue;
      }
#if DEBUG == 1
      for (auto i = 0; i < N; ++i)
      {
        cerr << "Z[" << i << "] = (" << get<0>(Z[i]) << ", " << get<1>(Z[i]) << ")" << endl;
      }
#endif
      SegTree<ll> tree{N, unit2, func2, _update2};
      int tmp{0};
      for (auto i = 0; i < N; ++i)
      {
        int v{get<1>(Z[i])};
        tmp += tree.find(v, N);
        tree.update(v, 1);
      }
      ch_min(ans, tmp);
    }
  }
  if (ans == infty)
  {
    cout << -1 << endl;
  }
  else
  {
    cout << ans << endl;
  }
}

max_stars_repo_name: kazunetakahashi/atcoder

max_issues_repo_name: kazunetakahashi/atcoder

max_forks_repo_name: kazunetakahashi/atcoder


text:
//  (C) Copyright Gennadiy Rozental 2001-2008.
//  Distributed under the Boost Software License, Version 1.0.
//  (See accompanying file LICENSE_1_0.txt or copy at
//  http://www.boost.org/LICENSE_1_0.txt)

//  See http://www.boost.org/libs/test for the library home page.

// Boost.Runtime.Param
#include <boost/test/utils/runtime/env/variable.hpp>
#include <boost/test/utils/basic_cstring/io.hpp>

namespace rt  = boost::runtime;
namespace env = boost::runtime::env;

// STL
#include <iostream>

// Boost.Runtime.Param
#include <boost/test/utils/runtime/env/environment.hpp>
namespace rt  = boost::runtime;
namespace env = boost::runtime::environment;

// Boost.Test
#include <boost/test/utils/basic_cstring/io.hpp>

// STL
#include <iostream>

int main() {
    try {
        std::cout << env::var("ABC").value<int>();
    }
    catch ( rt::logic_error const& ex ) {
        std::cout << ex.msg();
    }

    return 0;
}

// EOF

max_stars_repo_name: randolphwong/mcsema

max_issues_repo_name: randolphwong/mcsema

max_forks_repo_name: randolphwong/mcsema


text:
//
//  Getplastic.hpp
//  hybrid_fem_bie
//
//  Created by Max on 3/20/18.
//
//

#ifndef Getplastic_hpp
#define Getplastic_hpp

#include <stdio.h>
#include <Eigen/Eigen>

using namespace Eigen;

void Getplastic(double E, double nu , VectorXd &strain, VectorXd &stress , VectorXd &stress_n, VectorXd &strain_n,double sxx_initial,
                double syy_initial, double sxy_initial, double cohes, double blkfric, MatrixXd &de_p);
#endif /* Getplastic_hpp */


text:
/****************************************************************************
 *
 * rtsp_image_transport
 * Copyright © 2021 Fraunhofer FKIE
 * Author: Timo Röhling
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 ****************************************************************************/
#include "stream_encoder.h"

#include "log_level.h"

#include <boost/format.hpp>
#include <sensor_msgs/image_encodings.h>

extern "C"
{
#include <libavformat/avformat.h>
#include <libavutil/opt.h>
#include <libswscale/swscale.h>
}

#include <ros/console.h>

#include <map>
#include <vector>

namespace rtsp_image_transport
{

namespace
{

void set_codec_option(std::shared_ptr<AVCodecContext> ctx,
                      const std::string& option, const std::string& value,
                      bool silent = false)
{
    int result = av_opt_set(ctx->priv_data, option.c_str(), value.c_str(), 0);
    if (result != 0 && !silent)
        ROS_WARN_NAMED("ffmpeg", "[%s] cannot set codec option %s=\"%s\"",
                       ctx->codec->name, option.c_str(), value.c_str());
}

void set_codec_option(std::shared_ptr<AVCodecContext> ctx,
                      const std::string& option, int value, bool silent = false)
{
    int result = av_opt_set_int(ctx->priv_data, option.c_str(), value, 0);
    if (result != 0 && !silent)
        ROS_WARN_NAMED("ffmpeg", "[%s] cannot set codec option %s=%d",
                       ctx->codec->name, option.c_str(), value);
}

void free_context(AVCodecContext* ctx)
{
    avcodec_free_context(&ctx);
}

void free_frame(AVFrame* frame)
{
    av_frame_free(&frame);
}

void free_packet(AVPacket* packet)
{
    av_packet_free(&packet);
}

#ifdef FFMPEG_HAS_HWFRAME_SUPPORT
AVPixelFormat getVAAPIFormat(AVCodecContext* ctx, const AVPixelFormat* formats)
{
    for (const AVPixelFormat* p = formats; *p != AV_PIX_FMT_NONE; ++p)
    {
        if (*p == AV_PIX_FMT_VAAPI)
            return *p;
    }
    ROS_ERROR("Hardware encoder does not support VAAPI format");
    return AV_PIX_FMT_NONE;
}

void free_buffer(AVBufferRef* buffer)
{
    av_buffer_unref(&buffer);
}
#endif

AVPixelFormat toAVPixelFormat(const sensor_msgs::Image& image)
{
    if (image.encoding == sensor_msgs::image_encodings::BGR8)
        return AV_PIX_FMT_BGR24;
    if (image.encoding == sensor_msgs::image_encodings::RGB8)
        return AV_PIX_FMT_RGB24;
    if (image.encoding == sensor_msgs::image_encodings::RGBA8)
        return AV_PIX_FMT_RGBA;
    if (image.encoding == sensor_msgs::image_encodings::BGRA8)
        return AV_PIX_FMT_BGRA;
    if (image.encoding == sensor_msgs::image_encodings::MONO8)
        return AV_PIX_FMT_GRAY8;
    if (image.encoding == sensor_msgs::image_encodings::RGB16)
        return image.is_bigendian ? AV_PIX_FMT_RGB48BE : AV_PIX_FMT_RGB48LE;
    if (image.encoding == sensor_msgs::image_encodings::BGR16)
        return image.is_bigendian ? AV_PIX_FMT_BGR48BE : AV_PIX_FMT_BGR48LE;
    if (image.encoding == sensor_msgs::image_encodings::RGBA16)
        return image.is_bigendian ? AV_PIX_FMT_RGBA64BE : AV_PIX_FMT_RGBA64LE;
    if (image.encoding == sensor_msgs::image_encodings::BGRA16)
        return image.is_bigendian ? AV_PIX_FMT_BGRA64BE : AV_PIX_FMT_BGRA64LE;
    if (image.encoding == sensor_msgs::image_encodings::MONO16)
        return image.is_bigendian ? AV_PIX_FMT_GRAY16BE : AV_PIX_FMT_GRAY16LE;
    if (image.encoding == sensor_msgs::image_encodings::YUV422)
        return AV_PIX_FMT_UYVY422;
    if (image.encoding == sensor_msgs::image_encodings::BAYER_RGGB8)
        return AV_PIX_FMT_BAYER_RGGB8;
    if (image.encoding == sensor_msgs::image_encodings::BAYER_BGGR8)
        return AV_PIX_FMT_BAYER_BGGR8;
    if (image.encoding == sensor_msgs::image_encodings::BAYER_GBRG8)
        return AV_PIX_FMT_BAYER_GBRG8;
    if (image.encoding == sensor_msgs::image_encodings::BAYER_GRBG8)
        return AV_PIX_FMT_BAYER_GRBG8;
    if (image.encoding == sensor_msgs::image_encodings::BAYER_RGGB16)
        return image.is_bigendian ? AV_PIX_FMT_BAYER_RGGB16BE
                                  : AV_PIX_FMT_BAYER_RGGB16LE;
    if (image.encoding == sensor_msgs::image_encodings::BAYER_BGGR16)
        return image.is_bigendian ? AV_PIX_FMT_BAYER_BGGR16BE
                                  : AV_PIX_FMT_BAYER_BGGR16LE;
    if (image.encoding == sensor_msgs::image_encodings::BAYER_GBRG16)
        return image.is_bigendian ? AV_PIX_FMT_BAYER_GBRG16BE
                                  : AV_PIX_FMT_BAYER_GBRG16LE;
    if (image.encoding == sensor_msgs::image_encodings::BAYER_GRBG16)
        return image.is_bigendian ? AV_PIX_FMT_BAYER_GRBG16BE
                                  : AV_PIX_FMT_BAYER_GRBG16LE;
    return AV_PIX_FMT_NONE;
}

bool scanForStartCode(const unsigned char* data, std::size_t length,
                      std::size_t offset, std::size_t& start_code_pos,
                      std::size_t& start_code_length)
{
    std::size_t i = offset, last = length - 4;
    while (i < last)
    {
        if (data[i + 2] == 0x01)
        {
            if (data[i] == 0x00 && data[i + 1] == 0x00)
            {
                start_code_pos = i;
                start_code_length = 3;
                return true;
            }
            else
            {
                i += 3;
            }
        }
        else if (data[i + 3] == 0x01)
        {
            if (data[i] == 0x00 && data[i + 1] == 0x00 && data[i + 2] == 0x00)
            {
                start_code_pos = i;
                start_code_length = 4;
                return true;
            }
            else
            {
                i += 4;
            }
        }
        else if (data[i + 3] != 0x00)
        {
            i += 4;
        }
        else if (data[i + 2] != 0x00)
        {
            i += 3;
        }
        else if (data[i + 1] != 0x00)
        {
            i += 2;
        }
        else
        {
            i += 1;
        }
    }
    return false;
}

template<class FrameContainer>
std::size_t splitNALs(FrameContainer& output, const unsigned char* data,
                      std::size_t length, const ros::Time& stamp)
{
    std::size_t nal_start, sc_len, nal_end = 0, count = 0;
    if (!scanForStartCode(data, length, 0, nal_start, sc_len))
        return 0;
    nal_start += sc_len;
    while (scanForStartCode(data, length, nal_start, nal_end, sc_len))
    {
        output.push_back(std::make_shared<FrameData>(
            data + nal_start, nal_end - nal_start, stamp));
        nal_start = nal_end + sc_len;
        count++;
    }
    output.push_back(std::make_shared<FrameData>(data + nal_start,
                                                 length - nal_start, stamp));
    return count + 1;
}

const std::map<VideoCodec, std::vector<std::string>> FFMPEG_ENCODERS{
    {VideoCodec::H264,
     {"h264_nvenc", "h264_omx", "h264_vaapi", "libx264", "h264"}},
    {VideoCodec::H265, {"hevc_nvenc", "hevc_vaapi", "libx265", "h265"}},
    {VideoCodec::MPEG4, {"mpeg4_omx", "libxvid", "mpeg4"}},
    {VideoCodec::VP8, {"vp8_vaapi", "libvpx", "vp8"}},
    {VideoCodec::VP9, {"vp9_vaapi", "libvpx-vp9", "vp9"}}};

}  // namespace

StreamEncoder::StreamEncoder(VideoCodec codec, bool use_hw_encoder)
    : codec_(codec), initialized_(false), is_vaapi_(false),
#ifdef FFMPEG_HAS_HWFRAME_SUPPORT
      hw_device_ctx_(nullptr), hw_frames_ctx_(nullptr),
#endif
      last_pixel_format_(AV_PIX_FMT_NONE), last_pts_(-1), picture_number_(0)
{
    auto encoders = FFMPEG_ENCODERS.find(codec);
    if (encoders == FFMPEG_ENCODERS.end())
        throw StreamingError(
            (boost::format("no encoder support available for %1%")
             % videoCodecName(codec))
                .str());
    for (const std::string& codec_name : encoders->second)
    {
        if (!use_hw_encoder && codec_name.find("_") != std::string::npos)
            continue;
        AVCodec* encoder = nullptr;
        try
        {
            encoder = avcodec_find_encoder_by_name(codec_name.c_str());
            if (encoder)
            {
                /* Setup encoder to see if it actually works */
                ROS_DEBUG_STREAM("[" << codec_name
                                     << "] attempting to initialize encoder");
                {
                    TemporaryAvLogLevel ll(AV_LOG_PANIC);
                    setupEncoder(encoder, true);
                    openEncoder(640, 480);
                }
                /* Encoder seems fine, now initialize it for real */
                setupEncoder(encoder, false);
                break;
            }
            else
            {
                ROS_DEBUG_STREAM("["
                                 << codec_name
                                 << "] not available in your FFmpeg library");
            }
        }
        catch (const std::exception& e)
        {
            ctx_.reset();
#ifdef FFMPEG_HAS_HWFRAME_SUPPORT
            hw_device_.reset();
            hw_frames_.reset();
#endif
            ROS_DEBUG_STREAM("[" << encoder->name << "] " << e.what());
        }
    }
    if (!ctx_)
        throw StreamingError(
            (boost::format("no usable encoder available for %1%")
             % videoCodecName(codec))
                .str());
}

void StreamEncoder::setupEncoder(AVCodec* encoder, bool silent)
{
    ctx_.reset();
#ifdef FFMPEG_HAS_HWFRAME_SUPPORT
    hw_device_.reset();
    hw_frames_.reset();
#endif
    is_vaapi_ = strstr(encoder->name, "vaapi") != nullptr;
    if (is_vaapi_)
    {
#ifdef FFMPEG_HAS_HWFRAME_SUPPORT
        char errbuf[80];
        AVBufferRef* device;
        int result;
        if ((result = av_hwdevice_ctx_create(&device, AV_HWDEVICE_TYPE_VAAPI,
                                             "/dev/dri/renderD128", nullptr, 0))
            != 0)
            throw StreamingError(
                (boost::format("failed to allocate VAAPI device context: %1%")
                 % av_make_error_string(errbuf, sizeof(errbuf), result))
                    .str());
        hw_device_.reset(device, free_buffer);
        hw_device_ctx_ = reinterpret_cast<AVHWDeviceContext*>(hw_device_->data);
#else
        throw StreamingError("FFmpeg library lacks hwframe support for VAAPI");
#endif
    }
    ctx_.reset(avcodec_alloc_context3(encoder), free_context);
    if (!ctx_)
        throw StreamingError("failed to initialize encoder context");
    ctx_->log_level_offset = 8;  // Turn errors into warnings
    ctx_->time_base = AVRational{1, 300};
    ctx_->gop_size = 30;
    ctx_->bit_rate = 1000000;  // 1MBit/s
    ctx_->framerate = AVRational{30, 1};
    ctx_->rc_min_rate = 0;
    ctx_->rc_max_rate = ctx_->bit_rate;
    ctx_->rc_buffer_size = 2 * ctx_->bit_rate;
    ctx_->flags &= ~AV_CODEC_FLAG_GLOBAL_HEADER;
    ctx_->flags |= AV_CODEC_FLAG_CLOSED_GOP;
    if (codec_ == VideoCodec::H264 || codec_ == VideoCodec::H265)
    {
        set_codec_option(ctx_, "profile", "main", silent);
        if (strstr(encoder->name, "nvenc"))
        {
            set_codec_option(ctx_, "preset", "llhp", silent);
            set_codec_option(ctx_, "zerolatency", 1, silent);
        }
        else if (strstr(encoder->name, "x26"))
        {
            set_codec_option(ctx_, "preset", "fast", silent);
            set_codec_option(ctx_, "tune", "zerolatency", silent);
        }
        if (is_vaapi_)
        {
            set_codec_option(ctx_, "rc_mode", "CQP", silent);
        }
    }
    if (codec_ == VideoCodec::H264)
    {
        if (strstr(encoder->name, "x264"))
            set_codec_option(ctx_, "b-pyramid", 0, silent);
    }
    if (codec_ == VideoCodec::VP8 || codec_ == VideoCodec::VP9)
    {
        set_codec_option(ctx_, "deadline", "realtime", silent);
    }
    if (codec_ == VideoCodec::MPEG4)
    {
        ctx_->max_b_frames = 0;
        ctx_->trellis = 1;
        ctx_->flags |= AV_CODEC_FLAG_LOW_DELAY;
    }
}

void StreamEncoder::setBitrate(unsigned long bit_rate)
{
    if (initialized_)
        throw StreamingError(
            "cannot modify bitrate after encoding has started");
    ctx_->bit_rate = bit_rate;
    ctx_->rc_max_rate = bit_rate;
}

void StreamEncoder::setFramerate(unsigned fps)
{
    if (initialized_)
        throw StreamingError(
            "cannot modify frame rate after encoding has started");
    ctx_->gop_size = fps;
    ctx_->framerate = AVRational{static_cast<int>(fps), 1};
}

void StreamEncoder::setPackageSizeHint(unsigned size)
{
    if (initialized_)
        throw StreamingError(
            "cannot modify package size hint after encoding has started");
    if (codec_ == VideoCodec::H264 && strstr(ctx_->codec->name, "x264"))
    {
        set_codec_option(ctx_, "slice-max-size", size);
    }
}

void StreamEncoder::openEncoder(int width, int height)
{
    int result;
    char errbuf[80];

    ctx_->width = width;
    ctx_->height = height;
#ifdef FFMPEG_HAS_HWFRAME_SUPPORT
    if (is_vaapi_)
    {
        AVBufferRef* frames = av_hwframe_ctx_alloc(hw_device_.get());
        if (!frames)
            throw StreamingError("failed to allocate VAAPI frame buffer");
        hw_frames_.reset(frames, free_buffer);
        hw_frames_ctx_ = reinterpret_cast<AVHWFramesContext*>(hw_frames_->data);
        hw_frames_ctx_->format = AV_PIX_FMT_VAAPI;
        hw_frames_ctx_->sw_format = AV_PIX_FMT_NV12;
        hw_frames_ctx_->width = width;
        hw_frames_ctx_->height = height;
        hw_frames_ctx_->initial_pool_size = 10;
        if ((result = av_hwframe_ctx_init(hw_frames_.get())) != 0)
        {
            throw StreamingError(
                (boost::format("failed to initialize VAAPI frame buffer: %1%")
                 % av_make_error_string(errbuf, sizeof(errbuf), result))
                    .str());
        }
        ctx_->hw_frames_ctx = av_buffer_ref(hw_frames_.get());
        ctx_->get_format = getVAAPIFormat;
        ctx_->pix_fmt = AV_PIX_FMT_VAAPI;
    }
    else
    {
        ctx_->pix_fmt = AV_PIX_FMT_YUV420P;
    }
#else
    ctx_->pix_fmt = AV_PIX_FMT_YUV420P;
#endif
    if ((result = avcodec_open2(ctx_.get(), nullptr, 0)) != 0)
    {
        throw StreamingError(
            (boost::format("failed to open encoder: %1%")
             % av_make_error_string(errbuf, sizeof(errbuf), result))
                .str());
    }
}

std::size_t StreamEncoder::encodeVideo(const sensor_msgs::Image& image)
{
    int result;
    if (!initialized_)
    {
        openEncoder(image.width, image.height);
        sw_frm_.reset(av_frame_alloc(), free_frame);
#ifdef FFMPEG_HAS_HWFRAME_SUPPORT
        if (is_vaapi_)
        {
            hw_frm_.reset(av_frame_alloc(), free_frame);
            if (av_hwframe_get_buffer(hw_frames_.get(), hw_frm_.get(), 0) != 0)
                throw StreamingError(
                    "failed to allocate HW frame from VAAPI frame buffer");
        }
#endif
        pkt_.reset(av_packet_alloc(), free_packet);
        first_ts_ = image.header.stamp;
        last_pts_ = -1;
        picture_number_ = 0;
        packets_.clear();
        last_pixel_format_ = AV_PIX_FMT_NONE;
        initialized_ = true;
    }
    if (image.width != static_cast<unsigned>(ctx_->width)
        || image.height != static_cast<unsigned>(ctx_->height))
        throw StreamingError("image size changed unexpectedly");

    AVPixelFormat av_format = toAVPixelFormat(image);
    if (av_format == AV_PIX_FMT_NONE)
        throw StreamingError(
            (boost::format("unsupported image format %1%") % image.encoding)
                .str());

    const uint8_t* input_data[] = {image.data.data()};
    int input_linesize[] = {int(image.step)};
    av_frame_unref(sw_frm_.get());
    sw_frm_->width = image.width;
    sw_frm_->height = image.height;
#ifdef FFMPEG_HAS_HWFRAME_SUPPORT
    sw_frm_->format = is_vaapi_ ? hw_frames_ctx_->sw_format : ctx_->pix_fmt;
#else
    sw_frm_->format = ctx_->pix_fmt;
#endif
    if (av_frame_get_buffer(sw_frm_.get(), 0) != 0)
        throw StreamingError("failed to allocate encoding frame buffer");

    if (!sws_ || av_format != last_pixel_format_)
    {
        sws_.reset(sws_getContext(image.width, image.height, av_format,
                                  image.width, image.height,
                                  AVPixelFormat(sw_frm_->format),
                                  SWS_FAST_BILINEAR, nullptr, nullptr, nullptr),
                   sws_freeContext);
        last_pixel_format_ = av_format;
    }
    sws_scale(sws_.get(), input_data, input_linesize, 0, image.height,
              sw_frm_->data, sw_frm_->linesize);

    AVFrame* encoder_input = sw_frm_.get();
#ifdef FFMPEG_HAS_HWFRAME_SUPPORT
    if (is_vaapi_)
    {
        av_hwframe_transfer_data(hw_frm_.get(), sw_frm_.get(), 0);
        encoder_input = hw_frm_.get();
    }
#endif
    ros::Duration d = image.header.stamp - first_ts_;
    std::int64_t pts = static_cast<std::int64_t>(300 * d.toSec());
    if (pts <= last_pts_)
        pts = last_pts_ + 1;
    encoder_input->pts = pts;
    encoder_input->display_picture_number = picture_number_++;
    last_pts_ = pts;
    if ((result = avcodec_send_frame(ctx_.get(), encoder_input)) != 0)
    {
        char errbuf[80];
        throw EncodingError(
            (boost::format("failed to send video frame to encoder: %1%")
             % av_make_error_string(errbuf, sizeof(errbuf), result))
                .str());
    }
    std::size_t count = 0;
    while ((result = avcodec_receive_packet(ctx_.get(), pkt_.get())) == 0)
    {
        if (codec_ == VideoCodec::H264 || codec_ == VideoCodec::H265)
        {
            count +=
                splitNALs(packets_, pkt_->data, pkt_->size, image.header.stamp);
        }
        else
        {
            count++;
            FrameDataPtr data = std::make_shared<FrameData>(
                pkt_->data, pkt_->size, image.header.stamp);
            packets_.push_back(data);
        }
    }
    av_packet_unref(pkt_.get());
    if (result != AVERROR(EAGAIN))
    {
        char errbuf[80];
        throw EncodingError(
            (boost::format("failed to receive packets from encoder: %1%")
             % av_make_error_string(errbuf, sizeof(errbuf), result))
                .str());
    }
    return count;
}

FrameDataPtr StreamEncoder::nextPacket() noexcept
{
    if (packets_.empty())
        return FrameDataPtr();
    FrameDataPtr data = packets_.front();
    packets_.pop_front();
    return data;
}

VideoCodec StreamEncoder::codec() const noexcept
{
    return codec_;
}

AVCodecContext* StreamEncoder::context() noexcept
{
    return ctx_.get();
}

}  // namespace rtsp_image_transport


text:
#include "decompressor.hpp"

#include <boost/circular_buffer.hpp>

using namespace std;
using namespace szxx;

decompressor::decompressor(const char* in_file,
                           const char* out_file)
		: is{ in_file, ios::binary }
		, os{ out_file, ios::binary } {
}

decompressor::~decompressor() {
	os.flush();
}

void decompressor::run() {
	boost::circular_buffer<char> back_buf { 512 };

	auto n = 0u;
	while (true) {
		char ctuple[3];
		is.read(ctuple, sizeof(ctuple));
		if (is.eof()) {
			auto char_count = is.gcount();
			if (char_count != 0 && char_count != size(ctuple)) {
				throw runtime_error("Invalid format of input file.");
			}
			break;
		}

		const auto& offset = ctuple[0];
		const auto& length = ctuple[1];
		const auto& symbol = ctuple[2];

		auto match_begin = back_buf.end() - (unsigned char) offset;
		auto match_end = match_begin + (unsigned char) length;
		copy(match_begin, match_end, ostream_iterator<char>(os));
		copy(match_begin, match_end, back_inserter(back_buf));
		os.write((char *) &symbol, 1);
		back_buf.push_back(symbol);
		n++;
	}
	cout << "Decompressed " << n << " tuples." << endl;
}

max_stars_repo_name: tonyganchev/stoyozipxx

max_issues_repo_name: tonyganchev/stoyozipxx

max_forks_repo_name: tonyganchev/stoyozipxx


text:
///////////////////////////////////////////////////////////////////////////////
// debug_out.hpp
//
// Copyright (c) 2009 Dmitry Timoshenko.
//
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
// smart++ Multipurpose C++ Library.

/** @file debug_out.hpp Debug logger.
 *
 *  Provides stream interface and maps output to system debug console.
 *  On linux platrom writes to rsyslog using LOG_DEBUG flag.
 */

#ifdef _MSC_VER
# pragma once
#endif // _MSC_VER

#ifndef SMART_DEBUG_OUT_HPP_
#define SMART_DEBUG_OUT_HPP_

#define SMART_SHORT_LIB_NAME "debug_out"
#include <smart/config/auto_link.hpp>
#undef SMART_SHORT_LIB_NAME

#ifdef SMART_VISUAL_CPP
# pragma warning (push)
# pragma warning (disable : 4511) // copy constructor could not be generated
# pragma warning (disable : 4512) // assignment operator could not be generated
# pragma warning (disable : 4702) // unreachable code
# pragma warning (disable : 4996)
#endif // SMART_VISUAL_CPP

#include <boost/iostreams/concepts.hpp>
#include <boost/iostreams/stream.hpp>
#include <boost/thread/thread.hpp>
#include <boost/thread/mutex.hpp>

#ifdef SMART_VISUAL_CPP
# pragma warning (pop)
#endif // SMART_VISUAL_CPP

#include <ostream>

namespace smart
{

/** debug_sink class.
 *
 *  Provides operation which puts data into system debug console.
 *  Under windows uses OutputDebugString to write to debugger console.
 *  Under linux uses rsyslog services, calls syslog(LOG_DEBUG, "%s", s.c_str());
 *
 *  @see openlog, syslog.
 */
class debug_sink : public boost::iostreams::sink
{
public:
  std::streamsize write(const char* s, std::streamsize n);
};

/** mt_debug_sink class.
 *
 *  Provides thread safe operation which puts data into system debug console.
 *  Under windows uses OutputDebugString to write to debugger console.
 *  Under linux uses rsyslog services, calls syslog(LOG_DEBUG, "%s", s.c_str());
 *
 *  @see openlog, syslog.
 */
class mt_debug_sink : public boost::iostreams::sink
{
public:
  std::streamsize write(const char* s, std::streamsize n);
};

/** Debug sink stream type. */
typedef boost::iostreams::stream<debug_sink> debug_sink_stream_type;

/** Multi threading debug sink stream type. */
typedef boost::iostreams::stream<mt_debug_sink> mt_debug_sink_stream_type;

/** Debug output stream.
 *
 *  Singleton implementation.
 */
debug_sink_stream_type& debug_ostream(void);

/** Multi threading debug output stream.
 *
 *  Singleton implementation.
 */
mt_debug_sink_stream_type& mt_debug_ostream(void);

namespace detail
{

//////////////////////////////////////////////////////////////////////////
// stream locker
struct locker
{
  locker(void): _lock(mutex()) { /* empty */ }

private:
  boost::mutex::scoped_lock _lock;

  static boost::mutex& mutex(void) { static boost::mutex m; return m; }
};

template<typename CharT, typename TraitsT>
inline std::basic_ostream<CharT, TraitsT>&
operator<<(std::basic_ostream<CharT, TraitsT>& os, const smart::detail::locker&)
{
  return os;
}

} // namespace detail

} // namespace smart

#ifdef SMART_DEBUG
/** Debug output macros. */
# define SMART_DEBUG_OUT(expr) { smart::debug_ostream() << \
  std::dec << __FILE__ << "[" << __LINE__ << "]: " << expr << std::endl; }
# define SMART_MT_DEBUG_OUT(expr) { smart::debug_ostream() << smart::detail::locker() \
  << std::dec << __FILE__ << "[" << __LINE__ << "]: (" << std::hex << std::showbase \
  << boost::this_thread::get_id() << ") " << std::dec << expr << std::endl; }
#else
# define SMART_DEBUG_OUT(expr)
# define SMART_MT_DEBUG_OUT(expr)
#endif // SMART_DEBUG

/** Debug output macros.
 *
 *  @deprecated Use SMART_DEBUG_OUT instead.
 */
#define SIMPLE_DEBUG_OUT(expr) SMART_DEBUG_OUT(expr)

/** Checks if debug configuration is used and throws out expression if not. */
#ifdef SMART_DEBUG
# define SMART_IFDEF_DEBUG(expr) expr
#else
# define SMART_IFDEF_DEBUG(expr)
#endif // #ifdef SMART_DEBUG

#endif // SMART_DEBUG_OUT_HPP_

max_stars_repo_name: Chrizzly/libunicomm

max_issues_repo_name: Chrizzly/libunicomm

max_forks_repo_name: Chrizzly/libunicomm


text:
/* HOG DETECTOR
 *
 */

#include <dlib/svm_threaded.h>
#include <dlib/gui_widgets.h>
#include <dlib/image_processing.h>
#include <dlib/data_io.h>
#include <dlib/image_transforms.h>
#include <dlib/cmd_line_parser.h>

#include <iostream>
#include <fstream>
#include <cstdlib>

using namespace std;
using namespace dlib;

struct TrafficSign {
  string name;
  string svm_path;
  rgb_pixel color;
  TrafficSign(string name, string svm_path, rgb_pixel color) :
    name(name), svm_path(svm_path), color(color) {};
};

int main(int argc, char** argv) {
  try {
    command_line_parser parser;

    parser.add_option("h","Display this help message.");
    parser.add_option("u", "Upsample each input image <arg> times. Each \
                      upsampling quadruples the number of pixels in the image \
                      (default: 0).", 1);
    parser.add_option("wait","Wait user input to show next image.");

    parser.parse(argc, argv);
    parser.check_option_arg_range("u", 0, 8);

    const char* one_time_opts[] = {"h","u","wait"};
    parser.check_one_time_options(one_time_opts);

    // Display help message
    if (parser.option("h")) {
      cout << "Usage: " << argv[0] << " [options] <list of images>" << endl;
      parser.print_options();

      return EXIT_SUCCESS;
    }

    if (parser.number_of_arguments() == 0) {
      cout << "You must give a list of input files." << endl;
      cout << "\nTry the -h option for more information." << endl;
      return EXIT_FAILURE;
    }

    const unsigned long upsample_amount = get_option(parser, "u", 0);

    dlib::array<array2d<unsigned char> > images;

    images.resize(parser.number_of_arguments());

    for (unsigned long i = 0; i < images.size(); ++i) {
      load_image(images[i], parser[i]);
    }

    for (unsigned long i = 0; i < upsample_amount; ++i) {
      for (unsigned long j = 0; j < images.size(); ++j) {
        pyramid_up(images[j]);
      }
    }

    typedef scan_fhog_pyramid<pyramid_down<6> > image_scanner_type;

    // Load SVM detectors
    std::vector<TrafficSign> signs;
    signs.push_back(TrafficSign("PARE", "svm_detectors/pare_detector.svm",
                                rgb_pixel(255,0,0)));
    signs.push_back(TrafficSign("LOMBADA", "svm_detectors/lombada_detector.svm",
                                rgb_pixel(255,122,0)));
    signs.push_back(TrafficSign("PEDESTRE", "svm_detectors/pedestre_detector.svm",
                                rgb_pixel(255,255,0)));

    std::vector<object_detector<image_scanner_type> > detectors;

    for (int i = 0; i < signs.size(); i++) {
      object_detector<image_scanner_type> detector;
      deserialize(signs[i].svm_path) >> detector;
      detectors.push_back(detector);
    }

    image_window win;
    std::vector<rect_detection> rects;
    for (unsigned long i = 0; i < images.size(); ++i) {
      evaluate_detectors(detectors, images[i], rects);

      // Put the image and detections into the window.
      win.clear_overlay();
      win.set_image(images[i]);

      for (unsigned long j = 0; j < rects.size(); ++j) {
        win.add_overlay(rects[j].rect, signs[rects[j].weight_index].color,
                        signs[rects[j].weight_index].name);
      }

      if (parser.option("wait")) {
        cout << "Press any key to continue...";
        cin.get();
      }
    }
  }
  catch (exception& e) {
    cout << "\nexception thrown!" << endl;
    cout << e.what() << endl;
  }
}

max_stars_repo_name: ifding/self-driving-car

max_issues_repo_name: ifding/autonomous-vehicles

max_forks_repo_name: ifding/autonomous-vehicles