<commit_before>/*
  BelaCsound.cpp:

  Copyright (C) 2017 V Lazzarini

  This file is part of Csound.

  The Csound Library is free software; you can redistribute it
  and/or modify it under the terms of the GNU Lesser General Public
  License as published by the Free Software Foundation; either
  version 2.1 of the License, or (at your option) any later version.

  Csound is distributed in the hope that it will be useful,
  but WITHOUT ANY WARRANTY; without even the implied warranty of
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  GNU Lesser General Public License for more details.

  You should have received a copy of the GNU Lesser General Public
  License along with Csound; if not, write to the Free Software
  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
  02111-1307 USA
*/

#include <Bela.h>
#include <Midi.h>
#include <csound/csound.hpp>
#include <csound/plugin.h>
#include <vector>
#include <sstream>
#include <iostream>
#include <atomic>

#define ANCHNS 8

static int OpenMidiInDevice(CSOUND *csound, void **userData, const char *dev);
static int CloseMidiInDevice(CSOUND *csound, void *userData);
static int ReadMidiData(CSOUND *csound, void *userData, unsigned char *mbuf,
			int nbytes);
static int OpenMidiOutDevice(CSOUND *csound, void **userData, const char *dev);
static int CloseMidiOutDevice(CSOUND *csound, void *userData);
static int WriteMidiData(CSOUND *csound, void *userData, const unsigned char *mbuf,
			 int nbytes);

/** DigiIn opcode
    ksig digiInBela ipin
    asig digiInBela ipin
*/
struct DigiIn : csnd::Plugin<1, 1> {
  int pin;
  int fcount;
  int frms;
  int init_done;
  BelaContext *context;

  int init() {
    pin = (int) inargs[0];
    if(pin < 0 ) pin = 0;
    if(pin > 15) pin = 15;
    context = (BelaContext *) csound->host_data();
    fcount = 0;
    init_done = 0;
    frms = context->digitalFrames;
    return OK;
  }

  int kperf() {
   if(!init_done) {
      pinMode(context,0,pin,0);
      init_done = 1;
    }
    outargs[0] = (MYFLT) digitalRead(context,fcount,pin);
    fcount += nsmps;
    fcount %= frms;
    return OK;
  }

  int aperf() {
    csnd::AudioSig out(this, outargs(0));
    int cnt = fcount;
    if(!init_done) {
      pinMode(context,0,pin,0);
      init_done = 1;
    }
    for (auto &s : out) {
      s = (MYFLT) digitalRead(context,cnt,pin);
      if(cnt == frms - 1) cnt = 0;
      else cnt++;
    }
    fcount = cnt;
    return OK;
  }
};

/** DigiOut opcode
    digiOutBela ksig,ipin
    digiOutBela asig,ipin
*/
struct DigiOut : csnd::Plugin<0, 2> {
  int pin;
  int fcount;
  int frms;
  int init_done;
  BelaContext *context;

  int init() {
    pin = (int) inargs[1];
    if(pin < 0 ) pin = 0;
    if(pin > 15) pin = 15;
    context = (BelaContext *) csound->host_data();
    init_done = 0;
    fcount = 0;
    frms = context->digitalFrames;
    return OK;
  }

  int kperf() {
    if(!init_done) {
      pinMode(context,0,pin,1);
      init_done = 1;
    }
    digitalWrite(context,fcount,pin,(inargs[0] > 0.0 ? 1 : 0));
    fcount += nsmps;
    fcount %= frms;
    return OK;
  }

  int aperf() {
    csnd::AudioSig in(this, inargs(0));
    int cnt = fcount;
    if(!init_done) {
      pinMode(context,0,pin,1);
      init_done = 1;
    }
    for (auto s : in) {
      digitalWriteOnce(context,cnt,pin, (s > 0.0 ? 1 : 0));
      if(cnt == frms - 1) cnt = 0;
      else cnt++;
    }
    fcount = cnt;
    return OK;
  }
};

struct CsChan {
  std::vector<MYFLT> samples;
  std::stringstream name;
};

struct CsData {
  Csound *csound;
  std::string csdfile;
  int blocksize;
  std::atomic_int res;
  int count;
  CsChan channel[ANCHNS];
  CsChan ochannel[ANCHNS];
  Midi midi;
};

extern "C"
{
int (*csound_setup)(BelaContext*, void*);
void (*csound_render)(BelaContext*, void*);
void (*csound_cleanup)(BelaContext*, void*);
};

bool csound_setup(BelaContext *context, void *p)
{
  CsData *csData = (CsData *) p;
  Csound *csound;
  const char *midiDev = "-Mhw:1,0,0"; /* MIDI IN device */
  const char *midiOutDev = "-Qhw:1,0,0"; /* MIDI OUT device */
  const char *args[] = { "csound", csdData->csdfile.c_str(), "-iadc",
			 "-odac", "-+rtaudio=null",
			 "--realtime", "--daemon",
			 midiDev, midiOutDev };
  int numArgs = (int) (sizeof(args)/sizeof(char *));

  if(context->audioInChannels != context->audioOutChannels) {
    printf("Error: number of audio inputs != number of audio outputs.\n");
    return false;
  }

  if(context->analogInChannels != context->analogOutChannels) {
    printf("Error: number of analog inputs != number of analog outputs.\n");
    return false;
  }

  /* set up Csound */
  csound = new Csound();
  csData->csound = csound;
  csound->SetHostData((void *) context);
  csound->SetHostImplementedAudioIO(1,0);
  csound->SetHostImplementedMIDIIO(1);
  csound->SetExternalMidiInOpenCallback(OpenMidiInDevice);
  csound->SetExternalMidiReadCallback(ReadMidiData);
  csound->SetExternalMidiInCloseCallback(CloseMidiInDevice);
  csound->SetExternalMidiOutOpenCallback(OpenMidiOutDevice);
  csound->SetExternalMidiWriteCallback(WriteMidiData);
  csound->SetExternalMidiOutCloseCallback(CloseMidiOutDevice);
  /* set up digi opcodes */
  if(csnd::plugin<DigiIn>((csnd::Csound *) csound->GetCsound(), "digiInBela",
			  "k","i", csnd::thread::ik) != 0)
    printf("Warning: could not add digiInBela k-rate opcode\n");
  if(csnd::plugin<DigiIn>((csnd::Csound *) csound->GetCsound(), "digiInBela",
			  "a", "i", csnd::thread::ia) != 0)
    printf("Warning: could not add digiInBela a-rate opcode\n");
  if(csnd::plugin<DigiOut>((csnd::Csound *) csound->GetCsound(), "digiOutBela" ,
			   "", "ki", csnd::thread::ik) != 0)
    printf("Warning: could not add digiOutBela k-rate opcode\n");
  if(csnd::plugin<DigiOut>((csnd::Csound *) csound->GetCsound(), "digiOutBela" ,
			   "", "ai", csnd::thread::ia) != 0)
    printf("Warning: could not add digiOutBela a-rate opcode\n");

  /* compile CSD */
  if((csData->res = csound->Compile(numArgs, args)) != 0) {
    printf("Error: Csound could not compile CSD file.\n");
    return false;
  }
  csData->blocksize = csound->GetKsmps()*csound->GetNchnls();
  csData->count = 0;

  /* set up the channels */
  for(int i=0; i < ANCHNS; i++) {
    csData->channel[i].samples.resize(csound->GetKsmps());
    csData->channel[i].name << "analogIn" << i;
    csData->ochannel[i].samples.resize(csound->GetKsmps());
    csData->ochannel[i].name << "analogOut" << i;
  }

  return true;
}

void csound_render(BelaContext *context, void *p)
{
  CsData *csData = (CsData *) p;
  if(csData->res == 0) {
    int n,i,k,count, frmcount,blocksize,res;
    Csound *csound = csData->csound;
    MYFLT scal = csound->Get0dBFS();
    MYFLT* audioIn = csound->GetSpin();
    MYFLT* audioOut = csound->GetSpout();
    int nchnls = csound->GetNchnls();
    int chns = nchnls < context->audioOutChannels ?
      nchnls : context->audioOutChannels;
    int an_chns = context->analogInChannels > ANCHNS ?
      ANCHNS : context->analogInChannels;
    CsChan *channel = csData->channel;
    CsChan *ochannel = csData->ochannel;
    float frm = 0.f, incr =
      ((float) context->analogFrames)/context->audioFrames;
    count = csData->count;
    blocksize = csData->blocksize;

    /* processing loop */
    for(n = 0; n < context->audioFrames; n++, frm+=incr, count+=nchnls){
      if(count == blocksize) {
	/* set the channels */
	for(i = 0; i < an_chns; i++) {
          csound->SetChannel(channel[i].name.str().c_str(),
			     channel[i].samples.data());
	  csound->GetAudioChannel(ochannel[i].name.str().c_str(),
				  ochannel[i].samples.data());
	}
	/* run csound */
	if((res = csound->PerformKsmps()) == 0) count = 0;
	else break;
      }
      /* read/write audio data */
      for(i = 0; i < chns; i++){
	audioIn[count+i] = audioRead(context,n,i);
	audioWrite(context,n,i,audioOut[count+i]/scal);
      }
      /* read analogue data
         analogue frame pos frm gets incremented according to the
         ratio analogFrames/audioFrames.
      */
      frmcount = count/nchnls;
      for(i = 0; i < an_chns; i++) {
	k = (int) frm;
        channel[i].samples[frmcount] = analogRead(context,k,i);
	analogWriteOnce(context,k,i,ochannel[i].samples[frmcount]);
      }
    }
    gCsData.res = res;
    gCsData.count = count;
  }
}

void csound_cleanup(BelaContext *context, void *p)
{
  CsData *csData = (CsData *) p;
  delete csData->csound;
}

/** MIDI functions
 */
int OpenMidiInDevice(CSOUND *csound, void **userData, const char *dev) {
  CsData *hdata = (CsData *) csound->GetHostData(csound);
  Midi *midi = &(hdata->midi);
  if(midi->readFrom(dev) == 1) {
    midi->enableParser(false);
    *userData = (void *) midi;
    return 0;
  }
  csoundMessage(csound, "Could not open Midi in device %s", dev);
  return -1;
}

int CloseMidiInDevice(CSOUND *csound, void *userData) {
  return 0;
}

int ReadMidiData(CSOUND *csound, void *userData,
		 unsigned char *mbuf, int nbytes) {
  int n = 0, byte;
  if(userData) {
    Midi *midi = (Midi *) userData;
    while((byte = midi->getInput()) >= 0) {
      *mbuf++ = (unsigned char) byte;
      if(++n == nbytes) break;
    }
    return n;
  }
  return 0;
}

int OpenMidiOutDevice(CSOUND *csound, void **userData, const char *dev) {
  CsData *hdata = (CsData *) csound->GetHostData(csound);
  Midi *midi = &(hdata->midi);
  if(midi->writeTo(dev) == 1) {
    midi->enableParser(false);
    *userData = (void *) midi;
    return 0;
  }
  csoundMessage(csound, "Could not open Midi out device %s", dev);
  return -1;
}

int CloseMidiOutDevice(CSOUND *csound, void *userData) {
  return 0;
}

int WriteMidiData(CSOUND *csound, void *userData,
		  const unsigned char *mbuf, int nbytes) {
  if(userData) {
    Midi *midi = (Midi *) userData;
    if(midi->writeOutput((midi_byte_t *)mbuf, nbytes) > 0) return nbytes;
    return 0;
  }
  return 0;
}

void usage(const char *prg) {
  std::cerr << prg << " [options]\n";
  Bela_usage();
  std::cerr << "  --csd=name [-f name]: CSD file name\n";
  std::cerr << "  --help [-h]: help message\n";
}

/**
   Main program: takes Bela options and a --csd=<csdfile>
   option for Csound
*/
int main(int argc, const char *argv[]) {
  CsData csData;
  int c;
  bool res = false;
  BelaInitSettings settings;
  const option opt[] = {{"csd", required_argument, NULL, 'f'},
			{"help", 0, NULL, 'h'},
			{NULL, 0, NULL, 0}};

  Bela_defaultSettings(&settings);
  settings.setup = setup;
  settings.render = render;
  settings.cleanup = cleanup;

  while((c = Bela_getopt_long(argc, argv, "hf", opt, &settings)) >= 0) {
    if (c == 'h') {
      usage(argv[0]);
      return 1;
    } else if (c == 'f') {
      CsData.csdfile = optarg;
      res = true;
    } else {
      usage(argv[0]);
      return 1;
    }
  }

  if(res) {
    res = Bela_initAudio(&settings, &CsData);
    if(!res){
      if(Bela_startAudio() == 0) {
         while(CsData.res == 0)
	   usleep(100000);
      } else
	std::cerr << "error starting audio \n";
      Bela_stopAudio();
    } else
      std::cerr << "error initialising Bela \n";
    Bela_cleanupAudio();
    return 0;
  }
  std::cerr << "no csd provided, use --csd=name \n";
  return 1;
}
<commit_msg>other settings<commit_after>/*
  BelaCsound.cpp:

  Copyright (C) 2017 V Lazzarini

  This file is part of Csound.

  The Csound Library is free software; you can redistribute it
  and/or modify it under the terms of the GNU Lesser General Public
  License as published by the Free Software Foundation; either
  version 2.1 of the License, or (at your option) any later version.

  Csound is distributed in the hope that it will be useful,
  but WITHOUT ANY WARRANTY; without even the implied warranty of
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  GNU Lesser General Public License for more details.

  You should have received a copy of the GNU Lesser General Public
  License along with Csound; if not, write to the Free Software
  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
  02111-1307 USA
*/

