<commit_before>/*
 *  soundpicker.cpp  -  widget to select a sound file or a beep
 *  Program:  kalarm
 *  (C) 2002, 2004 by David Jarvie <software@astrojar.org.uk>
 *
 *  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.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 *
 *  In addition, as a special exception, the copyright holders give permission
 *  to link the code of this program with any edition of the Qt library by
 *  Trolltech AS, Norway (or with modified versions of Qt that use the same
 *  license as Qt), and distribute linked combinations including the two.
 *  You must obey the GNU General Public License in all respects for all of
 *  the code used other than Qt.  If you modify this file, you may extend
 *  this exception to your version of the file, but you are not obligated to
 *  do so. If you do not wish to do so, delete this exception statement from
 *  your version.
 */

#include "kalarm.h"

#include <qlayout.h>
#include <qregexp.h>
#include <qtooltip.h>
#include <qwhatsthis.h>

#include <kglobal.h>
#include <klocale.h>
#include <kfiledialog.h>
#include <kstandarddirs.h>
#include <kiconloader.h>
#ifndef WITHOUT_ARTS
#include <arts/kplayobjectfactory.h>
#endif

#include "checkbox.h"
#include "pushbutton.h"
#include "slider.h"
#include "soundpicker.moc"

// Collect these widget labels together to ensure consistent wording and
// translations across different modules.
QString SoundPicker::i18n_Sound()       { return i18n("An audio sound", "Sound"); }
QString SoundPicker::i18n_s_Sound()     { return i18n("An audio sound", "&Sound"); }
QString SoundPicker::i18n_SetVolume()   { return i18n("Set volume"); }
QString SoundPicker::i18n_v_SetVolume() { return i18n("Set &volume"); }
QString SoundPicker::i18n_Repeat()      { return i18n("Repeat"); }
QString SoundPicker::i18n_p_Repeat()    { return i18n("Re&peat"); }

SoundPicker::SoundPicker(QWidget* parent, const char* name)
	: QFrame(parent, name)
{
	// Sound checkbox
	setFrameStyle(QFrame::NoFrame);
	QHBoxLayout* soundLayout = new QHBoxLayout(this, 0, 2*KDialog::spacingHint());
	soundLayout->setAlignment(Qt::AlignVCenter);
	mCheckbox = new CheckBox(i18n_s_Sound(), this);
	mCheckbox->setFixedSize(mCheckbox->sizeHint());
	connect(mCheckbox, SIGNAL(toggled(bool)), SLOT(slotSoundToggled(bool)));
	QWhatsThis::add(mCheckbox,
	      i18n("If checked, a sound will be played when the message is displayed. Click the "
	           "button on the right to select the sound."));
	soundLayout->addWidget(mCheckbox);

	// Sound file picker button
	mFilePicker = new PushButton(this);
	mFilePicker->setPixmap(SmallIcon("playsound"));
	mFilePicker->setFixedSize(mFilePicker->sizeHint());
	mFilePicker->setToggleButton(true);
	connect(mFilePicker, SIGNAL(clicked()), SLOT(slotPickFile()));
	QWhatsThis::add(mFilePicker,
	      i18n("Select a sound file to play when the message is displayed. If no sound file is "
	           "selected, a beep will sound."));
	soundLayout->addWidget(mFilePicker);

	// Sound repetition checkbox
	mRepeatCheckbox = new CheckBox(i18n_p_Repeat(), this);
	mRepeatCheckbox->setFixedSize(mRepeatCheckbox->sizeHint());
	QWhatsThis::add(mRepeatCheckbox,
	      i18n("If checked, the sound file will be played repeatedly for as long as the message is displayed."));
	soundLayout->addWidget(mRepeatCheckbox);

	// Set volume checkbox
	mVolumeCheckbox = new CheckBox(i18n_v_SetVolume(), this);
	mVolumeCheckbox->setFixedSize(mVolumeCheckbox->sizeHint());
	connect(mVolumeCheckbox, SIGNAL(toggled(bool)), SLOT(slotVolumeToggled(bool)));
	QWhatsThis::add(mVolumeCheckbox,
	      i18n("Select to choose the volume for playing the sound file."));
	soundLayout->addWidget(mVolumeCheckbox);

	// Volume slider
	mVolumeSlider = new Slider(0, 100, 10, 0, Qt::Horizontal, this);
	mVolumeSlider->setFixedSize(mVolumeSlider->sizeHint());
	QWhatsThis::add(mVolumeSlider,
	      i18n("Choose the volume for playing the sound file."));
	mVolumeCheckbox->setFocusWidget(mVolumeSlider);
	soundLayout->addWidget(mVolumeSlider);
	soundLayout->addStretch();

#ifdef WITHOUT_ARTS
	mRepeatCheckbox->hide();
	mVolumeCheckbox->hide();
	mVolumeSlider->hide();
#endif

	// Initialise the file picker button state and tooltip
	slotSoundToggled(false);
}

/******************************************************************************
 * Set the read-only status of the widget.
 */
void SoundPicker::setReadOnly(bool readOnly)
{
	mCheckbox->setReadOnly(readOnly);
	mFilePicker->setReadOnly(readOnly);
	mVolumeCheckbox->setReadOnly(readOnly);
	mRepeatCheckbox->setReadOnly(readOnly);
	mVolumeSlider->setReadOnly(readOnly);
}

/******************************************************************************
 * Return whether beep is selected.
 */
bool SoundPicker::beep() const
{
	return mCheckbox->isChecked()  &&  !mFilePicker->isOn();
}

/******************************************************************************
 * Return the selected sound file, if the main checkbox is checked.
 * Returns null string if beep is currently selected.
 */
QString SoundPicker::file() const
{
	return mCheckbox->isChecked() && mFilePicker->isOn() ? mFile : QString::null;
}

/******************************************************************************
 * Return the specified volume (range 0 - 1).
 * Returns < 0 if beep is currently selected, or if 'set volume' is not selected.
 */
float SoundPicker::volume() const
{
	return mVolumeSlider->isEnabled() ? (float)mVolumeSlider->value() / 100 : -1;
}

/******************************************************************************
 * Return whether sound file repetition is selected, if the main checkbox is checked.
 * Returns false if beep is currently selected.
 */
bool SoundPicker::repeat() const
{
	return mCheckbox->isChecked() && mFilePicker->isOn() && !mFile.isEmpty() && mRepeatCheckbox->isChecked();
}

/******************************************************************************
 * Return whether repetition is selected, regardless of the current beep and
 * file settings.
 */
bool SoundPicker::repeatSetting() const
{
	return mRepeatCheckbox->isChecked();
}

/******************************************************************************
 * Initialise the widget's state.
 */
void SoundPicker::set(bool beep, const QString& f, float volume, bool repeat)
{
	mCheckbox->setChecked(beep || !f.isEmpty());
	setFile(!beep  &&  !f.isEmpty(), f, volume, repeat);
}

/******************************************************************************
 * Set sound on or off.
 */
void SoundPicker::setChecked(bool on)
{
	mCheckbox->setChecked(on);
}

/******************************************************************************
 * Set the current beep status.
 */
void SoundPicker::setBeep(bool beep)
{
	mFilePicker->setOn(!beep);
	setFilePicker();
}

/******************************************************************************
 * Set the current sound file selection, volume and repetition status.
 */
void SoundPicker::setFile(bool on, const QString& f, float volume, bool repeat)
{
	mFile = f;
	mVolumeCheckbox->setChecked(volume >= 0);
	mVolumeSlider->setValue(volume >= 0 ? volume*100 : 100);
	mRepeatCheckbox->setChecked(repeat);
	mFilePicker->setOn(on);
	setFilePicker();
}

/******************************************************************************
 * Called when the sound checkbox is toggled.
 */
void SoundPicker::slotSoundToggled(bool on)
{
	mFilePicker->setEnabled(on);
	setFilePicker();
}

/******************************************************************************
 * Called when the Set Volume checkbox is toggled.
 */
void SoundPicker::slotVolumeToggled(bool on)
{
	mVolumeSlider->setEnabled(on && mVolumeCheckbox->isEnabled());
}

/******************************************************************************
 * Called when the file picker button is clicked.
 */
void SoundPicker::slotPickFile()
{
	if (mFilePicker->isOn())
	{
		KURL url = browseFile(mFile, mDefaultDir);
		if (!url.isEmpty())
		{
			mFile = url.prettyURL();
			mDefaultDir = url.path();
			setFilePicker();
		}
		else if (mFile.isEmpty())
			mFilePicker->setOn(false);
	}
	setFilePicker();
}

/******************************************************************************
 * Display a dialogue to choose a sound file, initially highlighting any
 * specified file. 'initialFile' must be a full path name or URL.
 * Reply = URL selected. If none is selected, URL.isEmpty() is true.
 */
KURL SoundPicker::browseFile(const QString& initialFile, const QString& defaultDir)
{
	QString initialDir = !initialFile.isEmpty() ? QString(initialFile).remove(QRegExp("/[^/]*$"))
	                   : !defaultDir.isEmpty()  ? defaultDir
	                   : KGlobal::dirs()->findResourceDir("sound", "KDE_Notify.wav");
#ifdef WITHOUT_ARTS
	KFileDialog fileDlg(initialDir, QString::fromLatin1("*.wav *.mp3 *.ogg|%1\n*|%2").arg(i18n("Sound Files")).arg(i18n("All Files")), 0, "soundFileDlg", true);
#else
	KFileDialog fileDlg(initialDir, KDE::PlayObjectFactory::mimeTypes().join(" "), 0, "soundFileDlg", true);
#endif
	fileDlg.setCaption(i18n("Choose Sound File"));
	fileDlg.setMode(KFile::File | KFile::ExistingOnly);
	if (!initialFile.isEmpty())
		fileDlg.setSelection(initialFile);
	if (fileDlg.exec() == QDialog::Accepted)
		return fileDlg.selectedURL();
	return KURL();
}

/******************************************************************************
 * Set the sound picker button according to whether a sound file is selected.
 */
void SoundPicker::setFilePicker()
{
	bool file = false;
	QToolTip::remove(mFilePicker);
	if (mFilePicker->isEnabled())
	{
		file = mFilePicker->isOn();
		if (mFilePicker->isOn())
			QToolTip::add(mFilePicker, i18n("Play '%1'").arg(mFile));
		else
			QToolTip::add(mFilePicker, i18n("Beep"));
	}
	mVolumeCheckbox->setEnabled(file);
	mRepeatCheckbox->setEnabled(file);
	mVolumeSlider->setEnabled(file && mVolumeCheckbox->isChecked());
}
<commit_msg>Fix bug where sound file is selected even when Cancel is pressed<commit_after>/*
 *  soundpicker.cpp  -  widget to select a sound file or a beep
 *  Program:  kalarm
 *  (C) 2002, 2004 by David Jarvie <software@astrojar.org.uk>
 *
 *  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.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 *
 *  In addition, as a special exception, the copyright holders give permission
 *  to link the code of this program with any edition of the Qt library by
 *  Trolltech AS, Norway (or with modified versions of Qt that use the same
 *  license as Qt), and distribute linked combinations including the two.
 *  You must obey the GNU General Public License in all respects for all of
 *  the code used other than Qt.  If you modify this file, you may extend
 *  this exception to your version of the file, but you are not obligated to
 *  do so. If you do not wish to do so, delete this exception statement from
 *  your version.
 */

#include "kalarm.h"

#include <qlayout.h>
#include <qregexp.h>
#include <qtooltip.h>
#include <qwhatsthis.h>

#include <kglobal.h>
#include <klocale.h>
#include <kfiledialog.h>
#include <kstandarddirs.h>
#include <kiconloader.h>
#ifndef WITHOUT_ARTS
#include <arts/kplayobjectfactory.h>
#endif

#include "checkbox.h"
#include "pushbutton.h"
#include "slider.h"
#include "soundpicker.moc"

// Collect these widget labels together to ensure consistent wording and
// translations across different modules.
QString SoundPicker::i18n_Sound()       { return i18n("An audio sound", "Sound"); }
QString SoundPicker::i18n_s_Sound()     { return i18n("An audio sound", "&Sound"); }
QString SoundPicker::i18n_SetVolume()   { return i18n("Set volume"); }
QString SoundPicker::i18n_v_SetVolume() { return i18n("Set &volume"); }
QString SoundPicker::i18n_Repeat()      { return i18n("Repeat"); }
QString SoundPicker::i18n_p_Repeat()    { return i18n("Re&peat"); }

SoundPicker::SoundPicker(QWidget* parent, const char* name)
	: QFrame(parent, name)
{
	// Sound checkbox
	setFrameStyle(QFrame::NoFrame);
	QHBoxLayout* soundLayout = new QHBoxLayout(this, 0, 2*KDialog::spacingHint());
	soundLayout->setAlignment(Qt::AlignVCenter);
	mCheckbox = new CheckBox(i18n_s_Sound(), this);
	mCheckbox->setFixedSize(mCheckbox->sizeHint());
	connect(mCheckbox, SIGNAL(toggled(bool)), SLOT(slotSoundToggled(bool)));
	QWhatsThis::add(mCheckbox,
	      i18n("If checked, a sound will be played when the message is displayed. Click the "
	           "button on the right to select the sound."));
	soundLayout->addWidget(mCheckbox);

	// Sound file picker button
	mFilePicker = new PushButton(this);
	mFilePicker->setPixmap(SmallIcon("playsound"));
	mFilePicker->setFixedSize(mFilePicker->sizeHint());
	mFilePicker->setToggleButton(true);
	connect(mFilePicker, SIGNAL(clicked()), SLOT(slotPickFile()));
	QWhatsThis::add(mFilePicker,
	      i18n("Select a sound file to play when the message is displayed. If no sound file is "
	           "selected, a beep will sound."));
	soundLayout->addWidget(mFilePicker);

	// Sound repetition checkbox
	mRepeatCheckbox = new CheckBox(i18n_p_Repeat(), this);
	mRepeatCheckbox->setFixedSize(mRepeatCheckbox->sizeHint());
	QWhatsThis::add(mRepeatCheckbox,
	      i18n("If checked, the sound file will be played repeatedly for as long as the message is displayed."));
	soundLayout->addWidget(mRepeatCheckbox);

	// Set volume checkbox
	mVolumeCheckbox = new CheckBox(i18n_v_SetVolume(), this);
	mVolumeCheckbox->setFixedSize(mVolumeCheckbox->sizeHint());
	connect(mVolumeCheckbox, SIGNAL(toggled(bool)), SLOT(slotVolumeToggled(bool)));
	QWhatsThis::add(mVolumeCheckbox,
	      i18n("Select to choose the volume for playing the sound file."));
	soundLayout->addWidget(mVolumeCheckbox);

	// Volume slider
	mVolumeSlider = new Slider(0, 100, 10, 0, Qt::Horizontal, this);
	mVolumeSlider->setFixedSize(mVolumeSlider->sizeHint());
	QWhatsThis::add(mVolumeSlider,
	      i18n("Choose the volume for playing the sound file."));
	mVolumeCheckbox->setFocusWidget(mVolumeSlider);
	soundLayout->addWidget(mVolumeSlider);
	soundLayout->addStretch();

#ifdef WITHOUT_ARTS
	mRepeatCheckbox->hide();
	mVolumeCheckbox->hide();
	mVolumeSlider->hide();
#endif

	// Initialise the file picker button state and tooltip
	slotSoundToggled(false);
}

