#include #include #include using namespace std; double ForceRange(double NewRange, double ExistingRange, double Value); // CLASSES // Line points class clLineBox { // Dimensions of box unsigned int Y1; unsigned int Y2; unsigned int X1; unsigned int X2; unsigned int XRange; unsigned int YRange; unsigned int YCenter; unsigned int BorderThickness; unsigned int LineColour; unsigned int BorderColour; unsigned int BackgroundColour; // Array containing line points int * LinePoint; public: // Constructor clLineBox(int pY1, int pY2, int pX1, int pX2, int pBorderThickness, unsigned int pLineColour, unsigned int pBorderColour, unsigned int pBackgroundColour) { Y1 = pY1; Y2 = pY2; X1 = pX1; X2 = pX2; BorderThickness = pBorderThickness; LineColour = pLineColour; BorderColour = pBorderColour; BackgroundColour = pBackgroundColour; YRange = Y2-Y1; XRange = X2-X1; YCenter = Y1+(YRange/2); LinePoint = new int[XRange]; for(unsigned int n = 0;n XRange) { Size = XRange; } // 16 bits = 2 bytes if(BitsPerSample == 16) { Size = Size/2; } // Shift bytes down to make new space for(unsigned int n = 0;n(Calculation); } else { // Get sound data LinePoint[n] = mnGetShortInt(SoundData); // Make wave positive int iLinePoint = LinePoint[n] += SHRT_MAX; // The following will ensure that values are kept within the box and scaled appropriately // Convert to double for calculation double dNewRange = YRange; double dValue = iLinePoint; double Calculation = ForceRange(dNewRange, USHRT_MAX, dValue); LinePoint[n] = static_cast(Calculation); } // Ensure line is far enough down the screen LinePoint[n] += Y1; } } }; // Volume box information class clVolumeBox { int X1; int Y1; int X2; int Y2; int BoxWidth; int BoxHeight; int BorderThickness; int BarLevel; static const int i8Sensitivity = 3; static const int i16Sensitivity = 2; unsigned int BarColour; unsigned int BorderColour; unsigned int BackgroundColour; public: // Constructor clVolumeBox(int pY1, int pY2, int pX1, int pX2, int pBorderThickness, unsigned int pBarColour, unsigned int pBorderColour, unsigned int pBackgroundColour) { Y1 = pY1; Y2 = pY2; X1 = pX1; X2 = pX2; BorderThickness = pBorderThickness; BoxWidth = X2 - X1; BoxHeight = Y2 - Y1; BarColour = pBarColour; BorderColour = pBorderColour; BackgroundColour = pBackgroundColour; } // Set display void SetLevel(long long int SoundData, unsigned short BitsPerSample) { // Get average volume of sound int SoundVolume = mnGetDataVolume(BitsPerSample,SoundData); // Convert to double for calculation double dNewRange = BoxHeight; double dValue = SoundVolume; // Determine height of bar double dHeight; if(BitsPerSample == 8) { dHeight = ForceRange(dNewRange,UCHAR_MAX/i8Sensitivity,dValue); } else { // Determine height of bar dHeight = ForceRange(dNewRange, SHRT_MAX/i16Sensitivity, dValue); } BarLevel = static_cast(dHeight); } // Update display void UpdateDisplay() { // Background dbInk(BackgroundColour,dbRGB(0,0,0)); dbBox(X1, Y1, X2, Y2); // Border dbInk(BorderColour,dbRGB(0,0,0)); dbBox(X1-BorderThickness, Y1, X1, Y2+BorderThickness); // Left vertical line dbBox(X1-BorderThickness, Y1-BorderThickness, X2+BorderThickness, Y1); // Top horizontal line dbBox(X1, Y2, X2, Y2+BorderThickness); // Bottom horizontal line dbBox(X2, Y1, X2+BorderThickness, Y2+BorderThickness); // Right vertical line // Bar int DrawLevel; if(BarLevel > BoxHeight) { DrawLevel = BoxHeight; } else { DrawLevel = BarLevel; } dbInk(BarColour,dbRGB(0,0,0)); dbBox(X1,Y1+(BoxHeight-DrawLevel),X2,Y2); } }; // GLOBAL VARIABLES const unsigned int ScreenWidth = 800, ScreenHeight = 600; // Border is the width of the line surrounding objects // Padding is the distance from the edge of the screen const unsigned int Border = 3, Padding = 5, FullOffset = Border+Padding, BottomSize = 25*6; // Line box const unsigned int LineBoxTitleX = 95+Padding, LineBoxTitleY = Padding; char * LineBoxTitleText = "VISUAL REPRESENTATION OF SOUND WAVE"; clLineBox BaseLineBox(20+FullOffset, ScreenHeight-FullOffset-BottomSize, 100, ScreenWidth-FullOffset, Border, dbRGB(255, 0, 0), dbRGB(255,255,255), dbRGB(64, 0, 64)); // Volume box const unsigned int VolumeBoxTitleX = Padding, VolumeBoxTitleY = Padding; char * VolumeBoxTitleText = "VOLUME"; clVolumeBox VolumeBox(20+FullOffset, ScreenHeight-FullOffset-BottomSize, FullOffset, 65+FullOffset, Border, dbRGB(0, 255, 64), dbRGB(255,255,255), dbRGB(64, 0, 64)); // Text at bottom of window const unsigned int BottomX = FullOffset, BottomY = ScreenHeight-BottomSize; // FUNCTIONS // Converts Value so that it fits within NewRange double ForceRange(double NewRange, double ExistingRange, double Value) { double Calculation = (NewRange / ExistingRange) * Value; return(Calculation); } // dbInput returning an unsigned integer unsigned int dbInputUI() { char * strInput = dbInput(); // Get user input unsigned int iReturn = atoi(strInput); // Convert string into integer delete[] strInput; // Deallocate memory return(iReturn); } // dbInput returning boolean bool dbInputB() { bool bReturn = false; // Get user input char * strInput = dbInput(); // Avoid going out of bounds if (strlen(strInput) > 0) { // If first character is 1 then return true if(strInput[0] == '1') { bReturn = true; } else { bReturn = false; } } // Deallocate memory delete[] strInput; // Return return(bReturn); } // Returns the ID of an input device selected by user unsigned int SelectInputDevice() { unsigned int iReturn; // Number of available input devices on system unsigned int iInputDevices = mnGetNumInputDevices(); dbPrintC("Number of input devices: "); dbPrint((LONGLONG)iInputDevices); // Information about each input device dbPrint("input device information:"); for(unsigned int n = 0;n 0) { // Get sound volume int SoundVolume = mnGetDataVolume(mnGetInputBitsPerSample(0),Data); // Keep volume at cap if(bFixVolume == true) { // When volume cap is at this point it has reached full volume // Note: full volume may be displayed by volume bars before // this point is reached due to volume bars' sensitivity adjustment // which ensures that smaller fluctuations in volume are better represented const double Sensitivity = 500; // Convert integers to double for increased accuracy double TempChange; double dSoundVolume = SoundVolume; double dVolumeCap = Value; // Avoid division by zero if(dSoundVolume != 0) { // Calculate percentage change necassary to adjust volume to required level double dRealVolumeCap; if(mnGetInputBitsPerSample(0) == 8) { dRealVolumeCap = ForceRange(UCHAR_MAX, Sensitivity, dVolumeCap); } else { dRealVolumeCap = ForceRange(USHRT_MAX, Sensitivity, dVolumeCap); } TempChange = ((dRealVolumeCap/dSoundVolume)*100)-100; } else { TempChange = 0.0; } // Adjust volume by calculated percentage mnSetDataVolume(mnGetInputBitsPerSample(0),Data,static_cast(TempChange)); } else { // Adjust sound volume by specified percentage mnSetDataVolume(mnGetInputBitsPerSample(0),Data,Value); } // Update line display array BaseLineBox.AddData(Data,mnGetInputBitsPerSample(0)); VolumeBox.SetLevel(Data,mnGetInputBitsPerSample(0)); // Play input data mnPlayData(0,Data); } // UPDATE DISPLAY // Refresh screen dbCLS(); // Line box title dbInk(dbRGB(255,255,255),dbRGB(0,0,0)); dbText(LineBoxTitleX, LineBoxTitleY, LineBoxTitleText); // Line box display BaseLineBox.UpdateDisplay(); // Volume box title dbInk(dbRGB(255,255,255),dbRGB(0,0,0)); dbText(VolumeBoxTitleX, VolumeBoxTitleY, VolumeBoxTitleText); // Volume box display VolumeBox.UpdateDisplay(); // Text at bottom of screen // Information about the status of things such as options stringstream ssStatus; if(bFixVolume == true) { ssStatus << "Fixing volume at " << abs(Value); } else { if(Value > 0) { ssStatus << "Increasing volume by " << Value << "%"; } else { if(Value == 0) { ssStatus << "No volume increase or decrease"; } else { ssStatus << "Decreasing volume by " << abs(Value) << "%"; } } } if(mnGetInputPaused(0) == 0) { ssStatus << ". Input is unpaused."; } else { ssStatus << ". Input is paused."; } dbInk(dbRGB(255,255,255),dbRGB(0,0,0)); dbText(BottomX, BottomY, (char*)ssStatus.str().c_str()); // Instructions stringstream ssInstructions; ssInstructions << "\n\nINSTRUCTIONS \nLCTRL = Gather input \nRCTRL = Exit \nTab = Switch between fixing/adjusting volume \nLSHIFT/RSHIFT = Increase/Decrease value to fix/adjust volume by"; dbInk(dbRGB(128, 128, 128),dbRGB(0,0,0)); dbText(BottomX, BottomY, (char*)ssInstructions.str().c_str()); } // CLEANUP // Delete packet mnDeletePacket(Data); // Cleanup input and output instance mnFinishOutput(0); mnFinishInput(0); // Cleanup sound instance mnFinishSound(); // Exit dbInk(dbRGB(255,255,255),dbRGB(0,0,0)); dbCLS(); dbPrint("Cleanup complete, thanks for using this application"); dbPrint("Press any key to exit..."); while(dbScanCode() != 0) { Sleep(1); } dbWaitKey(); }