Question: Please use c++ to write the code Start with the startA.cpp file for this part. You CANNOT change main() from how it is currently written.

Please use c++ to write the code

Start with the startA.cpp file for this part. You CANNOT change main() from how it is currently written. Instead, you need to add to the Beeper class to make main() work and play sound. You should first be able to enter the beats-per-minute of the song. Thus 60 bpm is 1 note a second and 120 bpm is 2 notes a second. Computers typically calculate time in milliseconds (1 / 1,000th of a second) so you will have to convert units. Next the user will input notes (in upper case), which you should play at the bpm entered (the playing should happen on the cin >> b; line of code).

To play notes, you will need to specify the pitch in Hertz (Hz) of the notes. You can reference this webpage: http://www.phy.mtu.edu/~suits/NoteFreqCalcs.html

For those of you unfamiliar with music, there are seven notes: C D E F G A B The link above says to start the A note at 440 Hz (please choose this definition). Then they give you a formula based on the number of half-steps.

These are: A -> B = 2 half-steps A -> A = 0 half-steps A -> G = -2 half-steps A -> F = -4 half-steps A -> E = -5 half-steps A -> D = -7 half-steps A -> C = -9 half-steps (Hint: you should look around the SDLaudioPlayer.cpp example to figure out how to play sound.)

In addition to reading notes, your program should also read periods (.) as rests (no sound). To do this, simply put a very low frequency Hz (outside of the hearing range). Example 1 (user input underlined, desired sound posted on website): Enter tempo (bpm) 60 Enter song CEG.GEC Hint: try playing around with Beeper's beep() function.

Here is the original code:

#include  #include  #include  #include  #include  /** Consts used for standard audio playback **/ const int AMPLITUDE = 28000*2; const int FREQUENCY = 44100; const int DURATION = 250; class Beeper; /** FUNCTIONS THAT ARE DONE **/ void onKeyDown(SDL_KeyboardEvent&,Beeper*); void createWindow(SDL_Window*); void destroyWindow(SDL_Window*); void handleInput(SDL_Event,Beeper*); void audio_callback(void*, Uint8*, int); /** Helper struct used to generate samples **/ struct BeepObject { double freq; int samplesLeft; }; /** You will need to add to this class ** Code given can be played interactively **/ class Beeper { private: double v; std::queue beeps; public: Beeper(); ~Beeper(); void beep(double, int); void generateSamples(Sint16 *stream, int length); void wait(); // TODO: Add input overloaded function to read a "song" }; bool closingTime = false; //used if running in "interactive" mode int main(int argc, char* argv[]) { /* All initialization stuff */ SDL_Init(SDL_INIT_AUDIO); Beeper b; /* TODO: Place all your main code from here */ /* Run this loop if you would like * to "play" a song on the keyboard * and close the app by pressing the 'escape' key */ // below is sample code (that you should get rid of for your program) SDL_Window* window; createWindow(window); while(!closingTime) { SDL_Event event; if(SDL_WaitEvent(&event)) { handleInput(event,&b); } } destroyWindow(window); return 0; } /** SHOULD NOT NEED TO TOUCH ANYTHING BELOW HERE **/ /** USE IT TO LEARN BUT NO CHANGES NEED TO BE MADE **/ /* ... But you can use on key down as reference on * using the beeper class */ void audio_callback(void *_beeper, Uint8 *_stream, int _length) { Sint16 *stream = (Sint16*) _stream; int length = _length / 2; Beeper* beeper = (Beeper*) _beeper; beeper->generateSamples(stream, length); } void createWindow(SDL_Window *window) { window = SDL_CreateWindow("HW8", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, 100, 100, SDL_WINDOW_SHOWN); if (window == NULL) std::cout << "Failed to create window"; } void destroyWindow(SDL_Window *window) { SDL_DestroyWindow(window); } void handleInput(SDL_Event event, Beeper* b) { switch (event.type) { case SDL_KEYDOWN: onKeyDown(event.key,b); break; } } void onKeyDown(SDL_KeyboardEvent &e, Beeper* b) { bool keyboardPlayed = false; double Hz; if(e.type == SDL_KEYDOWN) { if(e.keysym.scancode == SDL_SCANCODE_ESCAPE){ std::cout << "Closing.. "; closingTime = true; } else { if(e.keysym.scancode == SDL_SCANCODE_A) { // key "a" is pressed Hz = 261.63; // middle C keyboardPlayed = true; std::cout << "Played C" << std::endl; } else if(e.keysym.scancode == SDL_SCANCODE_S) { keyboardPlayed = true; Hz = 293.66; // D std::cout << "Played D" << std::endl; } else if(e.keysym.scancode == SDL_SCANCODE_D) { keyboardPlayed = true; Hz = 329.63; // E std::cout << "Played E" << std::endl; } else if(e.keysym.scancode == SDL_SCANCODE_F) { keyboardPlayed = true; Hz = 349.23; // F std::cout << "Played F" << std::endl; } else if(e.keysym.scancode == SDL_SCANCODE_G) { keyboardPlayed = true; Hz = 392; // G std::cout << "Played G" << std::endl; } else if(e.keysym.scancode == SDL_SCANCODE_H) { keyboardPlayed = true; Hz = 440; // A std::cout << "Played A" << std::endl; } else if(e.keysym.scancode == SDL_SCANCODE_J) { keyboardPlayed = true; Hz = 493.88; // B std::cout << "Played B" << std::endl; } if(keyboardPlayed) { b->beep(Hz,250); // comment out this line if having trouble remote connecting b->wait(); } } } } Beeper::Beeper() { SDL_AudioSpec desiredSpec; desiredSpec.freq = FREQUENCY; desiredSpec.format = AUDIO_S16SYS; desiredSpec.channels = 1; desiredSpec.samples = 2048; desiredSpec.callback = audio_callback; desiredSpec.userdata = this; SDL_AudioSpec obtainedSpec; SDL_OpenAudio(&desiredSpec, &obtainedSpec); // start play audio SDL_PauseAudio(0); } Beeper::~Beeper() { SDL_CloseAudio(); } void Beeper::generateSamples(Sint16 *stream, int length) { int i = 0; while (i < length) { if (beeps.empty()) { while (i < length) { stream[i] = 0; i++; } return; } BeepObject& bo = beeps.front(); int samplesToDo = std::min(i + bo.samplesLeft, length); bo.samplesLeft -= samplesToDo - i; while (i < samplesToDo) { stream[i] = AMPLITUDE * std::sin(v * 2 * M_PI / FREQUENCY); i++; v += bo.freq; } if (bo.samplesLeft == 0) { beeps.pop(); } } } void Beeper::beep(double freq, int duration) { BeepObject bo; bo.freq = freq; bo.samplesLeft = duration * FREQUENCY / 1000; SDL_LockAudio(); beeps.push(bo); SDL_UnlockAudio(); } void Beeper::wait() { int size; do { SDL_Delay(20); SDL_LockAudio(); size = beeps.size(); SDL_UnlockAudio(); } while (size > 0); } 

Step by Step Solution

There are 3 Steps involved in it

1 Expert Approved Answer
Step: 1 Unlock blur-text-image
Question Has Been Solved by an Expert!

Get step-by-step solutions from verified subject matter experts

Step: 2 Unlock
Step: 3 Unlock

Students Have Also Explored These Related Databases Questions!