/******************************************************************************
 * Set the read-only status of the widget.
 */
void SoundPicker::setReadOnly(bool readOnly)
{
	mCheckbox->setReadOnly(readOnly);
	mFilePicker->setReadOnly(readOnly);
	mVolumeCheckbox->setReadOnly(readOnly);
	mRepeatCheckbox->setReadOnly(readOnly);
	mVolumeSlider->setReadOnly(readOnly);
}

/******************************************************************************
 * Return whether beep is selected.
 */
bool SoundPicker::beep() const
{
	return mCheckbox->isChecked()  &&  !mFilePicker->isOn();
}

/******************************************************************************
 * Return the selected sound file, if the main checkbox is checked.
 * Returns null string if beep is currently selected.
 */
QString SoundPicker::file() const
{
	return mCheckbox->isChecked() && mFilePicker->isOn() ? mFile : QString::null;
}

/******************************************************************************
 * Return the specified volume (range 0 - 1).
 * Returns < 0 if beep is currently selected, or if 'set volume' is not selected.
 */
float SoundPicker::volume() const
{
	return mVolumeSlider->isEnabled() ? (float)mVolumeSlider->value() / 100 : -1;
}

/******************************************************************************
 * Return whether sound file repetition is selected, if the main checkbox is checked.
 * Returns false if beep is currently selected.
 */
bool SoundPicker::repeat() const
{
	return mCheckbox->isChecked() && mFilePicker->isOn() && !mFile.isEmpty() && mRepeatCheckbox->isChecked();
}

/******************************************************************************
 * Return whether repetition is selected, regardless of the current beep and
 * file settings.
 */
bool SoundPicker::repeatSetting() const
{
	return mRepeatCheckbox->isChecked();
}

/******************************************************************************
 * Initialise the widget's state.
 */
void SoundPicker::set(bool beep, const QString& f, float volume, bool repeat)
{
	mCheckbox->setChecked(beep || !f.isEmpty());
	setFile(!beep  &&  !f.isEmpty(), f, volume, repeat);
}

/******************************************************************************
 * Set sound on or off.
 */
void SoundPicker::setChecked(bool on)
{
	mCheckbox->setChecked(on);
}

/******************************************************************************
 * Set the current beep status.
 */
void SoundPicker::setBeep(bool beep)
{
	mFilePicker->setOn(!beep);
	setFilePicker();
}

/******************************************************************************
 * Set the current sound file selection, volume and repetition status.
 */
void SoundPicker::setFile(bool on, const QString& f, float volume, bool repeat)
{
	mFile = f;
	mVolumeCheckbox->setChecked(volume >= 0);
	mVolumeSlider->setValue(volume >= 0 ? volume*100 : 100);
	mRepeatCheckbox->setChecked(repeat);
	mFilePicker->setOn(on);
	setFilePicker();
}

/******************************************************************************
 * Called when the sound checkbox is toggled.
 */
void SoundPicker::slotSoundToggled(bool on)
{
	mFilePicker->setEnabled(on);
	setFilePicker();
}

/******************************************************************************
 * Called when the Set Volume checkbox is toggled.
 */
void SoundPicker::slotVolumeToggled(bool on)
{
	mVolumeSlider->setEnabled(on && mVolumeCheckbox->isEnabled());
}

/******************************************************************************
 * Called when the file picker button is clicked.
 */
void SoundPicker::slotPickFile()
{
	if (mFilePicker->isOn())
	{
		KURL url = browseFile(mFile, mDefaultDir);
		if (!url.isEmpty())
		{
			mFile = url.prettyURL();
			mDefaultDir = url.path();
			setFilePicker();
		}
		else
			mFilePicker->setOn(false);
	}
	setFilePicker();
}

/******************************************************************************
 * Display a dialogue to choose a sound file, initially highlighting any
 * specified file. 'initialFile' must be a full path name or URL.
 * Reply = URL selected. If none is selected, URL.isEmpty() is true.
 */
KURL SoundPicker::browseFile(const QString& initialFile, const QString& defaultDir)
{
	QString initialDir = !initialFile.isEmpty() ? QString(initialFile).remove(QRegExp("/[^/]*$"))
	                   : !defaultDir.isEmpty()  ? defaultDir
	                   : KGlobal::dirs()->findResourceDir("sound", "KDE_Notify.wav");
#ifdef WITHOUT_ARTS
	KFileDialog fileDlg(initialDir, QString::fromLatin1("*.wav *.mp3 *.ogg|%1\n*|%2").arg(i18n("Sound Files")).arg(i18n("All Files")), 0, "soundFileDlg", true);
#else
	KFileDialog fileDlg(initialDir, KDE::PlayObjectFactory::mimeTypes().join(" "), 0, "soundFileDlg", true);
#endif
	fileDlg.setCaption(i18n("Choose Sound File"));
	fileDlg.setMode(KFile::File | KFile::ExistingOnly);
	if (!initialFile.isEmpty())
		fileDlg.setSelection(initialFile);
	if (fileDlg.exec() == QDialog::Accepted)
		return fileDlg.selectedURL();
	return KURL();
}

/******************************************************************************
 * Set the sound picker button according to whether a sound file is selected.
 */
void SoundPicker::setFilePicker()
{
	bool file = false;
	QToolTip::remove(mFilePicker);
	if (mFilePicker->isEnabled())
	{
		file = mFilePicker->isOn();
		if (mFilePicker->isOn())
			QToolTip::add(mFilePicker, i18n("Play '%1'").arg(mFile));
		else
			QToolTip::add(mFilePicker, i18n("Beep"));
	}
	mVolumeCheckbox->setEnabled(file);
	mRepeatCheckbox->setEnabled(file);
	mVolumeSlider->setEnabled(file && mVolumeCheckbox->isChecked());
}
<|endoftext|>


<commit_before>#include "exon.h"

#include <cstdlib>
#include <iostream>
#include <sstream>
#include <cassert>
#include <cstdio>

exon::exon(const string &s)
{
	parse(s);
}

int exon::parse(const string &s)
{
	char buf[10240];
	stringstream sstr(s);
	sstr>>buf;
	seqname.assign(buf);
	sstr>>buf;
	source.assign(buf);
	sstr>>buf;
	feature.assign(buf);
	sstr>>start>>end;
	start--;			// gtf: (from 1, both inclusive)
	sstr>>buf;
	if(buf[0] == '.') score = -1;
	else score = atof(buf);
	sstr>>buf;
	strand = buf[0];
	sstr>>buf;
	frame = buf[0];

	char buf2[10240];
	expression = 0;
	coverage = 0;
	while(sstr.eof() == false)
	{
		sstr>>buf;
		sstr.getline(buf2, 10240, '"');
		sstr.getline(buf2, 10240, '"');
		string v(buf2);
		if(string(buf) == "" || v == "") break;

		//printf(" |%s|%s|%lu|%lu|\n", buf, k.c_str(), p1, p2);

		if(string(buf) == "transcript_id") transcript_id = v;
		else if(string(buf) == "gene_id") gene_id = v;
		else if(string(buf) == "expression") expression = atoi(v.c_str());
		else if(string(buf) == "coverage") coverage = atof(v.c_str());
		else if(string(buf) == "numreads") numreads = atoi(v.c_str());
		else if(string(buf) == "RPKM") RPKM = atof(v.c_str());

		sstr.getline(buf2, 10240, ';');
	}

	return 0;
}

int exon::print() const
{
	printf("%s\t%s\t%s\t%d\t%d\t%.1lf\t%c\t%c\ttranscript_id \"%s\"; gene_id \"%s\"; expression \"%d\"; coverage \"%.2f\"; numreads \"%d\"; RPKM \"%.2lf\"\n",
			seqname.c_str(), source.c_str(), feature.c_str(), start, end, score, strand, frame,
			transcript_id.c_str(), gene_id.c_str(), expression, coverage, numreads, RPKM);
	return 0;
}

bool exon::operator<(const exon &ge) const
{
	if(start < ge.start) return true;
	else return false;
}

int exon::length() const
{
	assert(end > start);
	return end - start;
}
<commit_msg>update reading exons<commit_after>#include "exon.h"

#include <cstdlib>
#include <iostream>
#include <sstream>
#include <cassert>
#include <cstdio>

exon::exon(const string &s)
{
	parse(s);
}

int exon::parse(const string &s)
{
	char buf[10240];
	stringstream sstr(s);
	sstr>>buf;
	seqname.assign(buf);
	sstr>>buf;
	source.assign(buf);
	sstr>>buf;
	feature.assign(buf);
	sstr>>start>>end;
	start--;			// gtf: (from 1, both inclusive)
	sstr>>buf;
	if(buf[0] == '.') score = -1;
	else score = atof(buf);
	sstr>>buf;
	strand = buf[0];
	sstr>>buf;
	frame = buf[0];

	char buf2[10240];
	expression = 0;
	coverage = 0;
	while(sstr.eof() == false)
	{
		sstr>>buf;
		/*
		sstr.getline(buf2, 10240, '"');
		sstr.getline(buf2, 10240, '"');
		*/
		sstr.getline(buf2, 10240, ';');
		string v(buf2);
		int k1 = v.find('"');
		int k2 = v.rfind('"');
		if(k1 >= 0 && k1 < k2 && k2 < v.size()) v = v.substr(k1 + 1, k2 - k1 - 1);

		if(string(buf) == "" || v == "") break;

		printf("|%s|%s|\n", buf, v.c_str());

		if(string(buf) == "transcript_id") transcript_id = v;
		else if(string(buf) == "gene_id") gene_id = v;
		else if(string(buf) == "expression") expression = atoi(v.c_str());
		else if(string(buf) == "cov") coverage = atof(v.c_str());
		else if(string(buf) == "coverage") coverage = atof(v.c_str());
		else if(string(buf) == "numreads") numreads = atoi(v.c_str());
		else if(string(buf) == "RPKM") RPKM = atof(v.c_str());

		//sstr.getline(buf2, 10240, ';');
	}

	return 0;
}

int exon::print() const
{
	printf("%s\t%s\t%s\t%d\t%d\t%.1lf\t%c\t%c\ttranscript_id \"%s\"; gene_id \"%s\"; expression \"%d\"; coverage \"%.2f\"; numreads \"%d\"; RPKM \"%.2lf\"\n",
			seqname.c_str(), source.c_str(), feature.c_str(), start, end, score, strand, frame,
			transcript_id.c_str(), gene_id.c_str(), expression, coverage, numreads, RPKM);
	return 0;
}

bool exon::operator<(const exon &ge) const
{
	if(start < ge.start) return true;
	else return false;
}

int exon::length() const
{
	assert(end > start);
	return end - start;
}
<|endoftext|>


<commit_before>

#include <os.h>
#include <ext2.h>

File* ext2_mount(char* name,u32 flag,File* dev){
	int ret=ext2_check_disk(dev);
	if (ret!=RETURN_OK){
		io.print("ext2: can't mount %s in %s \n",dev->getName(),name);
		return NULL;
	}
	else{
		io.print("ext2:  mount %s in %s \n",dev->getName(),name);
		Ext2* ret=new Ext2(name);
		ret->ext2inode=EXT2_INUM_ROOT;
		ext2_get_disk_info(dev,ret);
		ret->scan();
		return ret;
	}
}

module("module.ext2",MODULE_FILESYSTEM,Ext2,ext2_mount)

Ext2::~Ext2(){

}

Ext2::Ext2(char* n) : File(n,TYPE_DIRECTORY)
{
	map=NULL;
}

void Ext2::scan(){
	ext2_scan(this);
}

u32	Ext2::close(){
	return NOT_DEFINED;
}

u32	Ext2::open(u32 flag){
	ext2_inode *inodee=ext2_read_inode(disk,ext2inode);
	map=ext2_read_file(disk,inodee);
	kfree(inodee);
	return RETURN_OK;
}

u32	Ext2::read(u32 pos,u8* buffer,u32 sizee){
	u32 bufsize=sizee;
	if ((pos + bufsize) > (size))
		bufsize = (u32)(size) - pos;
	memcpy((char*)buffer, (char *) (map + pos), bufsize);
	return bufsize;
}

u32	Ext2::write(u32 pos,u8* buffer,u32 sizee){
	return NOT_DEFINED;
}

u32	Ext2::ioctl(u32 id,u8* buffer){
	return NOT_DEFINED;
}

u32	Ext2::remove(){
	delete this;
	return RETURN_OK;
}

/*
 *	EXT2 specification
 */