#include <Bela.h>
#include <Midi.h>
#include <csound/csound.hpp>
#include <csound/plugin.h>
#include <vector>
#include <sstream>
#include <iostream>
#include <atomic>

#define ANCHNS 8

static int OpenMidiInDevice(CSOUND *csound, void **userData, const char *dev);
static int CloseMidiInDevice(CSOUND *csound, void *userData);
static int ReadMidiData(CSOUND *csound, void *userData, unsigned char *mbuf,
			int nbytes);
static int OpenMidiOutDevice(CSOUND *csound, void **userData, const char *dev);
static int CloseMidiOutDevice(CSOUND *csound, void *userData);
static int WriteMidiData(CSOUND *csound, void *userData, const unsigned char *mbuf,
			 int nbytes);

/** DigiIn opcode
    ksig digiInBela ipin
    asig digiInBela ipin
*/
struct DigiIn : csnd::Plugin<1, 1> {
  int pin;
  int fcount;
  int frms;
  int init_done;
  BelaContext *context;

  int init() {
    pin = (int) inargs[0];
    if(pin < 0 ) pin = 0;
    if(pin > 15) pin = 15;
    context = (BelaContext *) csound->host_data();
    fcount = 0;
    init_done = 0;
    frms = context->digitalFrames;
    return OK;
  }

  int kperf() {
   if(!init_done) {
      pinMode(context,0,pin,0);
      init_done = 1;
    }
    outargs[0] = (MYFLT) digitalRead(context,fcount,pin);
    fcount += nsmps;
    fcount %= frms;
    return OK;
  }

  int aperf() {
    csnd::AudioSig out(this, outargs(0));
    int cnt = fcount;
    if(!init_done) {
      pinMode(context,0,pin,0);
      init_done = 1;
    }
    for (auto &s : out) {
      s = (MYFLT) digitalRead(context,cnt,pin);
      if(cnt == frms - 1) cnt = 0;
      else cnt++;
    }
    fcount = cnt;
    return OK;
  }
};

/** DigiOut opcode
    digiOutBela ksig,ipin
    digiOutBela asig,ipin
*/
struct DigiOut : csnd::Plugin<0, 2> {
  int pin;
  int fcount;
  int frms;
  int init_done;
  BelaContext *context;

  int init() {
    pin = (int) inargs[1];
    if(pin < 0 ) pin = 0;
    if(pin > 15) pin = 15;
    context = (BelaContext *) csound->host_data();
    init_done = 0;
    fcount = 0;
    frms = context->digitalFrames;
    return OK;
  }

  int kperf() {
    if(!init_done) {
      pinMode(context,0,pin,1);
      init_done = 1;
    }
    digitalWrite(context,fcount,pin,(inargs[0] > 0.0 ? 1 : 0));
    fcount += nsmps;
    fcount %= frms;
    return OK;
  }

  int aperf() {
    csnd::AudioSig in(this, inargs(0));
    int cnt = fcount;
    if(!init_done) {
      pinMode(context,0,pin,1);
      init_done = 1;
    }
    for (auto s : in) {
      digitalWriteOnce(context,cnt,pin, (s > 0.0 ? 1 : 0));
      if(cnt == frms - 1) cnt = 0;
      else cnt++;
    }
    fcount = cnt;
    return OK;
  }
};

struct CsChan {
  std::vector<MYFLT> samples;
  std::stringstream name;
};

struct CsData {
  Csound *csound;
  std::string csdfile;
  int blocksize;
  std::atomic_int res;
  int count;
  CsChan channel[ANCHNS];
  CsChan ochannel[ANCHNS];
  Midi midi;
};

extern "C"
{
int (*csound_setup)(BelaContext*, void*);
void (*csound_render)(BelaContext*, void*);
void (*csound_cleanup)(BelaContext*, void*);
};

bool csound_setup(BelaContext *context, void *p)
{
  CsData *csData = (CsData *) p;
  Csound *csound;
  const char *midiDev = "-Mhw:1,0,0"; /* MIDI IN device */
  const char *midiOutDev = "-Qhw:1,0,0"; /* MIDI OUT device */
  const char *args[] = { "csound", csdData->csdfile.c_str(), "-iadc",
			 "-odac", "-+rtaudio=null",
			 "--realtime", "--daemon",
			 midiDev, midiOutDev };
  int numArgs = (int) (sizeof(args)/sizeof(char *));

  if(context->audioInChannels != context->audioOutChannels) {
    printf("Error: number of audio inputs != number of audio outputs.\n");
    return false;
  }

  if(context->analogInChannels != context->analogOutChannels) {
    printf("Error: number of analog inputs != number of analog outputs.\n");
    return false;
  }

  /* set up Csound */
  csound = new Csound();
  csData->csound = csound;
  csound->SetHostData((void *) context);
  csound->SetHostImplementedAudioIO(1,0);
  csound->SetHostImplementedMIDIIO(1);
  csound->SetExternalMidiInOpenCallback(OpenMidiInDevice);
  csound->SetExternalMidiReadCallback(ReadMidiData);
  csound->SetExternalMidiInCloseCallback(CloseMidiInDevice);
  csound->SetExternalMidiOutOpenCallback(OpenMidiOutDevice);
  csound->SetExternalMidiWriteCallback(WriteMidiData);
  csound->SetExternalMidiOutCloseCallback(CloseMidiOutDevice);
  /* set up digi opcodes */
  if(csnd::plugin<DigiIn>((csnd::Csound *) csound->GetCsound(), "digiInBela",
			  "k","i", csnd::thread::ik) != 0)
    printf("Warning: could not add digiInBela k-rate opcode\n");
  if(csnd::plugin<DigiIn>((csnd::Csound *) csound->GetCsound(), "digiInBela",
			  "a", "i", csnd::thread::ia) != 0)
    printf("Warning: could not add digiInBela a-rate opcode\n");
  if(csnd::plugin<DigiOut>((csnd::Csound *) csound->GetCsound(), "digiOutBela" ,
			   "", "ki", csnd::thread::ik) != 0)
    printf("Warning: could not add digiOutBela k-rate opcode\n");
  if(csnd::plugin<DigiOut>((csnd::Csound *) csound->GetCsound(), "digiOutBela" ,
			   "", "ai", csnd::thread::ia) != 0)
    printf("Warning: could not add digiOutBela a-rate opcode\n");

  /* compile CSD */
  if((csData->res = csound->Compile(numArgs, args)) != 0) {
    printf("Error: Csound could not compile CSD file.\n");
    return false;
  }
  csData->blocksize = csound->GetKsmps()*csound->GetNchnls();
  csData->count = 0;

  /* set up the channels */
  for(int i=0; i < ANCHNS; i++) {
    csData->channel[i].samples.resize(csound->GetKsmps());
    csData->channel[i].name << "analogIn" << i;
    csData->ochannel[i].samples.resize(csound->GetKsmps());
    csData->ochannel[i].name << "analogOut" << i;
  }

  return true;
}

void csound_render(BelaContext *context, void *p)
{
  CsData *csData = (CsData *) p;
  if(csData->res == 0) {
    int n,i,k,count, frmcount,blocksize,res;
    Csound *csound = csData->csound;
    MYFLT scal = csound->Get0dBFS();
    MYFLT* audioIn = csound->GetSpin();
    MYFLT* audioOut = csound->GetSpout();
    int nchnls = csound->GetNchnls();
    int chns = nchnls < context->audioOutChannels ?
      nchnls : context->audioOutChannels;
    int an_chns = context->analogInChannels > ANCHNS ?
      ANCHNS : context->analogInChannels;
    CsChan *channel = csData->channel;
    CsChan *ochannel = csData->ochannel;
    float frm = 0.f, incr =
      ((float) context->analogFrames)/context->audioFrames;
    count = csData->count;
    blocksize = csData->blocksize;

    /* processing loop */
    for(n = 0; n < context->audioFrames; n++, frm+=incr, count+=nchnls){
      if(count == blocksize) {
	/* set the channels */
	for(i = 0; i < an_chns; i++) {
          csound->SetChannel(channel[i].name.str().c_str(),
			     channel[i].samples.data());
	  csound->GetAudioChannel(ochannel[i].name.str().c_str(),
				  ochannel[i].samples.data());
	}
	/* run csound */
	if((res = csound->PerformKsmps()) == 0) count = 0;
	else break;
      }
      /* read/write audio data */
      for(i = 0; i < chns; i++){
	audioIn[count+i] = audioRead(context,n,i);
	audioWrite(context,n,i,audioOut[count+i]/scal);
      }
      /* read analogue data
         analogue frame pos frm gets incremented according to the
         ratio analogFrames/audioFrames.
      */
      frmcount = count/nchnls;
      for(i = 0; i < an_chns; i++) {
	k = (int) frm;
        channel[i].samples[frmcount] = analogRead(context,k,i);
	analogWriteOnce(context,k,i,ochannel[i].samples[frmcount]);
      }
    }
    gCsData.res = res;
    gCsData.count = count;
  }
}

void csound_cleanup(BelaContext *context, void *p)
{
  CsData *csData = (CsData *) p;
  delete csData->csound;
}

/** MIDI functions
 */
int OpenMidiInDevice(CSOUND *csound, void **userData, const char *dev) {
  CsData *hdata = (CsData *) csound->GetHostData(csound);
  Midi *midi = &(hdata->midi);
  if(midi->readFrom(dev) == 1) {
    midi->enableParser(false);
    *userData = (void *) midi;
    return 0;
  }
  csoundMessage(csound, "Could not open Midi in device %s", dev);
  return -1;
}

int CloseMidiInDevice(CSOUND *csound, void *userData) {
  return 0;
}

int ReadMidiData(CSOUND *csound, void *userData,
		 unsigned char *mbuf, int nbytes) {
  int n = 0, byte;
  if(userData) {
    Midi *midi = (Midi *) userData;
    while((byte = midi->getInput()) >= 0) {
      *mbuf++ = (unsigned char) byte;
      if(++n == nbytes) break;
    }
    return n;
  }
  return 0;
}

int OpenMidiOutDevice(CSOUND *csound, void **userData, const char *dev) {
  CsData *hdata = (CsData *) csound->GetHostData(csound);
  Midi *midi = &(hdata->midi);
  if(midi->writeTo(dev) == 1) {
    midi->enableParser(false);
    *userData = (void *) midi;
    return 0;
  }
  csoundMessage(csound, "Could not open Midi out device %s", dev);
  return -1;
}

int CloseMidiOutDevice(CSOUND *csound, void *userData) {
  return 0;
}

int WriteMidiData(CSOUND *csound, void *userData,
		  const unsigned char *mbuf, int nbytes) {
  if(userData) {
    Midi *midi = (Midi *) userData;
    if(midi->writeOutput((midi_byte_t *)mbuf, nbytes) > 0) return nbytes;
    return 0;
  }
  return 0;
}

void usage(const char *prg) {
  std::cerr << prg << " [options]\n";
  Bela_usage();
  std::cerr << "  --csd=name [-f name]: CSD file name\n";
  std::cerr << "  --help [-h]: help message\n";
}

/**
   Main program: takes Bela options and a --csd=<csdfile>
   option for Csound
*/
int main(int argc, const char *argv[]) {
  CsData csData;
  int c;
  bool res = false;
  BelaInitSettings settings;
  const option opt[] = {{"csd", required_argument, NULL, 'f'},
			{"help", 0, NULL, 'h'},
			{NULL, 0, NULL, 0}};

  Bela_defaultSettings(&settings);
  settings.setup = setup;
  settings.render = render;
  settings.cleanup = cleanup;
  settings.highPerformanceMode = 1;
  settings.interleave = 1;
  settings.analogOutputsPersist = 0;

  while((c = Bela_getopt_long(argc, argv, "hf", opt, &settings)) >= 0) {
    if (c == 'h') {
      usage(argv[0]);
      return 1;
    } else if (c == 'f') {
      CsData.csdfile = optarg;
      res = true;
    } else {
      usage(argv[0]);
      return 1;
    }
  }

  if(res) {
    res = Bela_initAudio(&settings, &CsData);
    if(!res){
      if(Bela_startAudio() == 0) {
         while(CsData.res == 0)
	   usleep(100000);
      } else
	std::cerr << "error starting audio \n";
      Bela_stopAudio();
    } else
      std::cerr << "error initialising Bela \n";
    Bela_cleanupAudio();
    return 0;
  }
  std::cerr << "no csd provided, use --csd=name \n";
  return 1;
}
<|endoftext|>


<commit_before>#include "k/context.h"

#include "etl/array_count.h"
#include "etl/armv7m/mpu.h"
#include "etl/armv7m/types.h"

#include "common/message.h"
#include "common/descriptor.h"

#include "k/address_range.h"
#include "k/context_layout.h"
#include "k/object_table.h"
#include "k/registers.h"
#include "k/reply_sender.h"
#include "k/scheduler.h"
#include "k/unprivileged.h"

using etl::armv7m::Word;

