|
9 | 9 | #include "audio/Playback.hpp" |
10 | 10 | #include <format> |
11 | 11 |
|
| 12 | +static auto printBanner() |
| 13 | +{ |
| 14 | + std::cout << "──────────────────────────────────────────────\n" |
| 15 | + << "\nAudio Control Commands:\n" |
| 16 | + << " play, pause, restart, back <s>, forward <s>, seek <s>\n" |
| 17 | + << " volume <0.0–1.0>, info, quit\n" |
| 18 | + << "──────────────────────────────────────────────\n"; |
| 19 | +} |
| 20 | + |
| 21 | +static auto handleAudioCommand(audio::AudioEngine& eng, |
| 22 | + const std::string& input, |
| 23 | + const Metadata& meta) -> bool |
| 24 | +{ |
| 25 | + std::istringstream iss(input); |
| 26 | + std::string cmd; |
| 27 | + iss >> cmd; |
| 28 | + |
| 29 | + if (cmd.empty()) |
| 30 | + return true; |
| 31 | + |
| 32 | + const auto toLower = [](std::string s) { |
| 33 | + std::transform(s.begin(), s.end(), s.begin(), |
| 34 | + [](unsigned char c) { return std::tolower(c); }); |
| 35 | + return s; |
| 36 | + }; |
| 37 | + |
| 38 | + cmd = toLower(cmd); |
| 39 | + |
| 40 | + if (cmd == "play") { |
| 41 | + eng.play(); |
| 42 | + std::cout << "-- Resumed playback.\n"; |
| 43 | + } |
| 44 | + else if (cmd == "pause") { |
| 45 | + eng.pause(); |
| 46 | + std::cout << "-- Paused.\n"; |
| 47 | + } |
| 48 | + else if (cmd == "restart") { |
| 49 | + eng.restart(); |
| 50 | + std::cout << "-- Restarted track.\n"; |
| 51 | + } |
| 52 | + else if (cmd == "info") { |
| 53 | + std::cout << "\n📀 Metadata Info:\n" |
| 54 | + << " Title: " << meta.title << "\n" |
| 55 | + << " Artist: " << meta.artist << "\n" |
| 56 | + << " Album: " << meta.album << "\n" |
| 57 | + << " Track: " << meta.discNumber << "/" << meta.track << "\n" |
| 58 | + << " Year: " << meta.year << "\n" |
| 59 | + << " Duration: " << meta.duration << " sec\n" |
| 60 | + << " Bitrate: " << meta.bitrate << " kbps\n"; |
| 61 | + } |
| 62 | + else if (cmd == "seek" || cmd == "back" || cmd == "forward") { |
| 63 | + double seconds = 0.0; |
| 64 | + if (!(iss >> seconds)) { |
| 65 | + std::cout << "Usage: " << cmd << " <seconds>\n"; |
| 66 | + return true; |
| 67 | + } |
| 68 | + |
| 69 | + if (cmd == "seek") eng.seekTo(seconds); |
| 70 | + else if (cmd == "back") eng.seekBackward(seconds); |
| 71 | + else if (cmd == "forward") eng.seekForward(seconds); |
| 72 | + |
| 73 | + std::cout << "-- Seek: " << cmd << " " << seconds << "s\n"; |
| 74 | + } |
| 75 | + else if (cmd == "volume") { |
| 76 | + float vol = -1.0f; |
| 77 | + if (!(iss >> vol) || vol < 0.0f || vol > 1.0f) { |
| 78 | + std::cout << "Usage: volume <0.0 - 1.0>\n"; |
| 79 | + return true; |
| 80 | + } |
| 81 | + eng.setVolume(vol); |
| 82 | + std::cout << "-- Volume set to " << vol * 100.0f << "%.\n"; |
| 83 | + } |
| 84 | + else if (cmd == "quit") { |
| 85 | + std::cout << "!! Stopping playback and exiting...\n"; |
| 86 | + eng.stopInteractiveLoop(); |
| 87 | + return false; |
| 88 | + } |
| 89 | + else { |
| 90 | + std::cout << "❓ Unknown command: " << cmd << "\n" |
| 91 | + << "Available: play, pause, info, restart, seek, back, forward, volume, info, quit\n"; |
| 92 | + } |
| 93 | + |
| 94 | + return true; |
| 95 | +} |
| 96 | + |
12 | 97 | auto main(int argc, char* argv[]) -> int |
13 | 98 | { |
14 | 99 | RECORD_FUNC_TO_BACKTRACE("MAIN"); |
@@ -87,6 +172,7 @@ auto main(int argc, char* argv[]) -> int |
87 | 172 | assert(exampleSong != nullptr && "Example file not found in the library!"); |
88 | 173 |
|
89 | 174 | auto exampleFilePath = exampleSong->metadata.filePath; |
| 175 | + auto exampleFileMetadata = exampleSong->metadata; |
90 | 176 |
|
91 | 177 | LOG_INFO("Example file: {}", exampleFilePath); |
92 | 178 |
|
@@ -135,86 +221,18 @@ auto main(int argc, char* argv[]) -> int |
135 | 221 | engine.setVolume(1.0f); |
136 | 222 |
|
137 | 223 | // simple interactive loop to connect with audio backend (should work well with any UI frontend) |
138 | | - engine.startInteractiveLoop([](audio::AudioEngine& eng) { |
| 224 | + engine.startInteractiveLoop([&exampleFileMetadata](audio::AudioEngine& eng) { |
139 | 225 | std::string cmd; |
140 | | - |
141 | | - std::cout << "\nAudio Control Commands:\n" |
142 | | - << " play → Resume playback\n" |
143 | | - << " pause → Pause playback\n" |
144 | | - << " restart → Restart current track\n" |
145 | | - << " back <seconds> → Rewind by N seconds\n" |
146 | | - << " forward <seconds> → Skip ahead by N seconds\n" |
147 | | - << " seek <seconds> → Seek to absolute N seconds\n" |
148 | | - << " volume <0.0-1.0> → Set playback volume\n" |
149 | | - << " quit → Stop and exit\n" |
150 | | - << "──────────────────────────────────────────────\n"; |
| 226 | + |
| 227 | + printBanner(); |
151 | 228 |
|
152 | 229 | while (eng.shouldRun()) { |
153 | 230 | std::cout << "\n[audio]> "; |
154 | 231 | if (!std::getline(std::cin, cmd)) |
155 | | - break; // EOF or input stream closed |
156 | | - |
157 | | - std::istringstream iss(cmd); |
158 | | - std::string action; |
159 | | - iss >> action; |
160 | | - |
161 | | - if (action == "play") { |
162 | | - eng.play(); |
163 | | - std::cout << "Resumed playback.\n"; |
164 | | - } |
165 | | - else if (action == "pause") { |
166 | | - eng.pause(); |
167 | | - std::cout << "Paused.\n"; |
168 | | - } |
169 | | - else if (action == "restart") { |
170 | | - eng.restart(); |
171 | | - std::cout << "Restarted track.\n"; |
172 | | - } |
173 | | - else if (action == "seek") { |
174 | | - double seconds = 0.0; |
175 | | - if (iss >> seconds) { |
176 | | - eng.seekTo(seconds); |
177 | | - std::cout << "Seeked to " << seconds << " seconds.\n"; |
178 | | - } else { |
179 | | - std::cout << "Usage: seek <seconds>\n"; |
180 | | - } |
181 | | - } |
182 | | - else if (action == "back") { |
183 | | - double seconds = 0.0; |
184 | | - if (iss >> seconds) { |
185 | | - eng.seekBackward(seconds); |
186 | | - std::cout << "Rewound " << seconds << " seconds.\n"; |
187 | | - } else { |
188 | | - std::cout << "Usage: back <seconds>\n"; |
189 | | - } |
190 | | - } |
191 | | - else if (action == "forward") { |
192 | | - double seconds = 0.0; |
193 | | - if (iss >> seconds) { |
194 | | - eng.seekForward(seconds); |
195 | | - std::cout << "Skipped ahead " << seconds << " seconds.\n"; |
196 | | - } else { |
197 | | - std::cout << "Usage: forward <seconds>\n"; |
198 | | - } |
199 | | - } |
200 | | - else if (action == "volume") { |
201 | | - float vol = -1.0f; |
202 | | - if (iss >> vol && vol >= 0.0f && vol <= 1.0f) { |
203 | | - eng.setVolume(vol); |
204 | | - std::cout << "Volume set to " << vol * 100.0f << "%.\n"; |
205 | | - } else { |
206 | | - std::cout << "Usage: volume <0.0 - 1.0>\n"; |
207 | | - } |
208 | | - } |
209 | | - else if (action == "quit") { |
210 | | - std::cout << "🛑 Stopping playback and exiting...\n"; |
211 | | - eng.stopInteractiveLoop(); |
212 | 232 | break; |
213 | | - } |
214 | | - else if (!action.empty()) { |
215 | | - std::cout << "Unknown command: " << action << "\n" |
216 | | - << "Type one of: play, pause, restart, seek, back, forward, volume, quit\n"; |
217 | | - } |
| 233 | + |
| 234 | + if (!handleAudioCommand(eng, cmd, exampleFileMetadata)) |
| 235 | + break; |
218 | 236 | } |
219 | 237 | }); |
220 | 238 |
|
|
0 commit comments