int ext2_read_sb(File* dev,ext2_super_block *sb)
{
	if (dev!=NULL){
		dev->read((u32)1024,(u8 *) sb,sizeof(ext2_super_block));
		return RETURN_OK;
	}
	else
		return ERROR_PARAM;
}

int ext2_read_gd(File* fdev,ext2_group_desc *gd,ext2_disk* info)
{
	if (fdev!=NULL){
		u32 offset;
		offset = ((info->blocksize == 1024) ? 2048 : info->blocksize);
		int gd_size = (info->groups * ((int)sizeof(struct ext2_group_desc)));
		fdev->read(offset,(u8*) gd,gd_size);
		return RETURN_OK;
	}
	else
		return ERROR_PARAM;
}

void ext2_get_disk_info(File*dev,Ext2 *fp)
{
	ext2_disk* info=(ext2_disk*)kmalloc(sizeof(ext2_disk));
	info->sb=(ext2_super_block*)kmalloc(sizeof(ext2_super_block));
	info->dev=dev;
	int i, j;
	ext2_read_sb(dev,info->sb);
	info->blocksize = 1024 << ((info->sb)->s_log_block_size);
	i = (info->sb->s_blocks_count / info->sb->s_blocks_per_group) + ((info->sb->s_blocks_count % info->sb->s_blocks_per_group) ? 1 : 0);
	j = (info->sb->s_inodes_count / info->sb->s_inodes_per_group) + ((info->sb->s_inodes_count % info->sb->s_inodes_per_group) ? 1 : 0);
	info->groups = (i > j) ? i : j;
	int gd_size = info->groups * ((int)sizeof(ext2_group_desc));
	info->gd = (ext2_group_desc *) kmalloc(gd_size);
	ext2_read_gd(info->dev,info->gd,info);
	fp->disk=info;
	return;
}
int ext2_check_disk(File *dev)
{
	ext2_super_block *sb=(ext2_super_block *)kmalloc(sizeof(ext2_super_block));
	if (ext2_read_sb(dev,sb)!=RETURN_OK)
		return ERROR_PARAM;
	if (sb->s_magic==0xEF53){
		kfree(sb);
		return RETURN_OK;
	}
	else{
		kfree(sb);
		return ERROR_PARAM;
	}
}
ext2_inode *ext2_read_inode(ext2_disk* hd, int i_num)
{
	int gr_num, index;
	u32 offset;
	ext2_inode *inode;
	ext2_group_desc * info=hd->gd;
	inode = (ext2_inode *) kmalloc((hd->sb)->s_inode_size);//sizeof(ext2_inode));
	gr_num = (i_num - 1) / ((hd->sb)->s_inodes_per_group);
	index = (i_num - 1) % ((hd->sb)->s_inodes_per_group);
	offset = (info[gr_num].bg_inode_table * (hd->blocksize)) + (index * ((hd->sb)->s_inode_size));
	if ((hd->dev)!=NULL){
		(hd->dev)->read(offset,(u8*) inode,(hd->sb)->s_inode_size);
	}
	return inode;
}
int ext2_is_directory(Ext2 *fp)
{
	ext2_inode *inod=ext2_read_inode(fp->disk,fp->ext2inode);
	int ret=(inod->i_mode & EXT2_S_IFDIR) ? 1 : 0;
	kfree(inod);
	return ret;
}
char *ext2_read_file(ext2_disk *hd,ext2_inode *inode)
{
	File *dev=hd->dev;

	char *mmap_base, *mmap_head, *buf;

	int *p, *pp, *ppp;
	int i, j, k;
	int n, size;

	buf = (char *) kmalloc(hd->blocksize);
	p = (int *) kmalloc(hd->blocksize);
	pp = (int *) kmalloc(hd->blocksize);
	ppp = (int *) kmalloc(hd->blocksize);

	/* taille totale du fichier */
	size = inode->i_size;
	mmap_head = mmap_base = (char*)kmalloc(size);
	/* direct block number */
	for (i = 0; i < 12 && inode->i_block[i]; i++) {
        dev->read((u32)(inode->i_block[i] * hd->blocksize),(u8*) buf, (hd->blocksize));
		n = ((size > (int)hd->blocksize) ? (int)hd->blocksize : size);
		memcpy(mmap_head, buf, n);
		mmap_head += n;
		size -= n;
	}
	/* indirect block number */
	if (inode->i_block[12]) {
	    dev->read((u32)(inode->i_block[12] * hd->blocksize), (u8*) p, (hd->blocksize));

		for (i = 0; i < (int)hd->blocksize / 4 && p[i]; i++) {
            dev->read((u32)(p[i] * hd->blocksize),(u8*)buf, (hd->blocksize));
			n = ((size > (int)hd->blocksize) ? (int)hd->blocksize : size);
			memcpy(mmap_head, buf, n);
			mmap_head += n;
			size -= n;
		}
	}

	/* bi-indirect block number */
	if (inode->i_block[13]) {
	    dev->read((u32)(inode->i_block[13] * hd->blocksize), (u8*) p, (hd->blocksize));

		for (i = 0; i < (int)hd->blocksize / 4 && p[i]; i++) {
            dev->read((u32)(p[i] * (int)hd->blocksize), (u8*) pp,(hd->blocksize));
			for (j = 0; j < (int)hd->blocksize / 4 && pp[j]; j++) {
                dev->read((u32)(pp[j] * hd->blocksize),(u8*)buf,(hd->blocksize));
				n = ((size > (int)hd-> blocksize) ? (int)hd->blocksize : size);
				memcpy(mmap_head, buf, n);
				mmap_head += n;
				size -= n;
			}
		}
	}
	/* tri-indirect block number */
	if (inode->i_block[14]) {
        dev->read((u32)(inode->i_block[14] * hd->blocksize), (u8*) p,(hd->blocksize));
		for (i = 0; i < (int)hd->blocksize / 4 && p[i]; i++) {
            dev->read((u32)(p[i] * hd->blocksize), (u8*) pp,(hd->blocksize));
			for (j = 0; j < (int)hd->blocksize / 4 && pp[j]; j++) {
                dev->read((u32)(pp[j] * hd->blocksize), (u8*) ppp,(hd->blocksize));
				for (k = 0; k < (int)hd->blocksize / 4 && ppp[k]; k++) {
                    dev->read((u32)(ppp[k] * hd->blocksize),(u8*)buf,(hd->blocksize));
					n = ((size > (int)hd->blocksize) ? (int)hd->blocksize : size);
					memcpy(mmap_head, buf, n);
					mmap_head += n;
					size -= n;
				}
			}
		}
	}
	kfree(buf);
	kfree(p);
	kfree(pp);
	kfree(ppp);;
	return mmap_base;
}
int ext2_scan(Ext2 *dir)
{
	ext2_directory_entry *dentry;
	Ext2 *leaf;
	u32 dsize;
	char *filename;
	int f_toclose;
	ext2_inode *inode = ext2_read_inode(dir->disk, dir->ext2inode);
	if (dir->getType()!=TYPE_DIRECTORY) {
		return ERROR_PARAM;
	}

	if (!dir->map) {
		dir->map = ext2_read_file(dir->disk, inode);
		f_toclose = 1;
	} else {
		f_toclose = 0;
	}

	dsize = inode->i_size;
	dentry = (ext2_directory_entry *) dir->map;
	while (inode && dsize) {
				filename = (char *) kmalloc(dentry->name_len + 1);
				memcpy(filename,(char*)&(dentry->name), dentry->name_len);
				filename[dentry->name_len] = 0;
				if (strcmp(".", filename) && strcmp("..", filename)) {
					if (dir->find(filename)==NULL) {
						leaf= new Ext2(filename);
						leaf->ext2inode = dentry->inode;
						leaf->disk=dir->disk;
						if (ext2_is_directory(leaf))
							leaf->setType(TYPE_DIRECTORY);
						else
							leaf->setType(TYPE_FILE);
						dir->addChild(leaf);
						leaf->map = 0;
						ext2_inode *inod=ext2_read_inode((ext2_disk*)leaf->disk,leaf->ext2inode);
						leaf->setSize(inod->i_size);
						kfree(inod);
					}
				}
				kfree(filename);
		dsize -= dentry->rec_len;
		dentry = (ext2_directory_entry *) ((char *) dentry + dentry->rec_len);
	}
	kfree(inode);
	if (f_toclose == 1) {
		kfree(dir->map);
		dir->map = 0;
	}
	return 0;
}
<commit_msg>Update ext2.cc<commit_after>

#include <os.h>
#include <ext2.h>

File* ext2_mount(char* name,u32 flag,File* suriyaa){
	int ret=ext2_check_disk(suriyaa);
	if (ret!=RETURN_OK){
		io.print("ext2: can't mount %s in %s \n",suriyaa->getName(),name);
		return NULL;
	}
	else{
		io.print("ext2:  mount %s in %s \n",suriyaa->getName(),name);
		Ext2* ret=new Ext2(name);
		ret->ext2inode=EXT2_INUM_ROOT;
		ext2_get_disk_info(suriyaa,ret);
		ret->scan();
		return ret;
	}
}

module("module.ext2",MODULE_FILESYSTEM,Ext2,ext2_mount)

Ext2::~Ext2(){

}

Ext2::Ext2(char* n) : File(n,TYPE_DIRECTORY)
{
	map=NULL;
}

void Ext2::scan(){
	ext2_scan(this);
}

u32	Ext2::close(){
	return NOT_DEFINED;
}

u32	Ext2::open(u32 flag){
	ext2_inode *inodee=ext2_read_inode(disk,ext2inode);
	map=ext2_read_file(disk,inodee);
	kfree(inodee);
	return RETURN_OK;
}

u32	Ext2::read(u32 pos,u8* buffer,u32 sizee){
	u32 bufsize=sizee;
	if ((pos + bufsize) > (size))
		bufsize = (u32)(size) - pos;
	memcpy((char*)buffer, (char *) (map + pos), bufsize);
	return bufsize;
}

u32	Ext2::write(u32 pos,u8* buffer,u32 sizee){
	return NOT_DEFINED;
}

u32	Ext2::ioctl(u32 id,u8* buffer){
	return NOT_DEFINED;
}

u32	Ext2::remove(){
	delete this;
	return RETURN_OK;
}

/*
 *	EXT2 specification
 */
int ext2_read_sb(File* suriya,ext2_super_block *sb)
{
	if (suriyaa!=NULL){
		suriyaa->read((u32)1024,(u8 *) sb,sizeof(ext2_super_block));
		return RETURN_OK;
	}
	else
		return ERROR_PARAM;
}

int ext2_read_gd(File* fsuriyaa,ext2_group_desc *gd,ext2_disk* info)
{
	if (fsuriyaa!=NULL){
		u32 offset;
		offset = ((info->blocksize == 1024) ? 2048 : info->blocksize);
		int gd_size = (info->groups * ((int)sizeof(struct ext2_group_desc)));
		fsuriyaa->read(offset,(u8*) gd,gd_size);
		return RETURN_OK;
	}
	else
		return ERROR_PARAM;
}