namespace k {

/*******************************************************************************
 * Context-specific stuff
 */

Context::Context()
  : _stack{nullptr},
    _save{},
    _keys{},
    _ctx_item{this},
    _sender_item{this},
    _priority{0},
    _state{State::stopped},
    _saved_brand{0} {}

void Context::nullify_exchanged_keys(unsigned preserved) {
  // Had to do this somewhere, this is as good a place as any.
  // (The fields in question are private, so this can't be at top level.)
  // (Putting it in the ctor hits the ill-defined non-trivial ctor rules.)
  static_assert(K_CONTEXT_SAVE_OFFSET == __builtin_offsetof(Context, _save),
                "K_CONTEXT_SAVE_OFFSET is wrong");

  // Right, actual implementation now:
  for (unsigned i = preserved; i < config::n_message_keys; ++i) {
    _keys[i] = Key::null();
  }
}

Descriptor Context::get_descriptor() const {
  return _save.sys.m.d0;
}

Keys & Context::get_message_keys() {
  return *reinterpret_cast<Keys *>(_keys);
}

void Context::do_syscall() {
  switch (get_descriptor().get_sysnum()) {
    case 0:  // IPC
      do_ipc();
      break;

    case 1:  // Copy Key
      do_copy_key();
      break;

    default:
      do_bad_sys();
      break;
  }
}

void Context::do_ipc() {
  auto d = get_descriptor();

  // Perform first phase of IPC.
  if (d.get_send_enabled()) {
    key(d.get_target()).deliver_from(this);
  } else if (d.get_receive_enabled()) {
    key(d.get_source()).get()->deliver_to(this);
  } else {
    // Simply return with registers unchanged.
    // (Weirdo.)
  }

  do_deferred_switch();
}

void Context::do_copy_key() {
  auto d = get_descriptor();
  key(d.get_target()) = key(d.get_source());
}

void Context::do_bad_sys() {
  put_message(0, Message::failure(Exception::bad_syscall));
}

void Context::complete_receive(BlockingSender * sender) {
  sender->on_blocked_delivery_accepted(_save.sys.m,
                                       _save.sys.b,
                                       get_message_keys());
}

void Context::complete_receive(Exception e, uint32_t param) {
  _save.sys.m = Message::failure(e, param);
  _save.sys.b = 0;
  nullify_exchanged_keys();
}

void Context::block_in_receive(List<Context> & list) {
  // TODO should we decide to permit non-blocking recieves... here's the spot.
  _ctx_item.unlink();
  list.insert(&_ctx_item);
  _state = State::receiving;

  pend_switch();
}

void Context::complete_blocked_receive(Brand const & brand, Sender * sender) {
  runnable.insert(&_ctx_item);
  _state = State::runnable;
  _save.sys.b = brand;

  pend_switch();

  sender->on_delivery_accepted(_save.sys.m, get_message_keys());
}

void Context::complete_blocked_receive(Exception e, uint32_t param) {
  runnable.insert(&_ctx_item);
  _state = State::runnable;

  pend_switch();

  complete_receive(e, param);
}

void Context::put_message(Brand brand, Message const & m) {
  _save.sys.m = m.sanitized();
  _save.sys.b = brand;
}

void Context::apply_to_mpu() {
  using etl::armv7m::mpu;

  for (unsigned i = 0; i < config::n_task_regions; ++i) {
    mpu.write_rnr(i);
    auto object = _memory_regions[i].get();
    // TODO: this cast pattern is sub-optimal.  Better to have a cast method.
    if (object->is_address_range()) {
      auto range = static_cast<AddressRange *>(object);
      auto region = range->get_region_for_brand(_memory_regions[i].get_brand());
      mpu.write_rbar(region.rbar);
      mpu.write_rasr(region.rasr);
    } else {
      mpu.write_rasr(0);
      mpu.write_rbar(0);
    }
  }
}

void Context::make_runnable() {
  switch (_state) {
    case State::sending:
      on_blocked_delivery_failed(Exception::would_block);
      break;

    case State::receiving:
      complete_blocked_receive(Exception::would_block);
      break;

    case State::stopped:
      runnable.insert(&_ctx_item);
      _state = State::runnable;
      break;

    case State::runnable:
      break;
  }
}

/*******************************************************************************
 * Implementation of Sender and BlockingSender
 */

Priority Context::get_priority() const {
  return _priority;
}

void Context::on_delivery_accepted(Message & m, Keys & k) {
  auto d = get_descriptor();

  m = _save.sys.m.sanitized();

  k.keys[0] = d.is_call() ? make_reply_key() : Key::null();
  for (unsigned ki = 1; ki < config::n_message_keys; ++ki) {
    k.keys[ki] = key(ki);
  }

  if (d.get_receive_enabled()) {
    auto & source = d.is_call() ? k.keys[0]
                                : key(d.get_source());
    source.get()->deliver_to(this);
  }
}

void Context::on_delivery_failed(Exception e, uint32_t param) {
  // Deliver the exception.
  _save.sys.m = Message::failure(e, param);
  _save.sys.b = 0;
  // Avoid looking like we delivered any pre-existing keys.
  nullify_exchanged_keys();
}

void Context::block_in_send(Brand const & brand, List<BlockingSender> & list) {
  ETL_ASSERT(this == current);

  if (get_descriptor().get_block()) {
    _saved_brand = brand;
    list.insert(&_sender_item);
    _ctx_item.unlink();
    _state = State::sending;

    pend_switch();
  } else {
    // Unprivileged code is unwilling to block for delivery.
    on_delivery_failed(Exception::would_block);
  }
}

void Context::on_blocked_delivery_accepted(Message & m, Brand & b, Keys & k) {
  runnable.insert(&_ctx_item);
  _state = State::runnable;

  b = _saved_brand;
  pend_switch();
  on_delivery_accepted(m, k);
}

void Context::on_blocked_delivery_failed(Exception e, uint32_t param) {
  runnable.insert(&_ctx_item);
  _state = State::runnable;
  pend_switch();

  on_delivery_failed(e, param);
}

Key Context::make_reply_key() const {
  auto maybe_key = object_table[_reply_gate_index].ptr->make_key(0);
  if (maybe_key) return maybe_key.ref();
  return Key::null();
}

/*******************************************************************************
 * Implementation of Context protocol.
 */

using IpcImpl = void (Context::*)(ScopedReplySender &,
                                  Brand const &,
                                  Message const &,
                                  Keys &);

void Context::deliver_from(Brand const & brand, Sender * sender) {
  Message m;
  Keys k;
  sender->on_delivery_accepted(m, k);

  static constexpr IpcImpl dispatch[] {
    &Context::do_read_register,
    &Context::do_write_register,
    &Context::do_read_key,
    &Context::do_write_key,
    &Context::do_read_region,
    &Context::do_write_region,
    &Context::do_make_runnable,
    &Context::do_read_priority,
    &Context::do_write_priority,
  };
  if (m.d0.get_selector() < etl::array_count(dispatch)) {
    ScopedReplySender reply_sender{k.keys[0]};
    auto fn = dispatch[m.d0.get_selector()];
    (this->*fn)(reply_sender, brand, m, k);
  } else {
    do_badop(m, k);
  }
}

void Context::do_read_register(ScopedReplySender & reply_sender,
                               Brand const &,
                               Message const & arg,
                               Keys & k) {
  switch (arg.d1) {
    case 13:
      reply_sender.get_message().d1 = reinterpret_cast<Word>(_stack);
      return;

#define GP_EF(num, nam) \
    case num: { \
      apply_to_mpu(); \
      auto r = uload(&_stack->nam); \
      current->apply_to_mpu(); \
      if (r) { \
        reply_sender.get_message().d1 = r.ref(); \
      } else { \
        reply_sender.get_message() = Message::failure(Exception::fault); \
      } \
      return; \
    }
    GP_EF(0, r0);
    GP_EF(1, r1);
    GP_EF(2, r2);
    GP_EF(3, r3);
    GP_EF(12, r12);
    GP_EF(14, r14);
    GP_EF(15, r15);
    GP_EF(16, psr);
#undef GP_EF

    case 4 ... 11:
      reply_sender.get_message().d1 = _save.raw[arg.d1 - 4];
      return;

    case 17:  // BASEPRI
      reply_sender.get_message().d1 = _save.named.basepri;
      return;

    default:
      reply_sender.get_message() = Message::failure(Exception::index_out_of_range);
      return;
  }
}

void Context::do_write_register(ScopedReplySender & reply_sender,
                                Brand const &,
                                Message const & arg,
                                Keys & k) {
  auto r = arg.d1;
  auto v = arg.d2;

  switch (r) {
    case 13:
      _stack = reinterpret_cast<decltype(_stack)>(v);
      return;

#define GP_EF(num, nam) \
    case num: { \
      if (!ustore(&_stack->nam, v)) { \
        reply_sender.get_message() = Message::failure(Exception::fault); \
      } \
      return; \
    }
    GP_EF(0, r0);
    GP_EF(1, r1);
    GP_EF(2, r2);
    GP_EF(3, r3);
    GP_EF(12, r12);
    GP_EF(14, r14);
    GP_EF(15, r15);
    GP_EF(16, psr);
#undef GP

    case 4 ... 11:
      _save.raw[r - 4] = v;
      return;

    case 17:  // BASEPRI
      _save.named.basepri = v;
      return;

    default:
      reply_sender.get_message() = Message::failure(Exception::index_out_of_range);
      return;
  }
}

void Context::do_read_key(ScopedReplySender & reply_sender,
                          Brand const &,
                          Message const & arg,
                          Keys & k) {
  auto r = arg.d1;

  if (r >= config::n_task_keys) {
    reply_sender.get_message() = Message::failure(Exception::index_out_of_range);
  } else {
    reply_sender.set_key(1, key(r));
  }
}

void Context::do_write_key(ScopedReplySender & reply_sender,
                           Brand const &,
                           Message const & arg,
                           Keys & k) {
  auto r = arg.d1;

  auto & new_key = k.keys[1];

  if (r >= config::n_task_keys) {
    reply_sender.get_message() = Message::failure(Exception::index_out_of_range);
  } else {
    key(r) = new_key;
  }
}

void Context::do_read_region(ScopedReplySender & reply_sender,
                             Brand const &,
                             Message const & arg,
                             Keys & k) {
  auto n = arg.d1;

  if (n < config::n_task_regions) {
    reply_sender.set_key(1, _memory_regions[n]);
  } else {
    reply_sender.get_message() = Message::failure(Exception::index_out_of_range);
  }
}

void Context::do_write_region(ScopedReplySender & reply_sender,
                              Brand const &,
                              Message const & arg,
                              Keys & k) {
  auto n = arg.d1;
  auto & object_key = k.keys[1];

  if (n < config::n_task_regions) {
    _memory_regions[n] = object_key;
  } else {
    reply_sender.get_message() = Message::failure(Exception::index_out_of_range);
  }

  if (current == this) apply_to_mpu();
}

void Context::do_make_runnable(ScopedReplySender &,
                               Brand const &,
                               Message const & arg,
                               Keys & k) {
  make_runnable();
  pend_switch();
}

void Context::do_read_priority(ScopedReplySender & reply_sender,
                               Brand const &,
                               Message const & arg,
                               Keys & k) {
  reply_sender.get_message().d1 = _priority;
}

void Context::do_write_priority(ScopedReplySender & reply_sender,
                                Brand const &,
                                Message const & arg,
                                Keys & k) {
  auto priority = arg.d1;

  if (priority < config::n_priorities) {
    _priority = priority;

    if (_ctx_item.is_linked()) _ctx_item.reinsert();
    if (_sender_item.is_linked()) _sender_item.reinsert();
  } else {
    reply_sender.get_message() = Message::failure(Exception::index_out_of_range);
  }
}

}  // namespace k
<commit_msg>k/context: use right MPU settings to write registers.<commit_after>#include "k/context.h"

#include "etl/array_count.h"
#include "etl/armv7m/mpu.h"
#include "etl/armv7m/types.h"

#include "common/message.h"
#include "common/descriptor.h"

#include "k/address_range.h"
#include "k/context_layout.h"
#include "k/object_table.h"
#include "k/registers.h"
#include "k/reply_sender.h"
#include "k/scheduler.h"
#include "k/unprivileged.h"

using etl::armv7m::Word;

