Arduino addition assignment - c++

I do some programming using Arduino, but I have a problem. In the loop() function I want to add a value to a variable, pwm, each time the loop() function is executed. I obtain that value from some function I wrote and add it to pwm with the command pwm += result, but it does not work. If I print pwm, I always get zero. Even though printing result gives me some non-zero value. The whole code is:
float pwm = 0;
float result = 0;
void loop(){
....
errV = w - cm;
errDtV = errOldV - errV;
result = flc->cog(errV, errDtV);
Serial.print("RESULT: ");
Serial.println(result);
pwm += result;
Serial.println(pwm);
}
And the output is like this:
RESULT: 31.98
0.00
What might be wrong?
EDIT: Here is the whole sketch
#include "FSet.h"
#include "FRule.h"
#include "Flc.h"
#include <NewPing.h>
#include "MotorControl.h"
MotorControl* m;
Flc* flc;
FRule* rule1,*rule2,*rule3,*rule4,*rule5,*rule6,*rule7,*rule8,*rule9;
NewPing sonar1(32,33,200);
static int dirA = 9;
static int pwmA = 8;
// Setup the FSets
FSet errZ(0,5,0);
FSet errMP(-15,15,0);
FSet errLP(-30,15,-1);
FSet errDtLN(-4,2,-1);
FSet errDtMN(-2,2,0);
FSet errDtZ(0,2,0);
FSet errDtMP(2,2,0);
FSet errDtLP(4,2,1);
FSet cntLN(-40,20,0);
FSet cntMN(-20,20,0);
FSet cntZ(0,20,0);
FSet cntMP(20,20,0);
FSet cntLP(40,20,0);
void setup(){
Serial.begin(4800);
pinMode(dirA,INPUT);
//Creating FRules for test
rule1 = new FRule(&errZ,&errDtMP,&cntMN);
rule2 = new FRule(&errZ,&errDtZ,&cntZ);
rule3 = new FRule(&errZ,&errDtMN,&cntMP);
rule4 = new FRule(&errMP,&errDtLP,&cntMN);
rule5 = new FRule(&errMP,&errDtMN,&cntMP);
rule6 = new FRule(&errLP,&errDtMP,&cntMP);
rule7 = new FRule(&errLP,&errDtZ,&cntLP);
rule8 = new FRule(&errLP,&errDtMN,&cntLP);
rule9 = new FRule(&errLP,&errDtLN,&cntLP);
flc = new Flc(9);
flc->addRule(rule1);
flc->addRule(rule2);
flc->addRule(rule3);
flc->addRule(rule4);
flc->addRule(rule5);
flc->addRule(rule6);
flc->addRule(rule7);
flc->addRule(rule8);
flc->addRule(rule9);
}
int errV = 0;
int errOldV = 0;
int errDtV = 0;
int w = 30;
unsigned int uS;
unsigned int cm;
float pwm1 = 0;
float result = 0;
void loop(){
uS = sonar1.ping();
cm = (uS / US_ROUNDTRIP_CM);
errV = w - cm;
errDtV = errOldV - errV;
result = flc->cog(errV,errDtV);
Serial.print("RESULT: ");
Serial.println(result);
pwm1 = pwm1 + result;
Serial.println(pwm1);
analogWrite(pwmA,pwm1);
errOldV = errV;
}
FLC class header file:
#ifndef FLC_H
#define FLC_H
#include "Arduino.h"
#include "FRule.h"
class Flc {
public:
Flc(int size);
~Flc();
int addRule(FRule* rule);
int mom(float x1,float x2);
float cog(float x1,float x2);
FRule** rules;
private:
int last;
int size;
float h;
float numerator = 0;
float denominator = 0;
float result = 0;
};
#endif
FLC class source:
#include "Arduino.h"
#include "Flc.h"
Flc::Flc(int size){
this->rules = (FRule**) malloc(sizeof(FRule*) * size);
this->size = size;
last = -1;
}
Flc::~Flc(){
free(rules);
}
int Flc::addRule(FRule* rule){
this->rules[++last] = rule;
return last;
}
int Flc::mom(float x1,float x2){
return 0.0;a
}
float Flc::cog(float x1, float x2){
for(int i = 0; i < size;i++){
h = rules[i]->dof(x1,x2);
float area = rules[i]->widthOfCon() * ( h - h*h/2);
numerator += rules[i]->cntrOfCon() * area;
denominator += area;
}
result = numerator / denominator;
return result;
}

