[![Version](https://img.shields.io/badge/version-1.0.0-blue.svg)](https://gitea.hub.saturnux.com/sylvain/BitBuzzer) [![C++23](https://img.shields.io/badge/C%2B%2B-23-blue.svg)](https://en.cppreference.com/w/cpp/23) [![CMake](https://img.shields.io/badge/CMake-3.23+-064F8C.svg)](https://cmake.org/) [![License](https://img.shields.io/badge/License-CC0-green.svg)](https://creativecommons.org/publicdomain/zero/1.0/) [![Platform](https://img.shields.io/badge/Platform-Windows%20%7C%20Linux-lightgrey.svg)]() # 🎵 BitBuzzer - Musical Notes Library A simple and lightweight C++23 library for defining musical notes with their frequencies and durations. ## 📋 Description This library provides: - 📦 A simple header-only interface for musical notes - 🎶 A comprehensive set of musical notes from B0 (31 Hz) to DS8 (4978 Hz) - ⏱️ Support for note durations using `std::chrono::milliseconds` - ✨ A `Note` structure to represent a musical note with its frequency and duration - 🎹 Predefined constants for all notes from B0 (31 Hz) to DS8 (4978 Hz) - ⏱️ Duration support with `std::chrono::milliseconds` ## 🎼 Available Notes The library defines all notes of the Western musical system across 8 octaves: ### 🎹 Octave 0-1 - **B0** (31 Hz) to **B1** (62 Hz) ### 🎹 Octave 2 - **C2** (65 Hz) to **B2** (123 Hz) ### 🎹 Octave 3 - **C3** (131 Hz) to **B3** (247 Hz) ### 🎹 Octave 4 (Middle Octave) - **C4** (262 Hz) to **B4** (494 Hz) - **A4** = 440 Hz (Concert pitch reference) ### 🎹 Octave 5 - **C5** (523 Hz) to **B5** (988 Hz) ### 🎹 Octave 6 - **C6** (1047 Hz) to **B6** (1976 Hz) ### 🎹 Octave 7 - **C7** (2093 Hz) to **B7** (3951 Hz) ### 🎹 Octave 8 - **C8** (4186 Hz) to **DS8** (4978 Hz) ### 🔇 Special Notes - **silent** (0 Hz) - For rests/pauses ### 📝 Notation - Natural notes: C, D, E, F, G, A, B - Sharps (♯): CS, DS, FS, GS, AS (suffix 'S' for Sharp) - Flats (♭): DB3, EB3 (suffix 'B' for Flat) - Enharmonic equivalents available for some notes ## 🏗️ Note Structure ```cpp struct Note { uint16_t frequency; // Frequency in Hz std::chrono::milliseconds duration; // Note duration }; ``` ### 🔧 Constructors ```cpp // With std::chrono::milliseconds Note(uint16_t freq, std::chrono::milliseconds dur); // With uint32_t (automatically converted to milliseconds) Note(uint16_t freq, uint32_t dur); ``` ## 📦 Project Integration: Direct Inclusion 1. Copy the `pitches` folder to the root of your project or into a subfolder like `external/` or `libs/` 2. In your `CMakeLists.txt`, add the path to includes: ```cmake # Add the pitches folder to includes target_include_directories(your_project PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/pitches ) ``` 3. Include the header in your code: ```cpp #include ``` ## 💡 Usage Examples ### 🎯 Example 1: Create a Simple Note ```cpp #include int main() { // A4 note (440 Hz) for 500ms pitches::Note note1(pitches::A4, 500); // C5 note for 1 second pitches::Note note2(pitches::C5, std::chrono::milliseconds(1000)); // 200ms rest/silence pitches::Note pause(pitches::silent, 200); return 0; } ``` ### 🎶 Example 2: Simple Melody ```cpp #include #include std::vector createMelody() { using namespace pitches; return { Note(C4, 250), // Do Note(D4, 250), // Re Note(E4, 250), // Mi Note(F4, 250), // Fa Note(G4, 250), // Sol Note(A4, 250), // La Note(B4, 250), // Si Note(C5, 500) // Do (higher octave) }; } ``` ### 🔊 Example 3: Note Playback Function ```cpp #include #include #include void playNote(const pitches::Note& note) { if (note.frequency == pitches::silent) { std::cout << "Silence for " << note.duration.count() << "ms\n"; } else { std::cout << "Playing frequency " << note.frequency << " Hz for " << note.duration.count() << "ms\n"; // Here: code to generate sound with the given frequency } std::this_thread::sleep_for(note.duration); } int main() { using namespace pitches; std::vector melody = { Note(E5, 200), Note(E5, 200), Note(silent, 200), Note(E5, 200), Note(silent, 200), Note(C5, 200), Note(E5, 400), Note(G5, 400) }; for (const auto& note : melody) { playNote(note); } return 0; } ``` ### 🔌 Example 4: With Hardware Buzzer (Arduino-style) ```cpp #include class Buzzer { public: void play(const pitches::Note& note) { if (note.frequency > 0) { tone(buzzerPin, note.frequency); delay(note.duration.count()); noTone(buzzerPin); } else { delay(note.duration.count()); } } private: int buzzerPin = 9; // Buzzer pin }; ``` ## ⚙️ Requirements - **C++ Standard**: C++23 (or C++17 minimum for `std::chrono`) - **CMake**: Version 3.23 or higher - **Compiler**: C++23 compatible (GCC 11+, Clang 14+, MSVC 2022+) ## 🔍 Technical Notes - ⚡ All constants are `constexpr` for compile-time evaluation - 📊 Frequencies are stored as `uint16_t` (0-65535 Hz) - 🎯 `Note` structure is `constexpr`-compatible for static melodies - 📄 Header-only: no separate compilation needed ## 📜 License This project is licensed under CC0 1.0 Universal (Public Domain Dedication). To the extent possible under law, the author has waived all copyright and related or neighboring rights to this work. You can copy, modify, distribute and perform the work, even for commercial purposes, all without asking permission. ## 🤝 Contributing Sylvain Schneider (mailto:s.schneider.fr54@gmail.com)