namespace k {

/*******************************************************************************
 * Context-specific stuff
 */

Context::Context()
  : _stack{nullptr},
    _save{},
    _keys{},
    _ctx_item{this},
    _sender_item{this},
    _priority{0},
    _state{State::stopped},
    _saved_brand{0} {}

void Context::nullify_exchanged_keys(unsigned preserved) {
  // Had to do this somewhere, this is as good a place as any.
  // (The fields in question are private, so this can't be at top level.)
  // (Putting it in the ctor hits the ill-defined non-trivial ctor rules.)
  static_assert(K_CONTEXT_SAVE_OFFSET == __builtin_offsetof(Context, _save),
                "K_CONTEXT_SAVE_OFFSET is wrong");

  // Right, actual implementation now:
  for (unsigned i = preserved; i < config::n_message_keys; ++i) {
    _keys[i] = Key::null();
  }
}

Descriptor Context::get_descriptor() const {
  return _save.sys.m.d0;
}

Keys & Context::get_message_keys() {
  return *reinterpret_cast<Keys *>(_keys);
}

void Context::do_syscall() {
  switch (get_descriptor().get_sysnum()) {
    case 0:  // IPC
      do_ipc();
      break;

    case 1:  // Copy Key
      do_copy_key();
      break;

    default:
      do_bad_sys();
      break;
  }
}

void Context::do_ipc() {
  auto d = get_descriptor();

  // Perform first phase of IPC.
  if (d.get_send_enabled()) {
    key(d.get_target()).deliver_from(this);
  } else if (d.get_receive_enabled()) {
    key(d.get_source()).get()->deliver_to(this);
  } else {
    // Simply return with registers unchanged.
    // (Weirdo.)
  }

  do_deferred_switch();
}

void Context::do_copy_key() {
  auto d = get_descriptor();
  key(d.get_target()) = key(d.get_source());
}

void Context::do_bad_sys() {
  put_message(0, Message::failure(Exception::bad_syscall));
}

void Context::complete_receive(BlockingSender * sender) {
  sender->on_blocked_delivery_accepted(_save.sys.m,
                                       _save.sys.b,
                                       get_message_keys());
}

void Context::complete_receive(Exception e, uint32_t param) {
  _save.sys.m = Message::failure(e, param);
  _save.sys.b = 0;
  nullify_exchanged_keys();
}

void Context::block_in_receive(List<Context> & list) {
  // TODO should we decide to permit non-blocking recieves... here's the spot.
  _ctx_item.unlink();
  list.insert(&_ctx_item);
  _state = State::receiving;

  pend_switch();
}

void Context::complete_blocked_receive(Brand const & brand, Sender * sender) {
  runnable.insert(&_ctx_item);
  _state = State::runnable;
  _save.sys.b = brand;

  pend_switch();

  sender->on_delivery_accepted(_save.sys.m, get_message_keys());
}

void Context::complete_blocked_receive(Exception e, uint32_t param) {
  runnable.insert(&_ctx_item);
  _state = State::runnable;

  pend_switch();

  complete_receive(e, param);
}

void Context::put_message(Brand brand, Message const & m) {
  _save.sys.m = m.sanitized();
  _save.sys.b = brand;
}

void Context::apply_to_mpu() {
  using etl::armv7m::mpu;

  for (unsigned i = 0; i < config::n_task_regions; ++i) {
    mpu.write_rnr(i);
    auto object = _memory_regions[i].get();
    // TODO: this cast pattern is sub-optimal.  Better to have a cast method.
    if (object->is_address_range()) {
      auto range = static_cast<AddressRange *>(object);
      auto region = range->get_region_for_brand(_memory_regions[i].get_brand());
      mpu.write_rbar(region.rbar);
      mpu.write_rasr(region.rasr);
    } else {
      mpu.write_rasr(0);
      mpu.write_rbar(0);
    }
  }
}

void Context::make_runnable() {
  switch (_state) {
    case State::sending:
      on_blocked_delivery_failed(Exception::would_block);
      break;

    case State::receiving:
      complete_blocked_receive(Exception::would_block);
      break;

    case State::stopped:
      runnable.insert(&_ctx_item);
      _state = State::runnable;
      break;

    case State::runnable:
      break;
  }
}

/*******************************************************************************
 * Implementation of Sender and BlockingSender
 */

Priority Context::get_priority() const {
  return _priority;
}

void Context::on_delivery_accepted(Message & m, Keys & k) {
  auto d = get_descriptor();

  m = _save.sys.m.sanitized();

  k.keys[0] = d.is_call() ? make_reply_key() : Key::null();
  for (unsigned ki = 1; ki < config::n_message_keys; ++ki) {
    k.keys[ki] = key(ki);
  }

  if (d.get_receive_enabled()) {
    auto & source = d.is_call() ? k.keys[0]
                                : key(d.get_source());
    source.get()->deliver_to(this);
  }
}

void Context::on_delivery_failed(Exception e, uint32_t param) {
  // Deliver the exception.
  _save.sys.m = Message::failure(e, param);
  _save.sys.b = 0;
  // Avoid looking like we delivered any pre-existing keys.
  nullify_exchanged_keys();
}

void Context::block_in_send(Brand const & brand, List<BlockingSender> & list) {
  ETL_ASSERT(this == current);

  if (get_descriptor().get_block()) {
    _saved_brand = brand;
    list.insert(&_sender_item);
    _ctx_item.unlink();
    _state = State::sending;

    pend_switch();
  } else {
    // Unprivileged code is unwilling to block for delivery.
    on_delivery_failed(Exception::would_block);
  }
}

void Context::on_blocked_delivery_accepted(Message & m, Brand & b, Keys & k) {
  runnable.insert(&_ctx_item);
  _state = State::runnable;

  b = _saved_brand;
  pend_switch();
  on_delivery_accepted(m, k);
}

void Context::on_blocked_delivery_failed(Exception e, uint32_t param) {
  runnable.insert(&_ctx_item);
  _state = State::runnable;
  pend_switch();

  on_delivery_failed(e, param);
}

Key Context::make_reply_key() const {
  auto maybe_key = object_table[_reply_gate_index].ptr->make_key(0);
  if (maybe_key) return maybe_key.ref();
  return Key::null();
}

/*******************************************************************************
 * Implementation of Context protocol.
 */

using IpcImpl = void (Context::*)(ScopedReplySender &,
                                  Brand const &,
                                  Message const &,
                                  Keys &);

void Context::deliver_from(Brand const & brand, Sender * sender) {
  Message m;
  Keys k;
  sender->on_delivery_accepted(m, k);

  static constexpr IpcImpl dispatch[] {
    &Context::do_read_register,
    &Context::do_write_register,
    &Context::do_read_key,
    &Context::do_write_key,
    &Context::do_read_region,
    &Context::do_write_region,
    &Context::do_make_runnable,
    &Context::do_read_priority,
    &Context::do_write_priority,
  };
  if (m.d0.get_selector() < etl::array_count(dispatch)) {
    ScopedReplySender reply_sender{k.keys[0]};
    auto fn = dispatch[m.d0.get_selector()];
    (this->*fn)(reply_sender, brand, m, k);
  } else {
    do_badop(m, k);
  }
}

void Context::do_read_register(ScopedReplySender & reply_sender,
                               Brand const &,
                               Message const & arg,
                               Keys & k) {
  switch (arg.d1) {
    case 13:
      reply_sender.get_message().d1 = reinterpret_cast<Word>(_stack);
      return;

#define GP_EF(num, nam) \
    case num: { \
      apply_to_mpu(); \
      auto r = uload(&_stack->nam); \
      current->apply_to_mpu(); \
      if (r) { \
        reply_sender.get_message().d1 = r.ref(); \
      } else { \
        reply_sender.get_message() = Message::failure(Exception::fault); \
      } \
      return; \
    }
    GP_EF(0, r0);
    GP_EF(1, r1);
    GP_EF(2, r2);
    GP_EF(3, r3);
    GP_EF(12, r12);
    GP_EF(14, r14);
    GP_EF(15, r15);
    GP_EF(16, psr);
#undef GP_EF

    case 4 ... 11:
      reply_sender.get_message().d1 = _save.raw[arg.d1 - 4];
      return;

    case 17:  // BASEPRI
      reply_sender.get_message().d1 = _save.named.basepri;
      return;

    default:
      reply_sender.get_message() = Message::failure(Exception::index_out_of_range);
      return;
  }
}

void Context::do_write_register(ScopedReplySender & reply_sender,
                                Brand const &,
                                Message const & arg,
                                Keys & k) {
  auto r = arg.d1;
  auto v = arg.d2;

  switch (r) {
    case 13:
      _stack = reinterpret_cast<decltype(_stack)>(v);
      return;

#define GP_EF(num, nam) \
    case num: { \
      apply_to_mpu(); \
      if (!ustore(&_stack->nam, v)) { \
        reply_sender.get_message() = Message::failure(Exception::fault); \
      } \
      current->apply_to_mpu(); \
      return; \
    }
    GP_EF(0, r0);
    GP_EF(1, r1);
    GP_EF(2, r2);
    GP_EF(3, r3);
    GP_EF(12, r12);
    GP_EF(14, r14);
    GP_EF(15, r15);
    GP_EF(16, psr);
#undef GP

    case 4 ... 11:
      _save.raw[r - 4] = v;
      return;

    case 17:  // BASEPRI
      _save.named.basepri = v;
      return;

    default:
      reply_sender.get_message() = Message::failure(Exception::index_out_of_range);
      return;
  }
}

void Context::do_read_key(ScopedReplySender & reply_sender,
                          Brand const &,
                          Message const & arg,
                          Keys & k) {
  auto r = arg.d1;

  if (r >= config::n_task_keys) {
    reply_sender.get_message() = Message::failure(Exception::index_out_of_range);
  } else {
    reply_sender.set_key(1, key(r));
  }
}

void Context::do_write_key(ScopedReplySender & reply_sender,
                           Brand const &,
                           Message const & arg,
                           Keys & k) {
  auto r = arg.d1;

  auto & new_key = k.keys[1];

  if (r >= config::n_task_keys) {
    reply_sender.get_message() = Message::failure(Exception::index_out_of_range);
  } else {
    key(r) = new_key;
  }
}

void Context::do_read_region(ScopedReplySender & reply_sender,
                             Brand const &,
                             Message const & arg,
                             Keys & k) {
  auto n = arg.d1;

  if (n < config::n_task_regions) {
    reply_sender.set_key(1, _memory_regions[n]);
  } else {
    reply_sender.get_message() = Message::failure(Exception::index_out_of_range);
  }
}

void Context::do_write_region(ScopedReplySender & reply_sender,
                              Brand const &,
                              Message const & arg,
                              Keys & k) {
  auto n = arg.d1;
  auto & object_key = k.keys[1];

  if (n < config::n_task_regions) {
    _memory_regions[n] = object_key;
  } else {
    reply_sender.get_message() = Message::failure(Exception::index_out_of_range);
  }

  if (current == this) apply_to_mpu();
}

void Context::do_make_runnable(ScopedReplySender &,
                               Brand const &,
                               Message const & arg,
                               Keys & k) {
  make_runnable();
  pend_switch();
}

void Context::do_read_priority(ScopedReplySender & reply_sender,
                               Brand const &,
                               Message const & arg,
                               Keys & k) {
  reply_sender.get_message().d1 = _priority;
}

void Context::do_write_priority(ScopedReplySender & reply_sender,
                                Brand const &,
                                Message const & arg,
                                Keys & k) {
  auto priority = arg.d1;

  if (priority < config::n_priorities) {
    _priority = priority;

    if (_ctx_item.is_linked()) _ctx_item.reinsert();
    if (_sender_item.is_linked()) _sender_item.reinsert();
  } else {
    reply_sender.get_message() = Message::failure(Exception::index_out_of_range);
  }
}

}  // namespace k
<|endoftext|>


<commit_before>#include <iostream>
#include <mpi.h>

#include <cmath>
#include <cstdio>
#include <string>
#include <memory>
#include <chrono>

#include "os/global.hpp"
#include "os/config.hpp"
#include "os/output.hpp"
#include "os/index.hpp"
#include "os/mpi_size_t.hpp"
#include "os/alg.hpp"
#include "os/stat.hpp"

#include "lib/eratosthene.hpp"
#include "lib/prime.hpp"
#include "lib/ppm.hpp"
#include "lib/ulam.hpp"
#include "lib/io.hpp"
#include "lib/bits_t.hpp"
#include "lib/exception.hpp"
#include "lib/pixel_generator.hpp"

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

	MPI_Init(&argc, &argv);
	int tmp_rank, tmp_size;
	MPI_Comm_rank(MPI_COMM_WORLD, &tmp_rank);
	MPI_Comm_size(MPI_COMM_WORLD, &tmp_size);

	os::global::start = MPI_Wtime();

	size_t mpi_rank = tmp_rank, mpi_size = tmp_size;

	os::config::fill(argc, argv);

	if(os::global::help){
		if(mpi_rank == 0) os::config::help();
		MPI_Finalize();
		return 0;
	}

	try{
		os::config::check();

		const size_t nth = std::stoull(os::global::params[0]);
		size_t size = os::index::size(nth);
		size_t last = os::index::last(size);
		const size_t total_count = os::index::total_count(last);

		const size_t r = total_count % mpi_size;
		const size_t base_count = total_count / mpi_size;

		size_t o;
		size_t count = os::index::local_count(mpi_rank, r, base_count, o);

		bits_t<size_t> prime;

		if(mpi_rank == mpi_size - 1) os::global::start_c = MPI_Wtime();

		if(nth == 0) last = 0, count = 0, size = 0;
		else if(nth == 1) last = 4, count = 0, size = 2;
		else if(nth == 2) last = 4, count = 0, size = 2;
		else{

			MPI_Comm* forward = new MPI_Comm[mpi_size];
			for(size_t i = 0; i < mpi_size; ++i){
				MPI_Group group, orig;
				int range[3] = {int(i), tmp_size - 1, 1};
				MPI_Comm_group(MPI_COMM_WORLD, &orig);
				MPI_Group_range_incl(orig, 1, &range, &group);
				MPI_Comm_create(MPI_COMM_WORLD, group, &forward[i]);
			}

			prime.resize(count, true);

			os::global::checkpoint = hrclock::now();
			os::alg::parallel_eratosthene_23(mpi_rank, mpi_size, forward, prime, count, last, o);
			os::global::duration += hrclock::now() - os::global::checkpoint;

			delete[] forward;
		}

		std::cout << "Process " << mpi_rank << " : " << os::global::duration.count() << " ns" << std::endl;

		if(mpi_rank == mpi_size - 1){
			os::global::stop_c = MPI_Wtime();
			std::cout << "Computation time : " << (os::global::stop_c - os::global::start_c) << " sec" << std::endl;
		}

		if(!os::global::speed){

			if(mpi_rank == 0) std::cout << "Begin writing to file" << std::endl;

			uint16_t max;
			pixel::generator<ppm::pixel_t> *painter_p, *painter_c;
			os::output::create_painters(painter_p, painter_c, max);

			const std::string prefix = os::global::params[1];
			const size_t pixels = size * size;

			std::string tmp_file_name = prefix + std::to_string(size) + ".tmp";
			MPI_File file;
			MPI_File_open(MPI_COMM_WORLD, (char *) tmp_file_name.c_str(), MPI_MODE_CREATE | MPI_MODE_WRONLY, MPI_INFO_NULL, &file);
			MPI_Status status;

			size_t offset = ppm::write_header(file, '6', size, size, max, status), prime_n;

			if(os::global::ssd){
				size_t tmp = os::output::apply_write_strategy_random(mpi_rank, file, status, offset, count, o, size, pixels, painter_p, painter_c, prime);
				MPI_Reduce(&tmp, &prime_n, 1, MPI_SIZE_T, MPI_SUM, 0, MPI_COMM_WORLD);
			}

			else{
				prime_n = os::output::apply_write_strategy_sequential(mpi_rank, mpi_size, file, status, offset, nth, base_count, o, r, size, pixels, painter_p, painter_c, prime, tmp_file_name);
			}

			MPI_File_close(&file);

			if(mpi_rank == 0){
				std::string file_name = prefix + std::to_string(prime_n) + ".ppm";
				std::rename(tmp_file_name.c_str(), file_name.c_str());
			}

			delete painter_p;
			delete painter_c;

			if(mpi_rank == 0) os::stat::print(last, prime_n);
		}

		MPI_Barrier(MPI_COMM_WORLD);

		os::global::stop = MPI_Wtime();

		if(mpi_rank == 0) std::cout << "Total time : " << (os::global::stop - os::global::start) << " sec" << std::endl;

		MPI_Finalize();

	}
	catch(const std::exception& e){
		MPI_Finalize();
		std::cout << "error -> " << e.what() << std::endl;
		return 1;
	}

	return 0;
}<commit_msg>add proc# in catch + fix computation time unit<commit_after>#include <iostream>
#include <mpi.h>