void ext2_get_disk_info(File*suriyaa,Ext2 *fp)
{
	ext2_disk* info=(ext2_disk*)kmalloc(sizeof(ext2_disk));
	info->sb=(ext2_super_block*)kmalloc(sizeof(ext2_super_block));
	info->suriyaa=suriyaa;
	int i, j;
	ext2_read_sb(suriyaa,info->sb);
	info->blocksize = 1024 << ((info->sb)->s_log_block_size);
	i = (info->sb->s_blocks_count / info->sb->s_blocks_per_group) + ((info->sb->s_blocks_count % info->sb->s_blocks_per_group) ? 1 : 0);
	j = (info->sb->s_inodes_count / info->sb->s_inodes_per_group) + ((info->sb->s_inodes_count % info->sb->s_inodes_per_group) ? 1 : 0);
	info->groups = (i > j) ? i : j;
	int gd_size = info->groups * ((int)sizeof(ext2_group_desc));
	info->gd = (ext2_group_desc *) kmalloc(gd_size);
	ext2_read_gd(info->suriyaa,info->gd,info);
	fp->disk=info;
	return;
}
int ext2_check_disk(File *suriyaa)
{
	ext2_super_block *sb=(ext2_super_block *)kmalloc(sizeof(ext2_super_block));
	if (ext2_read_sb(suriyaa,sb)!=RETURN_OK)
		return ERROR_PARAM;
	if (sb->s_magic==0xEF53){
		kfree(sb);
		return RETURN_OK;
	}
	else{
		kfree(sb);
		return ERROR_PARAM;
	}
}
ext2_inode *ext2_read_inode(ext2_disk* hd, int i_num)
{
	int gr_num, index;
	u32 offset;
	ext2_inode *inode;
	ext2_group_desc * info=hd->gd;
	inode = (ext2_inode *) kmalloc((hd->sb)->s_inode_size);//sizeof(ext2_inode));
	gr_num = (i_num - 1) / ((hd->sb)->s_inodes_per_group);
	index = (i_num - 1) % ((hd->sb)->s_inodes_per_group);
	offset = (info[gr_num].bg_inode_table * (hd->blocksize)) + (index * ((hd->sb)->s_inode_size));
	if ((hd->suriyaa)!=NULL){
		(hd->suriyaa)->read(offset,(u8*) inode,(hd->sb)->s_inode_size);
	}
	return inode;
}
int ext2_is_directory(Ext2 *fp)
{
	ext2_inode *inod=ext2_read_inode(fp->disk,fp->ext2inode);
	int ret=(inod->i_mode & EXT2_S_IFDIR) ? 1 : 0;
	kfree(inod);
	return ret;
}
char *ext2_read_file(ext2_disk *hd,ext2_inode *inode)
{
	File *suriyaa=hd->suriyaa;

	char *mmap_base, *mmap_head, *buf;

	int *p, *pp, *ppp;
	int i, j, k;
	int n, size;

	buf = (char *) kmalloc(hd->blocksize);
	p = (int *) kmalloc(hd->blocksize);
	pp = (int *) kmalloc(hd->blocksize);
	ppp = (int *) kmalloc(hd->blocksize);

	/* taille totale du fichier */
	size = inode->i_size;
	mmap_head = mmap_base = (char*)kmalloc(size);
	/* direct block number */
	for (i = 0; i < 12 && inode->i_block[i]; i++) {
        suriyaa->read((u32)(inode->i_block[i] * hd->blocksize),(u8*) buf, (hd->blocksize));
		n = ((size > (int)hd->blocksize) ? (int)hd->blocksize : size);
		memcpy(mmap_head, buf, n);
		mmap_head += n;
		size -= n;
	}
	/* indirect block number */
	if (inode->i_block[12]) {
	    suriyaa->read((u32)(inode->i_block[12] * hd->blocksize), (u8*) p, (hd->blocksize));

		for (i = 0; i < (int)hd->blocksize / 4 && p[i]; i++) {
            suriyaa->read((u32)(p[i] * hd->blocksize),(u8*)buf, (hd->blocksize));
			n = ((size > (int)hd->blocksize) ? (int)hd->blocksize : size);
			memcpy(mmap_head, buf, n);
			mmap_head += n;
			size -= n;
		}
	}

	/* bi-indirect block number */
	if (inode->i_block[13]) {
	    suriyaa->read((u32)(inode->i_block[13] * hd->blocksize), (u8*) p, (hd->blocksize));

		for (i = 0; i < (int)hd->blocksize / 4 && p[i]; i++) {
            suriyaa->read((u32)(p[i] * (int)hd->blocksize), (u8*) pp,(hd->blocksize));
			for (j = 0; j < (int)hd->blocksize / 4 && pp[j]; j++) {
                suriyaa->read((u32)(pp[j] * hd->blocksize),(u8*)buf,(hd->blocksize));
				n = ((size > (int)hd-> blocksize) ? (int)hd->blocksize : size);
				memcpy(mmap_head, buf, n);
				mmap_head += n;
				size -= n;
			}
		}
	}
	/* tri-indirect block number */
	if (inode->i_block[14]) {
        suriyaa->read((u32)(inode->i_block[14] * hd->blocksize), (u8*) p,(hd->blocksize));
		for (i = 0; i < (int)hd->blocksize / 4 && p[i]; i++) {
            suriyaa->read((u32)(p[i] * hd->blocksize), (u8*) pp,(hd->blocksize));
			for (j = 0; j < (int)hd->blocksize / 4 && pp[j]; j++) {
                suriyaa->read((u32)(pp[j] * hd->blocksize), (u8*) ppp,(hd->blocksize));
				for (k = 0; k < (int)hd->blocksize / 4 && ppp[k]; k++) {
                    suriyaa->read((u32)(ppp[k] * hd->blocksize),(u8*)buf,(hd->blocksize));
					n = ((size > (int)hd->blocksize) ? (int)hd->blocksize : size);
					memcpy(mmap_head, buf, n);
					mmap_head += n;
					size -= n;
				}
			}
		}
	}
	kfree(buf);
	kfree(p);
	kfree(pp);
	kfree(ppp);;
	return mmap_base;
}
int ext2_scan(Ext2 *dir)
{
	ext2_directory_entry *dentry;
	Ext2 *leaf;
	u32 dsize;
	char *filename;
	int f_toclose;
	ext2_inode *inode = ext2_read_inode(dir->disk, dir->ext2inode);
	if (dir->getType()!=TYPE_DIRECTORY) {
		return ERROR_PARAM;
	}

	if (!dir->map) {
		dir->map = ext2_read_file(dir->disk, inode);
		f_toclose = 1;
	} else {
		f_toclose = 0;
	}

	dsize = inode->i_size;
	dentry = (ext2_directory_entry *) dir->map;
	while (inode && dsize) {
				filename = (char *) kmalloc(dentry->name_len + 1);
				memcpy(filename,(char*)&(dentry->name), dentry->name_len);
				filename[dentry->name_len] = 0;
				if (strcmp(".", filename) && strcmp("..", filename)) {
					if (dir->find(filename)==NULL) {
						leaf= new Ext2(filename);
						leaf->ext2inode = dentry->inode;
						leaf->disk=dir->disk;
						if (ext2_is_directory(leaf))
							leaf->setType(TYPE_DIRECTORY);
						else
							leaf->setType(TYPE_FILE);
						dir->addChild(leaf);
						leaf->map = 0;
						ext2_inode *inod=ext2_read_inode((ext2_disk*)leaf->disk,leaf->ext2inode);
						leaf->setSize(inod->i_size);
						kfree(inod);
					}
				}
				kfree(filename);
		dsize -= dentry->rec_len;
		dentry = (ext2_directory_entry *) ((char *) dentry + dentry->rec_len);
	}
	kfree(inode);
	if (f_toclose == 1) {
		kfree(dir->map);
		dir->map = 0;
	}
	return 0;
}
<|endoftext|>


<commit_before>// Copyright 2012-2013 Samplecount S.L.
//
// 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 "Methcla/Audio/IO/RemoteIODriver.hpp"

#include <AudioToolbox/AudioToolbox.h>

using namespace Methcla::Audio::IO;

#define METHCLA_THROW_IF_ERROR(expr, msg) \
    do { \
        OSStatus err__ = expr; \
        if (err__ != 0) { \
            BOOST_THROW_EXCEPTION(Methcla::Audio::IO::Exception() \
                    << Methcla::ErrorInfoString(msg) \
                    << OSStatusInfo(err__)); \
        } \
    } while (false);

const AudioUnitElement kOutputBus = 0;
const AudioUnitElement kInputBus = 1;

static void initStreamFormat(AudioStreamBasicDescription& desc, Float64 sampleRate, UInt32 numChannels)
{
	memset(&desc, 0, sizeof(desc));
	desc.mSampleRate = sampleRate;
	desc.mFormatID = kAudioFormatLinearPCM;
	// desc.mFormatFlags = kAudioFormatFlagsNativeFloatPacked | kAudioFormatFlagIsNonInterleaved;
	desc.mFormatFlags = kAudioFormatFlagsCanonical;
	desc.mChannelsPerFrame = numChannels;
	desc.mBitsPerChannel = 8 * sizeof(AudioSampleType);
	desc.mBytesPerFrame = desc.mChannelsPerFrame * sizeof(AudioSampleType);
	desc.mFramesPerPacket = 1;
	desc.mBytesPerPacket = desc.mFramesPerPacket * desc.mBytesPerFrame;
}

RemoteIODriver::RemoteIODriver()
    : m_numInputs(2)
    , m_numOutputs(2)
    , m_inputBuffers(0)
    , m_outputBuffers(0)
{
    // Initialize and configure the audio session
    METHCLA_THROW_IF_ERROR(
        AudioSessionInitialize(NULL, NULL, InterruptionCallback, this)
      , "couldn't initialize audio session");

    UInt32 audioCategory = kAudioSessionCategory_PlayAndRecord;
    METHCLA_THROW_IF_ERROR(
        AudioSessionSetProperty(
            kAudioSessionProperty_AudioCategory
          , sizeof(audioCategory)
          , &audioCategory)
      , "couldn't set audio category");
    //METHCLA_THROW_IF_ERROR(AudioSessionAddPropertyListener(kAudioSessionProperty_AudioRouteChange, propListener, self), "couldn't set property listener");

    // NOTE: This needs to be called *before* trying to determine the
    //       number of input/output channels.
    METHCLA_THROW_IF_ERROR(
        AudioSessionSetActive(true)
      , "couldn't activate audio session");

    Float64 hwSampleRate;
    UInt32 outSize = sizeof(hwSampleRate);
    METHCLA_THROW_IF_ERROR(
        AudioSessionGetProperty(
            kAudioSessionProperty_CurrentHardwareSampleRate
          , &outSize
          , &hwSampleRate)
      , "couldn't get hw sample rate");
    m_sampleRate = hwSampleRate;

    Float32 hwBufferSize;
    outSize = sizeof(hwBufferSize);
	METHCLA_THROW_IF_ERROR(
	    AudioSessionGetProperty(
            kAudioSessionProperty_CurrentHardwareIOBufferDuration
          , &outSize
          , &hwBufferSize)
      , "couldn't set i/o buffer duration");

    // Check whether input is available
	UInt32 inputAvailable;
    outSize = sizeof(inputAvailable);
	METHCLA_THROW_IF_ERROR(
        AudioSessionGetProperty(
            kAudioSessionProperty_AudioInputAvailable
          ,	&outSize
          ,	&inputAvailable)
      , "couldn't determine whether audio input is available");

	// Number of hardware inputs
	UInt32 hwNumInputs = 0;
    if (inputAvailable) {
        outSize = sizeof(hwNumInputs);
        METHCLA_THROW_IF_ERROR(
            AudioSessionGetProperty(
                kAudioSessionProperty_CurrentHardwareInputNumberChannels
              , &outSize
              , &hwNumInputs)
          , "couldn't determine number of hardware input channels");
    }
    m_numInputs = hwNumInputs;

	// Number of hardware outputs
	UInt32 hwNumOutputs;
    outSize = sizeof(m_numOutputs);
	METHCLA_THROW_IF_ERROR(
	    AudioSessionGetProperty(
            kAudioSessionProperty_CurrentHardwareOutputNumberChannels
          , &outSize
          , &hwNumOutputs)
     ,  "couldn't determine number of hardware output channels");
	m_numOutputs = hwNumOutputs;

    // Float32 preferredBufferSize = .005;
    // METHCLA_THROW_IF_ERROR(
    //     AudioSessionSetProperty(kAudioSessionProperty_PreferredHardwareIOBufferDuration, sizeof(preferredBufferSize), &preferredBufferSize)
    //   , "couldn't set i/o buffer duration");

    // Find remote I/O audio component
    AudioComponentDescription desc;
    desc.componentType = kAudioUnitType_Output;
    desc.componentSubType = kAudioUnitSubType_RemoteIO;
    desc.componentManufacturer = kAudioUnitManufacturer_Apple;
    desc.componentFlags = 0;
    desc.componentFlagsMask = 0;

    AudioComponent comp = AudioComponentFindNext(NULL, &desc);

	// Instantiate remote I/O unit
    METHCLA_THROW_IF_ERROR(
        AudioComponentInstanceNew(comp, &m_rioUnit)
      , "couldn't open the remote I/O unit");

    // Enable output
    UInt32 enableOutput = 1;
    METHCLA_THROW_IF_ERROR(
        AudioUnitSetProperty(
            m_rioUnit
          , kAudioOutputUnitProperty_EnableIO
          , kAudioUnitScope_Output
          , kOutputBus
          , &enableOutput
          , sizeof(enableOutput))
      , "couldn't enable output on the remote I/O unit");

    // Enable input
    if (m_numInputs > 0) {
        UInt32 enableInput = 1;
        METHCLA_THROW_IF_ERROR(
            AudioUnitSetProperty(
               m_rioUnit
             , kAudioOutputUnitProperty_EnableIO
             , kAudioUnitScope_Input
             , kInputBus
             , &enableInput
             , sizeof(enableInput))
          , "couldn't enable input on the remote I/O unit");
    }

    // This needs to be set before initializing the AudioUnit?
    m_bufferSize = (size_t)(m_sampleRate * hwBufferSize + .5);
    UInt32 maxFPS = m_bufferSize;
    METHCLA_THROW_IF_ERROR(
        AudioUnitSetProperty(
            m_rioUnit
          , kAudioUnitProperty_MaximumFramesPerSlice
          , kAudioUnitScope_Global
          , kInputBus
          , &maxFPS
          , sizeof(maxFPS))
      , "couldn't set AudioUnit buffer size");

    METHCLA_THROW_IF_ERROR(
        AudioUnitSetProperty(
            m_rioUnit
          , kAudioUnitProperty_MaximumFramesPerSlice
          , kAudioUnitScope_Global
          , kOutputBus
          , &maxFPS
          , sizeof(maxFPS))
      , "couldn't set AudioUnit buffer size");

    // UInt32 maxFPS = m_bufferSize;
    // METHCLA_THROW_IF_ERROR(
    //     AudioUnitGetProperty(
    //         m_rioUnit
    //       , kAudioUnitProperty_MaximumFramesPerSlice
    //       , kAudioUnitScope_Global
    //       , kOutputBus
    //       , &maxFPS
    //       , &outSize)
    //   , "couldn't get AudioUnit buffer size");
    // m_bufferSize = maxFPS;

    // Set input format
    if (m_numInputs > 0) {
        AudioStreamBasicDescription inputFormat;
        initStreamFormat(inputFormat, m_sampleRate, m_numInputs);
        METHCLA_THROW_IF_ERROR(
            AudioUnitSetProperty(
                m_rioUnit
              , kAudioUnitProperty_StreamFormat
              , kAudioUnitScope_Output
              , kInputBus
              , &inputFormat
              , sizeof(inputFormat))
          , "couldn't set the remote I/O unit's input client format");
    }

    // Set output format
	AudioStreamBasicDescription outputFormat;
	initStreamFormat(outputFormat, m_sampleRate, m_numOutputs);
    METHCLA_THROW_IF_ERROR(
        AudioUnitSetProperty(
            m_rioUnit
          , kAudioUnitProperty_StreamFormat
          , kAudioUnitScope_Input
          , kOutputBus
          , &outputFormat
          , sizeof(outputFormat))
      , "couldn't set the remote I/O unit's output client format");

    // outSize = sizeof(outputFormat);
    // METHCLA_THROW_IF_ERROR(
    //     AudioUnitGetProperty(m_rioUnit, kAudioUnitProperty_StreamFormat, kAudioUnitScope_Input, kOutputBus, &outputFormat, &outSize)
    //   , "couldn't get the remote I/O unit's output client format");
    // outputFormat.Print();

    // Set input callback
    if (m_numInputs > 0) {
        AURenderCallbackStruct inputCallback;
        inputCallback.inputProc = InputCallback;
        inputCallback.inputProcRefCon = this;

        METHCLA_THROW_IF_ERROR(
            AudioUnitSetProperty(
                m_rioUnit
              , kAudioOutputUnitProperty_SetInputCallback
              , kAudioUnitScope_Global
              , kInputBus
              , &inputCallback
              , sizeof(inputCallback))
          , "couldn't set remote i/o input callback");
    }

    // Set output callback
    AURenderCallbackStruct outputCallback;
    outputCallback.inputProc = RenderCallback;
    outputCallback.inputProcRefCon = this;

    METHCLA_THROW_IF_ERROR(
        AudioUnitSetProperty(
            m_rioUnit
          , kAudioUnitProperty_SetRenderCallback
          , kAudioUnitScope_Global
          , kOutputBus
          , &outputCallback
          , sizeof(outputCallback))
      , "couldn't set remote i/o output callback");

	// Initialize audio unit
    METHCLA_THROW_IF_ERROR(
        AudioUnitInitialize(m_rioUnit)
      , "couldn't initialize the remote I/O unit");

    // Initialize I/O buffers
    m_inputBuffers = new sample_t*[m_numInputs];
    m_outputBuffers = new sample_t*[m_numOutputs];
    for (size_t i = 0; i < m_numInputs; i++) {
        m_inputBuffers[i] =
            Methcla::Memory::allocAlignedOf<sample_t>(Methcla::Memory::kSIMDAlignment, m_bufferSize);
    }
    for (size_t i = 0; i < m_numOutputs; i++) {
        m_outputBuffers[i] =
            Methcla::Memory::allocAlignedOf<sample_t>(Methcla::Memory::kSIMDAlignment, m_bufferSize);
    }
}

