-
Notifications
You must be signed in to change notification settings - Fork 1
/
keyboardpiano.cpp
127 lines (103 loc) · 3.79 KB
/
keyboardpiano.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
#include <iostream>
#include <string>
#include <thread>
#include <vector>
// SDL (Simple DirectMedia Layer)
// - multimedia library that provides crossplatform access to audio, keyboard, mouse, etc.
// SDL Mixer
// - extension for SDL, focusing on audio playback.
#include <SDL.h>
#include <SDL_mixer.h>
#include <ncurses.h>
using namespace std;
class Piano {
public:
Piano() {
initscr();
cbreak();
noecho();
keypad(stdscr, TRUE);
if (SDL_Init(SDL_INIT_AUDIO) < 0) {
cerr << "SDL initialization failed: " << SDL_GetError() << endl;
endwin();
exit(1);
}
if (Mix_OpenAudio(44100, MIX_DEFAULT_FORMAT, 2, 2048) < 0) {
cerr << "SDL_mixer initialization failed: " << Mix_GetError() << endl;
SDL_Quit();
endwin();
exit(1);
}
}
~Piano() {
Mix_CloseAudio();
SDL_Quit();
endwin();
}
void startPiano() {
int tuneNumber;
vector<thread> threads;
printPiano();
while (true) {
mvprintw(14, 0, "Happy Birthday Tune - 223254 223265 2265432 665432\nEnter a tune number from 0 to 9 to play (or 'q' to quit): ");
refresh();
int key = getch();
if (key == 'q') {
break;
}
tuneNumber = key - '0';
if (tuneNumber >= 0 && tuneNumber <= 9) {
threads.push_back(thread(playTune, tuneNumber));
}
else {
mvprintw(15, 0, "Invalid tune number. Please enter a number from 0 to 9.");
refresh();
}
}
for (auto& thread : threads) {
thread.join();
}
}
private:
void printPiano() {
mvprintw(0, 0, "=============================================================================");
mvprintw(1, 0, "|-------------------------------[Keyboard Piano]----------------------------|");
mvprintw(2, 0, "=============================================================================");
mvprintw(3, 0, "| ___________________________________________ |");
mvprintw(4, 0, "| ||=======================================|| |");
mvprintw(5, 0, "| |-----------------------------------------| |");
mvprintw(6, 0, "| || C | D | E | F | G | A | B | C | D | E || |");
mvprintw(7, 0, "| || ~ | ~ | ~ | ~ | ~ | ~ | ~ | ~ | ~ | ~ || |");
mvprintw(8, 0, "| || 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 0 || |");
mvprintw(9, 0, "|___________________=== === === === === === === === === ===_________________|");
}
static string getTuneFilename(int tune_number) {
return "piano_tunes/" + to_string(tune_number) + ".mp3";
}
static void playTune(int tune_number) {
string tuneFilename = getTuneFilename(tune_number);
Mix_Music* music = Mix_LoadMUS(tuneFilename.c_str());
if (!music) {
cerr << "Failed to load MP3: " << Mix_GetError() << endl;
return;
}
mvprintw(11, 0, "Playing tune %d...", tune_number);
refresh();
Mix_PlayMusic(music, 0);
SDL_Delay(3000);
Mix_FreeMusic(music);
mvprintw(11, 0, " ");
refresh();
}
};
int main() {
Piano piano;
cout << "Do you want to start the piano? (Y/N): ";
char response;
cin >> response;
if (response == 'Y' || response == 'y') {
piano.startPiano();
}
return 0;
}
// For compilation use "g++ -o piano piano.cpp -I/usr/include/SDL2 -L/usr/lib/x86_64-linux-gnu -lSDL2 -lSDL2_mixer -lncurses"