#include <cmath>
#include <cstdio>
#include <string>
#include <memory>
#include <chrono>

#include "os/global.hpp"
#include "os/config.hpp"
#include "os/output.hpp"
#include "os/index.hpp"
#include "os/mpi_size_t.hpp"
#include "os/alg.hpp"
#include "os/stat.hpp"

#include "lib/eratosthene.hpp"
#include "lib/prime.hpp"
#include "lib/ppm.hpp"
#include "lib/ulam.hpp"
#include "lib/io.hpp"
#include "lib/bits_t.hpp"
#include "lib/exception.hpp"
#include "lib/pixel_generator.hpp"

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

	MPI_Init(&argc, &argv);
	int tmp_rank, tmp_size;
	MPI_Comm_rank(MPI_COMM_WORLD, &tmp_rank);
	MPI_Comm_size(MPI_COMM_WORLD, &tmp_size);

	os::global::start = MPI_Wtime();

	size_t mpi_rank = tmp_rank, mpi_size = tmp_size;

	os::config::fill(argc, argv);

	if(os::global::help){
		if(mpi_rank == 0) os::config::help();
		MPI_Finalize();
		return 0;
	}

	try{
		os::config::check();

		const size_t nth = std::stoull(os::global::params[0]);
		size_t size = os::index::size(nth);
		size_t last = os::index::last(size);
		const size_t total_count = os::index::total_count(last);

		const size_t r = total_count % mpi_size;
		const size_t base_count = total_count / mpi_size;

		size_t o;
		size_t count = os::index::local_count(mpi_rank, r, base_count, o);

		bits_t<size_t> prime;

		if(mpi_rank == mpi_size - 1) os::global::start_c = MPI_Wtime();

		if(nth == 0) last = 0, count = 0, size = 0;
		else if(nth == 1) last = 4, count = 0, size = 2;
		else if(nth == 2) last = 4, count = 0, size = 2;
		else{

			MPI_Comm* forward = new MPI_Comm[mpi_size];
			for(size_t i = 0; i < mpi_size; ++i){
				MPI_Group group, orig;
				int range[3] = {int(i), tmp_size - 1, 1};
				MPI_Comm_group(MPI_COMM_WORLD, &orig);
				MPI_Group_range_incl(orig, 1, &range, &group);
				MPI_Comm_create(MPI_COMM_WORLD, group, &forward[i]);
			}

			prime.resize(count, true);

			os::global::checkpoint = hrclock::now();
			os::alg::parallel_eratosthene_23(mpi_rank, mpi_size, forward, prime, count, last, o);
			os::global::duration += hrclock::now() - os::global::checkpoint;

			delete[] forward;
		}

		std::cout << "Process " << mpi_rank << " : " << ( double(os::global::duration.count()) / hrclock::period::den * hrclock::period::num ) << " sec" << std::endl;

		if(mpi_rank == mpi_size - 1){
			os::global::stop_c = MPI_Wtime();
			std::cout << "Computation time : " << (os::global::stop_c - os::global::start_c) << " sec" << std::endl;
		}

		if(!os::global::speed){

			if(mpi_rank == 0) std::cout << "Begin writing to file" << std::endl;

			uint16_t max;
			pixel::generator<ppm::pixel_t> *painter_p, *painter_c;
			os::output::create_painters(painter_p, painter_c, max);

			const std::string prefix = os::global::params[1];
			const size_t pixels = size * size;

			std::string tmp_file_name = prefix + std::to_string(size) + ".tmp";
			MPI_File file;
			MPI_File_open(MPI_COMM_WORLD, (char *) tmp_file_name.c_str(), MPI_MODE_CREATE | MPI_MODE_WRONLY, MPI_INFO_NULL, &file);
			MPI_Status status;

			size_t offset = ppm::write_header(file, '6', size, size, max, status), prime_n;

			if(os::global::ssd){
				size_t tmp = os::output::apply_write_strategy_random(mpi_rank, file, status, offset, count, o, size, pixels, painter_p, painter_c, prime);
				MPI_Reduce(&tmp, &prime_n, 1, MPI_SIZE_T, MPI_SUM, 0, MPI_COMM_WORLD);
			}

			else{
				prime_n = os::output::apply_write_strategy_sequential(mpi_rank, mpi_size, file, status, offset, nth, base_count, o, r, size, pixels, painter_p, painter_c, prime, tmp_file_name);
			}

			MPI_File_close(&file);

			if(mpi_rank == 0){
				std::string file_name = prefix + std::to_string(prime_n) + ".ppm";
				std::rename(tmp_file_name.c_str(), file_name.c_str());
			}

			delete painter_p;
			delete painter_c;

			if(mpi_rank == 0) os::stat::print(last, prime_n);
		}

		MPI_Barrier(MPI_COMM_WORLD);

		os::global::stop = MPI_Wtime();

		if(mpi_rank == 0) std::cout << "Total time : " << (os::global::stop - os::global::start) << " sec" << std::endl;

		MPI_Finalize();

	}
	catch(const std::exception& e){
		MPI_Finalize();
		std::cout << '[' << mpi_rank << ']' << " error -> " << e.what() << std::endl;
		return 1;
	}

	return 0;
}<|endoftext|>


<commit_before><commit_msg>Quick note about mirroring TODO.<commit_after><|endoftext|>


<commit_before>#include "CApplication.h"

#ifdef _WIN32
#include <GL/glew.h>
#endif

#include <iostream>
#include <iomanip>

#include "CEventManager.h"
#include "CStateManager.h"

CApplication::CApplication()
{}

void CApplication::setupRenderContext()
{
    SDL_VideoInfo const * video;

    if (SDL_Init(SDL_INIT_VIDEO) < 0)
    {
        fprintf(stderr, "Couldn't initialize SDL: %s\n", SDL_GetError());
        waitForUser();
        exit(1);
    }

    atexit(SDL_Quit);

    video = SDL_GetVideoInfo();
    if(video == NULL)
    {
        fprintf(stderr, "Couldn't get video information: %s\n", SDL_GetError());
        waitForUser();
        exit(2);
    }

    SDL_GL_SetAttribute(SDL_GL_RED_SIZE, 5);
    SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, 5);
    SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, 5);
    SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 16);
    SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);

    if(! SDL_SetVideoMode(WindowSize.X, WindowSize.Y, video->vfmt->BitsPerPixel, SDL_OPENGL))
    {
        fprintf(stderr, "Couldn't set video mode: %s\n", SDL_GetError());
        waitForUser();
        exit(1);
    }

#ifdef _WIN32
    GLenum err = glewInit();
    if (GLEW_OK != err)
    {
        std::cerr << "Error initializing glew! " << glewGetErrorString(err) << std::endl;
        waitForUser();
        exit(3);
    }
#endif

    double const VersionNumber = std::atof((char const *)glGetString(GL_VERSION));
    if (VersionNumber < 2.0)
    {
        std::cerr << "Your OpenGL Version Number (" << std::setprecision(2) << VersionNumber <<
			") is not high enough for shaders. Please download and install the latest drivers"
			"for your graphics hardware." <<
			std::endl << std::endl;
    }

    std::cerr << "Your OpenGL Version Number: " << std::setprecision(2) << VersionNumber << std::endl << std::endl;

    glViewport(0, 0, (GLsizei)(WindowSize.X), (GLsizei)(WindowSize.Y));
}

void CApplication::init(SPosition2 const & windowSize)
{
    WindowSize = windowSize;

    setupRenderContext();

    EventManager = new CEventManager();
    StateManager = new CStateManager();
    SceneManager = new CSceneManager(windowSize);
	GUIEngine = new CGUIEngine(windowSize);
}

CApplication & CApplication::get()
{
    static CApplication SingletonInstance;

    return SingletonInstance;
}

CEventManager & CApplication::getEventManager()
{
    return * EventManager;
}

CStateManager & CApplication::getStateManager()
{
    return * StateManager;
}

CSceneManager & CApplication::getSceneManager()
{
    return * SceneManager;
}

CGUIEngine & CApplication::getGUIEngine()
{
	return * GUIEngine;
}

void CApplication::skipElapsedTime()
{
    Time0 = SDL_GetTicks();
}

void CApplication::updateTime()
{
	Time1 = SDL_GetTicks();
	ElapsedTime = (float) (Time1 - Time0) / 1000.f;
	RunTime += ElapsedTime;
	Time0 = Time1;
}

void CApplication::run()
{
    Running = true;

	Time0 = SDL_GetTicks();

	RunTime = ElapsedTime = 0.f;

	while (Running)
	{
		SDL_Event Event;
        while (SDL_PollEvent(& Event))
		{
            switch (Event.type)
			{

            case SDL_QUIT:
                Running = false;
                break;

			case SDL_MOUSEBUTTONDOWN:
			case SDL_MOUSEBUTTONUP:
				{

					SMouseEvent MouseEvent;
					MouseEvent.Type = SMouseEvent::EType::Click;
					MouseEvent.Location = EventManager->MouseLocation;
					MouseEvent.RelativeLocation = SVector2f(MouseEvent.Location.X / (float) WindowSize.X,
						MouseEvent.Location.Y / (float) WindowSize.Y);
					MouseEvent.Pressed = Event.button.state == SDL_PRESSED;

					switch (Event.button.button)
					{

					case SDL_BUTTON_LEFT:
						MouseEvent.Button = SMouseEvent::EButton::Left;
                        EventManager->MouseStates[SMouseEvent::EButton::Left] = MouseEvent.Pressed;
						EventManager->OnMouseEvent(MouseEvent);
						break;

					case SDL_BUTTON_RIGHT:
						MouseEvent.Button = SMouseEvent::EButton::Right;
                        EventManager->MouseStates[SMouseEvent::EButton::Right] = MouseEvent.Pressed;
						EventManager->OnMouseEvent(MouseEvent);
						break;

					case SDL_BUTTON_MIDDLE:
						MouseEvent.Button = SMouseEvent::EButton::Middle;
                        EventManager->MouseStates[SMouseEvent::EButton::Middle] = MouseEvent.Pressed;
						EventManager->OnMouseEvent(MouseEvent);
						break;

					default:
						break;

					}

					break;

				}

			case SDL_MOUSEMOTION:
				{

                    SMouseEvent MouseEvent;
                    MouseEvent.Type = SMouseEvent::EType::Move;
                    MouseEvent.Location = EventManager->MousePositionState = SPosition2(Event.motion.x, Event.motion.y);
					MouseEvent.RelativeLocation = SVector2f(MouseEvent.Location.X / (float) WindowSize.X,
						MouseEvent.Location.Y / (float) WindowSize.Y);
                    MouseEvent.Movement = SPosition2(Event.motion.xrel, Event.motion.yrel);
                    EventManager->OnMouseEvent(MouseEvent);

                    break;

                }

            case SDL_KEYDOWN:
            case SDL_KEYUP:
                {

                    SKeyboardEvent KeyEvent;
                    KeyEvent.Pressed = Event.key.state == SDL_PRESSED;
                    KeyEvent.Key = Event.key.keysym.sym;
                    EventManager->OnKeyboardEvent(KeyEvent);
                    EventManager->KeyStates[KeyEvent.Key] = KeyEvent.Pressed;

                    break;

                }
            } // switch (Event.type)
        } // while (SDL_PollEvent(& Event))

        updateTime();

        EventManager->OnGameTickStart(ElapsedTime);
        EventManager->OnGameTickEnd(ElapsedTime);

        EventManager->OnRenderStart(ElapsedTime);
        EventManager->OnRenderEnd(ElapsedTime);

        StateManager->doStateChange();

    } // while (Running)

	StateManager->shutDown();
}

