<commit_before>#include "mainwindow.h"
#include "ui_mainwindow.h"
#include "graphSettingsPopup.h"
#include <QDateTime>

MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);

#ifdef PMD_HAMP
    ui->pbtn_StartStop->setChecked(true);
#endif
	printf("This is MainWindow\n");
	qDebug("This is MainWindow via QDebug()\n");

    m_alarmBtnNormalStyleSheet=ui->pbtn_ECG_Alarm->styleSheet();
    m_alarmBtnRedStyleSheet= "*{border: 0px;background-image: url(:/images/icnBellRed.png);} *:checked{background-image:url();}";

    m_graphWidget1 = new Widget(ui->graphECGWidget,this);
#ifndef ONLY_SHOW_ECG_GRAPH
    m_graphWidget2 = new Widget(ui->graphABPWidget,this);
    m_graphWidget3 = new Widget(ui->graphPLETHWidget,this);
#endif

    m_graphWidget1->initialized(GraphECG,3);
#ifndef ONLY_SHOW_ECG_GRAPH
    m_graphWidget2->initialized(GraphABP,1);
    m_graphWidget3->initialized(GraphPLETH,2);
#endif

    m_selectedGraphWidget = NULL;

    // Set time
    updateTimeString();

    // Setup timer to update UI
    QTimer *timer = new QTimer(this);
    connect(timer, SIGNAL(timeout()), this, SLOT(updateTimeString()));
    timer->start(1000);

    m_timerAlarm =new QTimer (this);
    connect(m_timerAlarm, SIGNAL(timeout()), this, SLOT(animateAlarm()));
    m_timerAlarm->setInterval(500);
    m_timerAlarm->stop();

    m_timerDataValues = new QTimer(this);
#ifndef DISABLE_RIGHT_PANEL_NUMERIC_VALUES
    connect(m_timerDataValues, SIGNAL(timeout()), this, SLOT(updatePulse()));
    connect(m_timerDataValues, SIGNAL(timeout()), this, SLOT(updateABP()));
    connect(m_timerDataValues, SIGNAL(timeout()), this, SLOT(updatePLETH()));
    m_timerDataValues->setInterval(3000);
    #ifndef PMD_HAMP
        m_timerDataValues->start();
    #endif
#endif

    m_HB_Simulate_Data << 70 << 68 << 71 << 69<< 67<< 68;
    m_ABP_Higher_Simulate_Data << 100 << 110 << 107 << 124<< 137<< 119;
    m_ABP_Lower_Simulate_Data << 73 << 88 << 77 << 82 << 91 << 79;
    m_PLETH_Simulate_Data << 93 << 96 << 90 << 97 << 95 << 99;

    m_cstatus=true;

#ifdef PMD_MEHV
    m_nserver =new Server(this);
    m_cstatus=false;
#endif

#ifdef PMD_NUCLEUS
    m_dataSupplier=new DataSupplier(this);
#endif

#ifdef PMD_HAMP
	printf("Creating HAMPDataSupplier\n");
    m_hampdataSupplier =new HAMPDataSupplier(this);
    m_cstatus=true;

    // Setup timer to update UI
    QTimer *hamptimer = new QTimer(this);
    connect(hamptimer, SIGNAL(timeout()), this, SLOT(takeScreenSnapshort()));
    hamptimer->start(3000);

#endif

    m_isPauseAll=false;
    m_isStart=true;
    m_isAlarmSilent=false;
    m_btnSilentPressed=false;

    m_graphSettingsPop =new GraphSettingsPopup(this);
    m_graphSettingsPop->hide();

    // Setup graph scrolling mode
#ifdef ENABLE_GRAPH_SCROLLING
    on_pbtn_Scrolling_clicked(true);
    ui->pbtn_Scrolling->setChecked(true);
#else
    on_pbtn_Scrolling_clicked(false);
    ui->pbtn_Scrolling->setChecked(false);
#endif
}

MainWindow::~MainWindow()
{
    delete ui;
}

void MainWindow::updatePulse()
{
    QString value="0";

    if(m_isPauseAll==true || m_isStart==false)
        return;

    if(m_cstatus)
    {
        value.setNum(this->getPulseValue());
    }

    ui->labelPulse->setText(value);
    ui->labelPulse->repaint();
}

void MainWindow::updateABP()
{

    if(m_isPauseAll==true || m_isStart==false)
        return;

    if(m_cstatus)
    {
      ui->labelABP->setText(this->getABPValue());
    }
    else
        ui->labelABP->setText("0/0");

    ui->labelABP->repaint();
}

void MainWindow::updatePLETH()
{
    if(m_isPauseAll==true || m_isStart==false)
        return;

    if(m_cstatus)
    {
      ui->labelSPO2->setText(this->getPLETHValue());
    }
    else
        ui->labelSPO2->setText("0");

    ui->labelABP->repaint();
}

void MainWindow::updateTimeString()
{
    //get current date and time
    QDateTime dateTime = QDateTime::currentDateTime();
    QString dateTimeString = dateTime.toString("hh:mm:ss AP");
    ui->labelTime->setText(dateTimeString);
    ui->labelTime->repaint();
}

int MainWindow::getPulseValue()
{
    static int index=-1;

    if(index==this->m_HB_Simulate_Data.count()-1)
        index=0;
    else
        index++;

    return m_HB_Simulate_Data[index];
}

QString MainWindow::getABPValue()
{
    static int index=-1;

    if(index==this->m_ABP_Higher_Simulate_Data.count()-1)
        index=0;
    else
        index++;

    QString str=QString("%1/%2").arg(m_ABP_Higher_Simulate_Data[index]).arg(m_ABP_Lower_Simulate_Data[index]);
    return str;
}

QString MainWindow::getPLETHValue()
{
    static int index=-1;

    if(index==this->m_PLETH_Simulate_Data.count()-1)
        index=0;
    else
        index++;

    QString str=QString("%1").arg(m_PLETH_Simulate_Data[index]);
    return str;
}

void MainWindow::on_pbtn_Silent_clicked()
{
   m_btnSilentPressed=!m_btnSilentPressed;
    if(m_btnSilentPressed)
    {
        ui->pbtn_ECG_Alarm->setChecked(true);
        ui->pbtn_ABP_Alarm->setChecked(true);
        ui->pbtn_spo2_Alarm->setChecked(true);
        m_isAlarmSilent=true;
       // ui->pbtn_Silent->setStyleSheet("*{border: 0px;background-image: url(:/images/btn_pressed.png);}");
    }
    else
    {
        ui->pbtn_ECG_Alarm->setChecked(false);
        ui->pbtn_ABP_Alarm->setChecked(false);
        ui->pbtn_spo2_Alarm->setChecked(false);
        m_isAlarmSilent=false;
        //ui->pbtn_Silent->setStyleSheet("");
    }
}

void MainWindow::on_pbtn_StartStop_clicked(bool checked)
{

#ifdef PMD_HAMP

    if(checked)
    {
		qDebug("MainWindow::on_pbtn_StartStop_clicked button pushed - %d\n", checked);
        m_isStart=false;
        m_timerDataValues->stop();
        ui->pbtn_StartStop->setText("Start");
        m_hampdataSupplier->startStopNucleus(m_isStart);
        m_cstatus=false;
    }
    else
    {
		qDebug("MainWindow::on_pbtn_StartStop_clicked button pushed - %d\n", checked);
        m_isStart=true;
        ui->pbtn_StartStop->setText("Stop");
        m_timerDataValues->start();
        m_hampdataSupplier->startStopNucleus(m_isStart);
        m_cstatus=true;

    }
   fflush(stdout);
#else

    if(checked)
    {
        m_isStart=false;
        this->m_graphWidget1->clearWidget();
#ifndef ONLY_SHOW_ECG_GRAPH
        this->m_graphWidget2->clearWidget();
        this->m_graphWidget3->clearWidget();
#endif
        ui->pbtn_StartStop->setText("Start");
    }
    else
    {
        m_isStart=true;
        ui->pbtn_StartStop->setText("Stop");
    }

#endif

}

void MainWindow::on_pbtn_PauseAll_clicked(bool checked)
{
    if(!checked)
    {
        m_isPauseAll=false;
        ui->pbtn_PauseAll->setText("Pause All");
    }
    else
    {
        m_isPauseAll=true;
        this->m_graphWidget1->clearWidget();
#ifndef ONLY_SHOW_ECG_GRAPH
        this->m_graphWidget2->clearWidget();
        this->m_graphWidget3->clearWidget();
#endif
        ui->pbtn_PauseAll->setText("Start All");
    }
}

void MainWindow::on_pbtn_Scrolling_clicked(bool checked)
{
 (void)checked;
#ifndef PMD_HAMP
    m_graphWidget1->setScrollingMode(checked);
#ifndef ONLY_SHOW_ECG_GRAPH
    m_graphWidget2->setScrollingMode(checked);
    m_graphWidget3->setScrollingMode(checked);
#endif
#endif
}

void MainWindow::updateTimer()
{
#ifdef PMD_MEHV
    pm_data_struct pm={0,0,0,0};
    dataReceived (&pm);
#endif
}

void MainWindow::animateAlarm()
{
    ui->pbtn_ABP_Alarm->toggle();
    ui->pbtn_ECG_Alarm->toggle();
    ui->pbtn_spo2_Alarm->toggle();
}

void MainWindow::on_pbtn_ECG_Alarm_clicked(bool checked)
{
    (void)checked;
}

void MainWindow::on_pbtn_spo2_Alarm_clicked(bool checked)
{
    (void)checked;
}

void MainWindow::on_pbtn_ABP_Alarm_clicked(bool checked)
{
    (void)checked;
}

void MainWindow::dataReceived(pm_data_struct *current)
{
	qDebug("MainWindow::dataReceived: Entered\n");
	if (m_isPauseAll==false)
    {
		switch(m_graphWidget1->getGraphType())
        {

        case GraphECG:
            m_graphWidget1->animate(current->ecgValue);
        break;

        case GraphABP:
            m_graphWidget1->animate(current->abpValue);
        break;

        case GraphPLETH:
            m_graphWidget1->animate(current->plethValue);
        break;

        case GraphCO2:
            //TODO
        break;
        }

#ifndef ONLY_SHOW_ECG_GRAPH
        switch(m_graphWidget2->getGraphType())
        {
        case GraphECG:
            m_graphWidget2->animate(current->ecgValue);
        break;

        case GraphABP:
            m_graphWidget2->animate(current->abpValue);
        break;

        case GraphPLETH:
            m_graphWidget2->animate(current->plethValue);
        break;

        case GraphCO2:
            //TODO
        break;
        }

        switch(m_graphWidget3->getGraphType())
        {
        case GraphECG:
            m_graphWidget3->animate(current->ecgValue);
        break;

        case GraphABP:
            m_graphWidget3->animate(current->abpValue);
        break;

        case GraphPLETH:
            m_graphWidget3->animate(current->plethValue);
        break;

        case GraphCO2:
            //TODO
        break;
        }
#endif
    }
}

#ifndef PMD_NUCLEUS
void MainWindow::connectionStatus(bool status)
{
    QDateTime dateTime = QDateTime::currentDateTime();
    QString dateTimeString = dateTime.toString("hh:mmap");
    m_cstatus=status;

    if(status)
    {
        ui->labelBulletText->setText("External system connected at "+dateTimeString);
        ui->labelBulletText->repaint();
        ui->pbtn_ECG_Alarm->setStyleSheet(m_alarmBtnNormalStyleSheet);
        ui->pbtn_ABP_Alarm->setStyleSheet(m_alarmBtnNormalStyleSheet);
        ui->pbtn_spo2_Alarm->setStyleSheet(m_alarmBtnNormalStyleSheet);
        ui->pbtn_ABP_Alarm->setDisabled(false);
        ui->pbtn_ECG_Alarm->setDisabled(false);
        ui->pbtn_spo2_Alarm->setDisabled(false);
        m_timerAlarm->stop();

    }
    else
    {
        ui->labelBulletText->setText("External system disconnected at "+dateTimeString);
        ui->labelBulletText->repaint();
        ui->pbtn_ECG_Alarm->setStyleSheet(m_alarmBtnRedStyleSheet);
        ui->pbtn_ABP_Alarm->setStyleSheet(m_alarmBtnRedStyleSheet);
        ui->pbtn_spo2_Alarm->setStyleSheet(m_alarmBtnRedStyleSheet);
        ui->pbtn_ABP_Alarm->setDisabled(true);
        ui->pbtn_ECG_Alarm->setDisabled(true);
        ui->pbtn_spo2_Alarm->setDisabled(true);

        m_timerAlarm->start();
        updatePLETH();
        updateABP();
        updatePulse();
    }
}
#endif

void MainWindow::launchGraphMenuPopup(Widget *widget)
{
   if(m_graphSettingsPop->m_isVisible==false)
   {
       m_selectedGraphWidget=widget;
       switch(m_selectedGraphWidget->getGraphType())
       {
           case GraphECG:
            m_graphSettingsPop->initialized(m_selectedGraphWidget->getGraphWaveSize(),GraphECG);
           break;

           case GraphABP:
            m_graphSettingsPop->initialized(m_selectedGraphWidget->getGraphWaveSize(),GraphABP);
           break;

           case GraphPLETH:
            m_graphSettingsPop->initialized(m_selectedGraphWidget->getGraphWaveSize(),GraphPLETH);
           break;

           case GraphCO2:
                 //TODO
           break;
       }
       m_graphSettingsPop->show();
   }
}