Something in your function cog() is stomping on the variable pwm. Once the float variable is corrupt, Serial.print() will just show zero. The sample below shows that with the float set to 0xffffff, the floating point math library stops making any operation on the variable.
Run the sample program below and you will see that one time pwm prints correctly. After the first bad call, it prints zeros. Also the memory occupied no longer changes.
pwm=0.50 zpwm=0.50
pwm=0.00 zpwm=3.95 result=3.45
255-255-255-255
pwm=0.00 zpwm=4.45
pwm=0.00 zpwm=7.90 result=3.45
255-255-255-255
Sample program showing a function that writes to wrong memory location.
Looking at the memory map output by the linker, the variables are placed in memory in the order listed. So writing past the end of var, will corrupt pwm.
float zpwm = 0;
byte var = 0;
float pwm = 0;
float result = 0;
float badactor() {
*((long*)(&var+1)) = -1;
return 3.45;
}
void setup() {
Serial.begin(57600);
}
void loop() {
zpwm += 0.5;
pwm += 0.5;
Serial.print("pwm=");
Serial.print(pwm);
Serial.print(" zpwm=");
Serial.println(zpwm);
result = badactor();
pwm += result;
zpwm += result;
Serial.print("pwm=");
Serial.print(pwm);
Serial.print(" zpwm=");
Serial.print(zpwm);
Serial.print(" result=");
Serial.println(result);
uint8_t* ptr;
ptr = (uint8_t*)&pwm;
Serial.print((int)*(ptr));
Serial.print("-");
Serial.print((int)*(ptr+1));
Serial.print("-");
Serial.print((int)*(ptr+2));
Serial.print("-");
Serial.println((int)*(ptr+3));
delay(1000);
}

Related

C++ got wrong value from array of struct