float const CApplication::getElapsedTime() const
{
    return ElapsedTime;
}

float const CApplication::getRunTime() const
{
	return RunTime;
}

float const CApplication::getAspectRatio() {
   return (float)get().WindowSize.X/(float)get().WindowSize.Y;
}

SPosition2 const & CApplication::getWindowSize() const
{
    return WindowSize;
}

bool CApplication::isShuttingDown() const
{
	return ! Running;
}

void CApplication::close()
{
	Running = false;
}
<commit_msg>+ Formatting of application<commit_after>#include "CApplication.h"

#ifdef _WIN32
#include <GL/glew.h>
#endif

#include <iostream>
#include <iomanip>

#include "CEventManager.h"
#include "CStateManager.h"

CApplication::CApplication()
	: StateManager(0),
	GUIEngine(0),
	SceneManager(0),
	EventManager(0)
{}

void CApplication::setupRenderContext()
{
	SDL_VideoInfo const * video;

	if (SDL_Init(SDL_INIT_VIDEO) < 0)
	{
		fprintf(stderr, "Couldn't initialize SDL: %s\n", SDL_GetError());
		waitForUser();
		exit(1);
	}

	atexit(SDL_Quit);

	video = SDL_GetVideoInfo();
	if(video == NULL)
	{
		fprintf(stderr, "Couldn't get video information: %s\n", SDL_GetError());
		waitForUser();
		exit(2);
	}

	SDL_GL_SetAttribute(SDL_GL_RED_SIZE, 5);
	SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, 5);
	SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, 5);
	SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 16);
	SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);

	if(! SDL_SetVideoMode(WindowSize.X, WindowSize.Y, video->vfmt->BitsPerPixel, SDL_OPENGL))
	{
		fprintf(stderr, "Couldn't set video mode: %s\n", SDL_GetError());
		waitForUser();
		exit(1);
	}

	GLenum err = glewInit();
	if (GLEW_OK != err)
	{
		std::cerr << "Error initializing glew! " << glewGetErrorString(err) << std::endl;
		waitForUser();
		exit(3);
	}

	double const VersionNumber = std::atof((char const *)glGetString(GL_VERSION));
	if (VersionNumber < 2.0)
	{
		std::cerr << "Your OpenGL Version Number (" << std::setprecision(2) << VersionNumber <<
			") is not high enough for shaders. Please download and install the latest drivers"
			"for your graphics hardware." <<
			std::endl << std::endl;
	}

	std::cerr << "Your OpenGL Version Number: " << std::setprecision(2) << VersionNumber << std::endl << std::endl;

	//glViewport(0, 0, (GLsizei)(WindowSize.X), (GLsizei)(WindowSize.Y));
}

void CApplication::init(SPosition2 const & windowSize)
{
	WindowSize = windowSize;

	setupRenderContext();

	EventManager = new CEventManager();
	StateManager = new CStateManager();
	SceneManager = new CSceneManager(windowSize);
	GUIEngine = new CGUIEngine(windowSize);
}

CApplication & CApplication::get()
{
	static CApplication SingletonInstance;

	return SingletonInstance;
}

CEventManager & CApplication::getEventManager()
{
	return * EventManager;
}

CStateManager & CApplication::getStateManager()
{
	return * StateManager;
}

CSceneManager & CApplication::getSceneManager()
{
	return * SceneManager;
}

CGUIEngine & CApplication::getGUIEngine()
{
	return * GUIEngine;
}

void CApplication::skipElapsedTime()
{
	Time0 = SDL_GetTicks();
}

void CApplication::updateTime()
{
	Time1 = SDL_GetTicks();
	ElapsedTime = (float) (Time1 - Time0) / 1000.f;
	RunTime += ElapsedTime;
	Time0 = Time1;
}

void CApplication::run()
{
	Running = true;

	Time0 = SDL_GetTicks();

	RunTime = ElapsedTime = 0.f;

	while (Running)
	{
		SDL_Event Event;
		while (SDL_PollEvent(& Event))
		{
			switch (Event.type)
			{

			case SDL_QUIT:
				Running = false;
				break;

			case SDL_MOUSEBUTTONDOWN:
			case SDL_MOUSEBUTTONUP:
				{

					SMouseEvent MouseEvent;
					MouseEvent.Type = SMouseEvent::EType::Click;
					MouseEvent.Location = EventManager->MouseLocation;
					MouseEvent.RelativeLocation = SVector2f(MouseEvent.Location.X / (float) WindowSize.X,
						MouseEvent.Location.Y / (float) WindowSize.Y);
					MouseEvent.Pressed = Event.button.state == SDL_PRESSED;

					switch (Event.button.button)
					{

					case SDL_BUTTON_LEFT:
						MouseEvent.Button = SMouseEvent::EButton::Left;
						EventManager->MouseStates[SMouseEvent::EButton::Left] = MouseEvent.Pressed;
						EventManager->OnMouseEvent(MouseEvent);
						break;

					case SDL_BUTTON_RIGHT:
						MouseEvent.Button = SMouseEvent::EButton::Right;
						EventManager->MouseStates[SMouseEvent::EButton::Right] = MouseEvent.Pressed;
						EventManager->OnMouseEvent(MouseEvent);
						break;

					case SDL_BUTTON_MIDDLE:
						MouseEvent.Button = SMouseEvent::EButton::Middle;
						EventManager->MouseStates[SMouseEvent::EButton::Middle] = MouseEvent.Pressed;
						EventManager->OnMouseEvent(MouseEvent);
						break;

					default:
						break;

					}

					break;

				}

			case SDL_MOUSEMOTION:
				{

					SMouseEvent MouseEvent;
					MouseEvent.Type = SMouseEvent::EType::Move;
					MouseEvent.Location = EventManager->MousePositionState = SPosition2(Event.motion.x, Event.motion.y);
					MouseEvent.RelativeLocation = SVector2f(MouseEvent.Location.X / (float) WindowSize.X,
						MouseEvent.Location.Y / (float) WindowSize.Y);
					MouseEvent.Movement = SPosition2(Event.motion.xrel, Event.motion.yrel);
					EventManager->OnMouseEvent(MouseEvent);

					break;

				}

			case SDL_KEYDOWN:
			case SDL_KEYUP:
				{

					SKeyboardEvent KeyEvent;
					KeyEvent.Pressed = Event.key.state == SDL_PRESSED;
					KeyEvent.Key = Event.key.keysym.sym;
					EventManager->OnKeyboardEvent(KeyEvent);
					EventManager->KeyStates[KeyEvent.Key] = KeyEvent.Pressed;

					break;

				}
			} // switch (Event.type)
		} // while (SDL_PollEvent(& Event))

		updateTime();

		EventManager->OnGameTickStart(ElapsedTime);
		EventManager->OnGameTickEnd(ElapsedTime);

		EventManager->OnRenderStart(ElapsedTime);
		EventManager->OnRenderEnd(ElapsedTime);

		StateManager->doStateChange();

	} // while (Running)

	StateManager->shutDown();
}

float const CApplication::getElapsedTime() const
{
	return ElapsedTime;
}

float const CApplication::getRunTime() const
{
	return RunTime;
}

float const CApplication::getAspectRatio()
{
	return (float)get().WindowSize.X/(float)get().WindowSize.Y;
}

SPosition2 const & CApplication::getWindowSize() const
{
	return WindowSize;
}

bool CApplication::isShuttingDown() const
{
	return ! Running;
}

void CApplication::close()
{
	Running = false;
}
<|endoftext|>


<commit_before>
//
// This source file is part of appleseed.
// Visit https://appleseedhq.net/ for additional information and resources.
//
// This software is released under the MIT license.
//
// Copyright (c) 2010-2013 Francois Beaune, Jupiter Jazz Limited
// Copyright (c) 2014-2018 Francois Beaune, The appleseedhq Organization
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
//

// Interface header.
#include "colorsource.h"

// appleseed.renderer headers.
#include "renderer/modeling/color/colorentity.h"
#include "renderer/modeling/color/colorspace.h"
#include "renderer/modeling/color/wavelengths.h"
#include "renderer/modeling/entity/entity.h"

// appleseed.foundation headers.
#include "foundation/image/colorspace.h"
#include "foundation/image/regularspectrum.h"
#include "foundation/utility/api/specializedapiarrays.h"

// Standard headers.
#include <cassert>

using namespace foundation;
using namespace std;

namespace renderer
{

//
// ColorSource class implementation.
//

ColorSource::ColorSource(const ColorEntity& color_entity)
  : Source(true)
  , m_color_entity(color_entity)
{
    // Retrieve the color values.
    if (color_entity.get_color_space() == ColorSpaceSpectral)
        initialize_from_spectrum(color_entity);
    else initialize_from_color3(color_entity);

    // Apply the multiplier to the color values.
    const float multiplier = color_entity.get_multiplier();
    m_scalar *= multiplier;
    m_linear_rgb *= multiplier;
    m_spectrum *= multiplier;

    // Store the alpha values.
    const ColorValueArray& alpha = color_entity.get_alpha();
    m_alpha[0] = alpha.size() == 1 ? alpha[0] : 0.0f;
}

uint64 ColorSource::compute_signature() const
{
    return m_color_entity.compute_signature();
}

ColorSource::Hints ColorSource::get_hints() const
{
    Hints hints;
    hints.m_width = 1;
    hints.m_height = 1;
    return hints;
}

void ColorSource::initialize_from_spectrum(const ColorEntity& color_entity)
{
    const ColorValueArray& values = color_entity.get_values();

    if (values.empty())
    {
        m_scalar = 0.0f;
        m_linear_rgb.set(0.0f);
        m_spectrum.set(0.0f);
        return;
    }

    m_scalar = values[0];

    RegularSpectrum31f s;
    spectral_values_to_spectrum(
        color_entity.get_wavelength_range()[0],
        color_entity.get_wavelength_range()[1],
        values.size(),
        &values[0],
        s);

    m_linear_rgb =
        ciexyz_to_linear_rgb(
            spectrum_to_ciexyz<float>(g_std_lighting_conditions, s));

    m_spectrum.set(s, g_std_lighting_conditions, Spectrum::Reflectance);
}

void ColorSource::initialize_from_color3(const ColorEntity& color_entity)
{
    Color3f color;

    const ColorValueArray& values = color_entity.get_values();
    if (values.size() == 1)
        color.set(values[0]);
    else if (values.size() == 3)
        color = Color3f(values[0], values[1], values[2]);
    else
    {
        m_scalar = 0.0f;
        m_linear_rgb.set(0.0f);
        m_spectrum.set(0.0f);
        return;
    }

    m_scalar = color[0];

    switch (color_entity.get_color_space())
    {
      case ColorSpaceLinearRGB:
        m_linear_rgb = color;
        break;

      case ColorSpaceSRGB:
        m_linear_rgb = fast_srgb_to_linear_rgb(color);
        break;

      case ColorSpaceCIEXYZ:
        m_linear_rgb = ciexyz_to_linear_rgb(color);
        break;

      default:
        assert(!"Invalid color space.");
        break;
    }

    m_spectrum.set(m_linear_rgb, g_std_lighting_conditions, Spectrum::Reflectance);
}

}   // namespace renderer
<commit_msg>In the case of multiple alpha values, keep the first one<commit_after>
//
// This source file is part of appleseed.
// Visit https://appleseedhq.net/ for additional information and resources.
//
// This software is released under the MIT license.
//
// Copyright (c) 2010-2013 Francois Beaune, Jupiter Jazz Limited
// Copyright (c) 2014-2018 Francois Beaune, The appleseedhq Organization
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
//

// Interface header.
#include "colorsource.h"

// appleseed.renderer headers.
#include "renderer/modeling/color/colorentity.h"
#include "renderer/modeling/color/colorspace.h"
#include "renderer/modeling/color/wavelengths.h"
#include "renderer/modeling/entity/entity.h"

// appleseed.foundation headers.
#include "foundation/image/colorspace.h"
#include "foundation/image/regularspectrum.h"
#include "foundation/utility/api/specializedapiarrays.h"

// Standard headers.
#include <cassert>

using namespace foundation;
using namespace std;