void MainWindow::onGraphMenuPopupOk()
{
    if(m_selectedGraphWidget->getGraphWaveSize()!=m_graphSettingsPop->m_graphWaveSize)
    {
        switch(m_selectedGraphWidget->getGraphType())
        {
            case GraphECG:
                 m_selectedGraphWidget->initialized(GraphECG,m_graphSettingsPop->m_graphWaveSize);
                 m_selectedGraphWidget->repaint();
            break;

            case GraphABP:
                m_selectedGraphWidget->initialized(GraphABP,m_graphSettingsPop->m_graphWaveSize);
                m_selectedGraphWidget->repaint();
            break;

            case GraphPLETH:
                m_selectedGraphWidget->initialized(GraphPLETH,m_graphSettingsPop->m_graphWaveSize);
                m_selectedGraphWidget->repaint();
            break;

            case GraphCO2:
                  //TODO
            break;
        }
    }

    m_graphSettingsPop->hide();
    m_graphSettingsPop->close();
    m_graphSettingsPop->m_isVisible=false;
    m_selectedGraphWidget=NULL;
}

void MainWindow::onGraphMenuPopupCancel()
{
    m_graphSettingsPop->hide();
    m_graphSettingsPop->close();
    m_graphSettingsPop->m_isVisible=false;
    m_selectedGraphWidget=NULL;
}

#ifdef PMD_HAMP

void  MainWindow::takeScreenSnapshort()
{
    QRect r= this->rect();
    QPixmap pixmap=this->grab(r);
    QString fileName = m_hampdataSupplier->getScreenShortPath();

	qDebug("MainWindow::takeScreenSnapshort - fileName %s\n", fileName);

    if(pixmap.isNull()==false)
        pixmap.save(fileName,"PNG");
    else
        printf("pixmap is NULL\n");
}

#endif
<commit_msg>test14<commit_after>#include "mainwindow.h"
#include "ui_mainwindow.h"
#include "graphSettingsPopup.h"
#include <QDateTime>

MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);

#ifdef PMD_HAMP
    ui->pbtn_StartStop->setChecked(true);
#endif
	qDebug("This is MainWindow via QDebug()\n");

    m_alarmBtnNormalStyleSheet=ui->pbtn_ECG_Alarm->styleSheet();
    m_alarmBtnRedStyleSheet= "*{border: 0px;background-image: url(:/images/icnBellRed.png);} *:checked{background-image:url();}";

    m_graphWidget1 = new Widget(ui->graphECGWidget,this);
#ifndef ONLY_SHOW_ECG_GRAPH
    m_graphWidget2 = new Widget(ui->graphABPWidget,this);
    m_graphWidget3 = new Widget(ui->graphPLETHWidget,this);
#endif

    m_graphWidget1->initialized(GraphECG,3);
#ifndef ONLY_SHOW_ECG_GRAPH
    m_graphWidget2->initialized(GraphABP,1);
    m_graphWidget3->initialized(GraphPLETH,2);
#endif

    m_selectedGraphWidget = NULL;

    // Set time
    updateTimeString();

    // Setup timer to update UI
    QTimer *timer = new QTimer(this);
    connect(timer, SIGNAL(timeout()), this, SLOT(updateTimeString()));
    timer->start(1000);

    m_timerAlarm =new QTimer (this);
    connect(m_timerAlarm, SIGNAL(timeout()), this, SLOT(animateAlarm()));
    m_timerAlarm->setInterval(500);
    m_timerAlarm->stop();

    m_timerDataValues = new QTimer(this);
#ifndef DISABLE_RIGHT_PANEL_NUMERIC_VALUES
    connect(m_timerDataValues, SIGNAL(timeout()), this, SLOT(updatePulse()));
    connect(m_timerDataValues, SIGNAL(timeout()), this, SLOT(updateABP()));
    connect(m_timerDataValues, SIGNAL(timeout()), this, SLOT(updatePLETH()));
    m_timerDataValues->setInterval(3000);
    #ifndef PMD_HAMP
        m_timerDataValues->start();
    #endif
#endif

    m_HB_Simulate_Data << 70 << 68 << 71 << 69<< 67<< 68;
    m_ABP_Higher_Simulate_Data << 100 << 110 << 107 << 124<< 137<< 119;
    m_ABP_Lower_Simulate_Data << 73 << 88 << 77 << 82 << 91 << 79;
    m_PLETH_Simulate_Data << 93 << 96 << 90 << 97 << 95 << 99;

    m_cstatus=true;

#ifdef PMD_MEHV
    m_nserver =new Server(this);
    m_cstatus=false;
#endif

#ifdef PMD_NUCLEUS
    m_dataSupplier=new DataSupplier(this);
#endif

#ifdef PMD_HAMP
	printf("Creating HAMPDataSupplier\n");
    m_hampdataSupplier =new HAMPDataSupplier(this);
    m_cstatus=true;

    // Setup timer to update UI
    QTimer *hamptimer = new QTimer(this);
    connect(hamptimer, SIGNAL(timeout()), this, SLOT(takeScreenSnapshort()));
    hamptimer->start(3000);

#endif

    m_isPauseAll=false;
    m_isStart=true;
    m_isAlarmSilent=false;
    m_btnSilentPressed=false;

    m_graphSettingsPop =new GraphSettingsPopup(this);
    m_graphSettingsPop->hide();

    // Setup graph scrolling mode
#ifdef ENABLE_GRAPH_SCROLLING
    on_pbtn_Scrolling_clicked(true);
    ui->pbtn_Scrolling->setChecked(true);
#else
    on_pbtn_Scrolling_clicked(false);
    ui->pbtn_Scrolling->setChecked(false);
#endif
}

MainWindow::~MainWindow()
{
    delete ui;
}

void MainWindow::updatePulse()
{
    QString value="0";

    if(m_isPauseAll==true || m_isStart==false)
        return;

    if(m_cstatus)
    {
        value.setNum(this->getPulseValue());
    }

    ui->labelPulse->setText(value);
    ui->labelPulse->repaint();
}

void MainWindow::updateABP()
{

    if(m_isPauseAll==true || m_isStart==false)
        return;

    if(m_cstatus)
    {
      ui->labelABP->setText(this->getABPValue());
    }
    else
        ui->labelABP->setText("0/0");

    ui->labelABP->repaint();
}

void MainWindow::updatePLETH()
{
    if(m_isPauseAll==true || m_isStart==false)
        return;

    if(m_cstatus)
    {
      ui->labelSPO2->setText(this->getPLETHValue());
    }
    else
        ui->labelSPO2->setText("0");

    ui->labelABP->repaint();
}

void MainWindow::updateTimeString()
{
    //get current date and time
    QDateTime dateTime = QDateTime::currentDateTime();
    QString dateTimeString = dateTime.toString("hh:mm:ss AP");
    ui->labelTime->setText(dateTimeString);
    ui->labelTime->repaint();
}

int MainWindow::getPulseValue()
{
    static int index=-1;

    if(index==this->m_HB_Simulate_Data.count()-1)
        index=0;
    else
        index++;

    return m_HB_Simulate_Data[index];
}

QString MainWindow::getABPValue()
{
    static int index=-1;

    if(index==this->m_ABP_Higher_Simulate_Data.count()-1)
        index=0;
    else
        index++;

    QString str=QString("%1/%2").arg(m_ABP_Higher_Simulate_Data[index]).arg(m_ABP_Lower_Simulate_Data[index]);
    return str;
}

QString MainWindow::getPLETHValue()
{
    static int index=-1;

    if(index==this->m_PLETH_Simulate_Data.count()-1)
        index=0;
    else
        index++;

    QString str=QString("%1").arg(m_PLETH_Simulate_Data[index]);
    return str;
}

void MainWindow::on_pbtn_Silent_clicked()
{
   m_btnSilentPressed=!m_btnSilentPressed;
    if(m_btnSilentPressed)
    {
        ui->pbtn_ECG_Alarm->setChecked(true);
        ui->pbtn_ABP_Alarm->setChecked(true);
        ui->pbtn_spo2_Alarm->setChecked(true);
        m_isAlarmSilent=true;
       // ui->pbtn_Silent->setStyleSheet("*{border: 0px;background-image: url(:/images/btn_pressed.png);}");
    }
    else
    {
        ui->pbtn_ECG_Alarm->setChecked(false);
        ui->pbtn_ABP_Alarm->setChecked(false);
        ui->pbtn_spo2_Alarm->setChecked(false);
        m_isAlarmSilent=false;
        //ui->pbtn_Silent->setStyleSheet("");
    }
}

void MainWindow::on_pbtn_StartStop_clicked(bool checked)
{

#ifdef PMD_HAMP

    if(checked)
    {
		qDebug("MainWindow::on_pbtn_StartStop_clicked button pushed - %d\n", checked);
        m_isStart=false;
        m_timerDataValues->stop();
        ui->pbtn_StartStop->setText("Start");
        m_hampdataSupplier->startStopNucleus(m_isStart);
        m_cstatus=false;
    }
    else
    {
		qDebug("MainWindow::on_pbtn_StartStop_clicked button pushed - %d\n", checked);
        m_isStart=true;
        ui->pbtn_StartStop->setText("Stop");
        m_timerDataValues->start();
        m_hampdataSupplier->startStopNucleus(m_isStart);
        m_cstatus=true;

    }
   fflush(stdout);
#else

    if(checked)
    {
        m_isStart=false;
        this->m_graphWidget1->clearWidget();
#ifndef ONLY_SHOW_ECG_GRAPH
        this->m_graphWidget2->clearWidget();
        this->m_graphWidget3->clearWidget();
#endif
        ui->pbtn_StartStop->setText("Start");
    }
    else
    {
        m_isStart=true;
        ui->pbtn_StartStop->setText("Stop");
    }

#endif

}

void MainWindow::on_pbtn_PauseAll_clicked(bool checked)
{
    if(!checked)
    {
        m_isPauseAll=false;
        ui->pbtn_PauseAll->setText("Pause All");
    }
    else
    {
        m_isPauseAll=true;
        this->m_graphWidget1->clearWidget();
#ifndef ONLY_SHOW_ECG_GRAPH
        this->m_graphWidget2->clearWidget();
        this->m_graphWidget3->clearWidget();
#endif
        ui->pbtn_PauseAll->setText("Start All");
    }
}

void MainWindow::on_pbtn_Scrolling_clicked(bool checked)
{
 (void)checked;
#ifndef PMD_HAMP
    m_graphWidget1->setScrollingMode(checked);
#ifndef ONLY_SHOW_ECG_GRAPH
    m_graphWidget2->setScrollingMode(checked);
    m_graphWidget3->setScrollingMode(checked);
#endif
#endif
}

void MainWindow::updateTimer()
{
#ifdef PMD_MEHV
    pm_data_struct pm={0,0,0,0};
    dataReceived (&pm);
#endif
}

void MainWindow::animateAlarm()
{
    ui->pbtn_ABP_Alarm->toggle();
    ui->pbtn_ECG_Alarm->toggle();
    ui->pbtn_spo2_Alarm->toggle();
}

void MainWindow::on_pbtn_ECG_Alarm_clicked(bool checked)
{
    (void)checked;
}

void MainWindow::on_pbtn_spo2_Alarm_clicked(bool checked)
{
    (void)checked;
}

void MainWindow::on_pbtn_ABP_Alarm_clicked(bool checked)
{
    (void)checked;
}

void MainWindow::dataReceived(pm_data_struct *current)
{
	qDebug("MainWindow::dataReceived: Entered\n");
	if (m_isPauseAll==false)
    {
		switch(m_graphWidget1->getGraphType())
        {

        case GraphECG:
            m_graphWidget1->animate(current->ecgValue);
        break;

        case GraphABP:
            m_graphWidget1->animate(current->abpValue);
        break;

        case GraphPLETH:
            m_graphWidget1->animate(current->plethValue);
        break;

        case GraphCO2:
            //TODO
        break;
        }

#ifndef ONLY_SHOW_ECG_GRAPH
        switch(m_graphWidget2->getGraphType())
        {
        case GraphECG:
            m_graphWidget2->animate(current->ecgValue);
        break;

        case GraphABP:
            m_graphWidget2->animate(current->abpValue);
        break;

        case GraphPLETH:
            m_graphWidget2->animate(current->plethValue);
        break;

        case GraphCO2:
            //TODO
        break;
        }

        switch(m_graphWidget3->getGraphType())
        {
        case GraphECG:
            m_graphWidget3->animate(current->ecgValue);
        break;

        case GraphABP:
            m_graphWidget3->animate(current->abpValue);
        break;

        case GraphPLETH:
            m_graphWidget3->animate(current->plethValue);
        break;

        case GraphCO2:
            //TODO
        break;
        }
#endif
    }
}