RemoteIODriver::~RemoteIODriver()
{
	// Free audio units
	AudioComponentInstanceDispose(m_rioUnit);

    // Free input buffer memory
    for (size_t i=0; i < m_numInputs; i++) {
        Methcla::Memory::free(m_inputBuffers[i]);
    }

    // Free buffer pointer arrays
    delete [] m_inputBuffers;
    delete [] m_outputBuffers;
}

void RemoteIODriver::start()
{
    METHCLA_THROW_IF_ERROR(
        AudioOutputUnitStart(m_rioUnit)
      , "couldn't start remote i/o unit");
}

void RemoteIODriver::stop()
{
    METHCLA_THROW_IF_ERROR(
        AudioOutputUnitStop(m_rioUnit)
      , "couldn't start remote i/o unit");
}

void RemoteIODriver::InterruptionCallback(void *inClientData, UInt32 inInterruption)
{
    RemoteIODriver* self = static_cast<RemoteIODriver*>(inClientData);

    if (inInterruption == kAudioSessionEndInterruption) {
        // make sure we are again the active session
        METHCLA_THROW_IF_ERROR(AudioSessionSetActive(true), "couldn't set audio session active");
        self->start();
    }

    if (inInterruption == kAudioSessionBeginInterruption) {
        self->stop();
    }
}

OSStatus RemoteIODriver::InputCallback(
    void*                       inRefCon,
    AudioUnitRenderActionFlags* ioActionFlags,
    const AudioTimeStamp*       inTimeStamp,
    UInt32                      inBusNumber,
    UInt32                      inNumberFrames,
    AudioBufferList*            /* ioData */)
{
    RemoteIODriver* self = static_cast<RemoteIODriver*>(inRefCon);

    AudioBufferList bufferList;
    bufferList.mNumberBuffers = 1;
    bufferList.mBuffers[0].mData = nullptr;

    AudioBufferList* ioData = &bufferList;

	// Pull data from input bus
    OSStatus err = AudioUnitRender(
        self->m_rioUnit
      , ioActionFlags
      , inTimeStamp
      , inBusNumber
      , inNumberFrames
      , ioData);
    if (err != noErr) return err;

	const UInt32 numInputs = self->m_numInputs;
	sample_t** inputBuffers = self->m_inputBuffers;

	for (size_t bufCount = 0; bufCount < ioData->mNumberBuffers; bufCount++) {
		AudioBuffer& buf = ioData->mBuffers[bufCount];
		BOOST_ASSERT( buf.mNumberChannels == numInputs );

		AudioSampleType* pcm = static_cast<AudioSampleType*>(buf.mData);

		// Deinterleave and convert input
		for (UInt32 curChan = 0; curChan < numInputs; curChan++) {
			for (UInt32 curFrame = 0; curFrame < inNumberFrames; curFrame++) {
				inputBuffers[curChan][curFrame] = pcm[curFrame * numInputs + curChan] / 32768.f;
			}
		}
	}

    return noErr;
}

OSStatus RemoteIODriver::RenderCallback(
    void*                       inRefCon,
    AudioUnitRenderActionFlags* ioActionFlags,
    const AudioTimeStamp*       inTimeStamp,
    UInt32                      inBusNumber,
    UInt32                      inNumberFrames,
    AudioBufferList*            ioData)
{
    RemoteIODriver* self = static_cast<RemoteIODriver*>(inRefCon);

    const sample_t* const* inputBuffers = self->m_inputBuffers;
    const UInt32 numOutputs = self->m_numOutputs;
    sample_t* const* outputBuffers = self->m_outputBuffers;

	for (size_t bufCount = 0; bufCount < ioData->mNumberBuffers; bufCount++) {
		AudioBuffer& buf = ioData->mBuffers[bufCount];
		BOOST_ASSERT( buf.mNumberChannels == numOutputs );

		AudioSampleType* pcm = static_cast<AudioSampleType*>(buf.mData);

	    // Run DSP graph
        self->process(inNumberFrames, inputBuffers, outputBuffers);

	    // Convert and interleave output
		for (UInt32 curChan = 0; curChan < numOutputs; curChan++) {
			for (UInt32 curFrame = 0; curFrame < inNumberFrames; curFrame++) {
#if METHCLA_AUDIO_THROUGH
                if (curChan < self->m_numInputs) {
                    pcm[curFrame * numOutputs + curChan] = inputBuffers[curChan][curFrame] * 32767.f;
                } else {
                    pcm[curFrame * numOutputs + curChan] = 0.f;
                }
#else
                pcm[curFrame * numOutputs + curChan] = outputBuffers[curChan][curFrame] * 32767.f;
#endif
			}
		}
	}

    return noErr;
}

Driver* Methcla::Audio::IO::defaultPlatformDriver()
{
    return new RemoteIODriver();
}
<commit_msg>Whitespace fix<commit_after>// Copyright 2012-2013 Samplecount S.L.
//
// 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 "Methcla/Audio/IO/RemoteIODriver.hpp"

#include <AudioToolbox/AudioToolbox.h>

using namespace Methcla::Audio::IO;

#define METHCLA_THROW_IF_ERROR(expr, msg) \
    do { \
        OSStatus err__ = expr; \
        if (err__ != 0) { \
            BOOST_THROW_EXCEPTION(Methcla::Audio::IO::Exception() \
                    << Methcla::ErrorInfoString(msg) \
                    << OSStatusInfo(err__)); \
        } \
    } while (false);

const AudioUnitElement kOutputBus = 0;
const AudioUnitElement kInputBus = 1;

static void initStreamFormat(AudioStreamBasicDescription& desc, Float64 sampleRate, UInt32 numChannels)
{
    memset(&desc, 0, sizeof(desc));
    desc.mSampleRate = sampleRate;
    desc.mFormatID = kAudioFormatLinearPCM;
    // desc.mFormatFlags = kAudioFormatFlagsNativeFloatPacked | kAudioFormatFlagIsNonInterleaved;
    desc.mFormatFlags = kAudioFormatFlagsCanonical;
    desc.mChannelsPerFrame = numChannels;
    desc.mBitsPerChannel = 8 * sizeof(AudioSampleType);
    desc.mBytesPerFrame = desc.mChannelsPerFrame * sizeof(AudioSampleType);
    desc.mFramesPerPacket = 1;
    desc.mBytesPerPacket = desc.mFramesPerPacket * desc.mBytesPerFrame;
}

RemoteIODriver::RemoteIODriver()
    : m_numInputs(2)
    , m_numOutputs(2)
    , m_inputBuffers(0)
    , m_outputBuffers(0)
{
    // Initialize and configure the audio session
    METHCLA_THROW_IF_ERROR(
        AudioSessionInitialize(NULL, NULL, InterruptionCallback, this)
      , "couldn't initialize audio session");

    UInt32 audioCategory = kAudioSessionCategory_PlayAndRecord;
    METHCLA_THROW_IF_ERROR(
        AudioSessionSetProperty(
            kAudioSessionProperty_AudioCategory
          , sizeof(audioCategory)
          , &audioCategory)
      , "couldn't set audio category");
    //METHCLA_THROW_IF_ERROR(AudioSessionAddPropertyListener(kAudioSessionProperty_AudioRouteChange, propListener, self), "couldn't set property listener");

    // NOTE: This needs to be called *before* trying to determine the
    //       number of input/output channels.
    METHCLA_THROW_IF_ERROR(
        AudioSessionSetActive(true)
      , "couldn't activate audio session");

    Float64 hwSampleRate;
    UInt32 outSize = sizeof(hwSampleRate);
    METHCLA_THROW_IF_ERROR(
        AudioSessionGetProperty(
            kAudioSessionProperty_CurrentHardwareSampleRate
          , &outSize
          , &hwSampleRate)
      , "couldn't get hw sample rate");
    m_sampleRate = hwSampleRate;

    Float32 hwBufferSize;
    outSize = sizeof(hwBufferSize);
    METHCLA_THROW_IF_ERROR(
        AudioSessionGetProperty(
            kAudioSessionProperty_CurrentHardwareIOBufferDuration
          , &outSize
          , &hwBufferSize)
      , "couldn't set i/o buffer duration");

    // Check whether input is available
    UInt32 inputAvailable;
    outSize = sizeof(inputAvailable);
    METHCLA_THROW_IF_ERROR(
        AudioSessionGetProperty(
            kAudioSessionProperty_AudioInputAvailable
          , &outSize
          , &inputAvailable)
      , "couldn't determine whether audio input is available");

    // Number of hardware inputs
    UInt32 hwNumInputs = 0;
    if (inputAvailable) {
        outSize = sizeof(hwNumInputs);
        METHCLA_THROW_IF_ERROR(
            AudioSessionGetProperty(
                kAudioSessionProperty_CurrentHardwareInputNumberChannels
              , &outSize
              , &hwNumInputs)
          , "couldn't determine number of hardware input channels");
    }
    m_numInputs = hwNumInputs;

    // Number of hardware outputs
    UInt32 hwNumOutputs;
    outSize = sizeof(m_numOutputs);
    METHCLA_THROW_IF_ERROR(
        AudioSessionGetProperty(
            kAudioSessionProperty_CurrentHardwareOutputNumberChannels
          , &outSize
          , &hwNumOutputs)
     ,  "couldn't determine number of hardware output channels");
    m_numOutputs = hwNumOutputs;

    // Float32 preferredBufferSize = .005;
    // METHCLA_THROW_IF_ERROR(
    //     AudioSessionSetProperty(kAudioSessionProperty_PreferredHardwareIOBufferDuration, sizeof(preferredBufferSize), &preferredBufferSize)
    //   , "couldn't set i/o buffer duration");

    // Find remote I/O audio component
    AudioComponentDescription desc;
    desc.componentType = kAudioUnitType_Output;
    desc.componentSubType = kAudioUnitSubType_RemoteIO;
    desc.componentManufacturer = kAudioUnitManufacturer_Apple;
    desc.componentFlags = 0;
    desc.componentFlagsMask = 0;

    AudioComponent comp = AudioComponentFindNext(NULL, &desc);

    // Instantiate remote I/O unit
    METHCLA_THROW_IF_ERROR(
        AudioComponentInstanceNew(comp, &m_rioUnit)
      , "couldn't open the remote I/O unit");

    // Enable output
    UInt32 enableOutput = 1;
    METHCLA_THROW_IF_ERROR(
        AudioUnitSetProperty(
            m_rioUnit
          , kAudioOutputUnitProperty_EnableIO
          , kAudioUnitScope_Output
          , kOutputBus
          , &enableOutput
          , sizeof(enableOutput))
      , "couldn't enable output on the remote I/O unit");

    // Enable input
    if (m_numInputs > 0) {
        UInt32 enableInput = 1;
        METHCLA_THROW_IF_ERROR(
            AudioUnitSetProperty(
               m_rioUnit
             , kAudioOutputUnitProperty_EnableIO
             , kAudioUnitScope_Input
             , kInputBus
             , &enableInput
             , sizeof(enableInput))
          , "couldn't enable input on the remote I/O unit");
    }

    // This needs to be set before initializing the AudioUnit?
    m_bufferSize = (size_t)(m_sampleRate * hwBufferSize + .5);
    UInt32 maxFPS = m_bufferSize;
    METHCLA_THROW_IF_ERROR(
        AudioUnitSetProperty(
            m_rioUnit
          , kAudioUnitProperty_MaximumFramesPerSlice
          , kAudioUnitScope_Global
          , kInputBus
          , &maxFPS
          , sizeof(maxFPS))
      , "couldn't set AudioUnit buffer size");

    METHCLA_THROW_IF_ERROR(
        AudioUnitSetProperty(
            m_rioUnit
          , kAudioUnitProperty_MaximumFramesPerSlice
          , kAudioUnitScope_Global
          , kOutputBus
          , &maxFPS
          , sizeof(maxFPS))
      , "couldn't set AudioUnit buffer size");

    // UInt32 maxFPS = m_bufferSize;
    // METHCLA_THROW_IF_ERROR(
    //     AudioUnitGetProperty(
    //         m_rioUnit
    //       , kAudioUnitProperty_MaximumFramesPerSlice
    //       , kAudioUnitScope_Global
    //       , kOutputBus
    //       , &maxFPS
    //       , &outSize)
    //   , "couldn't get AudioUnit buffer size");
    // m_bufferSize = maxFPS;

    // Set input format
    if (m_numInputs > 0) {
        AudioStreamBasicDescription inputFormat;
        initStreamFormat(inputFormat, m_sampleRate, m_numInputs);
        METHCLA_THROW_IF_ERROR(
            AudioUnitSetProperty(
                m_rioUnit
              , kAudioUnitProperty_StreamFormat
              , kAudioUnitScope_Output
              , kInputBus
              , &inputFormat
              , sizeof(inputFormat))
          , "couldn't set the remote I/O unit's input client format");
    }

    // Set output format
    AudioStreamBasicDescription outputFormat;
    initStreamFormat(outputFormat, m_sampleRate, m_numOutputs);
    METHCLA_THROW_IF_ERROR(
        AudioUnitSetProperty(
            m_rioUnit
          , kAudioUnitProperty_StreamFormat
          , kAudioUnitScope_Input
          , kOutputBus
          , &outputFormat
          , sizeof(outputFormat))
      , "couldn't set the remote I/O unit's output client format");

    // outSize = sizeof(outputFormat);
    // METHCLA_THROW_IF_ERROR(
    //     AudioUnitGetProperty(m_rioUnit, kAudioUnitProperty_StreamFormat, kAudioUnitScope_Input, kOutputBus, &outputFormat, &outSize)
    //   , "couldn't get the remote I/O unit's output client format");
    // outputFormat.Print();

    // Set input callback
    if (m_numInputs > 0) {
        AURenderCallbackStruct inputCallback;
        inputCallback.inputProc = InputCallback;
        inputCallback.inputProcRefCon = this;

        METHCLA_THROW_IF_ERROR(
            AudioUnitSetProperty(
                m_rioUnit
              , kAudioOutputUnitProperty_SetInputCallback
              , kAudioUnitScope_Global
              , kInputBus
              , &inputCallback
              , sizeof(inputCallback))
          , "couldn't set remote i/o input callback");
    }

    // Set output callback
    AURenderCallbackStruct outputCallback;
    outputCallback.inputProc = RenderCallback;
    outputCallback.inputProcRefCon = this;

    METHCLA_THROW_IF_ERROR(
        AudioUnitSetProperty(
            m_rioUnit
          , kAudioUnitProperty_SetRenderCallback
          , kAudioUnitScope_Global
          , kOutputBus
          , &outputCallback
          , sizeof(outputCallback))
      , "couldn't set remote i/o output callback");

    // Initialize audio unit
    METHCLA_THROW_IF_ERROR(
        AudioUnitInitialize(m_rioUnit)
      , "couldn't initialize the remote I/O unit");

    // Initialize I/O buffers
    m_inputBuffers = new sample_t*[m_numInputs];
    m_outputBuffers = new sample_t*[m_numOutputs];
    for (size_t i = 0; i < m_numInputs; i++) {
        m_inputBuffers[i] =
            Methcla::Memory::allocAlignedOf<sample_t>(Methcla::Memory::kSIMDAlignment, m_bufferSize);
    }
    for (size_t i = 0; i < m_numOutputs; i++) {
        m_outputBuffers[i] =
            Methcla::Memory::allocAlignedOf<sample_t>(Methcla::Memory::kSIMDAlignment, m_bufferSize);
    }
}