namespace renderer
{

//
// ColorSource class implementation.
//

ColorSource::ColorSource(const ColorEntity& color_entity)
  : Source(true)
  , m_color_entity(color_entity)
{
    // Retrieve the color values.
    if (color_entity.get_color_space() == ColorSpaceSpectral)
        initialize_from_spectrum(color_entity);
    else initialize_from_color3(color_entity);

    // Apply the multiplier to the color values.
    const float multiplier = color_entity.get_multiplier();
    m_scalar *= multiplier;
    m_linear_rgb *= multiplier;
    m_spectrum *= multiplier;

    // Store the alpha values.
    // In the case of multiple alpha values, we keep the first one.
    const ColorValueArray& alpha = color_entity.get_alpha();
    m_alpha[0] = alpha.size() >= 1 ? alpha[0] : 0.0f;
}

uint64 ColorSource::compute_signature() const
{
    return m_color_entity.compute_signature();
}

ColorSource::Hints ColorSource::get_hints() const
{
    Hints hints;
    hints.m_width = 1;
    hints.m_height = 1;
    return hints;
}

void ColorSource::initialize_from_spectrum(const ColorEntity& color_entity)
{
    const ColorValueArray& values = color_entity.get_values();

    if (values.empty())
    {
        m_scalar = 0.0f;
        m_linear_rgb.set(0.0f);
        m_spectrum.set(0.0f);
        return;
    }

    m_scalar = values[0];

    RegularSpectrum31f s;
    spectral_values_to_spectrum(
        color_entity.get_wavelength_range()[0],
        color_entity.get_wavelength_range()[1],
        values.size(),
        &values[0],
        s);

    m_linear_rgb =
        ciexyz_to_linear_rgb(
            spectrum_to_ciexyz<float>(g_std_lighting_conditions, s));

    m_spectrum.set(s, g_std_lighting_conditions, Spectrum::Reflectance);
}

void ColorSource::initialize_from_color3(const ColorEntity& color_entity)
{
    Color3f color;

    const ColorValueArray& values = color_entity.get_values();
    if (values.size() == 1)
        color.set(values[0]);
    else if (values.size() == 3)
        color = Color3f(values[0], values[1], values[2]);
    else
    {
        m_scalar = 0.0f;
        m_linear_rgb.set(0.0f);
        m_spectrum.set(0.0f);
        return;
    }

    m_scalar = color[0];

    switch (color_entity.get_color_space())
    {
      case ColorSpaceLinearRGB:
        m_linear_rgb = color;
        break;

      case ColorSpaceSRGB:
        m_linear_rgb = fast_srgb_to_linear_rgb(color);
        break;

      case ColorSpaceCIEXYZ:
        m_linear_rgb = ciexyz_to_linear_rgb(color);
        break;

      default:
        assert(!"Invalid color space.");
        break;
    }

    m_spectrum.set(m_linear_rgb, g_std_lighting_conditions, Spectrum::Reflectance);
}

}   // namespace renderer
<|endoftext|>


<commit_before>/**
 * \file OculusInterface.hpp
 * \brief Simple class for accessing Oculus Rift data
 * \author A. Brainville (Ybalrid)
 */

#ifndef OCULUS_INTERFACE
#define OCULUS_INTERFACE

#include <iostream>

//Oculus VR API
//#include <OVR.h>
#include <OVR_CAPI.h>

#include "systemMacro.h"
#include "AnnErrorCode.hpp"
#include <Ogre.h>
#define USE_OGRE
using namespace std;
//using namespace OVR;

///Comunicate with the Rift (initialize OVR and get the info)
class DLL OculusInterface
{
    public:
    OculusInterface();
    ~OculusInterface();

    ///Update. We use the predicted values from the rift. Therefore, we want the timecode of the "pose". Default : exact current time
    void update(double time = ovr_GetTimeInSeconds());

    ///Return a position vector
    //OVR::Vector3f getPosition();

    ///Return a quaternion orentetion
    //OVR::Quatf getOrientation();

	///Return the active hmd desk object
    ovrHmdDesc getHmdDesc();

	///Return the active hmd object
    //ovrHmd getHmd();

    ///Print debuggin information to standard input;
    //void debugPrint();

    private:
	///Print to the log all information about the headset
    void customReport();
	///Init the oculus library
    void init();

	///Shutdown the oculus library
    void shutdown();

	ovrSession getSession();

    private:
    bool initialized;
    bool firstUpdated;

    ovrSession hmd;
    ovrHmdDesc hmdDesc;
	ovrTrackingState ss;
#ifdef _WIN32
	ovrGraphicsLuid luid;

#endif
};
#endif
<commit_msg>OculusInterface::getSession() is now public<commit_after>/**
 * \file OculusInterface.hpp
 * \brief Simple class for accessing Oculus Rift data
 * \author A. Brainville (Ybalrid)
 */

#ifndef OCULUS_INTERFACE
#define OCULUS_INTERFACE

#include <iostream>

//Oculus VR API
//#include <OVR.h>
#include <OVR_CAPI.h>

#include "systemMacro.h"
#include "AnnErrorCode.hpp"
#include <Ogre.h>
#define USE_OGRE
using namespace std;
//using namespace OVR;

///Comunicate with the Rift (initialize OVR and get the info)
class DLL OculusInterface
{
    public:
    OculusInterface();
    ~OculusInterface();

    ///Update. We use the predicted values from the rift. Therefore, we want the timecode of the "pose". Default : exact current time
    void update(double time = ovr_GetTimeInSeconds());

    ///Return a position vector
    //OVR::Vector3f getPosition();

    ///Return a quaternion orentetion
    //OVR::Quatf getOrientation();

	///Return the active hmd desk object
    ovrHmdDesc getHmdDesc();

	///Return the active hmd object
    //ovrHmd getHmd();

    ///Print debuggin information to standard input;
    //void debugPrint();
	ovrSession getSession();

    private:
	///Print to the log all information about the headset
    void customReport();
	///Init the oculus library
    void init();

	///Shutdown the oculus library
    void shutdown();

    private:
    bool initialized;
    bool firstUpdated;

    ovrSession hmd;
    ovrHmdDesc hmdDesc;
	ovrTrackingState ss;
#ifdef _WIN32
	ovrGraphicsLuid luid;

#endif
};
#endif
<|endoftext|>


<commit_before>/*
    <one line to give the library's name and an idea of what it does.>
    Copyright (C) 2012  Hong Jen Yee (PCMan) <pcman.tw@gmail.com>

    This library is free software; you can redistribute it and/or
    modify it under the terms of the GNU Lesser General Public
    License as published by the Free Software Foundation; either
    version 2.1 of the License, or (at your option) any later version.

    This library is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
    Lesser General Public License for more details.

    You should have received a copy of the GNU Lesser General Public
    License along with this library; if not, write to the Free Software
    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
*/

#include "filelauncher.h"
#include "applaunchcontext.h"
#include <QMessageBox>
#include <QDebug>
#include "execfiledialog_p.h"
#include "appchooserdialog.h"
#include "utilities.h"

using namespace Fm;

FmFileLauncher FileLauncher::funcs = {
  FileLauncher::_getApp,
  /* gboolean (*before_open)(GAppLaunchContext* ctx, GList* folder_infos, gpointer user_data); */
  (FmLaunchFolderFunc)FileLauncher::_openFolder,
  FileLauncher::_execFile,
  FileLauncher::_error,
  FileLauncher::_ask
};

FileLauncher::FileLauncher() {

}

FileLauncher::~FileLauncher() {

}

//static
bool FileLauncher::launchFiles(QWidget* parent, GList* file_infos) {
  FmAppLaunchContext* context = fm_app_launch_context_new_for_widget(parent);
  bool ret = fm_launch_files(G_APP_LAUNCH_CONTEXT(context), file_infos, &funcs, this);
  g_object_unref(context);
  return ret;
}

bool FileLauncher::launchPaths(QWidget* parent, GList* paths) {
  FmAppLaunchContext* context = fm_app_launch_context_new_for_widget(parent);
  bool ret = fm_launch_paths(G_APP_LAUNCH_CONTEXT(context), paths, &funcs, this);
  g_object_unref(context);
  return ret;
}

GAppInfo* FileLauncher::getApp(GList* file_infos, FmMimeType* mime_type, GError** err) {
  AppChooserDialog dlg(NULL);
  if(mime_type)
    dlg.setMimeType(mime_type);
  else
    dlg.setCanSetDefault(false);
  // FIXME: show error properly?
  if(execModelessDialog(&dlg) == QDialog::Accepted) {
    return dlg.selectedApp();
  }
  return NULL;
}

bool FileLauncher::openFolder(GAppLaunchContext* ctx, GList* folder_infos, GError** err) {
  for(GList* l = folder_infos; l; l = l->next) {
    FmFileInfo* fi = FM_FILE_INFO(l->data);
    qDebug() << "  folder:" << QString::fromUtf8(fm_file_info_get_disp_name(fi));
  }
  return false;
}

FmFileLauncherExecAction FileLauncher::execFile(FmFileInfo* file) {
  FmFileLauncherExecAction res = FM_FILE_LAUNCHER_EXEC_CANCEL;
  ExecFileDialog dlg(file);
  if(execModelessDialog(&dlg) == QDialog::Accepted) {
    res = dlg.result();
  }
  return res;
}

int FileLauncher::ask(const char* msg, char* const* btn_labels, int default_btn) {
  /* FIXME: set default button properly */
  // return fm_askv(data->parent, NULL, msg, btn_labels);
  return -1;
}

bool FileLauncher::error(GAppLaunchContext* ctx, GError* err, FmPath* path) {
  /* ask for mount if trying to launch unmounted path */
  if(err->domain == G_IO_ERROR) {
    if(path && err->code == G_IO_ERROR_NOT_MOUNTED) {
      //if(fm_mount_path(data->parent, path, TRUE))
      //  return FALSE; /* ask to retry */
    }
    else if(err->code == G_IO_ERROR_FAILED_HANDLED)
      return true; /* don't show error message */
  }
  QMessageBox dlg(QMessageBox::Critical, QObject::tr("Error"), QString::fromUtf8(err->message), QMessageBox::Ok);
  execModelessDialog(&dlg);
  return false;
}

<commit_msg>Avoid endless popups of error dialogs when there are errors launching files.<commit_after>/*
    <one line to give the library's name and an idea of what it does.>
    Copyright (C) 2012  Hong Jen Yee (PCMan) <pcman.tw@gmail.com>

    This library is free software; you can redistribute it and/or
    modify it under the terms of the GNU Lesser General Public
    License as published by the Free Software Foundation; either
    version 2.1 of the License, or (at your option) any later version.

    This library is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
    Lesser General Public License for more details.

    You should have received a copy of the GNU Lesser General Public
    License along with this library; if not, write to the Free Software
    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
*/

#include "filelauncher.h"
#include "applaunchcontext.h"
#include <QMessageBox>
#include <QDebug>
#include "execfiledialog_p.h"
#include "appchooserdialog.h"
#include "utilities.h"

using namespace Fm;

FmFileLauncher FileLauncher::funcs = {
  FileLauncher::_getApp,
  /* gboolean (*before_open)(GAppLaunchContext* ctx, GList* folder_infos, gpointer user_data); */
  (FmLaunchFolderFunc)FileLauncher::_openFolder,
  FileLauncher::_execFile,
  FileLauncher::_error,
  FileLauncher::_ask
};

FileLauncher::FileLauncher() {

}

FileLauncher::~FileLauncher() {

}

//static
bool FileLauncher::launchFiles(QWidget* parent, GList* file_infos) {
  FmAppLaunchContext* context = fm_app_launch_context_new_for_widget(parent);
  bool ret = fm_launch_files(G_APP_LAUNCH_CONTEXT(context), file_infos, &funcs, this);
  g_object_unref(context);
  return ret;
}

bool FileLauncher::launchPaths(QWidget* parent, GList* paths) {
  FmAppLaunchContext* context = fm_app_launch_context_new_for_widget(parent);
  bool ret = fm_launch_paths(G_APP_LAUNCH_CONTEXT(context), paths, &funcs, this);
  g_object_unref(context);
  return ret;
}

GAppInfo* FileLauncher::getApp(GList* file_infos, FmMimeType* mime_type, GError** err) {
  AppChooserDialog dlg(NULL);
  if(mime_type)
    dlg.setMimeType(mime_type);
  else
    dlg.setCanSetDefault(false);
  // FIXME: show error properly?
  if(execModelessDialog(&dlg) == QDialog::Accepted) {
    return dlg.selectedApp();
  }
  return NULL;
}

bool FileLauncher::openFolder(GAppLaunchContext* ctx, GList* folder_infos, GError** err) {
  for(GList* l = folder_infos; l; l = l->next) {
    FmFileInfo* fi = FM_FILE_INFO(l->data);
    qDebug() << "  folder:" << QString::fromUtf8(fm_file_info_get_disp_name(fi));
  }
  return false;
}

FmFileLauncherExecAction FileLauncher::execFile(FmFileInfo* file) {
  FmFileLauncherExecAction res = FM_FILE_LAUNCHER_EXEC_CANCEL;
  ExecFileDialog dlg(file);
  if(execModelessDialog(&dlg) == QDialog::Accepted) {
    res = dlg.result();
  }
  return res;
}

int FileLauncher::ask(const char* msg, char* const* btn_labels, int default_btn) {
  /* FIXME: set default button properly */
  // return fm_askv(data->parent, NULL, msg, btn_labels);
  return -1;
}

bool FileLauncher::error(GAppLaunchContext* ctx, GError* err, FmPath* path) {
  /* ask for mount if trying to launch unmounted path */
  if(err->domain == G_IO_ERROR) {
    if(path && err->code == G_IO_ERROR_NOT_MOUNTED) {
      //if(fm_mount_path(data->parent, path, TRUE))
      //  return FALSE; /* ask to retry */
    }
    else if(err->code == G_IO_ERROR_FAILED_HANDLED)
      return true; /* don't show error message */
  }
  QMessageBox dlg(QMessageBox::Critical, QObject::tr("Error"), QString::fromUtf8(err->message), QMessageBox::Ok);
  execModelessDialog(&dlg);
  return true;
}