The problem is as described above. When I try to read values from loaded *.so file (using libdl), whih are in struct I am getting wrong values
Code of application:
#include <dlfcn.h>
#include <iostream>
/* For face data type reproduction */
#define GET_FACE_XYZ_SIZE 1
/* For face_array reproduction */
#define GET_FACE_ARRAY_SIZE 2
#define GET_OBJECT_DATA 3
typedef struct face {
float x[1000];
float y[1000];
float z[1000];
int vertices;
} face;
int main()
{
void *hook;
int (*fn)(int request_type, void *ptr);
hook = dlopen("/root/osms/dlopen-test/lib.so", RTLD_LAZY);
if(!hook)
{
std::cout << "Couldn't find lib.so" << std::endl;
}
fn = dlsym(hook, "object_info");
int face_array_size = fn(GET_FACE_ARRAY_SIZE, NULL);
std::cout << "FACE_ARRAY_SIZE: " << face_array_size << std::endl;
face pointer[face_array_size];
fn(NULL, pointer);
dlclose(hook);
std::cout << "pointer[0].z[1]: " << pointer[0].z[1] << std::endl;
return 0;
}
and code of lib.so:
/* For face data type reproduction */
#define GET_FACE_XYZ_SIZE 1
/* For face array reproduction */
#define GET_FACE_ARRAY_SIZE 2
#define GET_OBJECT_DATA 3
typedef struct face {
float x[1000];
float y[1000];
float z[1000];
int vertices;
} face;
extern "C" int object_info(int request, void *ptr)
{
face face_array[2];
face_array[0].x[0] = 1.1;
face_array[0].y[0] = 0.5;
face_array[0].z[0] = 1.2;
face_array[0].x[1] = 1.6;
face_array[0].y[1] = -0.11;
face_array[0].z[1] = -12;
face_array[0].x[2] = -0.12;
face_array[0].y[2] = 0.24;
face_array[0].z[2] = -0.12;
face_array[0].vertices = 3;
face_array[1].x[0] = -1.1;
face_array[1].y[0] = 0.15;
face_array[1].z[0] = -1.2;
face_array[1].x[1] = -1.6;
face_array[1].y[1] = 0.11;
face_array[1].z[1] = 1.2;
face_array[1].x[2] = 0.12;
face_array[1].y[2] = -0.24;
face_array[1].z[2] = 0.12;
face_array[1].vertices = 3;
if(request == GET_FACE_ARRAY_SIZE)
{
return 2;
}
else
{
ptr = face_array;
}
}
The expected output is pointer[0].z[1]: -12 but I am getting pointer[0].z[1]: -0.12. What's wrong in my code ?
Thanks in advance
Accessing
pointer[0].z[1]
Has undefined behaviour, because it has an indeterminate value.
object_info never modifies the array pointed by ptr. It simply modifies a local array, and assigns the local ptr to point to that local array.
A solution: Don't declare a local array, and instead modify the array pointed by the argument. In other words, repace face face_array[2]; with:
face* face_array = (face*)ptr;
And get rid of the ptr = face_array; that does nothing meaningful.
object_info is declared to return int, but not all code paths return a value. When the function reaches the end of object_info without a return statement, the behaviour is undefined.
A solution: Always return a value if the function is not void.
face_array_size is not a compile time constant value, so face pointer[face_array_size]; will declare a variable length array. VLA are not allowed in C++.
Either use C (VLA are supported since C99, but only optionally supported since C11) instead or use a dynamic array: std::vector<face> or make peace with the fact that your program is not standard compliant.
The variable "face_array" in function object_info and the variable "pointer" in main are not the same variable.
The statement "ptr = face_array" does not change the content of "pointer".
extern "C" int object_info(int request, face *face_array)
{
if(request == GET_FACE_ARRAY_SIZE)
return 2;
face_array[0].x[0] = 1.1;
face_array[0].y[0] = 0.5;
face_array[0].z[0] = 1.2;
face_array[0].x[1] = 1.6;
face_array[0].y[1] = -0.11;
face_array[0].z[1] = -12;
face_array[0].x[2] = -0.12;
face_array[0].y[2] = 0.24;
face_array[0].z[2] = -0.12;
face_array[0].vertices = 3;
face_array[1].x[0] = -1.1;
face_array[1].y[0] = 0.15;
face_array[1].z[0] = -1.2;
face_array[1].x[1] = -1.6;
face_array[1].y[1] = 0.11;
face_array[1].z[1] = 1.2;
face_array[1].x[2] = 0.12;
face_array[1].y[2] = -0.24;
face_array[1].z[2] = 0.12;
face_array[1].vertices = 3;
}

Array of object C++

In the image below (Character.cpp), may I know how to create only one Initialize method that can be called to stored many sprites? Do I need to change the Texture1,Sprite,PosX,PosY, etc to array?
The initialize method will be called in my MAIN.cpp. Sorry if the explaination is not good enough. That is just my idea of doing it but will there be a better ones instead of having so many arrays?
void Character::Initialize1(string image1, float PosX1, float PosY1, float CenterX1, float CenterY1)
{
D3DXCreateTextureFromFile(Pull->GETd3ddev(), image.c_str(), &Texture1);
D3DXCreateSprite(Pull->GETd3ddev(), &sprite1);
RECT SpriteRect1;
SpriteRect1.top = 0;
SpriteRect1.bottom = 127;
SpriteRect1.left = 0;
SpriteRect1.right = 128;
SpritePos1 = D3DXVECTOR2(PosX1, PosY1);
SpriteCenter1 = D3DXVECTOR2(CenterX1, CenterY1);
}
void Character::Initialize2(string image2, float PosX2, float PosY2, float CenterX2, float CenterY2)
{
D3DXCreateTextureFromFile(Pull->GETd3ddev(), image.c_str(), &Texture2);
D3DXCreateSprite(Pull->GETd3ddev(), &sprite2);
RECT SpriteRect2;
SpriteRect2.top = 0;
SpriteRect2.bottom = 14;
SpriteRect2.left = 0;
SpriteRect2.right = 14;
SpritePos2 = D3DXVECTOR2(PosX2, PosY2);
SpriteCenter2 = D3DXVECTOR2(CenterX2, CenterY2);
}
Create the necessary initialization method in your sprite class. Then in main() create your sprites and call the appropriate initialization methods. If using lots of Sprites, it will be probably handy to put the created sprites inside a vector in order to have less code for cleanup and probably other things.
A quick example for a Sprite class called SpriteConfig, which only contains position parameters.
#include <iostream>
#include <vector>
using namespace std;
class SpriteConfig {
public:
SpriteConfig() {
top = 0;
bottom = 0;
left = 0;
right = 0;
}
void setPos(float aTop, float aBottom, float aLeft, float aRight) {
mTop = aTop;
mBottom = aBottom;
mLeft = aLeft;
mRight = aRight;
}
private:
// position parameters
float mTop;
float mBottom;
float mLeft;
float mRight;
};
int main()
{
vector<SpriteConfig*> spriteConfigs;
SpriteConfig *sprCfg;
sprCfg = new SpriteConfig();
sprCfg->setPos(1,1,1,1);
spriteConfigs.push_back(sprCfg);
sprCfg = new SpriteConfig();
sprCfg->setPos(2,2,2,2);
spriteConfigs.push_back(sprCfg);
// We now have a number of Sprites
// Add code here to do something with it.
// ...
for(vector<SpriteConfig*>::iterator it = spriteConfigs.begin();
it != spriteConfigs.end();
++it) {
// cleanup
delete (*it);
(*it) = null;
}
return 0;
}