RemoteIODriver::~RemoteIODriver()
{
    // Free audio units
    AudioComponentInstanceDispose(m_rioUnit);

    // Free input buffer memory
    for (size_t i=0; i < m_numInputs; i++) {
        Methcla::Memory::free(m_inputBuffers[i]);
    }

    // Free buffer pointer arrays
    delete [] m_inputBuffers;
    delete [] m_outputBuffers;
}

void RemoteIODriver::start()
{
    METHCLA_THROW_IF_ERROR(
        AudioOutputUnitStart(m_rioUnit)
      , "couldn't start remote i/o unit");
}

void RemoteIODriver::stop()
{
    METHCLA_THROW_IF_ERROR(
        AudioOutputUnitStop(m_rioUnit)
      , "couldn't start remote i/o unit");
}

void RemoteIODriver::InterruptionCallback(void *inClientData, UInt32 inInterruption)
{
    RemoteIODriver* self = static_cast<RemoteIODriver*>(inClientData);

    if (inInterruption == kAudioSessionEndInterruption) {
        // make sure we are again the active session
        METHCLA_THROW_IF_ERROR(AudioSessionSetActive(true), "couldn't set audio session active");
        self->start();
    }

    if (inInterruption == kAudioSessionBeginInterruption) {
        self->stop();
    }
}

OSStatus RemoteIODriver::InputCallback(
    void*                       inRefCon,
    AudioUnitRenderActionFlags* ioActionFlags,
    const AudioTimeStamp*       inTimeStamp,
    UInt32                      inBusNumber,
    UInt32                      inNumberFrames,
    AudioBufferList*            /* ioData */)
{
    RemoteIODriver* self = static_cast<RemoteIODriver*>(inRefCon);

    AudioBufferList bufferList;
    bufferList.mNumberBuffers = 1;
    bufferList.mBuffers[0].mData = nullptr;

    AudioBufferList* ioData = &bufferList;

    // Pull data from input bus
    OSStatus err = AudioUnitRender(
        self->m_rioUnit
      , ioActionFlags
      , inTimeStamp
      , inBusNumber
      , inNumberFrames
      , ioData);
    if (err != noErr) return err;

    const UInt32 numInputs = self->m_numInputs;
    sample_t** inputBuffers = self->m_inputBuffers;

    for (size_t bufCount = 0; bufCount < ioData->mNumberBuffers; bufCount++) {
        AudioBuffer& buf = ioData->mBuffers[bufCount];
        BOOST_ASSERT( buf.mNumberChannels == numInputs );

        AudioSampleType* pcm = static_cast<AudioSampleType*>(buf.mData);

        // Deinterleave and convert input
        for (UInt32 curChan = 0; curChan < numInputs; curChan++) {
            for (UInt32 curFrame = 0; curFrame < inNumberFrames; curFrame++) {
                inputBuffers[curChan][curFrame] = pcm[curFrame * numInputs + curChan] / 32768.f;
            }
        }
    }

    return noErr;
}

OSStatus RemoteIODriver::RenderCallback(
    void*                       inRefCon,
    AudioUnitRenderActionFlags* ioActionFlags,
    const AudioTimeStamp*       inTimeStamp,
    UInt32                      inBusNumber,
    UInt32                      inNumberFrames,
    AudioBufferList*            ioData)
{
    RemoteIODriver* self = static_cast<RemoteIODriver*>(inRefCon);

    const sample_t* const* inputBuffers = self->m_inputBuffers;
    const UInt32 numOutputs = self->m_numOutputs;
    sample_t* const* outputBuffers = self->m_outputBuffers;

    for (size_t bufCount = 0; bufCount < ioData->mNumberBuffers; bufCount++) {
        AudioBuffer& buf = ioData->mBuffers[bufCount];
        BOOST_ASSERT( buf.mNumberChannels == numOutputs );

        AudioSampleType* pcm = static_cast<AudioSampleType*>(buf.mData);

        // Run DSP graph
        self->process(inNumberFrames, inputBuffers, outputBuffers);

        // Convert and interleave output
        for (UInt32 curChan = 0; curChan < numOutputs; curChan++) {
            for (UInt32 curFrame = 0; curFrame < inNumberFrames; curFrame++) {
#if METHCLA_AUDIO_THROUGH
                if (curChan < self->m_numInputs) {
                    pcm[curFrame * numOutputs + curChan] = inputBuffers[curChan][curFrame] * 32767.f;
                } else {
                    pcm[curFrame * numOutputs + curChan] = 0.f;
                }
#else
                pcm[curFrame * numOutputs + curChan] = outputBuffers[curChan][curFrame] * 32767.f;
#endif
            }
        }
    }

    return noErr;
}

Driver* Methcla::Audio::IO::defaultPlatformDriver()
{
    return new RemoteIODriver();
}
<|endoftext|>


<commit_before>/*
 * This is a simple kioslave to handle mbox-files.
 * Copyright (C) 2004 Mart Kelder (mart.kde@hccnet.nl)
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
 */
#include "mbox.h"

#include "readmbox.h"
#include "stat.h"
#include "urlinfo.h"

#include <qstring.h>
#include <qcstring.h>

#include <kdebug.h>
#include <klocale.h>
#include <kinstance.h>
#include <kglobal.h>
#include <kurl.h>
#include <kio/global.h>

#include <stdlib.h>

#include "kdepimmacros.h"

#include "mbox.h"

extern "C" { KDE_EXPORT int kdemain(int argc, char* argv[]); }

int kdemain( int argc, char * argv[] )
{
	KLocale::setMainCatalogue("kdelibs");
	KInstance instance("kio_mbox");
	(void) KGlobal::locale();

	if (argc != 4) {
		fprintf(stderr, "Usage: kio_mbox protocol "
	        	        "domain-socket1 domain-socket2\n");
		exit(-1);
	}

	MBoxProtocol slave(argv[2], argv[3]);
	slave.dispatchLoop();

	return 0;
}

MBoxProtocol::MBoxProtocol( const QCString& arg1, const QCString& arg2 )
	: KIO::SlaveBase( "mbox2", arg1, arg2 ),
	m_errorState( true )
{

}

MBoxProtocol::~MBoxProtocol()
{
}

void MBoxProtocol::get( const KURL& url )
{
	m_errorState = false;

	UrlInfo info( url, UrlInfo::message );
	QString line;

	if( info.type() == UrlInfo::invalid && !m_errorState )
	{
		error( KIO::ERR_DOES_NOT_EXIST, info.url() );
		return;
	}

	ReadMBox mbox( &info, this );

	while( !mbox.atEnd() && !m_errorState)
	{
		line = mbox.currentLine();
		line += '\n';
		data( line.utf8() );
		mbox.nextLine();
	};

	if( !m_errorState )
	{
		data( QCString() );
		finished();
	}
}

void MBoxProtocol::listDir( const KURL& url )
{
	m_errorState = false;

	KIO::UDSEntry entry;
	UrlInfo info( url, UrlInfo::directory );
	ReadMBox mbox( &info, this, hasMetaData( "onlynew" ), hasMetaData( "savetime" ) );

	if( m_errorState )
		return;

	if( info.type() != UrlInfo::directory )
	{
		error( KIO::ERR_DOES_NOT_EXIST, info.url() );
		return;
	}

	while( !mbox.atEnd() && !m_errorState )
	{
		entry = Stat::stat( mbox, info );
		if( mbox.inListing() )
			listEntry( entry, false );
	}

	listEntry( KIO::UDSEntry(), true );
	finished();
}

void MBoxProtocol::stat( const KURL& url )
{
	UrlInfo info( url );
	if( info.type() == UrlInfo::invalid )
	{
		error( KIO::ERR_DOES_NOT_EXIST, url.path() );
		return;
	} else
	{
		statEntry( Stat::stat( info ) );
	}
	finished();
}

void MBoxProtocol::mimetype( const KURL& url )
{
	m_errorState = false;

	UrlInfo info( url );

	if( m_errorState )
		return;

	if( info.type() == UrlInfo::invalid )
		error( KIO::ERR_DOES_NOT_EXIST, i18n( "Invalid URL" ) );
	else
		mimeType( info.mimetype() );
	finished();
}

void MBoxProtocol::emitError( int errno, const QString& arg )
{
	m_errorState = true;
	error( errno, arg );
}

<commit_msg>This fixed a bug while sending data with the data() command. By conversion to a QCString, a '\0' was added, which doesn't have to be send.<commit_after>/*
 * This is a simple kioslave to handle mbox-files.
 * Copyright (C) 2004 Mart Kelder (mart.kde@hccnet.nl)
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
 */
#include "mbox.h"

#include "readmbox.h"
#include "stat.h"
#include "urlinfo.h"

#include <qstring.h>
#include <qcstring.h>

#include <kdebug.h>
#include <klocale.h>
#include <kinstance.h>
#include <kglobal.h>
#include <kurl.h>
#include <kio/global.h>

#include <stdlib.h>

#include "kdepimmacros.h"

#include "mbox.h"

extern "C" { KDE_EXPORT int kdemain(int argc, char* argv[]); }

int kdemain( int argc, char * argv[] )
{
	KLocale::setMainCatalogue("kdelibs");
	KInstance instance("kio_mbox");
	(void) KGlobal::locale();

	if (argc != 4) {
		fprintf(stderr, "Usage: kio_mbox protocol "
	        	        "domain-socket1 domain-socket2\n");
		exit(-1);
	}

	MBoxProtocol slave(argv[2], argv[3]);
	slave.dispatchLoop();

	return 0;
}

MBoxProtocol::MBoxProtocol( const QCString& arg1, const QCString& arg2 )
	: KIO::SlaveBase( "mbox2", arg1, arg2 ),
	m_errorState( true )
{

}

MBoxProtocol::~MBoxProtocol()
{
}

void MBoxProtocol::get( const KURL& url )
{
	m_errorState = false;

	UrlInfo info( url, UrlInfo::message );
	QString line;
	QByteArray ba_line;

	if( info.type() == UrlInfo::invalid && !m_errorState )
	{
		error( KIO::ERR_DOES_NOT_EXIST, info.url() );
		return;
	}

	ReadMBox mbox( &info, this );

	while( !mbox.atEnd() && !m_errorState)
	{
		line = mbox.currentLine();
		line += '\n';
		ba_line = QCString( line.utf8() );
		ba_line.truncate( ba_line.size() - 1 ); //Removing training '\0'
		data( ba_line );
		mbox.nextLine();
	};

	if( !m_errorState )
	{
		data( QByteArray() );
		finished();
	}
}