<|endoftext|>


<commit_before>#include <opencv2/opencv.hpp>
#include "opencv2/highgui/highgui.hpp"
#include "opencv2/imgproc/imgproc.hpp"

using namespace cv;
using namespace std;

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

    // VideoCapture cap;
    // cap.open("../peopleInMarket.mp4");
    //cap.set(CV_CAP_PROP_FRAME_WIDTH, 320);
    //cap.set(CV_CAP_PROP_FRAME_HEIGHT, 240);

    // if (!cap.isOpened())
    //     return -1;

    Mat img;
    //namedWindow("opencv", CV_WINDOW_AUTOSIZE);
    HOGDescriptor hog;
    hog.setSVMDetector(HOGDescriptor::getDefaultPeopleDetector());

    while (true){
        //cap >> img;
        img = imread("../walkingPeople.jpeg");

        if (!img.data){
            cerr<<"Couldn't open image"<<endl;
            return -1;
        }

        //resizing the video since it's so massive
        resize(img, img, Size(640, 360), 0, 0, INTER_CUBIC);

        vector<Rect> found, found_filtered;
        hog.detectMultiScale(img, found, 0, Size(8,8), Size(32,32), 1.05, 2);
        size_t i, j;
        for (i=0; i<found.size(); i++)
        {
            Rect r = found[i];
            for (j=0; j<found.size(); j++)
                if (j!=i && (r & found[j]) == r)
                    break;
            if (j== found.size())
                found_filtered.push_back(r);
        }

        for (i=0; i<found_filtered.size(); i++)
        {
            Rect r = found_filtered[i];
            r.x += cvRound(r.width*0.1);
        r.width = cvRound(r.width*0.8);
        r.y += cvRound(r.height*0.07);
        r.height = cvRound(r.height*0.8);
        rectangle(img, r.tl(), r.br(), Scalar(0,255,0), 3);
        }
        if(found_filtered.size() > 0){
            cout<<"Rec: " << found_filtered[0].x << endl;
        }
        imwrite("tracking.jpeg",img);
        //imshow("opencv", img);
        // if (waitKey(10)>=0)
        //     break;
    }
    return 0;
}
<commit_msg>changing cpu for video processing<commit_after>#include <opencv2/opencv.hpp>
#include "opencv2/highgui/highgui.hpp"
#include "opencv2/imgproc/imgproc.hpp"

using namespace cv;
using namespace std;

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

    VideoCapture cap;
    cap.open("../peopleInMarket.mp4");
    //cap.set(CV_CAP_PROP_FRAME_WIDTH, 320);
    //cap.set(CV_CAP_PROP_FRAME_HEIGHT, 240);

    if (!cap.isOpened())
        return -1;

    Mat img;
    namedWindow("opencv", CV_WINDOW_AUTOSIZE);
    HOGDescriptor hog;
    hog.setSVMDetector(HOGDescriptor::getDefaultPeopleDetector());

    while (true){
        cap >> img;
        //img = imread("../walkingPeople.jpeg");

        if (!img.data){
            cerr<<"Couldn't open image"<<endl;
            return -1;
        }

        //resizing the video since it's so massive
        resize(img, img, Size(640, 360), 0, 0, INTER_CUBIC);

        vector<Rect> found, found_filtered;
        hog.detectMultiScale(img, found, 0, Size(8,8), Size(32,32), 1.05, 2);
        size_t i, j;
        for (i=0; i<found.size(); i++)
        {
            Rect r = found[i];
            for (j=0; j<found.size(); j++)
                if (j!=i && (r & found[j]) == r)
                    break;
            if (j== found.size())
                found_filtered.push_back(r);
        }

        for (i=0; i<found_filtered.size(); i++)
        {
            Rect r = found_filtered[i];
            r.x += cvRound(r.width*0.1);
        r.width = cvRound(r.width*0.8);
        r.y += cvRound(r.height*0.07);
        r.height = cvRound(r.height*0.8);
        rectangle(img, r.tl(), r.br(), Scalar(0,255,0), 3);
        }
        if(found_filtered.size() > 0){
            cout<<"Rec: " << found_filtered[0].x << endl;
        }
        //imwrite("tracking.jpeg",img);
        imshow("opencv", img);
        // if (waitKey(10)>=0)
        //     break;
    }
    return 0;
}
<|endoftext|>


<commit_before>/*
 * Copyright 2015 Facebook, Inc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include <folly/MapUtil.h>

#include <map>
#include <gtest/gtest.h>

using namespace folly;

TEST(MapUtil, get_default) {
  std::map<int, int> m;
  m[1] = 2;
  EXPECT_EQ(2, get_default(m, 1, 42));
  EXPECT_EQ(42, get_default(m, 2, 42));
  EXPECT_EQ(0, get_default(m, 3));
}

TEST(MapUtil, get_or_throw) {
  std::map<int, int> m;
  m[1] = 2;
  EXPECT_EQ(2, get_or_throw(m, 1));
  EXPECT_THROW(get_or_throw(m, 2), std::out_of_range);
}

TEST(MapUtil, get_or_throw_specified) {
  std::map<int, int> m;
  m[1] = 2;
  EXPECT_EQ(2, get_or_throw<std::runtime_error>(m, 1));
  EXPECT_THROW(get_or_throw<std::runtime_error>(m, 2), std::runtime_error);
}

TEST(MapUtil, get_optional) {
  std::map<int, int> m;
  m[1] = 2;
  EXPECT_TRUE(get_optional(m, 1));
  EXPECT_EQ(2, get_optional(m, 1).value());
  EXPECT_FALSE(get_optional(m, 2));
}

TEST(MapUtil, get_ref_default) {
  std::map<int, int> m;
  m[1] = 2;
  const int i = 42;
  EXPECT_EQ(2, get_ref_default(m, 1, i));
  EXPECT_EQ(42, get_ref_default(m, 2, i));
}

TEST(MapUtil, get_ptr) {
  std::map<int, int> m;
  m[1] = 2;
  EXPECT_EQ(2, *get_ptr(m, 1));
  EXPECT_TRUE(get_ptr(m, 2) == nullptr);
  *get_ptr(m, 1) = 4;
  EXPECT_EQ(4, m.at(1));
}
<commit_msg>fix unittest break<commit_after>/*
 * Copyright 2015 Facebook, Inc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include <folly/MapUtil.h>

#include <map>
#include <gtest/gtest.h>

using namespace folly;

TEST(MapUtil, get_default) {
  std::map<int, int> m;
  m[1] = 2;
  EXPECT_EQ(2, get_default(m, 1, 42));
  EXPECT_EQ(42, get_default(m, 2, 42));
  EXPECT_EQ(0, get_default(m, 3));
}

TEST(MapUtil, get_or_throw) {
  std::map<int, int> m;
  m[1] = 2;
  EXPECT_EQ(2, get_or_throw(m, 1));
  EXPECT_THROW(get_or_throw(m, 2), std::out_of_range);
}

TEST(MapUtil, get_or_throw_specified) {
  std::map<int, int> m;
  m[1] = 2;
  EXPECT_EQ(2, get_or_throw<std::runtime_error>(m, 1));
  EXPECT_THROW(get_or_throw<std::runtime_error>(m, 2), std::runtime_error);
}

TEST(MapUtil, get_optional) {
  std::map<int, int> m;
  m[1] = 2;
  EXPECT_TRUE(get_optional(m, 1).hasValue());
  EXPECT_EQ(2, get_optional(m, 1).value());
  EXPECT_FALSE(get_optional(m, 2).hasValue());
}

TEST(MapUtil, get_ref_default) {
  std::map<int, int> m;
  m[1] = 2;
  const int i = 42;
  EXPECT_EQ(2, get_ref_default(m, 1, i));
  EXPECT_EQ(42, get_ref_default(m, 2, i));
}

TEST(MapUtil, get_ptr) {
  std::map<int, int> m;
  m[1] = 2;
  EXPECT_EQ(2, *get_ptr(m, 1));
  EXPECT_TRUE(get_ptr(m, 2) == nullptr);
  *get_ptr(m, 1) = 4;
  EXPECT_EQ(4, m.at(1));
}
<|endoftext|>


<commit_before>#include <opencv2/opencv.hpp>
// #include "opencv2/highgui/highgui.hpp"
// #include "opencv2/imgproc/imgproc.hpp"
//#include "opencv2/gpu/gpu.hpp"
#include "opencv2/core/cuda.hpp"
#include "opencv2/cudaobjdetect.hpp"

using namespace cv;
using namespace std;

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

    Mat img;
    //init the descriptors
    cv::Ptr<cv::cuda::HOG> gpu_hog = cv::cuda::HOG::create();
    HOGDescriptor cpu_hog;

    //set the svm to default people detector
    gpu_hog->setSVMDetector(gpu_hog->getDefaultPeopleDetector());
    cpu_hog.setSVMDetector(HOGDescriptor::getDefaultPeopleDetector());

    while (true){

        img = imread("../walkingPeople.jpeg");

        if (!img.data){
            cerr<<"Couldn't open image"<<endl;
            return -1;
        }

        // //resizing the video since it's so massive
        // resize(img, img, Size(640, 360), 0, 0, INTER_CUBIC);

        vector<Rect> found, found_filtered;
        cpu_hog.detectMultiScale(img, found, 0, Size(8,8), Size(32,32), 1.05, 2);
        size_t i, j;
        for (i=0; i<found.size(); i++)
        {
            Rect r = found[i];
            for (j=0; j<found.size(); j++)
                if (j!=i && (r & found[j]) == r)
                    break;
            if (j== found.size())
                found_filtered.push_back(r);
        }

        for (i=0; i<found_filtered.size(); i++)
        {
            Rect r = found_filtered[i];
            r.x += cvRound(r.width*0.1);
        r.width = cvRound(r.width*0.8);
        r.y += cvRound(r.height*0.07);
        r.height = cvRound(r.height*0.8);
        rectangle(img, r.tl(), r.br(), Scalar(0,255,0), 3);
        }
        if(found_filtered.size() > 0){
            cout<<"Rec: " << found_filtered[0].x << endl;
        }
        imwrite("tracking.jpeg",img);

    }
    return 0;
}
<commit_msg>created the find object function for abstraction<commit_after>#include <opencv2/opencv.hpp>
// #include "opencv2/highgui/highgui.hpp"
// #include "opencv2/imgproc/imgproc.hpp"
//#include "opencv2/gpu/gpu.hpp"
#include "opencv2/core/cuda.hpp"
#include "opencv2/cudaobjdetect.hpp"

using namespace cv;
using namespace std;

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

    Mat img;
    //init the descriptors
    cv::Ptr<cv::cuda::HOG> gpu_hog = cv::cuda::HOG::create();
    HOGDescriptor cpu_hog;

    //set the svm to default people detector
    gpu_hog->setSVMDetector(gpu_hog->getDefaultPeopleDetector());
    cpu_hog.setSVMDetector(HOGDescriptor::getDefaultPeopleDetector());

    while (true){

        img = imread("../walkingPeople.jpeg");

        if (!img.data){
            cerr<<"Couldn't open image"<<endl;
            return -1;
        }

        // //resizing the video since it's so massive
        // resize(img, img, Size(640, 360), 0, 0, INTER_CUBIC);

        vector<Rect> found_cpu, found_filtered_cpu;
        vector<Rect> found_gpu, found_filtered_gpu;

        //comput for the gpu
        cuda::GpuMat gpu_img;
        gpu_img.upload(img);
        gpu_hog->detectMultiScale(gpu_img, found_gpu);

        //comput for the cpu
        cpu_hog.detectMultiScale(img, found_cpu, 0, Size(8,8), Size(32,32), 1.05, 2);
        size_t i, j;

        for (i=0; i<found.size(); i++)
        {
            Rect r = found[i];
            for (j=0; j<found.size(); j++)
                if (j!=i && (r & found[j]) == r)
                    break;
            if (j== found.size())
                found_filtered.push_back(r);
        }

        for (i=0; i<found_filtered.size(); i++)
        {
            Rect r = found_filtered[i];
            r.x += cvRound(r.width*0.1);
        r.width = cvRound(r.width*0.8);
        r.y += cvRound(r.height*0.07);
        r.height = cvRound(r.height*0.8);
        rectangle(img, r.tl(), r.br(), Scalar(0,255,0), 3);
        }
        if(found_filtered.size() > 0){
            cout<<"Rec: " << found_filtered[0].x << endl;
        }
        imwrite("tracking.jpeg",img);

    }
    return 0;
}

int findObject(vector<Rec> found, Mat img,string filename){
    size_t j = 0, i = 0;
    vector<Rec> found_filtered;

    for (i=0; i<found.size(); i++){
        Rect r = found[i];
        for (j=0; j<found.size(); j++){
            if (j!=i && (r & found[j]) == r){
                break;
            }
        }
        if (j== found.size()){
            found_filtered.push_back(r);
        }
    }

        for (i=0; i<found_filtered.size(); i++){
            Rect r = found_filtered[i];
            r.x += cvRound(r.width*0.1);
            r.width = cvRound(r.width*0.8);
            r.y += cvRound(r.height*0.07);
            r.height = cvRound(r.height*0.8);
            rectangle(img, r.tl(), r.br(), Scalar(0,255,0), 3);
        }

        imwrite(filename,img);
}
<|endoftext|>