Access Object attributes in C++ [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 8 years ago.
Improve this question
I am relatively new to C++ programming and I have done a code which is not performing as expected.
The code is a bit long [pasted at end for reference] but I will just point to my concern in the code:
I define an object of a class inside a while loop:
...
objVec[obj_i] = new ChipSeqRegion(refID, strand, midPoint, start, end, posArray, frac_posArray, negArray, frac_negArray);
//testing
cout<<"printing object number: "<<obj_i<<endl;
objVec[obj_i]->PrintID();
cout<<"printing frac pos array: "<<endl;
objVec[obj_i]->PrintFracPosArray();
obj_i++;
}
objVec[0]->PrintID();
cout<<endl;
objVec[0]->PrintFracPosArray();
cout<<endl;
objVec[1]->PrintID();
objVec[1]->PrintFracPosArray();
cout<<endl;
objVec[2]->PrintID();
objVec[2]->PrintFracPosArray();
}
In the above code fragment PrintID and PrintFracPosArray are just procedures[members of same class] to print contents of the variables/Arrays.
Now, If I try to print the object attributes refID and posArray inside the loop then all printed values come out different and as assigned and expected.
But outside the loop the printID attribute prints values uniquely [as expected] but posArray attributes just repeat the value last assigned in the loop.
I want to access all values uniquely outside the loop which is my concern.
I am sure this might be from a scope conflict or the way the variables are getting passed.
Any help will be great !!!
Thanks in advance.
A quick look on detailed code below can clarify any questions:
Detailed Code:[Apologies for bad presentation]
#include <iostream>
#include <string>
#include <fstream>
#include <cstring>
#include <sstream>
#include <cstdlib>
#include <vector>
#include <iomanip>
#include <cmath>
#include "api/BamReader.h"
#include "api/BamWriter.h"
#include "api/BamAlignment.h"
#include "api/BamAux.h"
using namespace std;
using namespace BamTools;
BamReader reader;
BamAlignment al;
int const windowSize = 10;
int halfWindowSize = windowSize/2;
int const N = windowSize + 1;
//determine the gap score
float gap = -2;
//default value for matrix F
double negNum = -100000;
float F[N][N];
int xTraceBack[N][N];
int yTraceBack[N][N];
float maxScore;
int x_coord = 0;
int y_coord = 0;
//collections of arrays from chipSeq data after loading data
class ChipSeqRegion{
private:
int ref_id, mid_p, start_p, end_p;
char genomeStrand;
float* pos_array;
float* frac_positiveArray;
float* neg_array;
float* frac_negativeArray;
float* gap;
public:
ChipSeqRegion (int refID, char strand, int midPoint, int start, int end, float* posArray, float* frac_posArray, float* negArray, float* frac_negArray);
//accessors
int GetRefID(){return ref_id;}
int GetMidPoint(){return mid_p;}
void PrintID();
void PrintFracPosArray();
//destructor
~ChipSeqRegion(){
delete [] pos_array;
delete [] frac_positiveArray;
delete [] neg_array;
delete [] frac_negativeArray;
}
};
ChipSeqRegion::ChipSeqRegion(int refID, char strand, int midPoint, int start, int end, float* posArray, float* frac_posArray, float* negArray, float* frac_negArray){
ref_id = refID;
genomeStrand = strand;
mid_p = midPoint;
start_p = start;
end_p = end;
pos_array = posArray;
frac_positiveArray = frac_posArray;
neg_array = negArray;
frac_negativeArray = frac_negArray;
}
void ChipSeqRegion::PrintID(){
cout<<"ref id is: "<<ref_id<<endl;
}
void ChipSeqRegion::PrintFracPosArray(){
cout<<"this is raw pos data"<<endl;
for (int i = 0; i<windowSize; i++){
cout<<pos_array[i]<<'\t';
}
cout<<"this is frac data"<<endl;
for (int i = 0; i<windowSize; i++){
cout<<frac_positiveArray[i]<<'\t';
}
cout<<endl;
}
class ChipSeqLoader{
public:
void LoadData (string bamFileName, string coordFileName);
void GetRegions();
private:
string nameOfBamFile;
string nameOfCoordFile;
};
void ChipSeqLoader::LoadData(string bamFileName, string coordFileName){
nameOfBamFile = bamFileName;
nameOfCoordFile = coordFileName;
int obj_i = 0;
int objSize = 6;
ChipSeqRegion **objVec = new ChipSeqRegion* [objSize];
//reading coordinates
ifstream CoordFile;
char chrom[5], strand;
string sChr1, sChr2, withmotif, dot;
int start, end, midPoint;
float tag;
CoordFile.open(coordFileName.c_str());
if (CoordFile.is_open()){
while (!CoordFile.eof()){
CoordFile>>chrom;
CoordFile>>withmotif;
CoordFile>>dot;
CoordFile>>start;
CoordFile>>end;
CoordFile>>tag;
CoordFile>>strand;
CoordFile.ignore(200,'\n');
midPoint = (start+end)/2;
ostringstream convert1;
ostringstream convert2;
convert1<<chrom[3];
convert2<<chrom[4];
sChr1 = convert1.str();
sChr2 = convert2.str();
string sChrom;
sChrom = sChr1+sChr2;
int refID;
if (sChr1 =="X\0"){
refID = 19;
}else if (sChr1 == "Y\0"){
refID = 20;
}else{
refID = atoi(sChrom.c_str())-1;
}
int intStrand;
if (strand == '+'){
intStrand = 0;
}else if (strand == '-'){
intStrand = 1;
}
cout<<endl;
cout<<sChrom<<'\t'<<refID<<'\t'<<start<<'\t'<<end<<'\t'<<midPoint<<'\t'
<<strand<<'\t'<<intStrand<<endl;
//get information from the coordinates to return array
BamRegion region(refID, midPoint-600, refID, midPoint+600);
reader.SetRegion(region);
if(!reader.SetRegion(region)){
std::cout<<"could not set region."<<endl;
}
float posArray[windowSize];
float negArray[windowSize];
float frac_posArray[windowSize];
float frac_negArray[windowSize];
for (int index = 0; index < windowSize; index ++){
posArray[index] = 0;
negArray[index] = 0;
}
int posPosition;
int negPosition;
//if reverse strand, calculate and return the end position
//if positive strand, return the position
//put them in separate arrays
while (reader.GetNextAlignment(al)){
if (al.MapQuality>0 && al.IsReverseStrand()== true){
negPosition = al.GetEndPosition();
if (negPosition>=midPoint-halfWindowSize && negPosition <midPoint+halfWindowSize){
negArray[negPosition-midPoint+halfWindowSize]++;
}
}else if (al.MapQuality>0){
posPosition = al.Position;
if (posPosition>=midPoint-halfWindowSize && posPosition <midPoint+halfWindowSize){
posArray[posPosition-midPoint+halfWindowSize]++;
}
}
}
float posMax = 0, negMax = 0, max = 0;
float temp;
for (int i= 0; i<windowSize; i++){
temp = posArray[i];
if (temp>posMax){
posMax = temp;
}
}
for (int i = 0; i<windowSize; i++){
temp = negArray[i];
if (temp>negMax){
negMax = temp;
}
}
if (posMax>=negMax){
max = posMax;
}else{
max = negMax;
}
for (int i = 0; i<windowSize; i++){
frac_posArray[i] = posArray[i]/max;
frac_negArray[i] = negArray[i]/max;
}
objVec[obj_i] = new ChipSeqRegion(refID, strand, midPoint, start, end, posArray, frac_posArray, negArray, frac_negArray);
//testing
cout<<"printing object number: "<<obj_i<<endl;
objVec[obj_i]->PrintID();
cout<<"printing frac pos array: "<<endl;
objVec[obj_i]->PrintFracPosArray();
obj_i++;
}
objVec[0]->PrintID();
cout<<endl;
objVec[0]->PrintFracPosArray();
cout<<endl;
objVec[1]->PrintID();
objVec[1]->PrintFracPosArray();
cout<<endl;
objVec[2]->PrintID();
objVec[2]->PrintFracPosArray();
}
}
int main(int argc, char* argv[]) {
string bamFileName, coordFileName;
if (argc == 3){
bamFileName = argv[1];
coordFileName = argv[2];
}else{
std::cout << "Wrong number of arguments." <<endl;
return 1;
}
if (!reader.Open(bamFileName)){
std::cout<< "Could not open input Bam file." <<endl;
return 1;
}
if (!reader.LocateIndex()){
std::cout<<"Could not locate index file."<<endl;
return 1;
}
ChipSeqLoader loader;
loader.LoadData(bamFileName, coordFileName);
return 0;
}
All your objects point to the same piece of data, namely posArray and frac_posArray which are defined in the loop: if you look at the ChipSeqRegion class constructor, it accepts 2 arrays (with the very same names as the arrays cited above), ie. 2 pointers to sequences of data in memory. These pointers in the constructors are simply copied over in the instance fields:
pos_array = posArray;
frac_positiveArray = frac_posArray;
instead of copying the array contents, as it should probably be:
pos_array = new int[windowSize];
memcpy(pos_array,posArray, sizeof(int)*windowSize); // or use std::copy_n
frac_positiveArray = new int[windowSize];
memcpy(frac_positivearray,frac_posArray, sizeof(int)*windowSize); // or use std::copy_n
You probably will have the same issue with other arrays in the class.