void MBoxProtocol::listDir( const KURL& url )
{
	m_errorState = false;

	KIO::UDSEntry entry;
	UrlInfo info( url, UrlInfo::directory );
	ReadMBox mbox( &info, this, hasMetaData( "onlynew" ), hasMetaData( "savetime" ) );

	if( m_errorState )
		return;

	if( info.type() != UrlInfo::directory )
	{
		error( KIO::ERR_DOES_NOT_EXIST, info.url() );
		return;
	}

	while( !mbox.atEnd() && !m_errorState )
	{
		entry = Stat::stat( mbox, info );
		if( mbox.inListing() )
			listEntry( entry, false );
	}

	listEntry( KIO::UDSEntry(), true );
	finished();
}

void MBoxProtocol::stat( const KURL& url )
{
	UrlInfo info( url );
	if( info.type() == UrlInfo::invalid )
	{
		error( KIO::ERR_DOES_NOT_EXIST, url.path() );
		return;
	} else
	{
		statEntry( Stat::stat( info ) );
	}
	finished();
}

void MBoxProtocol::mimetype( const KURL& url )
{
	m_errorState = false;

	UrlInfo info( url );

	if( m_errorState )
		return;

	if( info.type() == UrlInfo::invalid )
		error( KIO::ERR_DOES_NOT_EXIST, i18n( "Invalid URL" ) );
	else
		mimeType( info.mimetype() );
	finished();
}

void MBoxProtocol::emitError( int errno, const QString& arg )
{
	m_errorState = true;
	error( errno, arg );
}

<|endoftext|>


<commit_before>#include "game.hpp"

int64_t Game::negamax(BitBoard & b, int64_t alpha, int64_t beta, int depth, int real_depth, int rule, bool inNullMove, bool lazyEval, PV* pline) {
	++nodesCounter;
	/*if(game_board.testOfDraw()) {
		return 0;
	}*/

	int64_t oldAlpha = alpha;

	bool extended = false;

	int64_t eval = -WHITE_WIN;
	double margin = PAWN_EV / 2;

	int nextDepth = depth - 1;
	if(depth > 2) {
		if(rule == FIXED_TIME && timer.getTime() >= time) {
			return 0;
		}
	}

	uint8_t color;
	if(b.whiteMove) {
		color = WHITE;
	} else {
		color = BLACK;
	}

	if(depth <= 0 || real_depth >= 100) {
		pline->count = 0;
		return quies(b, alpha, beta, rule, real_depth);
	}

	//PV line;

	if(b.inCheck(color)) {
		++nextDepth;
		extended = true;
		inNullMove = true;
	}

	int tmp;

	uint64_t hash = b.getColorHash();

	Hash* currentHash = &boardHash[hash & hash_cutter];

	if(currentHash->flag != EMPTY && currentHash->key == hash && !extended) {
		if(real_depth > 0 && currentHash->depth >= depth) {
			double score = currentHash->score;

			if(score > WHITE_WIN - 100) {
				score -= real_depth;
			} else if(score < -WHITE_WIN + 100) {
				score += real_depth;
			}

			if(currentHash->flag == EXACT || currentHash->flag == BETA) {
				if(score > alpha) {
					alpha = score;
				}
				if(alpha >= beta) {
					return beta;
				}
			} else if(currentHash->flag == ALPHA) {
				if(score <= alpha) {
					return alpha;
				}
			}
		}

		if(currentHash->flag != ALPHA && real_depth > 0) {
			b.move(currentHash->move);
			tmp = -negamax(b, -beta, -alpha, depth - 1, real_depth + 1, rule, inNullMove, false, pline);
			b.goBack();

			if(tmp > alpha) {
				recordHash(depth, tmp, tmp<beta?EXACT:BETA, hash, currentHash->move, real_depth);
				alpha = tmp;
				if(alpha >= beta) {
		  			return beta;
				}
			}
		}
	}

	bool inCheck;
	if(color == WHITE) {
		inCheck = b.inCheck(WHITE);
	} else {
		inCheck = b.inCheck(BLACK);
	}

	/*if(!inNullMove && depth <= 2 && !extended && !b.attacked && !inCheck && b.getEvalute() - margin >= beta) {
		return beta;
	}*/

	if(option.nullMovePrunningEnable) {
		if(!inNullMove && !b.inCheck(color) && !extended && !b.attacked && real_depth > 2 && b.getFiguresCount() > 3) {
			b.whiteMove = !b.whiteMove;
			if(-negamax(b, -beta, -alpha, depth - 3, real_depth + 1, rule, true, true, pline) >= beta) {
				return beta;
			}
			b.whiteMove = !b.whiteMove;
		}
	}

	int num_moves = 0;

	b.bitBoardMoveGenerator(moveArray[real_depth]);
	sortAttacks(moveArray[real_depth]);
	sortMoves(moveArray[real_depth], real_depth);

	BitMove local_move;

	if(moveArray[real_depth].count > 0) {
		local_move = moveArray[real_depth].moveArray[0];
	}

/*	if(real_depth == 0) {
		std::cout << "info depth " << max_depth << "\n";
	}*/
	for(unsigned int i = 0; i < moveArray[real_depth].count; ++i) {
		b.move(moveArray[real_depth].moveArray[i]);

		if(game_board.inCheck(color)) {
			b.goBack();
			continue;
		}

		if(num_moves == 0) {
			local_move = moveArray[real_depth].moveArray[i];
		}

		++num_moves;

		/*if(!lazyEval && b.getEvalute() + margin <= alpha && !b.inCheck(color) && !extended && !b.attacked && -negamax(b, -beta, -alpha, depth - 3, real_depth + 1, rule, inNullMove, true, pline) <= alpha) {
			tmp = alpha;
		} else {
			tmp = -negamax(b, -beta, -alpha, nextDepth, real_depth + 1, rule, inNullMove, lazyEval, pline);
		}*/

		if(!option.lmrEnable) {
			tmp = -negamax(b, -(alpha + 1), -alpha, nextDepth, real_depth + 1, rule, inNullMove, lazyEval, pline);

			if(tmp > alpha && tmp < beta) {
				tmp = -negamax(b, -beta, -alpha, nextDepth, real_depth + 1, rule, inNullMove, lazyEval, pline);
			}
		} else {
			if(num_moves <= 3 || b.inCheck(color) || extended || inNullMove || b.attacked) {
				tmp = -negamax(b, -beta, -alpha, nextDepth, real_depth + 1, rule, inNullMove, lazyEval, pline);
			} else {
				tmp = -negamax(b, -(alpha + 1), -alpha, nextDepth-1, real_depth + 1, rule, inNullMove, lazyEval, pline);

				if(tmp > alpha) {
					tmp = -negamax(b, -beta, -alpha, nextDepth, real_depth + 1, rule, inNullMove, lazyEval, pline);
				}
			}
		}

		b.goBack();

		if(tmp > eval) {
			eval = tmp;
		}

		if(tmp > alpha) {
			alpha = tmp;
			local_move = moveArray[real_depth].moveArray[i];

			if(real_depth == 0) {
				if(num_moves >= 0) {
					std::cout << "info depth " << max_depth << " time " << (int)((clock() - start_timer) / (CLOCKS_PER_SEC / 1000)) << " nodes " << nodesCounter << " nps " << (int)(nodesCounter / ((clock() - start_timer) / CLOCKS_PER_SEC));
					std::cout << " ";
					printScore(eval);
					std::cout << " pv " << local_move.getMoveString() << "\n";
				} else {
					std::cout << "\n";
				}
			}

			if(!local_move.isAttack) {
				if(color == WHITE) {
					//whiteHistorySort[local_move.fromY][local_move.fromX][local_move.toY][local_move.toX] += pow(depth, 2);
					whiteKiller[real_depth] = Killer(local_move);
				} else {
					//blackHistorySort[local_move.fromY][local_move.fromX][local_move.toY][local_move.toX] += pow(depth, 2);
					blackKiller[real_depth] = Killer(local_move);
				}
			}

			recordHash(depth, tmp, tmp<beta?EXACT:BETA, hash, moveArray[real_depth].moveArray[i], real_depth);

			//pline->line[0] = local_move;
			//memcpy(pline->line + 1, line.line, line.count * sizeof(local_move));
			//pline->count = line.count + 1;
			//r7/p2kr1pp/1qp1p3/3pPbQ1/8/RPP2N2/5PPP/R5K1 b - - 6 23

		}

		if(alpha >= beta) {
			return beta;
		}
	}

	if(num_moves == 0) {
		if(game_board.inCheck(color)) {
			return BLACK_WIN + real_depth;
		} else {
			return 0;
		}
	}

	if(real_depth == 0) {
		if(rule == FIXED_TIME && timer.getTime() >= time) {
			return 0;
		}

		bestMove = local_move;
		bestScore = alpha;

		//for(int i = 0; i < pline->count; ++i) {
			//std::cout << pline->line[i].getMoveString() << " ";
		//}
	}

	if(alpha == oldAlpha) {
		recordHash(depth, alpha, ALPHA, hash, local_move, real_depth);
	}

	return alpha;
}

uint64_t Game::perft(int depth) {
	uint64_t res = 0;
	if(depth == 0) {
		return 1;
	}

	game_board.bitBoardMoveGenerator(moveArray[depth]);

	for(unsigned int i = 0; i < moveArray[depth].count; ++i) {
		game_board.move(moveArray[depth].moveArray[i]);
		if(game_board.whiteMove) {
			if(game_board.inCheck(BLACK)) {
				game_board.goBack();
				continue;
			}
		} else {
			if(game_board.inCheck(WHITE)) {
				game_board.goBack();
				continue;
			}
		}

		res += perft(depth - 1);
		game_board.goBack();
	}

	return res;
}

int64_t Game::quies(BitBoard & b, int64_t alpha, int64_t beta, int rule, int real_depth) {
	int64_t val = b.getEvalute();

	if(val >= beta) {
		return beta;
	}

	if(alpha < val) {
		alpha = val;
	}

	b.bitBoardAttackMoveGenerator(moveArray[real_depth]);
	sortAttacks(moveArray[real_depth]);

	for(unsigned int i = 0; i < moveArray[real_depth].count && alpha < beta; ++i) {
		++nodesCounter;
		b.move(moveArray[real_depth].moveArray[i]);

		if(!b.whiteMove) {
			if(game_board.inCheck(WHITE)) {
				b.goBack();
				continue;
			}
		} else {
			if(game_board.inCheck(BLACK)) {
				b.goBack();
				continue;
			}
		}

		val = -quies(b, -beta, -alpha, rule, real_depth + 1);
		b.goBack();

		if(val >= beta) {
			return val;
		}

		if(val > alpha) {
			alpha = val;
		}
	}

	return alpha;
}

bool Game::recordHash(int depth, int score, int flag, uint64_t key, BitMove move, int real_depth) {
	Hash* hash = &boardHash[key & hash_cutter];

	if(flag == ALPHA && (hash->flag == EXACT || hash->flag == BETA)) {
		return 0;
	}

	if(score > WHITE_WIN - 100) {
		score += real_depth;
	} else if(score < -WHITE_WIN + 100) {
		score -= real_depth;
	}

	hash->depth = depth;
	hash->score = score;
	hash->flag = flag;
	hash->key = key;

	if(flag != ALPHA) {
		hash->move = move;
	}
}
<commit_msg>last upd.<commit_after>#include "game.hpp"