#ifndef PMD_NUCLEUS
void MainWindow::connectionStatus(bool status)
{
    QDateTime dateTime = QDateTime::currentDateTime();
    QString dateTimeString = dateTime.toString("hh:mmap");
    m_cstatus=status;

    if(status)
    {
        ui->labelBulletText->setText("External system connected at "+dateTimeString);
        ui->labelBulletText->repaint();
        ui->pbtn_ECG_Alarm->setStyleSheet(m_alarmBtnNormalStyleSheet);
        ui->pbtn_ABP_Alarm->setStyleSheet(m_alarmBtnNormalStyleSheet);
        ui->pbtn_spo2_Alarm->setStyleSheet(m_alarmBtnNormalStyleSheet);
        ui->pbtn_ABP_Alarm->setDisabled(false);
        ui->pbtn_ECG_Alarm->setDisabled(false);
        ui->pbtn_spo2_Alarm->setDisabled(false);
        m_timerAlarm->stop();

    }
    else
    {
        ui->labelBulletText->setText("External system disconnected at "+dateTimeString);
        ui->labelBulletText->repaint();
        ui->pbtn_ECG_Alarm->setStyleSheet(m_alarmBtnRedStyleSheet);
        ui->pbtn_ABP_Alarm->setStyleSheet(m_alarmBtnRedStyleSheet);
        ui->pbtn_spo2_Alarm->setStyleSheet(m_alarmBtnRedStyleSheet);
        ui->pbtn_ABP_Alarm->setDisabled(true);
        ui->pbtn_ECG_Alarm->setDisabled(true);
        ui->pbtn_spo2_Alarm->setDisabled(true);

        m_timerAlarm->start();
        updatePLETH();
        updateABP();
        updatePulse();
    }
}
#endif

void MainWindow::launchGraphMenuPopup(Widget *widget)
{
   if(m_graphSettingsPop->m_isVisible==false)
   {
       m_selectedGraphWidget=widget;
       switch(m_selectedGraphWidget->getGraphType())
       {
           case GraphECG:
            m_graphSettingsPop->initialized(m_selectedGraphWidget->getGraphWaveSize(),GraphECG);
           break;

           case GraphABP:
            m_graphSettingsPop->initialized(m_selectedGraphWidget->getGraphWaveSize(),GraphABP);
           break;

           case GraphPLETH:
            m_graphSettingsPop->initialized(m_selectedGraphWidget->getGraphWaveSize(),GraphPLETH);
           break;

           case GraphCO2:
                 //TODO
           break;
       }
       m_graphSettingsPop->show();
   }
}

void MainWindow::onGraphMenuPopupOk()
{
    if(m_selectedGraphWidget->getGraphWaveSize()!=m_graphSettingsPop->m_graphWaveSize)
    {
        switch(m_selectedGraphWidget->getGraphType())
        {
            case GraphECG:
                 m_selectedGraphWidget->initialized(GraphECG,m_graphSettingsPop->m_graphWaveSize);
                 m_selectedGraphWidget->repaint();
            break;

            case GraphABP:
                m_selectedGraphWidget->initialized(GraphABP,m_graphSettingsPop->m_graphWaveSize);
                m_selectedGraphWidget->repaint();
            break;

            case GraphPLETH:
                m_selectedGraphWidget->initialized(GraphPLETH,m_graphSettingsPop->m_graphWaveSize);
                m_selectedGraphWidget->repaint();
            break;

            case GraphCO2:
                  //TODO
            break;
        }
    }

    m_graphSettingsPop->hide();
    m_graphSettingsPop->close();
    m_graphSettingsPop->m_isVisible=false;
    m_selectedGraphWidget=NULL;
}

void MainWindow::onGraphMenuPopupCancel()
{
    m_graphSettingsPop->hide();
    m_graphSettingsPop->close();
    m_graphSettingsPop->m_isVisible=false;
    m_selectedGraphWidget=NULL;
}

#ifdef PMD_HAMP

void  MainWindow::takeScreenSnapshort()
{
    QRect r= this->rect();
    QPixmap pixmap=this->grab(r);
    QString fileName = m_hampdataSupplier->getScreenShortPath();
	QByteArray tmp_ba = fileName.toLatin1();
	const char *tmp_mystr = tmp_ba.data();

	qDebug("MainWindow::takeScreenSnapshort - fileName %s\n", tmp_mystr);

    if(pixmap.isNull()==false)
        pixmap.save(fileName,"PNG");
    else
        printf("pixmap is NULL\n");
}

#endif
<|endoftext|>


<commit_before>#include "mainwindow.h"
#include "ui_mainwindow.h"

#include <KFileItem>
#include <KFileItemList>
#include <KIO/PreviewJob>

#include <TelepathyQt4/AccountManager>
#include <TelepathyQt4/PendingReady>

#include "accounts-model.h"
#include "flat-model-proxy.h"
#include "account-filter-model.h"

MainWindow::MainWindow(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::MainWindow)
{
    Tp::registerTypes();

    ui->setupUi(this);

    KFileItem file(KUrl("/home/david/a.png"), "image/png", KFileItem::Unknown);

    KIO::PreviewJob* job = KIO::filePreview(KFileItemList() << file, ui->filePreviewLabel->size());

    ui->fileNameLabel->setText(file.name());
    ui->filePreviewLabel->setText(QString());

    connect(job, SIGNAL(gotPreview(KFileItem, QPixmap)),
            this, SLOT(showPreview(KFileItem, QPixmap)));
    connect(job, SIGNAL(failed(KFileItem)),
            this, SLOT(showIcon(KFileItem)));

    Tp::AccountFactoryPtr  accountFactory = Tp::AccountFactory::create(QDBusConnection::sessionBus(),
                                                                       Tp::Features() << Tp::Account::FeatureCore
                                                                       << Tp::Account::FeatureAvatar
                                                                       << Tp::Account::FeatureProtocolInfo
                                                                       << Tp::Account::FeatureProfile);

    Tp::ConnectionFactoryPtr connectionFactory = Tp::ConnectionFactory::create(QDBusConnection::sessionBus(),
                                                                               Tp::Features() << Tp::Connection::FeatureCore
                                                                               << Tp::Connection::FeatureRosterGroups
                                                                               << Tp::Connection::FeatureRoster
                                                                               << Tp::Connection::FeatureSelfContact);

    Tp::ContactFactoryPtr contactFactory = Tp::ContactFactory::create(Tp::Features()  << Tp::Contact::FeatureAlias
                                                                      << Tp::Contact::FeatureAvatarData
                                                                      << Tp::Contact::FeatureSimplePresence
                                                                      << Tp::Contact::FeatureCapabilities);

    Tp::ChannelFactoryPtr channelFactory = Tp::ChannelFactory::create(QDBusConnection::sessionBus());

    m_accountManager = Tp::AccountManager::create(QDBusConnection::sessionBus(),
                                                  accountFactory,
                                                  connectionFactory,
                                                  channelFactory,
                                                  contactFactory);

    connect(m_accountManager->becomeReady(), SIGNAL(finished(Tp::PendingOperation*)), SLOT(onAccountManagerReady()));
}

MainWindow::~MainWindow()
{
    delete ui;
}

void MainWindow::showPreview(const KFileItem &file, const QPixmap &pixmap)
{
    ui->filePreviewLabel->setMinimumSize(pixmap.size());
    ui->filePreviewLabel->setPixmap(pixmap);
}

void MainWindow::showIcon(const KFileItem &file)
{
    //icon is     file.iconName();

}

void MainWindow::onAccountManagerReady()
{
    AccountsModel *model = new AccountsModel(m_accountManager, this);
    FlatModelProxy *flatProxyModel = new FlatModelProxy(model);
    AccountFilterModel *filterModel = new AccountFilterModel(this);
    filterModel->setSourceModel(flatProxyModel);
    filterModel->filterOfflineUsers(true);
    ui->listView->setModel(filterModel);
}
<commit_msg>Fix the models by switching round the use of the flat model proxy and the filter proxy.<commit_after>#include "mainwindow.h"
#include "ui_mainwindow.h"

#include <KFileItem>
#include <KFileItemList>
#include <KIO/PreviewJob>

#include <TelepathyQt4/AccountManager>
#include <TelepathyQt4/PendingReady>

#include "accounts-model.h"
#include "flat-model-proxy.h"
#include "account-filter-model.h"

MainWindow::MainWindow(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::MainWindow)
{
    Tp::registerTypes();

    ui->setupUi(this);

    KFileItem file(KUrl("/home/david/a.png"), "image/png", KFileItem::Unknown);

    KIO::PreviewJob* job = KIO::filePreview(KFileItemList() << file, ui->filePreviewLabel->size());

    ui->fileNameLabel->setText(file.name());
    ui->filePreviewLabel->setText(QString());

    connect(job, SIGNAL(gotPreview(KFileItem, QPixmap)),
            this, SLOT(showPreview(KFileItem, QPixmap)));
    connect(job, SIGNAL(failed(KFileItem)),
            this, SLOT(showIcon(KFileItem)));

    Tp::AccountFactoryPtr  accountFactory = Tp::AccountFactory::create(QDBusConnection::sessionBus(),
                                                                       Tp::Features() << Tp::Account::FeatureCore
                                                                       << Tp::Account::FeatureAvatar
                                                                       << Tp::Account::FeatureProtocolInfo
                                                                       << Tp::Account::FeatureProfile);

    Tp::ConnectionFactoryPtr connectionFactory = Tp::ConnectionFactory::create(QDBusConnection::sessionBus(),
                                                                               Tp::Features() << Tp::Connection::FeatureCore
                                                                               << Tp::Connection::FeatureRosterGroups
                                                                               << Tp::Connection::FeatureRoster
                                                                               << Tp::Connection::FeatureSelfContact);

    Tp::ContactFactoryPtr contactFactory = Tp::ContactFactory::create(Tp::Features()  << Tp::Contact::FeatureAlias
                                                                      << Tp::Contact::FeatureAvatarData
                                                                      << Tp::Contact::FeatureSimplePresence
                                                                      << Tp::Contact::FeatureCapabilities);

    Tp::ChannelFactoryPtr channelFactory = Tp::ChannelFactory::create(QDBusConnection::sessionBus());

    m_accountManager = Tp::AccountManager::create(QDBusConnection::sessionBus(),
                                                  accountFactory,
                                                  connectionFactory,
                                                  channelFactory,
                                                  contactFactory);

    connect(m_accountManager->becomeReady(), SIGNAL(finished(Tp::PendingOperation*)), SLOT(onAccountManagerReady()));
}

MainWindow::~MainWindow()
{
    delete ui;
}

void MainWindow::showPreview(const KFileItem &file, const QPixmap &pixmap)
{
    ui->filePreviewLabel->setMinimumSize(pixmap.size());
    ui->filePreviewLabel->setPixmap(pixmap);
}

void MainWindow::showIcon(const KFileItem &file)
{
    //icon is     file.iconName();

}

void MainWindow::onAccountManagerReady()
{
    AccountsModel *model = new AccountsModel(m_accountManager, this);
    AccountFilterModel *filterModel = new AccountFilterModel(this);
    filterModel->setSourceModel(model);
    filterModel->filterOfflineUsers(true);
    FlatModelProxy *flatProxyModel = new FlatModelProxy(filterModel);

    ui->listView->setModel(flatProxyModel);
}
<|endoftext|>


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

#include "ffmpeg.h"

#include <portaudio.h>

#ifdef __APPLE__
// PortAudio specific Mac stuff
#include "pa_mac_core.h"
#endif

// For setting the thread priority to realtime on MacOSX.
#ifdef __APPLE__
#include <mach/mach_init.h>
#include <mach/thread_policy.h>
#include <mach/thread_act.h> // the doc says mach/sched.h but that seems outdated...
#include <pthread.h>
#include <mach/mach_error.h>
#include <mach/mach_time.h>
#endif
static void setRealtime();

int initPlayerOutput() {
	PaError ret = Pa_Initialize();
	if(ret != paNoError)
		Py_FatalError("PortAudio init failed");
	return 0;
}

template<typename T> struct OutPaSampleFormat{};
template<> struct OutPaSampleFormat<int16_t> {
	static const PaSampleFormat format = paInt16;
};
template<> struct OutPaSampleFormat<float32_t> {
	static const PaSampleFormat format = paFloat32;
};

struct PlayerObject::OutStream {
	PlayerObject* const player;
	PaStream* stream;
	bool needRealtimeReset; // PortAudio callback thread must set itself to realtime

	OutStream(PlayerObject* p) : player(p), stream(NULL), needRealtimeReset(false) {
		mlock(this, sizeof(*this));
	}
	~OutStream() { close(); }

	static int paStreamCallback(
		const void *input, void *output,
		unsigned long frameCount,
		const PaStreamCallbackTimeInfo* timeInfo,
		PaStreamCallbackFlags statusFlags,
		void *userData )
	{
		OutStream* outStream = (OutStream*) userData;

		// We must not hold the PyGIL here!
		PyScopedLock lock(outStream->player->lock);

		if(outStream->needRealtimeReset) {
			outStream->needRealtimeReset = false;
			setRealtime();
		}

		outStream->player->readOutStream((OUTSAMPLE_t*) output, frameCount * outStream->player->outNumChannels, NULL);
		return paContinue;
	}