Pointer address changed - function

I have this code:
class pointLineVCN
{
public:
int v, vc, vn;
pointLineVCN(){};
pointLineVCN(int v, int vc, int vn)
{
this->v = v;
this ->vc = vc;
this->vn = vn;
}
};
pointLineVCN* newPoint;
void Triangulation3D(pointLineVCN* point, short numOfPoints)
{
newPoint = new pointLineVCN[(numOfPoints - 2) * 3];
//Code which changes newPoint
point = newPoint;
cout<<point<<endl;
}
And on the main:
pointLineVCN *vertices = new pointLineVCN[meshes[meshNum].face[*positionSaverFN].numOfPoints];
for (int i = 0; i < meshes[meshNum].face[*positionSaverFN].numOfPoints; i++)
{
sscanf(bufferStr.c_str(), "%i/%i/%i", &faceVec, &faceTex, &faceNor);
vertices[i].v = faceVec - 1;
vertices[i].vc = faceTex - 1;
vertices[i].vn = faceNor - 1;
}
Triangulation3D(vertices, meshes[meshNum].face[*positionSaverFN].numOfPoints);
cout<<vertices<<endl;
The problem is point address changes after Triangulation3D ends. On the cout calls the output is two different addresses.
I have seen another question about this problem and the solution is using pointLineVCN** point but it did not helped.
It's changing because you're changing it:
point = newPoint;
if you don't want to change it, then don't do it.