int64_t Game::negamax(BitBoard & b, int64_t alpha, int64_t beta, int depth, int real_depth, int rule, bool inNullMove, bool lazyEval, PV* pline) {
	++nodesCounter;
	/*if(game_board.testOfDraw()) {
		return 0;
	}*/

	int64_t oldAlpha = alpha;

	bool extended = false;

	int64_t eval = -WHITE_WIN;
	double margin = PAWN_EV / 2;

	int nextDepth = depth - 1;
	if(depth > 2) {
		if(rule == FIXED_TIME && timer.getTime() >= time) {
			return 0;
		}
	}

	uint8_t color;
	if(b.whiteMove) {
		color = WHITE;
	} else {
		color = BLACK;
	}

	if(depth <= 0 || real_depth >= 100) {
		pline->count = 0;
		return quies(b, alpha, beta, rule, real_depth);
	}

	//PV line;

	if(b.inCheck(color)) {
		++nextDepth;
		extended = true;
		inNullMove = true;
	}

	int tmp;

	uint64_t hash = b.getColorHash();

	Hash* currentHash = &boardHash[hash & hash_cutter];

	if(currentHash->flag != EMPTY && currentHash->key == hash && !extended) {
		if(real_depth > 0 && currentHash->depth >= depth) {
			double score = currentHash->score;

			if(score > WHITE_WIN - 100) {
				score -= real_depth;
			} else if(score < -WHITE_WIN + 100) {
				score += real_depth;
			}

			if(currentHash->flag == EXACT || currentHash->flag == BETA) {
				if(score > alpha) {
					alpha = score;
				}
				if(alpha >= beta) {
					return beta;
				}
			} else if(currentHash->flag == ALPHA) {
				if(score <= alpha) {
					return alpha;
				}
			}
		}

		if(currentHash->flag != ALPHA && real_depth > 0) {
			b.move(currentHash->move);
			tmp = -negamax(b, -beta, -alpha, depth - 1, real_depth + 1, rule, inNullMove, false, pline);
			b.goBack();

			if(tmp > alpha) {
				recordHash(depth, tmp, tmp<beta?EXACT:BETA, hash, currentHash->move, real_depth);
				alpha = tmp;
				if(alpha >= beta) {
		  			return beta;
				}
			}
		}
	}

	bool inCheck;
	if(color == WHITE) {
		inCheck = b.inCheck(WHITE);
	} else {
		inCheck = b.inCheck(BLACK);
	}

	/*if(!inNullMove && depth <= 2 && !extended && !b.attacked && !inCheck && b.getEvalute() - margin >= beta) {
		return beta;
	}*/

	if(option.nullMovePrunningEnable) {
		if(!inNullMove && !b.inCheck(color) && !extended && !b.attacked && real_depth > 2 && b.getFiguresCount() > 3) {
			b.whiteMove = !b.whiteMove;
			if(-negamax(b, -beta, -(beta - 1), depth - 3, real_depth + 1, rule, true, true, pline) >= beta) {
				b.whiteMove = !b.whiteMove;
				return beta;
			}
			b.whiteMove = !b.whiteMove;
		}
	}

	int num_moves = 0;

	b.bitBoardMoveGenerator(moveArray[real_depth]);
	sortAttacks(moveArray[real_depth]);
	sortMoves(moveArray[real_depth], real_depth);

	BitMove local_move;

	if(moveArray[real_depth].count > 0) {
		local_move = moveArray[real_depth].moveArray[0];
	}

/*	if(real_depth == 0) {
		std::cout << "info depth " << max_depth << "\n";
	}*/
	for(unsigned int i = 0; i < moveArray[real_depth].count; ++i) {
		b.move(moveArray[real_depth].moveArray[i]);

		if(game_board.inCheck(color)) {
			b.goBack();
			continue;
		}

		if(num_moves == 0) {
			local_move = moveArray[real_depth].moveArray[i];
		}

		++num_moves;

		/*if(!lazyEval && b.getEvalute() + margin <= alpha && !b.inCheck(color) && !extended && !b.attacked && -negamax(b, -beta, -alpha, depth - 3, real_depth + 1, rule, inNullMove, true, pline) <= alpha) {
			tmp = alpha;
		} else {
			tmp = -negamax(b, -beta, -alpha, nextDepth, real_depth + 1, rule, inNullMove, lazyEval, pline);
		}*/

		if(!option.lmrEnable) {
			tmp = -negamax(b, -(alpha + 1), -alpha, nextDepth, real_depth + 1, rule, inNullMove, lazyEval, pline);

			if(tmp > alpha && tmp < beta) {
				tmp = -negamax(b, -beta, -alpha, nextDepth, real_depth + 1, rule, inNullMove, lazyEval, pline);
			}
		} else {
			if(num_moves <= 3 || b.inCheck(color) || extended || inNullMove || b.attacked) {
				tmp = -negamax(b, -beta, -alpha, nextDepth, real_depth + 1, rule, inNullMove, lazyEval, pline);
			} else {
				tmp = -negamax(b, -(alpha + 1), -alpha, nextDepth-1, real_depth + 1, rule, inNullMove, lazyEval, pline);

				if(tmp > alpha) {
					tmp = -negamax(b, -beta, -alpha, nextDepth, real_depth + 1, rule, inNullMove, lazyEval, pline);
				}
			}
		}

		b.goBack();

		if(tmp > eval) {
			eval = tmp;
		}

		if(tmp > alpha) {
			alpha = tmp;
			local_move = moveArray[real_depth].moveArray[i];

			if(real_depth == 0) {
				if(num_moves >= 0) {
					std::cout << "info depth " << max_depth << " time " << (int)((clock() - start_timer) / (CLOCKS_PER_SEC / 1000)) << " nodes " << nodesCounter << " nps " << (int)(nodesCounter / ((clock() - start_timer) / CLOCKS_PER_SEC));
					std::cout << " ";
					printScore(eval);
					std::cout << " pv " << local_move.getMoveString() << "\n";
				} else {
					std::cout << "\n";
				}
			}

			if(!local_move.isAttack) {
				if(color == WHITE) {
					//whiteHistorySort[local_move.fromY][local_move.fromX][local_move.toY][local_move.toX] += pow(depth, 2);
					whiteKiller[real_depth] = Killer(local_move);
				} else {
					//blackHistorySort[local_move.fromY][local_move.fromX][local_move.toY][local_move.toX] += pow(depth, 2);
					blackKiller[real_depth] = Killer(local_move);
				}
			}

			recordHash(depth, tmp, tmp<beta?EXACT:BETA, hash, moveArray[real_depth].moveArray[i], real_depth);

			//pline->line[0] = local_move;
			//memcpy(pline->line + 1, line.line, line.count * sizeof(local_move));
			//pline->count = line.count + 1;
			//r7/p2kr1pp/1qp1p3/3pPbQ1/8/RPP2N2/5PPP/R5K1 b - - 6 23

		}

		if(alpha >= beta) {
			return beta;
		}
	}

	if(num_moves == 0) {
		if(game_board.inCheck(color)) {
			return BLACK_WIN + real_depth;
		} else {
			return 0;
		}
	}

	if(real_depth == 0) {
		if(rule == FIXED_TIME && timer.getTime() >= time) {
			return 0;
		}

		bestMove = local_move;
		bestScore = alpha;

		//for(int i = 0; i < pline->count; ++i) {
			//std::cout << pline->line[i].getMoveString() << " ";
		//}
	}

	if(alpha == oldAlpha) {
		recordHash(depth, alpha, ALPHA, hash, local_move, real_depth);
	}

	return alpha;
}

uint64_t Game::perft(int depth) {
	uint64_t res = 0;
	if(depth == 0) {
		return 1;
	}

	game_board.bitBoardMoveGenerator(moveArray[depth]);

	for(unsigned int i = 0; i < moveArray[depth].count; ++i) {
		game_board.move(moveArray[depth].moveArray[i]);
		if(game_board.whiteMove) {
			if(game_board.inCheck(BLACK)) {
				game_board.goBack();
				continue;
			}
		} else {
			if(game_board.inCheck(WHITE)) {
				game_board.goBack();
				continue;
			}
		}

		res += perft(depth - 1);
		game_board.goBack();
	}

	return res;
}

int64_t Game::quies(BitBoard & b, int64_t alpha, int64_t beta, int rule, int real_depth) {
	int64_t val = b.getEvalute();

	if(val >= beta) {
		return beta;
	}

	if(alpha < val) {
		alpha = val;
	}

	b.bitBoardAttackMoveGenerator(moveArray[real_depth]);
	sortAttacks(moveArray[real_depth]);

	for(unsigned int i = 0; i < moveArray[real_depth].count && alpha < beta; ++i) {
		++nodesCounter;
		b.move(moveArray[real_depth].moveArray[i]);

		if(!b.whiteMove) {
			if(game_board.inCheck(WHITE)) {
				b.goBack();
				continue;
			}
		} else {
			if(game_board.inCheck(BLACK)) {
				b.goBack();
				continue;
			}
		}

		val = -quies(b, -beta, -alpha, rule, real_depth + 1);
		b.goBack();

		if(val >= beta) {
			return val;
		}

		if(val > alpha) {
			alpha = val;
		}
	}

	return alpha;
}

bool Game::recordHash(int depth, int score, int flag, uint64_t key, BitMove move, int real_depth) {
	Hash* hash = &boardHash[key & hash_cutter];

	if(flag == ALPHA && (hash->flag == EXACT || hash->flag == BETA)) {
		return 0;
	}

	if(score > WHITE_WIN - 100) {
		score += real_depth;
	} else if(score < -WHITE_WIN + 100) {
		score -= real_depth;
	}

	hash->depth = depth;
	hash->score = score;
	hash->flag = flag;
	hash->key = key;

	if(flag != ALPHA) {
		hash->move = move;
	}
}
<|endoftext|>


<commit_before>#include <stdlib.h>
#include <sys/socket.h>
#include <string.h>
#include <netinet/in.h>
#include <cstring>
#include <stdio.h>
#include <string>
#include <iostream>
#include <list>
#include <map>

#include "server.h"
#include "duckchat.h"

// TODO Server can accept connections.
// TODO Server handles Login and Logout from users, and keeps records of which users are logged in.
// TODO Server handles Join and Leave from users, keeps records of which channels a user belongs to,
// and keeps records of which users are in a channel.
// TODO Server handles the Say message.
// TODO Server correctly handles List and Who.
// TODO Create copies of your client and server source. Modify them to send invalid packets to your good client
// and server, to see if you can make your client or server crash. Fix any bugs you find.

std::string user;

class Channel {
public:
  std::string name;
  std::list<User *> users;

  Channel(std::string name): name(name) {};
};

class User {
public:
  std::string name;
  int port;
  struct sockaddr_in *address;
  std::list<Channel *> channels;

  User(std::string name, int port, struct sockaddr_in *address): name(name), port(port), address(address) {};
};

std::map<std::string, User *> users;
std::map<std::string, Channel *> channels;

void Error(const char *msg) {
  perror(msg);
  exit(1);
}

void ProcessRequest(void *buffer) {
  struct request current_request;
  memcpy(&current_request, buffer, sizeof(struct request));
  std::cout << "request type: " << current_request.req_type << std::endl;
  request_t request_type = current_request.req_type;

  switch(request_type){
    case REQ_LOGIN:
      struct request_login login_request;
      memcpy(&login_request, buffer, sizeof(struct request_login));
      user = login_request.req_username;
      std::cout << "server: " << login_request.req_username << " logs in" << std::endl;
      break;
    case REQ_LOGOUT:
      struct request_logout logout_request;
      memcpy(&logout_request, buffer, sizeof(struct request_logout));
      std::cout << "server: " << user << " logs out" << std::endl;
      break;
    case REQ_JOIN:
      struct request_join join_request;
      memcpy(&join_request, buffer, sizeof(struct request_join));
      std::cout << "server: " << user << " joins channel " << join_request.req_channel << std::endl;
      break;
    default:
      break;
  }

}

int main(int argc, char *argv[]) {
  struct sockaddr_in server_addr;

  int server_socket;
  int receive_len;
  void* buffer[kBufferSize];
  int port;

  user = "";

  if (argc < 2) {
    std::cerr << "server: no port provided" << std::endl;
    exit(1);
  }

  port = atoi(argv[1]);

  memset((char *) &server_addr, 0, sizeof(server_addr));
  server_addr.sin_family = AF_INET;
  server_addr.sin_addr.s_addr = htonl(INADDR_ANY);
  server_addr.sin_port = htons(port);

  if ((server_socket = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
    Error("server: can't open socket\n");
  }

  if (bind(server_socket, (struct sockaddr *) &server_addr, sizeof(server_addr)) < 0) {
    Error("server: bind failed\n");
  }

  printf("server: waiting on port %d\n", port);
  while (1) {
    struct sockaddr_in client_addr;
    socklen_t client_addr_len = sizeof(client_addr);
    std::cout << "before recvfrom" << std::endl;
    receive_len = recvfrom(server_socket, buffer, kBufferSize, 0, (struct sockaddr *) &client_addr, &client_addr_len);
    if (receive_len > 0) {
      buffer[receive_len] = 0;
      ProcessRequest(buffer);
    }
  }
}
<commit_msg>maybe finished login, print users in user map<commit_after>#include <stdlib.h>
#include <sys/socket.h>
#include <string.h>
#include <netinet/in.h>
#include <cstring>
#include <stdio.h>
#include <string>
#include <iostream>
#include <list>
#include <map>

#include "server.h"
#include "duckchat.h"

// TODO Server can accept connections.
// TODO Server handles Login and Logout from users, and keeps records of which users are logged in.
// TODO Server handles Join and Leave from users, keeps records of which channels a user belongs to,
// and keeps records of which users are in a channel.
// TODO Server handles the Say message.
// TODO Server correctly handles List and Who.
// TODO Create copies of your client and server source. Modify them to send invalid packets to your good client
// and server, to see if you can make your client or server crash. Fix any bugs you find.

//std::string user;

class Channel {
public:
  std::string name;
  std::list<User *> users;

  Channel(std::string name): name(name) {};
};

class User {
public:
  std::string name;
  struct sockaddr_in *address;
  std::list<Channel *> channels;

  User(std::string name, struct sockaddr_in *address): name(name), address(address) {};
};

std::map<std::string, User *> users;
std::map<std::string, Channel *> channels;

void Error(const char *msg) {
  perror(msg);
  exit(1);
}

void ProcessRequest(void *buffer, struct sockaddr_in *address) {
  struct request current_request;
  memcpy(&current_request, buffer, sizeof(struct request));
  std::cout << "request type: " << current_request.req_type << std::endl;
  request_t request_type = current_request.req_type;

  switch(request_type){
    case REQ_LOGIN:
      struct request_login login_request;
      memcpy(&login_request, buffer, sizeof(struct request_login));

      User *new_user = new User(login_request.req_username, address);
      users.insert(login_request.req_username, new_user);

      for (auto user : users) {
        std::cout << user.first << " " << user.second << std::endl;
      }

      std::cout << "server: " << login_request.req_username << " logs in" << std::endl;
      break;
    case REQ_LOGOUT:
      struct request_logout logout_request;
      memcpy(&logout_request, buffer, sizeof(struct request_logout));
//      std::cout << "server: " << username << " logs out" << std::endl;
      break;
    case REQ_JOIN:
      struct request_join join_request;
      memcpy(&join_request, buffer, sizeof(struct request_join));
//      std::cout << "server: " << username << " joins channel " << join_request.req_channel << std::endl;
      break;
    default:
      break;
  }

}

int main(int argc, char *argv[]) {
  struct sockaddr_in server_addr;

  int server_socket;
  int receive_len;
  void* buffer[kBufferSize];
  int port;

//  user = "";

  if (argc < 2) {
    std::cerr << "server: no port provided" << std::endl;
    exit(1);
  }

  port = atoi(argv[1]);

  memset((char *) &server_addr, 0, sizeof(server_addr));
  server_addr.sin_family = AF_INET;
  server_addr.sin_addr.s_addr = htonl(INADDR_ANY);
  server_addr.sin_port = htons(port);

  if ((server_socket = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
    Error("server: can't open socket\n");
  }

  if (bind(server_socket, (struct sockaddr *) &server_addr, sizeof(server_addr)) < 0) {
    Error("server: bind failed\n");
  }

  printf("server: waiting on port %d\n", port);
  while (1) {
    struct sockaddr_in client_addr;
    socklen_t client_addr_len = sizeof(client_addr);
    std::cout << "before recvfrom" << std::endl;
    receive_len = recvfrom(server_socket, buffer, kBufferSize, 0, (struct sockaddr *) &client_addr, &client_addr_len);
    if (receive_len > 0) {
      buffer[receive_len] = 0;
      ProcessRequest(buffer, &client_addr);
    }
  }
}
<|endoftext|>