	bool open() {
		if(stream) close();
		assert(stream == NULL);

		PaStreamParameters outputParameters;

#if defined(__APPLE__)
		PaMacCoreStreamInfo macInfo;
		PaMacCore_SetupStreamInfo( &macInfo,
			paMacCorePlayNice | paMacCorePro );
		outputParameters.hostApiSpecificStreamInfo = &macInfo;
#elif defined(__LINUX__)
		// TODO: if we have PaAlsa_EnableRealtimeScheduling in portaudio,
		// we can call that to enable RT priority with ALSA.
		// We could check dynamically via dsym.
		outputParameters.hostApiSpecificStreamInfo = NULL;
#else
		outputParameters.hostApiSpecificStreamInfo = NULL;
#endif

		outputParameters.device = Pa_GetDefaultOutputDevice();
		if (outputParameters.device == paNoDevice) {
			PyErr_SetString(PyExc_RuntimeError, "Pa_GetDefaultOutputDevice didn't returned a device");
			return false;
		}
		outputParameters.channelCount = player->outNumChannels;
		outputParameters.sampleFormat = OutPaSampleFormat<OUTSAMPLE_t>::format;
		outputParameters.suggestedLatency = Pa_GetDeviceInfo( outputParameters.device )->defaultHighOutputLatency;

		// Note about framesPerBuffer:
		// Earlier, we used (2048 * 5 * OUTSAMPLEBYTELEN) which caused
		// some random more or less rare cracking noises.
		// See here: https://github.com/albertz/music-player/issues/35
		// This doesn't seem to happen with paFramesPerBufferUnspecified.

		PaError ret = Pa_OpenStream(
			&stream,
			NULL, // no input
			&outputParameters,
			player->outSamplerate, // sampleRate
			paFramesPerBufferUnspecified, // framesPerBuffer,
			paClipOff | paDitherOff,
			&paStreamCallback,
			this //void *userData
			);

		if(ret != paNoError) {
			PyErr_Format(PyExc_RuntimeError, "Pa_OpenStream failed: (err %i) %s", ret, Pa_GetErrorText(ret));
			if(stream)
				close();
			return false;
		}

		needRealtimeReset = true;
		Pa_StartStream(stream);
		return true;
	}

	void close() {
		if(this->stream == NULL) return;
		// we expect that we have the player lock here.
		// reset fader.
		player->fader.init(0,0);
		// we must release the player lock so that any thread-join can be done.
		PaStream* stream = NULL;
		std::swap(stream, this->stream);
		PyScopedUnlock unlock(player->lock);
		Pa_CloseStream(stream);
	}

	bool isOpen() const { return stream != NULL; }

};

int PlayerObject::setPlaying(bool playing) {
	PlayerObject* player = this;
	bool oldplayingstate = false;
	PyScopedGIL gil;
	{
		PyScopedGIUnlock gunlock;

		player->workerThread.start(); // if not running yet, start
		if(!player->outStream.get())
			player->outStream.reset(new OutStream(this));
		assert(player->outStream.get() != NULL);

		if(soundcardOutputEnabled) {
			if(playing && !player->outStream->stream) {
				if(!player->outStream->open())
					playing = false;
			}
		}

		oldplayingstate = player->playing;
		if(soundcardOutputEnabled && player->outStream.get() && player->outStream->isOpen() && oldplayingstate != playing)
			fader.init(playing ? 1 : -1, outSamplerate);
		player->playing = playing;
	}

	if(!PyErr_Occurred() && player->dict) {
		Py_INCREF(player->dict);
		PyObject* onPlayingStateChange = PyDict_GetItemString(player->dict, "onPlayingStateChange");
		if(onPlayingStateChange && onPlayingStateChange != Py_None) {
			Py_INCREF(onPlayingStateChange);

			PyObject* kwargs = PyDict_New();
			assert(kwargs);
			PyDict_SetItemString_retain(kwargs, "oldState", PyBool_FromLong(oldplayingstate));
			PyDict_SetItemString_retain(kwargs, "newState", PyBool_FromLong(playing));

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

			// errors are not fatal from the callback, so handle it now and go on
			if(PyErr_Occurred())
				PyErr_Print();

			Py_DECREF(kwargs);
			Py_DECREF(onPlayingStateChange);
		}
		Py_DECREF(player->dict);
	}

	return PyErr_Occurred() ? -1 : 0;
}

#ifdef __APPLE__
// https://developer.apple.com/library/mac/#documentation/Darwin/Conceptual/KernelProgramming/scheduler/scheduler.html
// Also, from Google Native Client, osx/nacl_thread_nice.c has some related code.
// Or, from Google Chrome, platform_thread_mac.mm.
void setRealtime() {
	kern_return_t ret;
	thread_port_t threadport = pthread_mach_thread_np(pthread_self());

	thread_extended_policy_data_t policy;
	policy.timeshare = 0;
	ret = thread_policy_set(threadport,
							THREAD_EXTENDED_POLICY,
							(thread_policy_t)&policy,
							THREAD_EXTENDED_POLICY_COUNT);
	if(ret != KERN_SUCCESS) {
		fprintf(stderr, "setRealtime() THREAD_EXTENDED_POLICY failed: %d, %s\n", ret, mach_error_string(ret));
		return;
	}

	thread_precedence_policy_data_t precedence;
	precedence.importance = 63;
	ret = thread_policy_set(threadport,
							THREAD_PRECEDENCE_POLICY,
							(thread_policy_t)&precedence,
							THREAD_PRECEDENCE_POLICY_COUNT);
	if(ret != KERN_SUCCESS) {
		fprintf(stderr, "setRealtime() THREAD_PRECEDENCE_POLICY failed: %d, %s\n", ret, mach_error_string(ret));
		return;
	}

	mach_timebase_info_data_t tb_info;
	mach_timebase_info(&tb_info);
	double timeFact = ((double)tb_info.denom / (double)tb_info.numer) * 1000000;

	thread_time_constraint_policy_data_t ttcpolicy;
	ttcpolicy.period = 2.9 * timeFact; // about 128 frames @44.1KHz
	ttcpolicy.computation = 0.75 * 2.9 * timeFact;
	ttcpolicy.constraint = 0.85 * 2.9 * timeFact;
	ttcpolicy.preemptible = 1;

	ret = thread_policy_set(threadport,
							THREAD_TIME_CONSTRAINT_POLICY,
							(thread_policy_t)&ttcpolicy,
							THREAD_TIME_CONSTRAINT_POLICY_COUNT);
	if(ret != KERN_SUCCESS) {
		fprintf(stderr, "setRealtime() THREAD_TIME_CONSTRAINT_POLICY failed: %d, %s\n", ret, mach_error_string(ret));
		return;
	}
}
#else
void setRealtime() {} // not implemented yet
#endif

<commit_msg>portaudio blocking implementation<commit_after>// ffmpeg player output (portaudio)
// part of MusicPlayer, https://github.com/albertz/music-player
// Copyright (c) 2012, Albert Zeyer, www.az2000.de
// All rights reserved.
// This code is under the 2-clause BSD license, see License.txt in the root directory of this project.

#include "ffmpeg.h"

#include <portaudio.h>
#include <boost/bind.hpp>

#ifdef __APPLE__
// PortAudio specific Mac stuff
#include "pa_mac_core.h"
#endif

// For setting the thread priority to realtime on MacOSX.
#ifdef __APPLE__
#include <mach/mach_init.h>
#include <mach/thread_policy.h>
#include <mach/thread_act.h> // the doc says mach/sched.h but that seems outdated...
#include <pthread.h>
#include <mach/mach_error.h>
#include <mach/mach_time.h>
#endif
static void setRealtime();

#define USE_PORTAUDIO_CALLBACK 0

int initPlayerOutput() {
	PaError ret = Pa_Initialize();
	if(ret != paNoError)
		Py_FatalError("PortAudio init failed");
	return 0;
}

template<typename T> struct OutPaSampleFormat{};
template<> struct OutPaSampleFormat<int16_t> {
	static const PaSampleFormat format = paInt16;
};
template<> struct OutPaSampleFormat<float32_t> {
	static const PaSampleFormat format = paFloat32;
};

struct PlayerObject::OutStream {
	PlayerObject* const player;
	PaStream* stream;
	bool needRealtimeReset; // PortAudio callback thread must set itself to realtime

	OutStream(PlayerObject* p) : player(p), stream(NULL), needRealtimeReset(false) {
		mlock(this, sizeof(*this));
	}
	~OutStream() { close(); }

#if USE_PORTAUDIO_CALLBACK
	static int paStreamCallback(
		const void *input, void *output,
		unsigned long frameCount,
		const PaStreamCallbackTimeInfo* timeInfo,
		PaStreamCallbackFlags statusFlags,
		void *userData )
	{
		OutStream* outStream = (OutStream*) userData;

		// We must not hold the PyGIL here!
		PyScopedLock lock(outStream->player->lock);

		if(outStream->needRealtimeReset) {
			outStream->needRealtimeReset = false;
			setRealtime();
		}

		outStream->player->readOutStream((OUTSAMPLE_t*) output, frameCount * outStream->player->outNumChannels, NULL);
		return paContinue;
	}
#else
	PyThread audioThread;
	void audioThreadProc(PyMutex& threadLock, bool& stopSignal) {
		while(true) {
			{
				PyScopedLock l(threadLock);
				if(stopSignal) return;
			}

			if(needRealtimeReset) {
				needRealtimeReset = false;
				setRealtime();
			}

			OUTSAMPLE_t buffer[4800 * 2]; // 100ms stereo in 48khz
			size_t sampleNumOut = 0;
			{
				PyScopedLock lock(player->lock);
				if(stopSignal) return;
				player->readOutStream(buffer, sizeof(buffer)/sizeof(OUTSAMPLE_t), NULL);
			}

			PaError ret = Pa_WriteStream(stream, buffer, sampleNumOut);
			if(ret == paOutputUnderflowed)
				printf("warning: paOutputUnderflowed\n");
		}
	}
#endif

	bool open() {
		if(stream) close();
		assert(stream == NULL);

		PaStreamParameters outputParameters;

#if defined(__APPLE__)
		PaMacCoreStreamInfo macInfo;
		PaMacCore_SetupStreamInfo( &macInfo,
			paMacCorePlayNice | paMacCorePro );
		outputParameters.hostApiSpecificStreamInfo = &macInfo;
#elif defined(__LINUX__)
		// TODO: if we have PaAlsa_EnableRealtimeScheduling in portaudio,
		// we can call that to enable RT priority with ALSA.
		// We could check dynamically via dsym.
		outputParameters.hostApiSpecificStreamInfo = NULL;
#else
		outputParameters.hostApiSpecificStreamInfo = NULL;
#endif

		outputParameters.device = Pa_GetDefaultOutputDevice();
		if (outputParameters.device == paNoDevice) {
			PyErr_SetString(PyExc_RuntimeError, "Pa_GetDefaultOutputDevice didn't returned a device");
			return false;
		}
		outputParameters.channelCount = player->outNumChannels;
		outputParameters.sampleFormat = OutPaSampleFormat<OUTSAMPLE_t>::format;
		outputParameters.suggestedLatency = Pa_GetDeviceInfo( outputParameters.device )->defaultHighOutputLatency;

		// Note about framesPerBuffer:
		// Earlier, we used (2048 * 5 * OUTSAMPLEBYTELEN) which caused
		// some random more or less rare cracking noises.
		// See here: https://github.com/albertz/music-player/issues/35
		// This doesn't seem to happen with paFramesPerBufferUnspecified.

		PaError ret = Pa_OpenStream(
			&stream,
			NULL, // no input
			&outputParameters,
			player->outSamplerate, // sampleRate
			paFramesPerBufferUnspecified, // framesPerBuffer,
			paClipOff | paDitherOff,
#if USE_PORTAUDIO_CALLBACK
			&paStreamCallback,
#else
			NULL,
#endif
			this //void *userData
			);

		if(ret != paNoError) {
			PyErr_Format(PyExc_RuntimeError, "Pa_OpenStream failed: (err %i) %s", ret, Pa_GetErrorText(ret));
			if(stream)
				close();
			return false;
		}

		needRealtimeReset = true;
		Pa_StartStream(stream);

#if !USE_PORTAUDIO_CALLBACK
		audioThread.func = boost::bind(&OutStream::audioThreadProc, this, _1, _2);
		audioThread.start();
#endif
		return true;
	}

	void close() {
		if(this->stream == NULL) return;
		// we expect that we have the player lock here.
		// reset fader.
		player->fader.init(0,0);
		// we must release the player lock so that any thread-join can be done.
		PaStream* stream = NULL;
		std::swap(stream, this->stream);
		PyScopedUnlock unlock(player->lock);
		audioThread.stop();
		Pa_CloseStream(stream);
	}

	bool isOpen() const { return stream != NULL; }

};

int PlayerObject::setPlaying(bool playing) {
	PlayerObject* player = this;
	bool oldplayingstate = false;
	PyScopedGIL gil;
	{
		PyScopedGIUnlock gunlock;

		player->workerThread.start(); // if not running yet, start
		if(!player->outStream.get())
			player->outStream.reset(new OutStream(this));
		assert(player->outStream.get() != NULL);

		if(soundcardOutputEnabled) {
			if(playing && !player->outStream->stream) {
				if(!player->outStream->open())
					playing = false;
			}
		}

		oldplayingstate = player->playing;
		if(soundcardOutputEnabled && player->outStream.get() && player->outStream->isOpen() && oldplayingstate != playing)
			fader.init(playing ? 1 : -1, outSamplerate);
		player->playing = playing;
	}

	if(!PyErr_Occurred() && player->dict) {
		Py_INCREF(player->dict);
		PyObject* onPlayingStateChange = PyDict_GetItemString(player->dict, "onPlayingStateChange");
		if(onPlayingStateChange && onPlayingStateChange != Py_None) {
			Py_INCREF(onPlayingStateChange);

			PyObject* kwargs = PyDict_New();
			assert(kwargs);
			PyDict_SetItemString_retain(kwargs, "oldState", PyBool_FromLong(oldplayingstate));
			PyDict_SetItemString_retain(kwargs, "newState", PyBool_FromLong(playing));

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

			// errors are not fatal from the callback, so handle it now and go on
			if(PyErr_Occurred())
				PyErr_Print();

			Py_DECREF(kwargs);
			Py_DECREF(onPlayingStateChange);
		}
		Py_DECREF(player->dict);
	}

	return PyErr_Occurred() ? -1 : 0;
}