Can't return anything other than 1 or 0 from int function

I wish my first post wasn't so newbie. I've been working with openframeworks, so far so good, but as I'm new to programming I'm having a real headache returning the right value from an int function. I would like the int to increment up until the Boolean condition is met and then decrement to zero. The int is used to move through an array from beginning to end and then back. When I put the guts of the function into the method that I'm using the int in, everything works perfectly, but very messy and I wonder how computationally expensive it is to put there, it just seems that my syntactic abilities are lacking to do otherwise. Advice appreciated, and thanks in advance.
int testApp::updown(int j){
if(j==0){
arp =true;
}
else if (j==7){
arp = false;
}
if(arp == true){
j++;
}
else if(arp == false){
j--;
}
return (j);
}
and then its called like this in an audioRequest block of the library I'm working with:
for (int i = 0; i < bufferSize; i++){
if ((int)timer.phasor(sorSpeed)) {
z = updown(_j);
noteOut = notes [z];
cout<<arp;
cout<<z;
}
EDIT: For addition of some information. Removed the last condition of the second if statement, it was there because I was experiencing strange happenings where j would start walking off the end of the array.
Excerpt of testApp.h
int z, _j=0;
Boolean arp;
EDIT 2: I've revised this now, it works, apologies for asking something so rudimentary and with such terrible code to go with. I do appreciate the time that people have taken to comment here. Here are my revised .cpp and my .h files for your perusal. Thanks again.
#include "testApp.h"
#include <iostream>
using namespace std;
testApp::~testApp() {
}
void testApp::setup(){
sampleRate = 44100;
initialBufferSize = 1024;
//MidiIn.openPort();
//ofAddListener(MidiIn.newMessageEvent, this, &testApp::newMessage);
j = 0;
z= 0;
state = 1;
tuning = 440;
inputNote = 127;
octave = 4;
sorSpeed = 2;
freqOut = (tuning/32) * pow(2,(inputNote-69)/12);
finalOut = freqOut * octave;
notes[7] = finalOut+640;
notes[6] = finalOut+320;
notes[5] = finalOut+160;
notes[4] = finalOut+840;
notes[3] = finalOut+160;
notes[2] = finalOut+500;
notes[1] = finalOut+240;
notes[0] = finalOut;
ofSoundStreamSetup(2,0,this, sampleRate, initialBufferSize, 4);/* Call this last ! */
}
void testApp::update(){
}
void testApp::draw(){
}
int testApp::updown(int &_j){
int tmp;
if(_j==0){
arp = true;
}
else if(_j==7) {
arp = false;
}
if(arp == true){
_j++;
}
else if(arp == false){
_j--;
}
tmp = _j;
return (tmp);
}
void testApp::audioRequested (float * output, int bufferSize, int nChannels){
for (int i = 0; i < bufferSize; i++){
if ((int)timer.phasor(sorSpeed)) {
noteOut = notes [updown(z)];
}
mymix.stereo(mySine.sinewave(noteOut),outputs,0.5);
output[i*nChannels ] = outputs[0];
output[i*nChannels + 1] = outputs[1];
}
}
testApp.h
class testApp : public ofBaseApp{
public:
~testApp();/* destructor is very useful */
void setup();
void update();
void draw();
void keyPressed (int key);
void keyReleased(int key);
void mouseMoved(int x, int y );
void mouseDragged(int x, int y, int button);
void mousePressed(int x, int y, int button);
void mouseReleased(int x, int y, int button);
void windowResized(int w, int h);
void dragEvent(ofDragInfo dragInfo);
void gotMessage(ofMessage msg);
void newMessage(ofxMidiEventArgs &args);
ofxMidiIn MidiIn;
void audioRequested (float * input, int bufferSize, int nChannels); /* output method */
void audioReceived (float * input, int bufferSize, int nChannels); /* input method */
Boolean arp;
int initialBufferSize; /* buffer size */
int sampleRate;
int updown(int &intVar);
/* stick you maximilian stuff below */
double filtered,sample,outputs[2];
maxiFilter filter1;
ofxMaxiMix mymix;
ofxMaxiOsc sine1;
ofxMaxiSample beats,beat;
ofxMaxiOsc mySine,myOtherSine,timer;
int currentCount,lastCount,i,j,z,octave,sorSpeed,state;
double notes[8];
double noteOut,freqOut,tuning,finalOut,inputNote;
};
It's pretty hard to piece this all together. I do think you need to go back to basics a bit, but all the same I think I can explain what is going on.
You initialise _j to 0 and then never modify the value of _j.
You therefore call updown passing 0 as the parameter every time.
updown returns a value of 1 when the input is 0.
Perhaps you meant to pass z to updown when you call it, but I cannot be sure.
Are you really declaring global variables in your header file? That's not good. Try to use local variables and/or parameters as much as possible. Global variables are pretty evil, especially declared in the header file like that!