// // SonificationEngine.cpp // SoniScan_2_0 // // Created by Hariharan Mohanraj on 4/15/13. // Copyright (c) 2013 Hariharan Mohanraj. All rights reserved. // #include "SonificationEngine.h" // =================================== // GETTERS AND SETTERS // =================================== void SonificationEngine::SetDataFilename(char* argDataFilename) { strcpy(dataFilename, argDataFilename); } int SonificationEngine::GetMode() { return mode; } void SonificationEngine::SetMode(int argMode) { if (argMode < 1 || argMode > NUM_MODES) { std::cout << "Invalid mode. SetMode() call ignored.\n"; return; } mode = argMode; } // ---------------------------------- int SonificationEngine::GetScan() { return scan; } void SonificationEngine::SetScan(int argScan) { if (argScan < 0 || argScan > NUM_SCANS-1) { std::cout << "Invalid scan number. SetScan() call ignored.\n"; return; } scan = argScan; } // ---------------------------------- int SonificationEngine::GetSlice() { return slice; } void SonificationEngine::SetSlice(int argSlice) { if (argSlice < 0 || argSlice > masterDataSize[2]) { std::cout << "Invalid scan number. SetSlice() call ignored.\n"; return; } slice = argSlice; } // ---------------------------------- int SonificationEngine::GetInstr() { return instr; } void SonificationEngine::SetInstr(int argInstr) { if (argInstr < 0 || argInstr > NUM_INSTR) { std::cout << "Invalid instr number. SetInstr() call ignored.\n"; return; } instr = argInstr; } // ---------------------------------- int SonificationEngine::GetOutput() { return output; } void SonificationEngine::SetOutput(int argOutput) { if (argOutput < 0 || argOutput >= NUM_OUTPUTS) { std::cout << "Invalid output number. SetOutput() call ignored.\n"; return; } output = argOutput; } // ---------------------------------- float SonificationEngine::GetInstrBoundary(int argIndex) { if (argIndex < 0 || argIndex >= NUM_INSTR+1) { std::cout << "Invalid index. -1 returned by default.\n"; return -1; } return instrBoundaries[argIndex]; } void SonificationEngine::SetInstrBoundary(float argValue,int argIndex) { if (argValue < 0 || argValue > 1) { std::cout << "Invalid value. SetInstrBoundary() call ignored.\n"; return; } if (argIndex < 0 || argIndex >= NUM_INSTR+1) { std::cout << "Invalid index. SetInstrBoundary() call ignored.\n"; return; } instrBoundaries[argIndex] = argValue; } float SonificationEngine::GetCenterFreq() { return centerFreq; } void SonificationEngine::SetCenterFreq(float argCenterFreq) { if (argCenterFreq <= 0) { std::cout << "Center frequency must be positive. SetCenterFreq() call ignored.\n"; return; } centerFreq = argCenterFreq; } float SonificationEngine::GetDetuneFactor() { return detuneFactor; } void SonificationEngine::SetDetuneFactor(float argDetuneFactor) { detuneFactor = argDetuneFactor; } // ---------------------------------- void SonificationEngine::SetMasterData(float*** argMasterData, int argMasterDataSize[]) { masterData = argMasterData; masterDataSize[0] = argMasterDataSize[0]; masterDataSize[1] = argMasterDataSize[1]; masterDataSize[2] = argMasterDataSize[2]; } // ============================== // SONIFICATION UTILITY FUNCTIONS // ============================== bool SonificationEngine::PointUpLine(int x, int y, int x1, int y1, int x2, int y2) { return (y > y1 + (x-x1)*(y2-y1)/(x2-x1)); } bool SonificationEngine::PointRightLine(int x, int y, int x1, int y1, int x2, int y2) { return (x > x1 + (y-y1)*(x2-x1)/(y2-y1)); } int SonificationEngine::GetInstrNum(float argValue) { for (int i=1; i MIDLINE) { // x = 2*MIDLINE - x; // } // Frontal Lobe if (!PointUpLine(x,y,QX,QY,PX,PY) && !PointRightLine(x,y,QX,QY,NX,NY)) { return 1; } // Sensory Motor Cortex if (!PointUpLine(x,y,QX,QY,PX,PY) && PointRightLine(x,y,QX,QY,NX,NY) && !PointRightLine(x,y,PX,PY,OX,OY)) { return 2; } // Parietal Lobe if (!PointUpLine (x,y,QX,QY,PX,PY) && PointRightLine(x,y,PX,PY,OX,OY)) { return 3; } } else if (std::abs(FPSLICE-slice) < std::abs(TOSLICE-slice)) { // Frontal Parietal slice // Frontal lobe if (!PointUpLine(x,y,AX,AX,BX,BY) && !PointUpLine(x,y,BX,BY,HX,HY) && !PointUpLine(x,y,HX,HY,EX,EY)) { return 1; } // Sensory Motor Cortex if ( (PointUpLine(x,y,AX,AX,BX,BY) && !PointUpLine(x,y,DX,DY,CX,CY) && !PointRightLine(x,y,BX,BY,CX,CY) ) || (PointUpLine(x,y,HX,HY,EX,EY) && !PointUpLine(x,y,GX,GY,FX,FY) && PointRightLine(x,y,HX,HY,GX,GY) ) ) { return 2; } // Parietal Lobe if (PointUpLine(x,y,DX,DX,CX,CY) || PointUpLine(x,y,CX,CY,GX,GY) || PointUpLine(x,y,GX,GY,FX,FY)) { return 3; } } else { // Temporal Occipital slice // Occipital Lobe if (PointUpLine(x,y,IX,IY,JX,JY) && PointUpLine(x,y,LX,LY,MX,MY) && ! (!PointUpLine(x,y,JX,JY,KX,KY) && !PointUpLine(x,y,KX,KY,LX,LY)) ) { return 5; } // Temporal Lobe if ( ( !PointUpLine(x,y,IX,IY,JX,JY) && !PointRightLine(x,y,JX,JY,JX,JY+1) ) || (!PointUpLine(x,y,LX,LY,MX,MY) && PointRightLine(x,y,LX,LY,LX,LY+1)) ) { return 4; } } return 0; } void SonificationEngine::UpdateSliceSize() { int flag; // ------------------- // Find width of slice // ------------------- // Starting from left, find first column with valid datapoints flag = 0; for (int x=0; x=0 && flag==0; x--) { for (int y=0; y=0 && flag==0; y--) { for (int x=0; x NUM_SCANS-1) { std::cout << "Error. Current scan value is invalid. SonifySelect() call ignored.\n"; break; } if (slice < 0 || slice > masterDataSize[2]) { std::cout << "Error. Current slice value is invalid. SonifySelect() call ignored.\n"; break; } ModeOneSonify(); break; case 2: if (scan < 0 || scan > NUM_SCANS-1) { std::cout << "Error. Current scan value is invalid. SonifySelect() call ignored.\n"; break; } if (slice < 0 || slice > masterDataSize[2]) { std::cout << "Error. Current slice value is invalid. SonifySelect() call ignored.\n"; break; } ModeTwoSonify(); break; case 3: if (scan < 0 || scan > NUM_SCANS-1) { std::cout << "Error. Current scan value is invalid. SonifySelect() call ignored.\n"; break; } if (slice < 0 || slice > masterDataSize[2]) { std::cout << "Error. Current slice value is invalid. SonifySelect() call ignored.\n"; break; } ModeThreeSonify(); break; default: std::cout << "Error. Current mode value is invalid. SonifySelect() call ignored.\n"; break; } } // ========================================================================= // // MODE ONE SONIFY // // ========================================================================= void SonificationEngine::ModeOneSonify() { int instrCount[NUM_INSTR]; for (int i=0; i std::abs(slice-29)) { for (int y=sliceHeightD; y <= sliceHeightU; y++) { for (int x=sliceWidthL; x <= sliceWidthR; x++) { localInstr = GetLobe(x,y); if (localInstr != 0 && masterData[x][y][slice] > TRIM_THRESHOLD) { localInstr = (localInstr-1)%3; if (x < ORTHOGL_MIDLINE) { averageArrayL[localInstr] += masterData[x][y][slice]; countArrayL[localInstr]++; } else { averageArrayR[localInstr] += masterData[x][y][slice]; countArrayR[localInstr]++; } } } } } else { for (int y=sliceHeightD; y <= sliceHeightU; y++) { for (int x=sliceWidthL; x <= sliceWidthR; x++) { if (x < PERSPEC_MIDLINE) { localInstr = GetLobe(x,y); if (localInstr != 0 && masterData[x][y][slice] > TRIM_THRESHOLD) { localInstr = (localInstr-1)%3; averageArrayL[localInstr] += masterData[x][y][slice]; countArrayL[localInstr]++; } } else { localInstr = GetLobe(2*PERSPEC_MIDLINE-x,y); if (localInstr != 0 && masterData[x][y][slice] > TRIM_THRESHOLD) { localInstr = (localInstr-1)%3; averageArrayR[localInstr] += masterData[x][y][slice]; countArrayR[localInstr]++; } } } } } for (int i=0; i<3; i++) { averageArrayL[i] /= countArrayL[i]; averageArrayR[i] /= countArrayR[i]; std::cout << averageArrayL[i] << "\t" << averageArrayR[i] << "\n"; } // Standard Deviation // ------------------ if (std::abs(slice - 0) > std::abs(slice-29)) { for (int y=sliceHeightD; y <= sliceHeightU; y++) { for (int x=sliceWidthL; x <= sliceWidthR; x++) { localInstr = GetLobe(x,y); if (localInstr != 0 && masterData[x][y][slice] > TRIM_THRESHOLD) { localInstr = (localInstr-1)%3; if (x < ORTHOGL_MIDLINE) { stdDevArrayL[localInstr] += (masterData[x][y][slice]-averageArrayL[localInstr]) * (masterData[x][y][slice]-averageArrayL[localInstr]); } else { stdDevArrayR[localInstr] += (masterData[x][y][slice]-averageArrayR[localInstr]) * (masterData[x][y][slice]-averageArrayR[localInstr]); } } } } } else { for (int y=sliceHeightD; y <= sliceHeightU; y++) { for (int x=sliceWidthL; x <= sliceWidthR; x++) { if (x < PERSPEC_MIDLINE) { localInstr = GetLobe(x,y); if (localInstr != 0 && masterData[x][y][slice] > TRIM_THRESHOLD) { localInstr = (localInstr-1)%3; stdDevArrayL[localInstr] += (masterData[x][y][slice]-averageArrayL[localInstr]) * (masterData[x][y][slice]-averageArrayL[localInstr]); } } else { localInstr = GetLobe(2*PERSPEC_MIDLINE-x,y); if (localInstr != 0 && masterData[x][y][slice] > TRIM_THRESHOLD) { localInstr = (localInstr-1)%3; stdDevArrayR[localInstr] += (masterData[x][y][slice]-averageArrayR[localInstr]) * (masterData[x][y][slice]-averageArrayR[localInstr]); } } } } } for (int i=0; i<3; i++) { stdDevArrayL[i] = pow(stdDevArrayL[i]/countArrayL[i], 0.5); stdDevArrayR[i] = pow(stdDevArrayR[i]/countArrayR[i], 0.5); std::cout << stdDevArrayL[i] << "\t" << stdDevArrayR[i] << "\n"; } for (int i=0; i<3; i++) { std::cout << countArrayL[i] << "\t" << countArrayR[i] << "\n"; } // ----------------------------- // Generate lines // ----------------------------- char fileLine[MAX_SCORELINE_LENGTH]; char flagLine[MAX_SCORELINE_LENGTH]; char commandLine[2*MAX_SCORELINE_LENGTH]; GenerateLines(fileLine,flagLine,commandLine); // ----------------------------- // Open score file pointer // ----------------------------- std::cout << "Opening : " << fileLine << "\n"; std::ofstream scoreFile; scoreFile.open(fileLine, std::ios::trunc); WriteHeader(scoreFile); std::ifstream scdOsc; std::string scdOscStr; if (averageArrayL[1] == 0) { averageArrayL[1] = 1; } if (averageArrayR[1] == 0) { averageArrayR[1] = 1; } for (int i=0; i<3; i++) { devL[i] = (averageArrayL[i]-averageArrayL[1]) / averageArrayL[1]; devR[i] = (averageArrayR[i]-averageArrayR[1]) / averageArrayR[1]; } for (int i=0; i<3; i++) { freqArrayL[i] = centerFreq * ( 1 + detuneFactor*devL[i]); freqArrayR[i] = centerFreq * ( 1 + detuneFactor*devR[i]); std::cout << "Calculated freq " << i << " : " << freqArrayL[i] << "\t" << freqArrayR[i] << "\n"; } scoreFile << "~bF = " << (devL[0]+devR[0])/2 << ";\n"; scoreFile << "~bMC = " << (devL[1]+devR[1])/2 << ";\n"; scoreFile << "~bP = " << (devL[2]+devR[2])/2 << ";\n"; scoreFile << "~lF = " << devL[0] << ";\n"; scoreFile << "~lMC = " << devL[1] << ";\n"; scoreFile << "~lP = " << devL[2] << ";\n"; scoreFile << "~rF = " << devR[0] << ";\n"; scoreFile << "~rMC = " << devR[1] << ";\n"; scoreFile << "~rP = " << devR[2] << ";\n"; scoreFile << "~output = \"" << bareOutputFile << "\";\n"; WriteFooter(scoreFile); scoreFile.close(); WriteToLog(fileLine, averageArrayL, averageArrayR, stdDevArrayL, stdDevArrayR); DisplayDiagnostics(fileLine, flagLine, commandLine, instrCount); } // ========================================================================= // // MODE TWO SONIFY // // ========================================================================= void SonificationEngine::ModeTwoSonify() { float value; int instrCount[NUM_INSTR]; for (int i=0; i (pow(2,DATA_BITDEPTH) - 1) * instrBoundaries[0] && masterData[x][y][slice] < (pow(2,DATA_BITDEPTH) - 1) * instrBoundaries[NUM_INSTR]) { value = masterData[x][y][slice]; currInstr = GetInstrNum(value); UpdateScoreLine((float)(x - sliceWidthL)/(float)sliceWidth, (float)(y - sliceHeightD)/(float)sliceHeight, value); switch (output) { case 0: std::sprintf(scoreLine, "i%d %f %f %d %f %d %f\n", currInstr, startTime, duration, noteIndex, amplitude, currInstr, panValue); scoreFile << scoreLine; break; case 1: std::sprintf(scoreLine, "i%d %f %f %d %d %d %d\n", currInstr, startTime, duration, noteIndex, midiVelocity, currInstr, midiPan); scoreFile << scoreLine; break; default: break; } instrCount[currInstr-1]++; // --------------------------------------------------- // TEMPO/DURATION VARIATION NEEDS TO BE INCLUDED HERE. // --------------------------------------------------- // duration *= pow(2,NUM_INSTR) / pow(2,currInstr-1); // // for (int i=0; i