#ifdef __APPLE__
// https://developer.apple.com/library/mac/#documentation/Darwin/Conceptual/KernelProgramming/scheduler/scheduler.html
// Also, from Google Native Client, osx/nacl_thread_nice.c has some related code.
// Or, from Google Chrome, platform_thread_mac.mm.
void setRealtime() {
	kern_return_t ret;
	thread_port_t threadport = pthread_mach_thread_np(pthread_self());

	thread_extended_policy_data_t policy;
	policy.timeshare = 0;
	ret = thread_policy_set(threadport,
							THREAD_EXTENDED_POLICY,
							(thread_policy_t)&policy,
							THREAD_EXTENDED_POLICY_COUNT);
	if(ret != KERN_SUCCESS) {
		fprintf(stderr, "setRealtime() THREAD_EXTENDED_POLICY failed: %d, %s\n", ret, mach_error_string(ret));
		return;
	}

	thread_precedence_policy_data_t precedence;
	precedence.importance = 63;
	ret = thread_policy_set(threadport,
							THREAD_PRECEDENCE_POLICY,
							(thread_policy_t)&precedence,
							THREAD_PRECEDENCE_POLICY_COUNT);
	if(ret != KERN_SUCCESS) {
		fprintf(stderr, "setRealtime() THREAD_PRECEDENCE_POLICY failed: %d, %s\n", ret, mach_error_string(ret));
		return;
	}

	mach_timebase_info_data_t tb_info;
	mach_timebase_info(&tb_info);
	double timeFact = ((double)tb_info.denom / (double)tb_info.numer) * 1000000;

	thread_time_constraint_policy_data_t ttcpolicy;
	ttcpolicy.period = 2.9 * timeFact; // about 128 frames @44.1KHz
	ttcpolicy.computation = 0.75 * 2.9 * timeFact;
	ttcpolicy.constraint = 0.85 * 2.9 * timeFact;
	ttcpolicy.preemptible = 1;

	ret = thread_policy_set(threadport,
							THREAD_TIME_CONSTRAINT_POLICY,
							(thread_policy_t)&ttcpolicy,
							THREAD_TIME_CONSTRAINT_POLICY_COUNT);
	if(ret != KERN_SUCCESS) {
		fprintf(stderr, "setRealtime() THREAD_TIME_CONSTRAINT_POLICY failed: %d, %s\n", ret, mach_error_string(ret));
		return;
	}
}
#else
void setRealtime() {} // not implemented yet
#endif

<|endoftext|>


<commit_before>// Copyright 2015-2018 Elviss Strazdins. All rights reserved.

#include "core/Setup.h"

#if OUZEL_COMPILE_OPENSL

#include "AudioDeviceSL.hpp"
#include "core/Engine.hpp"
#include "utils/Errors.hpp"
#include "utils/Log.hpp"

static void playerCallback(SLAndroidSimpleBufferQueueItf bufferQueue, void* context)
{
    try
    {
        ouzel::audio::AudioDeviceSL* audioDeviceSL = reinterpret_cast<ouzel::audio::AudioDeviceSL*>(context);

        audioDeviceSL->enqueue(bufferQueue);
    }
    catch (const std::exception& e)
    {
        ouzel::engine->log(ouzel::Log::Level::ERR) << e.what();
    }
}

namespace ouzel
{
    namespace audio
    {
        AudioDeviceSL::AudioDeviceSL():
            AudioDevice(Driver::OPENSL)
        {
            const SLuint32 engineMixIIDCount = 1;
            const SLInterfaceID engineMixIID = SL_IID_ENGINE;
            const SLboolean engineMixReq = SL_BOOLEAN_TRUE;

            if (slCreateEngine(&engineObject, 0, nullptr, engineMixIIDCount, &engineMixIID, &engineMixReq) != SL_RESULT_SUCCESS)
                throw SystemError("Failed to create OpenSL engine object");

            if ((*engineObject)->Realize(engineObject, SL_BOOLEAN_FALSE) != SL_RESULT_SUCCESS)
                throw SystemError("Failed to create OpenSL engine object");

            if ((*engineObject)->GetInterface(engineObject, SL_IID_ENGINE, &engine) != SL_RESULT_SUCCESS)
                throw SystemError("Failed to get OpenSL engine");

            if ((*engine)->CreateOutputMix(engine, &outputMixObject, 0, nullptr, nullptr) != SL_RESULT_SUCCESS)
                throw SystemError("Failed to create OpenSL output mix");

            if ((*outputMixObject)->Realize(outputMixObject, SL_BOOLEAN_FALSE) != SL_RESULT_SUCCESS)
                throw SystemError("Failed to create OpenSL output mix");

            SLDataLocator_AndroidSimpleBufferQueue location = {SL_DATALOCATOR_ANDROIDSIMPLEBUFFERQUEUE, 2};

            SLDataFormat_PCM dataFormat;
            dataFormat.formatType = SL_DATAFORMAT_PCM;
            dataFormat.numChannels = channels;
            dataFormat.samplesPerSec = sampleRate * 1000; //mHz
            dataFormat.bitsPerSample = 16;
            dataFormat.containerSize = dataFormat.bitsPerSample;

            switch (channels)
            {
                case 1: dataFormat.channelMask = SL_SPEAKER_FRONT_CENTER; break;
                case 2: dataFormat.channelMask = SL_SPEAKER_FRONT_LEFT | SL_SPEAKER_FRONT_RIGHT; break;
                case 4: dataFormat.channelMask = SL_SPEAKER_FRONT_LEFT | SL_SPEAKER_FRONT_RIGHT | SL_SPEAKER_BACK_LEFT | SL_SPEAKER_BACK_RIGHT; break;
                case 6: dataFormat.channelMask = SL_SPEAKER_FRONT_LEFT | SL_SPEAKER_FRONT_RIGHT | SL_SPEAKER_FRONT_CENTER | SL_SPEAKER_LOW_FREQUENCY | SL_SPEAKER_SIDE_LEFT|SL_SPEAKER_SIDE_RIGHT; break;
                case 7: dataFormat.channelMask = SL_SPEAKER_FRONT_LEFT | SL_SPEAKER_FRONT_RIGHT | SL_SPEAKER_FRONT_CENTER | SL_SPEAKER_LOW_FREQUENCY | SL_SPEAKER_BACK_CENTER | SL_SPEAKER_SIDE_LEFT | SL_SPEAKER_SIDE_RIGHT; break;
                case 8: dataFormat.channelMask = SL_SPEAKER_FRONT_LEFT | SL_SPEAKER_FRONT_RIGHT | SL_SPEAKER_FRONT_CENTER | SL_SPEAKER_LOW_FREQUENCY | SL_SPEAKER_BACK_LEFT|SL_SPEAKER_BACK_RIGHT | SL_SPEAKER_SIDE_LEFT | SL_SPEAKER_SIDE_RIGHT; break;
                default:
                    throw SystemError("Invalid channel count");
            }

            dataFormat.endianness = SL_BYTEORDER_LITTLEENDIAN;

            SLDataSource dataSource = {&location, &dataFormat};

            SLDataLocator_OutputMix dataLocatorOut;
            dataLocatorOut.locatorType = SL_DATALOCATOR_OUTPUTMIX;
            dataLocatorOut.outputMix = outputMixObject;

            SLDataSink dataSink;
            dataSink.pLocator = &dataLocatorOut;
            dataSink.pFormat = nullptr;

            const SLuint32 playerIIDCount = 3;
            const SLInterfaceID playerIIDs[] = {SL_IID_BUFFERQUEUE, SL_IID_PLAY, SL_IID_VOLUME};
            const SLboolean playerReqs[] = {SL_BOOLEAN_TRUE, SL_BOOLEAN_TRUE, SL_BOOLEAN_TRUE};

            if ((*engine)->CreateAudioPlayer(engine, &playerObject, &dataSource, &dataSink, playerIIDCount, playerIIDs, playerReqs) != SL_RESULT_SUCCESS)
                throw SystemError("Failed to create OpenSL player object");

            sampleFormat = SampleFormat::SINT16;

            if ((*playerObject)->Realize(playerObject, SL_BOOLEAN_FALSE) != SL_RESULT_SUCCESS)
                throw SystemError("Failed to create OpenSL player object");

            if ((*playerObject)->GetInterface(playerObject, SL_IID_PLAY, &player) != SL_RESULT_SUCCESS)
                throw SystemError("Failed to get OpenSL player interface");

            if ((*playerObject)->GetInterface(playerObject, SL_IID_BUFFERQUEUE, &bufferQueue) != SL_RESULT_SUCCESS)
                throw SystemError("Failed to get OpenSL buffer queue interface");

            if ((*playerObject)->GetInterface(playerObject, SL_IID_VOLUME, &playerVolume) != SL_RESULT_SUCCESS)
                throw SystemError("Failed to get OpenSL volume interface");

            if ((*bufferQueue)->Clear(bufferQueue) != SL_RESULT_SUCCESS)
                throw SystemError("Failed to clear OpenSL buffer");

            if ((*bufferQueue)->RegisterCallback(bufferQueue, playerCallback, this) != SL_RESULT_SUCCESS)
                throw SystemError("Failed to register OpenSL buffer queue callback");

            getData(bufferSize / (channels * sizeof(int16_t)), data);

            if ((*bufferQueue)->Enqueue(bufferQueue, data.data(), data.size()) != SL_RESULT_SUCCESS)
                throw SystemError("Failed to enqueue OpenSL data");

            if ((*player)->SetPlayState(player, SL_PLAYSTATE_PLAYING) != SL_RESULT_SUCCESS)
                throw SystemError("Failed to play sound");
        }

        AudioDeviceSL::~AudioDeviceSL()
        {
            if (playerObject)
                (*playerObject)->Destroy(playerObject);

            if (outputMixObject)
                (*outputMixObject)->Destroy(outputMixObject);

            if (engineObject)
                (*engineObject)->Destroy(engineObject);
        }

        void AudioDeviceSL::enqueue(SLAndroidSimpleBufferQueueItf bufferQueue)
        {
            process();

            getData(bufferSize / (channels * sizeof(int16_t)), data);

            if ((*bufferQueue)->Enqueue(bufferQueue, data.data(), data.size()) != SL_RESULT_SUCCESS)
                throw SystemError("Failed to enqueue OpenSL data");
        }
    } // namespace audio
} // namespace ouzel

#endif
<commit_msg>Print OpenSL error codes<commit_after>// Copyright 2015-2018 Elviss Strazdins. All rights reserved.

#include "core/Setup.h"

#if OUZEL_COMPILE_OPENSL

#include "AudioDeviceSL.hpp"
#include "core/Engine.hpp"
#include "utils/Errors.hpp"
#include "utils/Log.hpp"

static void playerCallback(SLAndroidSimpleBufferQueueItf bufferQueue, void* context)
{
    try
    {
        ouzel::audio::AudioDeviceSL* audioDeviceSL = reinterpret_cast<ouzel::audio::AudioDeviceSL*>(context);

        audioDeviceSL->enqueue(bufferQueue);
    }
    catch (const std::exception& e)
    {
        ouzel::engine->log(ouzel::Log::Level::ERR) << e.what();
    }
}

namespace ouzel
{
    namespace audio
    {
        AudioDeviceSL::AudioDeviceSL():
            AudioDevice(Driver::OPENSL)
        {
            SLresult result;
            const SLuint32 engineMixIIDCount = 1;
            const SLInterfaceID engineMixIID = SL_IID_ENGINE;
            const SLboolean engineMixReq = SL_BOOLEAN_TRUE;

            if ((result = slCreateEngine(&engineObject, 0, nullptr, engineMixIIDCount, &engineMixIID, &engineMixReq)) != SL_RESULT_SUCCESS)
                throw SystemError("Failed to create OpenSL engine object, error: " + std::to_string(result));

            if ((result = (*engineObject)->Realize(engineObject, SL_BOOLEAN_FALSE)) != SL_RESULT_SUCCESS)
                throw SystemError("Failed to create OpenSL engine object, error: " + std::to_string(result));

            if ((result = (*engineObject)->GetInterface(engineObject, SL_IID_ENGINE, &engine)) != SL_RESULT_SUCCESS)
                throw SystemError("Failed to get OpenSL engine, error: " + std::to_string(result));

            if ((result = (*engine)->CreateOutputMix(engine, &outputMixObject, 0, nullptr, nullptr)) != SL_RESULT_SUCCESS)
                throw SystemError("Failed to create OpenSL output mix, error: " + std::to_string(result));

            if ((result = (*outputMixObject)->Realize(outputMixObject, SL_BOOLEAN_FALSE)) != SL_RESULT_SUCCESS)
                throw SystemError("Failed to create OpenSL output mix, error: " + std::to_string(result));

            SLDataLocator_AndroidSimpleBufferQueue location = {SL_DATALOCATOR_ANDROIDSIMPLEBUFFERQUEUE, 2};

            SLDataFormat_PCM dataFormat;
            dataFormat.formatType = SL_DATAFORMAT_PCM;
            dataFormat.numChannels = channels;
            dataFormat.samplesPerSec = sampleRate * 1000; //mHz
            dataFormat.bitsPerSample = 16;
            dataFormat.containerSize = dataFormat.bitsPerSample;

            switch (channels)
            {
                case 1: dataFormat.channelMask = SL_SPEAKER_FRONT_CENTER; break;
                case 2: dataFormat.channelMask = SL_SPEAKER_FRONT_LEFT | SL_SPEAKER_FRONT_RIGHT; break;
                case 4: dataFormat.channelMask = SL_SPEAKER_FRONT_LEFT | SL_SPEAKER_FRONT_RIGHT | SL_SPEAKER_BACK_LEFT | SL_SPEAKER_BACK_RIGHT; break;
                case 6: dataFormat.channelMask = SL_SPEAKER_FRONT_LEFT | SL_SPEAKER_FRONT_RIGHT | SL_SPEAKER_FRONT_CENTER | SL_SPEAKER_LOW_FREQUENCY | SL_SPEAKER_SIDE_LEFT|SL_SPEAKER_SIDE_RIGHT; break;
                case 7: dataFormat.channelMask = SL_SPEAKER_FRONT_LEFT | SL_SPEAKER_FRONT_RIGHT | SL_SPEAKER_FRONT_CENTER | SL_SPEAKER_LOW_FREQUENCY | SL_SPEAKER_BACK_CENTER | SL_SPEAKER_SIDE_LEFT | SL_SPEAKER_SIDE_RIGHT; break;
                case 8: dataFormat.channelMask = SL_SPEAKER_FRONT_LEFT | SL_SPEAKER_FRONT_RIGHT | SL_SPEAKER_FRONT_CENTER | SL_SPEAKER_LOW_FREQUENCY | SL_SPEAKER_BACK_LEFT|SL_SPEAKER_BACK_RIGHT | SL_SPEAKER_SIDE_LEFT | SL_SPEAKER_SIDE_RIGHT; break;
                default:
                    throw SystemError("Invalid channel count");
            }

            dataFormat.endianness = SL_BYTEORDER_LITTLEENDIAN;

            SLDataSource dataSource = {&location, &dataFormat};

            SLDataLocator_OutputMix dataLocatorOut;
            dataLocatorOut.locatorType = SL_DATALOCATOR_OUTPUTMIX;
            dataLocatorOut.outputMix = outputMixObject;

            SLDataSink dataSink;
            dataSink.pLocator = &dataLocatorOut;
            dataSink.pFormat = nullptr;

            const SLuint32 playerIIDCount = 3;
            const SLInterfaceID playerIIDs[] = {SL_IID_BUFFERQUEUE, SL_IID_PLAY, SL_IID_VOLUME};
            const SLboolean playerReqs[] = {SL_BOOLEAN_TRUE, SL_BOOLEAN_TRUE, SL_BOOLEAN_TRUE};

            if ((result = (*engine)->CreateAudioPlayer(engine, &playerObject, &dataSource, &dataSink, playerIIDCount, playerIIDs, playerReqs)) != SL_RESULT_SUCCESS)
                throw SystemError("Failed to create OpenSL player object, error: " + std::to_string(result));

            sampleFormat = SampleFormat::SINT16;

            if ((result = (*playerObject)->Realize(playerObject, SL_BOOLEAN_FALSE)) != SL_RESULT_SUCCESS)
                throw SystemError("Failed to create OpenSL player object, error: " + std::to_string(result));

            if ((result = (*playerObject)->GetInterface(playerObject, SL_IID_PLAY, &player)) != SL_RESULT_SUCCESS)
                throw SystemError("Failed to get OpenSL player interface, error: " + std::to_string(result));

            if ((result = (*playerObject)->GetInterface(playerObject, SL_IID_BUFFERQUEUE, &bufferQueue)) != SL_RESULT_SUCCESS)
                throw SystemError("Failed to get OpenSL buffer queue interface, error: " + std::to_string(result));

            if ((result = (*playerObject)->GetInterface(playerObject, SL_IID_VOLUME, &playerVolume)) != SL_RESULT_SUCCESS)
                throw SystemError("Failed to get OpenSL volume interface, error: " + std::to_string(result));

            if ((result = (*bufferQueue)->Clear(bufferQueue)) != SL_RESULT_SUCCESS)
                throw SystemError("Failed to clear OpenSL buffer, error: " + std::to_string(result));

            if ((result = (*bufferQueue)->RegisterCallback(bufferQueue, playerCallback, this)) != SL_RESULT_SUCCESS)
                throw SystemError("Failed to register OpenSL buffer queue callback, error: " + std::to_string(result));

            getData(bufferSize / (channels * sizeof(int16_t)), data);

            if ((result = (*bufferQueue)->Enqueue(bufferQueue, data.data(), data.size())) != SL_RESULT_SUCCESS)
                throw SystemError("Failed to enqueue OpenSL data, error: " + std::to_string(result));

            if ((result = (*player)->SetPlayState(player, SL_PLAYSTATE_PLAYING)) != SL_RESULT_SUCCESS)
                throw SystemError("Failed to play sound, error: " + std::to_string(result));
        }

        AudioDeviceSL::~AudioDeviceSL()
        {
            if (playerObject)
                (*playerObject)->Destroy(playerObject);

            if (outputMixObject)
                (*outputMixObject)->Destroy(outputMixObject);

            if (engineObject)
                (*engineObject)->Destroy(engineObject);
        }

        void AudioDeviceSL::enqueue(SLAndroidSimpleBufferQueueItf bufferQueue)
        {
            process();

            getData(bufferSize / (channels * sizeof(int16_t)), data);

            SLresult result;
            if ((result = (*bufferQueue)->Enqueue(bufferQueue, data.data(), data.size())) != SL_RESULT_SUCCESS)
                throw SystemError("Failed to enqueue OpenSL data, error: " + std::to_string(result));
        }
    } // namespace audio
} // namespace ouzel

#endif
<|endoftext|>


<commit_before>#include <vector>
#include <string>
#include <cmath>
#include <complex>
#include <ctime>
#include <chrono>
#include <cassert>

#include <iostream>
#include <fstream>
#include <sstream>

#include <omp.h>
#include <sched.h>

#include <mpi.h>

#include <thread>
#include <stdlib.h>

#include "talshxx.hpp"
#ifdef _51q
#include "contraction_51q.h"
#endif
#ifdef _bris_60
#include "contraction_bris_60.h"
#endif
#ifdef _7x7x40
#include "contraction_7x7x40.h"
#endif
#ifdef _8x8x32
#include "contraction_8x8x32.h"
#endif

using namespace std;
using namespace chrono;

int main(int argc, char *argv[]) {

  // Three things to take as arguments: input file, output file, number of
  // amplitudes.

  // MPI
  // Initialize the MPI environment
  MPI_Init(NULL, NULL);

  // Get number of precesses
  int world_size;
  MPI_Comm_size(MPI_COMM_WORLD, &world_size);

  // Get the rank of the processes
  int rank;
  MPI_Comm_rank(MPI_COMM_WORLD, &rank);

  // Get the name of the processor
  char processor_name[MPI_MAX_PROCESSOR_NAME];
  int name_len;
  MPI_Get_processor_name(processor_name, &name_len);

  //////////////////////////////////////////////////////////

  // Read input parameters
  if (argc<5) throw logic_error("ERROR: Not enough arguments.");
  string in_filename = string(argv[1]);
  string out_filename = string(argv[2]);
  int mem_size_GB = atoi(argv[3]);
  unsigned long mem_size = mem_size_GB * size_t(1000000000);
  int num_entries = atoi(argv[4]); // How many entries from input file to run

  // Timing variables.
  high_resolution_clock::time_point t0, t1;
  high_resolution_clock::time_point t0_init_total, t0_total, t1_total;
  duration<double> span_total;
  t0 = high_resolution_clock::now();

  // Start here

  //////////////////////// Process 0
  if (rank==0)
  {

    int entries_left = num_entries;
    vector<MPI_Request> requests(world_size, MPI_REQUEST_NULL);
    vector<string> parameter_strings(world_size);
    vector<string> input_strings(world_size);

    // Written?
    vector<bool> written(world_size, false);
    // Input lines
    vector<string> input_lines(num_entries);

    // Output file
    ofstream out_file(out_filename);
    out_file.precision(7);

    // Input variables (from file)
    // Open file
    auto in_file = ifstream(in_filename);
    assert(in_file.good() && "Cannot open file.");
    // Gotten from the file.
    // Number of arguments per amplitude and number of amplitudes per line
    int num_args, num_amps;
    // The first element should be the number of arguments per line
    in_file >> num_args;
    in_file >> num_amps;
    int batch_size = num_args-2;

    // Grab lines one by one
    string line;
    getline(in_file, line); // "Read" one line to start next from the second.
    // Send num_args
    for (int p=1; p<world_size; ++p)
    {
      MPI_Send(vector<int>({num_args,num_amps}).data(), 2, MPI_INT, p, 0,
               MPI_COMM_WORLD);
    }
    // Send second line with metadata
    if (getline(in_file, line)) if (line.size() && line[0] != '#')
    {
      for (int p=1; p<world_size; ++p)
      {
        MPI_Send(line.c_str(), line.size(), MPI_CHAR, p, 0,
                 MPI_COMM_WORLD);
        parameter_strings[p] = line;
      }
    }

    // Read all other lines
    t0 = high_resolution_clock::now();
    int line_idx = 0;
    while (getline(in_file, line) && line_idx<num_entries) if (line.size() && line[0] != '#')
    {
      input_lines[line_idx] = line;
      ++line_idx;
    }
    in_file.close();
    line_idx = 0;
    t1 = high_resolution_clock::now();
    duration<double> span = duration_cast<duration<double>>(t1 - t0);
    cout << "Reading took " << span.count() << endl;

    // Set up for messages and storage
    vector<s_type> amplitudes_out(batch_size*num_amps*num_entries);
    vector<int> tasks_out(num_entries);
    vector<double> peak_times_out(num_entries);
    vector<string> input_strings_out(num_entries);
    int idx_entry = 0;
    // amplitudes buffer. +1 is to receive the time_largest_contraction.
    vector<s_type> amplitudes_buffer((batch_size*num_amps+1)*world_size);

    // BEGIN TIMER
    ////// MEASURE BEGIN TIMER
    {
    time_t t = time(NULL);
    tm* timePtr = localtime(&t);
    cout << "Initializing started at: "
         << timePtr->tm_mon << "/"
         << timePtr->tm_mday << "/"
         << (timePtr->tm_year)+1900 << " "
         << timePtr->tm_hour << ":"
         << timePtr->tm_min << ":"
         << timePtr->tm_sec << "\n" << flush;
    t0_init_total = high_resolution_clock::now();
    }
    ////// END MEASURE BEGIN TIMER

    // Send messages
    while (entries_left>0)
    {
      for (int p=1; p<world_size; ++p)
      {
        if (entries_left<=0) break;
        int flag = true;
        if (requests[p]!=MPI_REQUEST_NULL) // First time is flag=true;
        {
          MPI_Request_get_status(requests[p], &flag, MPI_STATUS_IGNORE);
          if (flag)
          {
            for (int a=0; a<batch_size*num_amps; ++a)
            {
              amplitudes_out[batch_size*num_amps*idx_entry+a] =
                amplitudes_buffer[(batch_size*num_amps+1)*p+a];
            }
            // Populate out vectors
            tasks_out[idx_entry] = p;
            input_strings_out[idx_entry] = input_strings[p];
            peak_times_out[idx_entry] =
              (double)amplitudes_buffer[(batch_size*num_amps+1)*(p+1)-1].real();
            ++idx_entry;

            written[p] = true;
          }
        }
        if (flag)
        {
          line = input_lines[line_idx];
          ++line_idx;
          {
            MPI_Send(line.c_str(), line.size(), MPI_CHAR, p, 0,
                     MPI_COMM_WORLD);

            written[p] = false;
            input_strings[p] = line;
            --entries_left;
            // Time
            t1 = high_resolution_clock::now();
            span = duration_cast<duration<double>>(t1 - t0);
            // Time
            //cout << span.count() << "s. Sent batch to process " << p
            //     << ". Entries left = " << entries_left << "\n";
            MPI_Irecv(amplitudes_buffer.data()+(batch_size*num_amps+1)*(p),
                      batch_size*num_amps+1, MPI_COMPLEX, p, 0,
                      MPI_COMM_WORLD, &requests[p]);
          }
        }
      }
    }

    // Clean up
    for (int p=1; p<world_size; ++p)
    {
      int flag;
      MPI_Request_get_status(requests[p], &flag, MPI_STATUS_IGNORE);
      if (!flag || !written[p])
      {
        MPI_Wait(&requests[p], MPI_STATUS_IGNORE);
        for (int a=0; a<batch_size*num_amps; ++a)
        {
          amplitudes_out[batch_size*num_amps*idx_entry+a] =
            amplitudes_buffer[(batch_size*num_amps+1)*p+a];
        }

        // Populate out vectors
        tasks_out[idx_entry] = p;
        input_strings_out[idx_entry] = input_strings[p];
        peak_times_out[idx_entry] =
          (double)amplitudes_buffer[(batch_size*num_amps+1)*(p+1)-1].real();
        ++idx_entry;

        written[p] = true;
      }
      // Send a dummy pointer to show that the we are done!
      MPI_Send(NULL, 0, MPI_CHAR, p, 0,
               MPI_COMM_WORLD);
    }

    // END TIMER
    {
    time_t t = time(NULL);
    tm* timePtr = localtime(&t);
    cout << "Computation ended at: "
         << timePtr->tm_mon << "/"
         << timePtr->tm_mday << "/"
         << (timePtr->tm_year)+1900 << " "
         << timePtr->tm_hour << ":"
         << timePtr->tm_min << ":"
         << timePtr->tm_sec << "\n" << flush;
    }
    t1_total = high_resolution_clock::now();
    span_total = duration_cast<duration<double>>(t1_total - t0_init_total);
    double total_time = span_total.count();
    cout << "Total time (s): " << total_time << endl;

    // Write everything to file
    t0 = high_resolution_clock::now();
    out_file << "\n---------- BEGIN OUTPUT ------------\n";
    out_file << "\nTotal time (s): " << total_time  << "\n\n" << endl;
    for (int l=0; l<tasks_out.size(); ++l)
    {
      out_file << "\nProcess " << tasks_out[l]
               << ": " << parameter_strings[tasks_out[l]] << "\n"
               << "Peak time (s): " << peak_times_out[l] << "\n"
               << input_strings_out[l] << "\n";
      for (int a=0; a<batch_size*num_amps; ++a)
      {
        out_file << amplitudes_out[batch_size*num_amps*l+a].real()
                 << " "<< amplitudes_out[batch_size*num_amps*l+a].imag()
                 << " ";
      }
      out_file << "\n";
    }
    out_file << "\n------------ END OUTPUT ------------\n" << flush;
    t1 = high_resolution_clock::now();
    span = duration_cast<duration<double>>(t1 - t0);
    cout << "Writing took " << span.count() << endl;

    // Close files
    out_file.close();

    // Report total time
    t1 = high_resolution_clock::now();
    span = duration_cast<duration<double>>(t1 - t0);
    //cout << "Total time = " << span.count() << endl;
  }

  ///////////////////////////// Process > 0
  else
  {
    MPI_Status status;
    int length;
    string local_line;
    vector<s_type> amplitudes;
    double time_largest_contraction;
    vector<s_type> amplitudes_p_time;
    double amplitude = 0.0;
    int num_args;
    int num_amps;

    // get num_args
    vector<int> num_args_amps(2);
    MPI_Recv(num_args_amps.data(), 2, MPI_INT, 0, 0,
             MPI_COMM_WORLD, MPI_STATUS_IGNORE);
    num_args = num_args_amps[0];
    num_amps = num_args_amps[1];
    // Get first string
    MPI_Probe(0, 0, MPI_COMM_WORLD, &status);
    MPI_Get_count(&status, MPI_CHAR, &length);
    char * char_ptr = new char[length];
    MPI_Recv(char_ptr, length, MPI_INT, 0, 0, MPI_COMM_WORLD,
             MPI_STATUS_IGNORE);
    local_line = string(char_ptr);
    delete[] char_ptr;
    char_ptr = nullptr;

    talsh::initialize(&mem_size);
    {
      Contraction contraction(local_line, num_args, num_amps);
      ////// MEASURE COMPUTATION BEGIN TIMER
      if (rank==1)
      {
        time_t t = time(NULL);
        tm* timePtr = localtime(&t);
        cout << "Rank 1 compuatation started at: "
             << timePtr->tm_mon << "/"
             << timePtr->tm_mday << "/"
             << (timePtr->tm_year)+1900 << " "
             << timePtr->tm_hour << ":"
             << timePtr->tm_min << ":"
             << timePtr->tm_sec << "\n" << flush;
      }
      ////// END MEASURE COMPUTATION BEGIN TIMER
      //cout << mem_size << endl << flush;

      bool load_circuit(true);
      t0 = high_resolution_clock::now();
      while (true)
      {
        // Start timer
        ///////////////// Get string
        MPI_Probe(0, 0, MPI_COMM_WORLD, &status);
        MPI_Get_count(&status, MPI_CHAR, &length);
        char_ptr = new char[length];
        if (length==0) break;
        MPI_Recv(char_ptr, length, MPI_INT, 0, 0, MPI_COMM_WORLD,
                 MPI_STATUS_IGNORE);
        local_line = string(char_ptr);
        delete[] char_ptr;
        char_ptr = nullptr;

        // Computation
        if (load_circuit) // load only once
        {
          contraction.load_circuit(local_line);
          load_circuit = false;
        }
        contraction.contract(local_line);
        t1 = high_resolution_clock::now();
        duration<double> span = duration_cast<duration<double>>(t1 - t0);
        t0 = high_resolution_clock::now();
        //cout << "A round took " << span.count() << "s" << endl;

        ///////////////// Message back
        amplitudes = contraction.get_amplitudes();
        time_largest_contraction = contraction.get_time_largest_contraction();
        amplitudes_p_time = vector<s_type>(amplitudes);
        amplitudes_p_time.push_back(s_type(time_largest_contraction));
        MPI_Send(amplitudes_p_time.data(), amplitudes_p_time.size(),
                 MPI_COMPLEX, 0, 0, MPI_COMM_WORLD);
      }
    }
    talsh::shutdown();

  }

  // Finalize the MPI environment.
  MPI_Finalize();

  return 0;
}
<commit_msg>Added barriers to measure time correctly between talsh::initialize() and talsh::shutdown()<commit_after>#include <vector>
#include <string>
#include <cmath>
#include <complex>
#include <ctime>
#include <chrono>
#include <cassert>

#include <iostream>
#include <fstream>
#include <sstream>

#include <omp.h>
#include <sched.h>

#include <mpi.h>

#include <thread>
#include <stdlib.h>

#include "talshxx.hpp"
#ifdef _51q
#include "contraction_51q.h"
#endif
#ifdef _bris_60
#include "contraction_bris_60.h"
#endif
#ifdef _7x7x40
#include "contraction_7x7x40.h"
#endif
#ifdef _8x8x32
#include "contraction_8x8x32.h"
#endif

using namespace std;
using namespace chrono;

int main(int argc, char *argv[]) {

  // Three things to take as arguments: input file, output file, number of
  // amplitudes.

  // MPI
  // Initialize the MPI environment
  MPI_Init(NULL, NULL);

  // Get number of precesses
  int world_size;
  MPI_Comm_size(MPI_COMM_WORLD, &world_size);

  // Get the rank of the processes
  int rank;
  MPI_Comm_rank(MPI_COMM_WORLD, &rank);

  // Get the name of the processor
  char processor_name[MPI_MAX_PROCESSOR_NAME];
  int name_len;
  MPI_Get_processor_name(processor_name, &name_len);

  //////////////////////////////////////////////////////////

  // Read input parameters
  if (argc<5) throw logic_error("ERROR: Not enough arguments.");
  string in_filename = string(argv[1]);
  string out_filename = string(argv[2]);
  int mem_size_GB = atoi(argv[3]);
  unsigned long mem_size = mem_size_GB * size_t(1000000000);
  int num_entries = atoi(argv[4]); // How many entries from input file to run

  // Timing variables.
  high_resolution_clock::time_point t0, t1;
  high_resolution_clock::time_point t0_init_total, t0_total, t1_total;
  duration<double> span_total;
  t0 = high_resolution_clock::now();

  // Start here

  //////////////////////// Process 0
  if (rank==0)
  {

    int entries_left = num_entries;
    vector<MPI_Request> requests(world_size, MPI_REQUEST_NULL);
    vector<string> parameter_strings(world_size);
    vector<string> input_strings(world_size);

    // Written?
    vector<bool> written(world_size, false);
    // Input lines
    vector<string> input_lines(num_entries);

    // Output file
    ofstream out_file(out_filename);
    out_file.precision(7);

    // Input variables (from file)
    // Open file
    auto in_file = ifstream(in_filename);
    assert(in_file.good() && "Cannot open file.");
    // Gotten from the file.
    // Number of arguments per amplitude and number of amplitudes per line
    int num_args, num_amps;
    // The first element should be the number of arguments per line
    in_file >> num_args;
    in_file >> num_amps;
    int batch_size = num_args-2;

    // Grab lines one by one
    string line;
    getline(in_file, line); // "Read" one line to start next from the second.
    // Send num_args
    for (int p=1; p<world_size; ++p)
    {
      MPI_Send(vector<int>({num_args,num_amps}).data(), 2, MPI_INT, p, 0,
               MPI_COMM_WORLD);
    }
    // Send second line with metadata
    if (getline(in_file, line)) if (line.size() && line[0] != '#')
    {
      for (int p=1; p<world_size; ++p)
      {
        MPI_Send(line.c_str(), line.size(), MPI_CHAR, p, 0,
                 MPI_COMM_WORLD);
        parameter_strings[p] = line;
      }
    }

    // Read all other lines
    t0 = high_resolution_clock::now();
    int line_idx = 0;
    while (getline(in_file, line) && line_idx<num_entries) if (line.size() && line[0] != '#')
    {
      input_lines[line_idx] = line;
      ++line_idx;
    }
    in_file.close();
    line_idx = 0;
    t1 = high_resolution_clock::now();
    duration<double> span = duration_cast<duration<double>>(t1 - t0);
    cout << "Reading took " << span.count() << endl;

    // Set up for messages and storage
    vector<s_type> amplitudes_out(batch_size*num_amps*num_entries);
    vector<int> tasks_out(num_entries);
    vector<double> peak_times_out(num_entries);
    vector<string> input_strings_out(num_entries);
    int idx_entry = 0;
    // amplitudes buffer. +1 is to receive the time_largest_contraction.
    vector<s_type> amplitudes_buffer((batch_size*num_amps+1)*world_size);

    // BEGIN TIMER
    ////// MEASURE BEGIN TIMER
    {
      time_t t = time(NULL);
      tm* timePtr = localtime(&t);
      cout << "Initializing started at: "
           << timePtr->tm_mon << "/"
           << timePtr->tm_mday << "/"
           << (timePtr->tm_year)+1900 << " "
           << timePtr->tm_hour << ":"
           << timePtr->tm_min << ":"
           << timePtr->tm_sec << "\n" << flush;
    }
    ////// END MEASURE BEGIN TIMER
    MPI_Barrier(MPI_COMM_WORLD);
    ////// MEASURE COMPUTATION BEGIN TIMER
    {
      time_t t = time(NULL);
      tm* timePtr = localtime(&t);
      cout << "Compuatation started at: "
           << timePtr->tm_mon << "/"
           << timePtr->tm_mday << "/"
           << (timePtr->tm_year)+1900 << " "
           << timePtr->tm_hour << ":"
           << timePtr->tm_min << ":"
           << timePtr->tm_sec << "\n" << flush;
      t0_init_total = high_resolution_clock::now();
    }
    ////// END MEASURE COMPUTATION BEGIN TIMER

    // Send messages
    while (entries_left>0)
    {
      for (int p=1; p<world_size; ++p)
      {
        if (entries_left<=0) break;
        int flag = true;
        if (requests[p]!=MPI_REQUEST_NULL) // First time is flag=true;
        {
          MPI_Request_get_status(requests[p], &flag, MPI_STATUS_IGNORE);
          if (flag)
          {
            for (int a=0; a<batch_size*num_amps; ++a)
            {
              amplitudes_out[batch_size*num_amps*idx_entry+a] =
                amplitudes_buffer[(batch_size*num_amps+1)*p+a];
            }
            // Populate out vectors
            tasks_out[idx_entry] = p;
            input_strings_out[idx_entry] = input_strings[p];
            peak_times_out[idx_entry] =
              (double)amplitudes_buffer[(batch_size*num_amps+1)*(p+1)-1].real();
            ++idx_entry;

            written[p] = true;
          }
        }
        if (flag)
        {
          line = input_lines[line_idx];
          ++line_idx;
          {
            MPI_Send(line.c_str(), line.size(), MPI_CHAR, p, 0,
                     MPI_COMM_WORLD);

            written[p] = false;
            input_strings[p] = line;
            --entries_left;
            // Time
            t1 = high_resolution_clock::now();
            span = duration_cast<duration<double>>(t1 - t0);
            // Time
            //cout << span.count() << "s. Sent batch to process " << p
            //     << ". Entries left = " << entries_left << "\n";
            MPI_Irecv(amplitudes_buffer.data()+(batch_size*num_amps+1)*(p),
                      batch_size*num_amps+1, MPI_COMPLEX, p, 0,
                      MPI_COMM_WORLD, &requests[p]);
          }
        }
      }
    }

    // Clean up
    for (int p=1; p<world_size; ++p)
    {
      int flag;
      MPI_Request_get_status(requests[p], &flag, MPI_STATUS_IGNORE);
      if (!flag || !written[p])
      {
        MPI_Wait(&requests[p], MPI_STATUS_IGNORE);
        for (int a=0; a<batch_size*num_amps; ++a)
        {
          amplitudes_out[batch_size*num_amps*idx_entry+a] =
            amplitudes_buffer[(batch_size*num_amps+1)*p+a];
        }

        // Populate out vectors
        tasks_out[idx_entry] = p;
        input_strings_out[idx_entry] = input_strings[p];
        peak_times_out[idx_entry] =
          (double)amplitudes_buffer[(batch_size*num_amps+1)*(p+1)-1].real();
        ++idx_entry;

        written[p] = true;
      }
      // Send a dummy pointer to show that the we are done!
      MPI_Send(NULL, 0, MPI_CHAR, p, 0,
               MPI_COMM_WORLD);
    }

    // END TIMER
    MPI_Barrier(MPI_COMM_WORLD);
    {
      time_t t = time(NULL);
      tm* timePtr = localtime(&t);
      cout << "Computation ended at: "
           << timePtr->tm_mon << "/"
           << timePtr->tm_mday << "/"
           << (timePtr->tm_year)+1900 << " "
           << timePtr->tm_hour << ":"
           << timePtr->tm_min << ":"
           << timePtr->tm_sec << "\n" << flush;
    }
    t1_total = high_resolution_clock::now();
    span_total = duration_cast<duration<double>>(t1_total - t0_init_total);
    double total_time = span_total.count();
    cout << "Total time (s): " << total_time << endl;

    // Write everything to file
    t0 = high_resolution_clock::now();
    out_file << "\n---------- BEGIN OUTPUT ------------\n";
    out_file << "\nTotal time (s): " << total_time  << "\n\n" << endl;
    for (int l=0; l<tasks_out.size(); ++l)
    {
      out_file << "\nProcess " << tasks_out[l]
               << ": " << parameter_strings[tasks_out[l]] << "\n"
               << "Peak time (s): " << peak_times_out[l] << "\n"
               << input_strings_out[l] << "\n";
      for (int a=0; a<batch_size*num_amps; ++a)
      {
        out_file << amplitudes_out[batch_size*num_amps*l+a].real()
                 << " "<< amplitudes_out[batch_size*num_amps*l+a].imag()
                 << " ";
      }
      out_file << "\n";
    }
    out_file << "\n------------ END OUTPUT ------------\n" << flush;
    t1 = high_resolution_clock::now();
    span = duration_cast<duration<double>>(t1 - t0);
    cout << "Writing took " << span.count() << endl;

    // Close files
    out_file.close();

    // Report total time
    t1 = high_resolution_clock::now();
    span = duration_cast<duration<double>>(t1 - t0);
    //cout << "Total time = " << span.count() << endl;
  }

  ///////////////////////////// Process > 0
  else
  {
    MPI_Status status;
    int length;
    string local_line;
    vector<s_type> amplitudes;
    double time_largest_contraction;
    vector<s_type> amplitudes_p_time;
    double amplitude = 0.0;
    int num_args;
    int num_amps;

    // get num_args
    vector<int> num_args_amps(2);
    MPI_Recv(num_args_amps.data(), 2, MPI_INT, 0, 0,
             MPI_COMM_WORLD, MPI_STATUS_IGNORE);
    num_args = num_args_amps[0];
    num_amps = num_args_amps[1];
    // Get first string
    MPI_Probe(0, 0, MPI_COMM_WORLD, &status);
    MPI_Get_count(&status, MPI_CHAR, &length);
    char * char_ptr = new char[length];
    MPI_Recv(char_ptr, length, MPI_INT, 0, 0, MPI_COMM_WORLD,
             MPI_STATUS_IGNORE);
    local_line = string(char_ptr);
    delete[] char_ptr;
    char_ptr = nullptr;

    talsh::initialize(&mem_size);
    MPI_Barrier(MPI_COMM_WORLD);
    {
      Contraction contraction(local_line, num_args, num_amps);
      //cout << mem_size << endl << flush;

      bool load_circuit(true);
      t0 = high_resolution_clock::now();
      while (true)
      {
        // Start timer
        ///////////////// Get string
        MPI_Probe(0, 0, MPI_COMM_WORLD, &status);
        MPI_Get_count(&status, MPI_CHAR, &length);
        char_ptr = new char[length];
        if (length==0) break;
        MPI_Recv(char_ptr, length, MPI_INT, 0, 0, MPI_COMM_WORLD,
                 MPI_STATUS_IGNORE);
        local_line = string(char_ptr);
        delete[] char_ptr;
        char_ptr = nullptr;

        // Computation
        if (load_circuit) // load only once
        {
          contraction.load_circuit(local_line);
          load_circuit = false;
        }
        contraction.contract(local_line);
        t1 = high_resolution_clock::now();
        duration<double> span = duration_cast<duration<double>>(t1 - t0);
        t0 = high_resolution_clock::now();
        //cout << "A round took " << span.count() << "s" << endl;

        ///////////////// Message back
        amplitudes = contraction.get_amplitudes();
        time_largest_contraction = contraction.get_time_largest_contraction();
        amplitudes_p_time = vector<s_type>(amplitudes);
        amplitudes_p_time.push_back(s_type(time_largest_contraction));
        MPI_Send(amplitudes_p_time.data(), amplitudes_p_time.size(),
                 MPI_COMPLEX, 0, 0, MPI_COMM_WORLD);
      }
    }
    MPI_Barrier(MPI_COMM_WORLD);
    talsh::shutdown();

  }

  // Finalize the MPI environment.
  MPI_Finalize();

  return 0;
}
<|endoftext|>


<commit_before>// Copyright 2014 Google Inc. All rights reserved.
//
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file or at
// https://developers.google.com/open-source/licenses/bsd

#include <gtest/gtest.h>

#include "packager/base/file_util.h"
#include "packager/media/file/file.h"

namespace {
const int kDataSize = 1024;
const char* kTestLocalFileName = "/tmp/local_file_test";
}

namespace edash_packager {
namespace media {

class LocalFileTest : public testing::Test {
 protected:
  virtual void SetUp() {
    data_.resize(kDataSize);
    for (int i = 0; i < kDataSize; ++i)
      data_[i] = i % 256;

    // Test file path for file_util API.
    test_file_path_ = base::FilePath(kTestLocalFileName);

    // Local file name with prefix for File API.
    local_file_name_ = kLocalFilePrefix;
    local_file_name_ += kTestLocalFileName;
  }

  virtual void TearDown() {
    // Remove test file if created.
    base::DeleteFile(base::FilePath(kTestLocalFileName), false);
  }

  std::string data_;
  base::FilePath test_file_path_;
  std::string local_file_name_;
};

TEST_F(LocalFileTest, ReadNotExist) {
  // Remove test file if it exists.
  base::DeleteFile(base::FilePath(kTestLocalFileName), false);
  ASSERT_TRUE(File::Open(local_file_name_.c_str(), "r") == NULL);
}

TEST_F(LocalFileTest, Size) {
  ASSERT_EQ(kDataSize,
            file_util::WriteFile(test_file_path_, data_.data(), kDataSize));
  ASSERT_EQ(kDataSize, File::GetFileSize(local_file_name_.c_str()));
}

TEST_F(LocalFileTest, Write) {
  // Write file using File API.
  File* file = File::Open(local_file_name_.c_str(), "w");
  ASSERT_TRUE(file != NULL);
  EXPECT_EQ(kDataSize, file->Write(&data_[0], kDataSize));
  EXPECT_EQ(kDataSize, file->Size());
  EXPECT_TRUE(file->Close());

  // Read file using file_util API.
  std::string read_data(kDataSize, 0);
  ASSERT_EQ(kDataSize,
            base::ReadFile(test_file_path_, &read_data[0], kDataSize));

  // Compare data written and read.
  EXPECT_EQ(data_, read_data);
}

TEST_F(LocalFileTest, Read_And_Eof) {
  // Write file using file_util API.
  ASSERT_EQ(kDataSize,
            file_util::WriteFile(test_file_path_, data_.data(), kDataSize));

  // Read file using File API.
  File* file = File::Open(local_file_name_.c_str(), "r");
  ASSERT_TRUE(file != NULL);

  // Read half of the file.
  const int kFirstReadBytes = kDataSize / 2;
  std::string read_data(kFirstReadBytes + kDataSize, 0);
  EXPECT_EQ(kFirstReadBytes, file->Read(&read_data[0], kFirstReadBytes));

  // Read the remaining half of the file and verify EOF.
  EXPECT_EQ(kDataSize - kFirstReadBytes,
            file->Read(&read_data[kFirstReadBytes], kDataSize));
  uint8_t single_byte;
  EXPECT_EQ(0, file->Read(&single_byte, sizeof(single_byte)));
  EXPECT_TRUE(file->Close());

  // Compare data written and read.
  read_data.resize(kDataSize);
  EXPECT_EQ(data_, read_data);
}

TEST_F(LocalFileTest, WriteRead) {
  // Write file using File API, using file name directly (without prefix).
  File* file = File::Open(kTestLocalFileName, "w");
  ASSERT_TRUE(file != NULL);
  EXPECT_EQ(kDataSize, file->Write(&data_[0], kDataSize));
  EXPECT_EQ(kDataSize, file->Size());
  EXPECT_TRUE(file->Close());

  // Read file using File API, using local file prefix + file name.
  file = File::Open(local_file_name_.c_str(), "r");
  ASSERT_TRUE(file != NULL);

  // Read half of the file and verify that Eof is not true.
  std::string read_data(kDataSize, 0);
  EXPECT_EQ(kDataSize, file->Read(&read_data[0], kDataSize));
  EXPECT_TRUE(file->Close());

  // Compare data written and read.
  EXPECT_EQ(data_, read_data);
}

}  // namespace media
}  // namespace edash_packager
<commit_msg>Change LocalFileTest to use CreateTemporaryFile<commit_after>// Copyright 2014 Google Inc. All rights reserved.
//
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file or at
// https://developers.google.com/open-source/licenses/bsd

#include <gtest/gtest.h>

#include "packager/base/file_util.h"
#include "packager/media/file/file.h"

namespace {
const int kDataSize = 1024;
}

namespace edash_packager {
namespace media {

class LocalFileTest : public testing::Test {
 protected:
  virtual void SetUp() {
    data_.resize(kDataSize);
    for (int i = 0; i < kDataSize; ++i)
      data_[i] = i % 256;

    // Test file path for file_util API.
    ASSERT_TRUE(base::CreateTemporaryFile(&test_file_path_));
    local_file_name_no_prefix_ = test_file_path_.value();

    // Local file name with prefix for File API.
    local_file_name_ = kLocalFilePrefix;
    local_file_name_ += local_file_name_no_prefix_;
  }

  virtual void TearDown() {
    // Remove test file if created.
    base::DeleteFile(base::FilePath(local_file_name_no_prefix_), false);
  }

  std::string data_;

  // Path to the temporary file for this test.
  base::FilePath test_file_path_;
  // Same as |test_file_path_| but in string form.
  std::string local_file_name_no_prefix_;

  // Same as |local_file_name_no_prefix_| but with the file prefix.
  std::string local_file_name_;
};

TEST_F(LocalFileTest, ReadNotExist) {
  // Remove test file if it exists.
  base::DeleteFile(base::FilePath(local_file_name_no_prefix_), false);
  ASSERT_TRUE(File::Open(local_file_name_.c_str(), "r") == NULL);
}

TEST_F(LocalFileTest, Size) {
  ASSERT_EQ(kDataSize,
            file_util::WriteFile(test_file_path_, data_.data(), kDataSize));
  ASSERT_EQ(kDataSize, File::GetFileSize(local_file_name_.c_str()));
}

TEST_F(LocalFileTest, Write) {
  // Write file using File API.
  File* file = File::Open(local_file_name_.c_str(), "w");
  ASSERT_TRUE(file != NULL);
  EXPECT_EQ(kDataSize, file->Write(&data_[0], kDataSize));
  EXPECT_EQ(kDataSize, file->Size());
  EXPECT_TRUE(file->Close());

  // Read file using file_util API.
  std::string read_data(kDataSize, 0);
  ASSERT_EQ(kDataSize,
            base::ReadFile(test_file_path_, &read_data[0], kDataSize));

  // Compare data written and read.
  EXPECT_EQ(data_, read_data);
}

TEST_F(LocalFileTest, Read_And_Eof) {
  // Write file using file_util API.
  ASSERT_EQ(kDataSize,
            file_util::WriteFile(test_file_path_, data_.data(), kDataSize));

  // Read file using File API.
  File* file = File::Open(local_file_name_.c_str(), "r");
  ASSERT_TRUE(file != NULL);

  // Read half of the file.
  const int kFirstReadBytes = kDataSize / 2;
  std::string read_data(kFirstReadBytes + kDataSize, 0);
  EXPECT_EQ(kFirstReadBytes, file->Read(&read_data[0], kFirstReadBytes));

  // Read the remaining half of the file and verify EOF.
  EXPECT_EQ(kDataSize - kFirstReadBytes,
            file->Read(&read_data[kFirstReadBytes], kDataSize));
  uint8_t single_byte;
  EXPECT_EQ(0, file->Read(&single_byte, sizeof(single_byte)));
  EXPECT_TRUE(file->Close());

  // Compare data written and read.
  read_data.resize(kDataSize);
  EXPECT_EQ(data_, read_data);
}

TEST_F(LocalFileTest, WriteRead) {
  // Write file using File API, using file name directly (without prefix).
  File* file = File::Open(local_file_name_no_prefix_.c_str(), "w");
  ASSERT_TRUE(file != NULL);
  EXPECT_EQ(kDataSize, file->Write(&data_[0], kDataSize));
  EXPECT_EQ(kDataSize, file->Size());
  EXPECT_TRUE(file->Close());

  // Read file using File API, using local file prefix + file name.
  file = File::Open(local_file_name_.c_str(), "r");
  ASSERT_TRUE(file != NULL);

  // Read half of the file and verify that Eof is not true.
  std::string read_data(kDataSize, 0);
  EXPECT_EQ(kDataSize, file->Read(&read_data[0], kDataSize));
  EXPECT_TRUE(file->Close());

  // Compare data written and read.
  EXPECT_EQ(data_, read_data);
}

}  // namespace media
}  // namespace edash_packager
<|endoftext|>