{"id":22551314,"url":"https://github.com/joelumbley/audio-playback-cs","last_synced_at":"2026-04-25T16:33:22.162Z","repository":{"id":253563301,"uuid":"843874648","full_name":"JoeLumbley/Audio-Playback-CS","owner":"JoeLumbley","description":"Play multiple audio files simultaneously.","archived":false,"fork":false,"pushed_at":"2025-01-24T16:41:09.000Z","size":648,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-03-28T10:12:08.132Z","etag":null,"topics":["adding-resources","audio-playback","audio-playback-tool","audio-player","creating-files-from-resources","csharp","windows-forms","windows-multimedia-api"],"latest_commit_sha":null,"homepage":"","language":"C#","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/JoeLumbley.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE.txt","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2024-08-17T17:23:02.000Z","updated_at":"2025-01-24T16:41:12.000Z","dependencies_parsed_at":"2024-12-09T06:49:04.661Z","dependency_job_id":null,"html_url":"https://github.com/JoeLumbley/Audio-Playback-CS","commit_stats":null,"previous_names":["joelumbley/audio-playback-cs"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/JoeLumbley/Audio-Playback-CS","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/JoeLumbley%2FAudio-Playback-CS","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/JoeLumbley%2FAudio-Playback-CS/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/JoeLumbley%2FAudio-Playback-CS/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/JoeLumbley%2FAudio-Playback-CS/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/JoeLumbley","download_url":"https://codeload.github.com/JoeLumbley/Audio-Playback-CS/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/JoeLumbley%2FAudio-Playback-CS/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":32269458,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-25T09:15:33.318Z","status":"ssl_error","status_checked_at":"2026-04-25T09:15:31.997Z","response_time":59,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["adding-resources","audio-playback","audio-playback-tool","audio-player","creating-files-from-resources","csharp","windows-forms","windows-multimedia-api"],"created_at":"2024-12-07T17:12:10.633Z","updated_at":"2026-04-25T16:33:22.145Z","avatar_url":"https://github.com/JoeLumbley.png","language":"C#","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Audio Playback C#\n\nAudio Playback C# is a powerful and versatile tool for managing audio playback using the Windows Multimedia API.\nThis application provides a comprehensive set of features for playing audio, making it an essential resource for developers and enthusiasts alike.\n\n\n\n\n![002](https://github.com/user-attachments/assets/4e243026-9f35-487b-ad6a-0f8d455c858b)\n\n\n## Key Features:\n\n- **Simultaneous Playback**: Harness the full potential of the Windows Multimedia API to play multiple audio files simultaneously, allowing for rich and immersive audio experiences.\n\n- **Volume Control**: Customize the volume levels of individual audio tracks with precision, ensuring an optimal audio balance tailored to your specific requirements.\n\n- **Looping and Overlapping**: Seamlessly loop audio tracks and play overlapping sounds, enabling the creation of captivating and dynamic audio compositions.\n\n- **MCI Integration**: Leverage the power of the Media Control Interface (MCI) to interact with multimedia devices, providing a standardized and platform-independent approach to controlling multimedia hardware.\n\n- **User-Friendly Interface**: Enjoy a user-friendly and intuitive interface, designed to streamline the process of managing and controlling audio playback operations.\n\nWith its robust functionality and seamless integration with the Windows Multimedia API, this application empowers users to create engaging multimedia applications with ease. Whether you are a seasoned developer or an aspiring enthusiast, the Audio Playback Application is your gateway to unlocking the full potential of audio playback on the Windows platform.\n\n**Clone the repository now and embark on a transformative audio playback experience!** Let's dive into the world of audio together!\n\n\n\n\n\n---\n\n\n\n\n\n\n# Code Walkthrough\n\nIn this walkthrough, we will break down the code that implements an `AudioPlayer` struct and a `Form1` class to manage audio playback.\n\n [Index](#index)\n\n---\n\n## Namespaces\n\n### Using Directives\n\n```csharp\nusing System.Runtime.InteropServices;\nusing System.Text;\nusing System.Diagnostics;\n\n\n```\n\nIn this example, we are importing:\n- `System.Runtime.InteropServices`\n- `System.Text`\n- `System.Diagnostics`\nThis line imports the `System.Diagnostics` namespace, which provides classes for debugging and tracing. It allows us to print debug messages to the console.\n\n### Namespace Declaration\n\n```csharp\n\nnamespace Audio_Playback_CS\n\n```\n- Here, we define a namespace called `Audio_Playback_CS`. Namespaces are used to organize code and avoid naming conflicts with other parts of the program.\n\n\n [Index](#index)\n\n\n---\n\n\n\n\n\n\n\n## AudioPlayer Structure\n\n```csharp\n\npublic struct AudioPlayer\n\n```\n\n- **Struct Definition**: The `AudioPlayer` struct is defined to encapsulate the functionalities related to audio playback.\n\n\n\n### DLL Import\n```csharp\n[DllImport(\"winmm.dll\", EntryPoint = \"mciSendStringW\")]\nprivate static extern int mciSendStringW([MarshalAs(UnmanagedType.LPTStr)] string lpszCommand,\n                                         [MarshalAs(UnmanagedType.LPWStr)] StringBuilder lpszReturnString,\n                                         uint cchReturn, IntPtr hwndCallback);\n```\n\n- **DllImport**: This attribute allows us to call functions from unmanaged libraries. Here, we are importing `mciSendStringW` from `winmm.dll`, which is used for multimedia control.\n- **Parameters**:\n  - `lpszCommand`: The command string to send to the MCI (Media Control Interface).\n  - `lpszReturnString`: A StringBuilder to store the return string from the command.\n  - `cchReturn`: The size of the return string.\n  - `hwndCallback`: A handle to a callback window (not used here).\n\n [Index](#index)\n\n---\n\n\n## Adding Sounds\n\n\n\n### Sounds Array\n\n```csharp\n\nprivate string[]? Sounds;\n\n```\n\nThis declares an array named `Sounds` to store the names of sounds that have been added.\n\n\n### AddSound Method\n\n```csharp\n\npublic bool AddSound(string SoundName, string FilePath)\n\n```\n\nThis method adds a sound to the player. It takes the name of the sound and the path to the sound file as parameters.\n\n```csharp\n\nif (!string.IsNullOrWhiteSpace(SoundName) \u0026\u0026 File.Exists(FilePath))\n\n```\n\nChecks if the sound name is not empty or whitespace and if the file exists.\n\n```csharp\n\nstring CommandOpen = $\"open \\\"{FilePath}\\\" alias {SoundName}\";\n\n```\n\nCreates a command string to open the sound file and assign it an alias.\n\n\nThe **escape character `\\`** is used to include special characters in a string. In this case, the escape sequence `\\\"` allows you to include a double quote within a string that's also enclosed in double quotes.\n\nHere's why it's needed: If your file path has spaces, it needs to be enclosed in quotes when you use it in commands. Without escaping the quotes, the string would get cut off at the first double quote it encounters.\n\nFor example, let's say your file path is `C:\\My Files\\file.wav`. \n\n- Without escaping: `string CommandOpen = $\"open \"{FilePath}\" alias {SoundName}\";` would cause an error because the quotes are not properly handled.\n- With escaping: `string CommandOpen = $\"open \\\"{FilePath}\\\" alias {SoundName}\";` ensures that the quotes are included as part of the string, making it `open \"C:\\My Files\\file.wav\" alias SoundAlias`.\n\nThis way, the entire file path is correctly recognized even if it contains spaces, and the command will execute as expected. \n\n\n\n\n\n\n\n\n\n\n```csharp\n\nif (Sounds == null)\n\n```\n\nChecks if the `Sounds` array is uninitialized.\n\n```csharp\n\nif (SendMciCommand(CommandOpen, IntPtr.Zero))\n\n```\n\nSends the command to open the sound file.\n\n```csharp\n\nSounds = new string[1];\nSounds[0] = SoundName;\nreturn true;\n\n```\n\nInitializes the `Sounds` array with the new sound and returns `True`.\n\n```csharp\n\nelse if (!Sounds.Contains(SoundName))\n\n```\n\nChecks if the sound is not already in the array.\n\n```csharp\n\nArray.Resize(ref Sounds, Sounds.Length + 1);\nSounds[Sounds.Length - 1] = SoundName;\nreturn true;\n\n```\n\nAdds the new sound to the `Sounds` array and returns `True`.\n\n```csharp\n\nDebug.Print($\"The sound was not added {SoundName}\");\nreturn false;\n\n```\n\nPrints a debug message and returns `False` if the sound could not be added.\n\n\n [Index](#index)\n\n---\n\n\n## Setting Volume\n\n### SetVolume Method\n\n```csharp\npublic bool SetVolume(string SoundName, int Level)\n{\n    if (Sounds != null \u0026\u0026 Sounds.Contains(SoundName) \u0026\u0026 Level \u003e= 0 \u0026\u0026 Level \u003c= 1000)\n    {\n        string CommandVolume = $\"setaudio {SoundName} volume to {Level}\";\n        return SendMciCommand(CommandVolume, IntPtr.Zero);\n    }\n\n    Debug.Print($\"The volume was not set {SoundName}\");\n    return false;\n}\n```\n\n- **Method `SetVolume`**:\n  - Checks if `Sounds` is not null, if the sound exists, and if the volume level is within the valid range (0 to 1000).\n  - Constructs a command to set the audio volume for the specified sound.\n  - Sends the command using `SendMciCommand` and returns the result.\n  - Logs a message and returns `false` if the conditions are not met.\n\n [Index](#index)\n\n---\n\n\n## Looping Sounds\n\n### LoopSound Method\n\n```csharp\npublic bool LoopSound(string SoundName)\n{\n    if (Sounds != null \u0026\u0026 Sounds.Contains(SoundName))\n    {\n        string CommandSeekToStart = $\"seek {SoundName} to start\";\n        string CommandPlayRepeat = $\"play {SoundName} repeat\";\n        return SendMciCommand(CommandSeekToStart, IntPtr.Zero) \u0026\u0026\n               SendMciCommand(CommandPlayRepeat, IntPtr.Zero);\n    }\n\n    Debug.Print($\"The sound is not looping {SoundName}\");\n    return false;\n}\n```\n\n- **Method `LoopSound`**:\n  - Checks if the sound exists in the `Sounds` array.\n  - Constructs commands to seek to the start of the sound and play it in repeat mode.\n  - Sends both commands and returns `true` if successful; otherwise, logs a message and returns `false`.\n\n [Index](#index)\n\n---\n\n\n## Playing Sounds\n\n### PlaySound Method\n\n```csharp\nprivate bool PlaySound(string SoundName)\n{\n    if (Sounds != null \u0026\u0026 Sounds.Contains(SoundName))\n    {\n        string CommandSeekToStart = $\"seek {SoundName} to start\";\n        string CommandPlay = $\"play {SoundName} notify\";\n        return SendMciCommand(CommandSeekToStart, IntPtr.Zero) \u0026\u0026\n               SendMciCommand(CommandPlay, IntPtr.Zero);\n    }\n\n    Debug.Print($\"The sound is not playing {SoundName}\");\n    return false;\n}\n```\n\n- **Method `PlaySound`**:\n  - Similar to `LoopSound`, but constructs commands to play the sound once.\n  - Uses `notify` to allow the program to receive notification when the sound finishes playing.\n  - Returns `true` if the commands were successful; otherwise, it logs a message and returns `false`.\n\n [Index](#index)\n\n---\n\n\n## Pausing Sounds\n\n### PauseSound Method\n\n```csharp\npublic bool PauseSound(string SoundName)\n{\n    if (Sounds != null \u0026\u0026 Sounds.Contains(SoundName))\n    {\n        string CommandPause = $\"pause {SoundName} notify\";\n        return SendMciCommand(CommandPause, IntPtr.Zero);\n    }\n\n    Debug.Print($\"The sound is not paused {SoundName}\");\n    return false;\n}\n```\n\n- **Method `PauseSound`**:\n  - Checks if the sound exists.\n  - Constructs a command to pause the sound and sends it.\n  - Returns `true` if successful; otherwise, logs a message and returns `false`.\n\n [Index](#index)\n\n---\n\n\n## Managing Overlapping Sounds\n\n### Adding Overlapping Sounds\n```csharp\npublic void AddOverlapping(string SoundName, string FilePath)\n{\n    foreach (string Suffix in new[] { \"A\", \"B\", \"C\", \"D\", \"E\", \"F\", \"G\", \"H\", \"I\", \"J\", \"K\", \"L\" })\n    {\n        AddSound(SoundName + Suffix, FilePath);\n    }\n}\n```\n\n- **Method `AddOverlapping`**:\n  - Adds multiple sounds with suffixes (A to L) to allow overlapping playback.\n  - Calls `AddSound` for each suffixed name.\n\n### Playing Overlapping Sounds\n```csharp\npublic void PlayOverlapping(string SoundName)\n{\n    foreach (string Suffix in new[] { \"A\", \"B\", \"C\", \"D\", \"E\", \"F\", \"G\", \"H\", \"I\", \"J\", \"K\", \"L\" })\n    {\n        if (!IsPlaying(SoundName + Suffix))\n        {\n            PlaySound(SoundName + Suffix);\n            return;\n        }\n    }\n}\n```\n\n- **Method `PlayOverlapping`**:\n  - Plays the first sound that is not currently playing among the suffixed sounds.\n\n### Setting Volume for Overlapping Sounds\n```csharp\npublic void SetVolumeOverlapping(string SoundName, int Level)\n{\n    foreach (string Suffix in new[] { \"A\", \"B\", \"C\", \"D\", \"E\", \"F\", \"G\", \"H\", \"I\", \"J\", \"K\", \"L\" })\n    {\n        SetVolume(SoundName + Suffix, Level);\n    }\n}\n```\n\n- **Method `SetVolumeOverlapping`**:\n  - Sets the volume for all suffixed sounds using the `SetVolume` method.\n\n [Index](#index)\n\n---\n\n\n## Sending MCI Commands\n\n```csharp\nprivate bool SendMciCommand(string command, IntPtr hwndCallback)\n{\n    StringBuilder ReturnString = new StringBuilder(128);\n\n    try\n    {\n        return mciSendStringW(command, ReturnString, 0, hwndCallback) == 0;\n    }\n    catch (Exception ex)\n    {\n        Debug.Print($\"Error: {ex.Message}\");\n        return false;\n    }\n}\n```\n\n- **Method `SendMciCommand`**:\n  - Sends a command to the MCI and checks for errors.\n  - Returns `true` if the command was successful; otherwise, logs the error and returns `false`.\n\n [Index](#index)\n\n---\n\n\n## Getting Sound Status\n\n```csharp\nprivate string GetStatus(string SoundName, string StatusType)\n{\n    try\n    {\n        if (Sounds != null \u0026\u0026 Sounds.Contains(SoundName))\n        {\n            string CommandStatus = $\"status {SoundName} {StatusType}\";\n            StringBuilder StatusReturn = new StringBuilder(128);\n            mciSendStringW(CommandStatus, StatusReturn, 128, IntPtr.Zero);\n            return StatusReturn.ToString().Trim().ToLower();\n        }\n    }\n    catch (Exception ex)\n    {\n        Debug.Print($\"Error getting status: {ex.Message}\");\n    }\n\n    return string.Empty;\n}\n```\n\n- **Method `GetStatus`**:\n  - Retrieves the status of a sound (e.g., whether it is playing).\n  - Constructs a status command and returns the result as a string.\n\n [Index](#index)\n\n---\n\n\n\n\n## Closing Sounds\n\n\n### CloseSounds Method\n\n\n```csharp\n\npublic void CloseSounds()\n{\n    if (Sounds != null)\n    {\n        foreach (string Sound in Sounds)\n        {\n            string CommandClose = $\"close {Sound}\";\n\n            SendMciCommand(CommandClose, IntPtr.Zero);\n\n        }\n\n        Sounds = null;\n\n    }\n\n}\n\n```\n\n  - Closes all open sounds by sending a close command for each sound in the `Sounds` array.\n  - **`Sounds = null;`**: This line sets the `Sounds` array to `null`. By doing this, it effectively clears the reference to the array, ensuring that all resources associated with the sounds are released. It also prevents further usage of the array without reinitializing it, which is a good practice for memory management and avoiding potential errors in your application.\n\n\n[Index](#index)\n\n---\n\n\n\n\n\n\n\n## Form Class and Event Handlers\n\n```csharp\npublic partial class Form1 : Form\n{\n    private AudioPlayer Player;\n\n    private void Form1_Load(object sender, EventArgs e)\n    {\n        Text = \"Audio Playback CS - Code with Joe\";\n\n        CreateSoundFiles();\n\n        string FilePath = Path.Combine(Application.StartupPath, \"level.mp3\");\n        Player.AddSound(\"Music\", FilePath);\n        Player.SetVolume(\"Music\", 600);\n\n        FilePath = Path.Combine(Application.StartupPath, \"CashCollected.mp3\");\n        Player.AddOverlapping(\"CashCollected\", FilePath);\n        Player.SetVolumeOverlapping(\"CashCollected\", 900);\n\n        Player.LoopSound(\"Music\");\n\n        Debug.Print($\"Running... {DateTime.Now}\");\n    }\n```\n\n- **Form1 Class**: Inherits from `Form`, which is part of Windows Forms for creating GUI applications.\n- **Player Field**: An instance of `AudioPlayer` is created to manage audio playback.\n- **Form1_Load Method**:\n  - Sets the form title.\n  - Calls `CreateSoundFiles` to ensure the sound files exist.\n  - Adds sounds and sets their volumes.\n  - Loops the background music and logs the current time.\n\n### Button Click Events\n```csharp\nprivate void Button1_Click(object sender, EventArgs e)\n{\n    Player.PlayOverlapping(\"CashCollected\");\n}\n\nprivate void Button2_Click(object sender, EventArgs e)\n{\n    if (Player.IsPlaying(\"Music\"))\n    {\n        Player.PauseSound(\"Music\");\n        button2.Text = \"Play Loop\";\n    }\n    else\n    {\n        Player.LoopSound(\"Music\");\n        button2.Text = \"Pause Loop\";\n    }\n}\n```\n- **Button1_Click**: Plays the overlapping \"CashCollected\" sound when the button is clicked.\n- **Button2_Click**: Toggles between pausing the music and looping it, updating the button text accordingly.\n\n### Form Closing Event\n```csharp\nprivate void Form1_Closing(object sender, System.ComponentModel.CancelEventArgs e)\n{\n    Player.CloseSounds();\n}\n```\n- **Form1_Closing**: Ensures all sounds are closed when the form is closing.\n\n [Index](#index)\n\n---\n\n\n## Creating Sound Files\n\n```csharp\nprivate void CreateSoundFiles()\n{\n    string filePath = Path.Combine(Application.StartupPath, \"level.mp3\");\n    CreateFileFromResource(filePath, Audio_Playback_CS.Resource1.level);\n\n    filePath = Path.Combine(Application.StartupPath, \"CashCollected.mp3\");\n    CreateFileFromResource(filePath, Audio_Playback_CS.Resource1.CashCollected);\n}\n```\n\n- **Method `CreateSoundFiles`**:\n  - Creates sound files from resources if they do not already exist.\n\n### Creating Files from Resources\n```csharp\nprivate void CreateFileFromResource(string filePath, byte[] resource)\n{\n    try\n    {\n        if (!File.Exists(filePath))\n        {\n            File.WriteAllBytes(filePath, resource);\n        }\n    }\n    catch (Exception ex)\n    {\n        Debug.Print($\"Error creating file: {ex.Message}\");\n    }\n}\n```\n- **Method `CreateFileFromResource`**:\n  - Writes byte arrays from resources to files on disk.\n  - Catches exceptions and logs errors if file creation fails.\n\n\n [Index](#index)\n\n\n---\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n## Adding Resources\n\nTo add a resource file to your Visual Studio project, follow these steps:\n\n1. **Add a New Resource File**:\n   - From the **Project** menu, select `Add New Item...`.\n   - In the dialog that appears, choose `Resource File` from the list of templates.\n   - Name your resource file (e.g., `Resource1.resx`) and click `Add`.\n\n  \n![005](https://github.com/user-attachments/assets/4c3c760e-7673-4666-a6cb-5080983a23cd)\n\n\n\n![006](https://github.com/user-attachments/assets/c193c0d4-a884-4613-9fd2-d3910f0ea23b)\n\n\n\n2. **Open the Resource Editor**:\n   - Double-click the newly created `.resx` file to open the resource editor.\n\n![007](https://github.com/user-attachments/assets/4dd230ed-a830-4490-8056-87ef0182a6cf)\n\n\n3. **Add Existing Files**:\n   - In the resource editor, click on the **Green Plus Sign** or right-click in the resource pane and select `Add Resource`.\n   - Choose `Add Existing File...` from the context menu.\n   - Navigate to the location of the MP3 file (or any other resource file) you want to add, select it, and click `Open`.\n\n![008](https://github.com/user-attachments/assets/c1da8b5e-7718-458f-9420-f2b4b6cc6084)\n\n\n4. **Verify the Addition**:\n   - Ensure that your MP3 file appears in the list of resources in the resource editor. It should now be accessible via the Resource class in your code.\n\n5. **Accessing the Resource in Code**:\n   - You can access the added resource in your code using the following syntax:\n     ```csharp\n     CreateFileFromResource(filePath, YourProjectNamespace.Resource1.YourResourceName);\n     \n     // Example\n     CreateFileFromResource(filePath, Resource1.CashCollected);\n\n     ```\n\n6. **Save Changes**:\n   - Don’t forget to save your changes to the `.resx` file.\n  \n![009](https://github.com/user-attachments/assets/6d632bee-c2f1-4692-8fde-e9c8ab849337)\n\n\nBy following these steps, you can easily add any existing MP3 file or other resources to your Visual Studio project and utilize them within your Audio Playback application.\n\n---\n\n\n\n\n# Related Projects\n\nThis project serves as a direct port of the original Audio Playback project created in VB.NET, which you can also explore for a different perspective on the same concepts. For more information and to access the complete code, visit the [Audio Playback Repository](https://github.com/JoeLumbley/Audio-Playback) and the [Audio Playback C# Repository](https://github.com/JoeLumbley/Audio-Playback-CS). Happy coding!\n\n\n\n\n![013](https://github.com/user-attachments/assets/503ac6a1-c71d-4a26-ba3e-f6122c83cbe4)\n\n\n\n\n\n---\n\n\n## Index\n\n\n\n\n\n- [Namespaces](#namespaces)\n\n- [AudioPlayer Structure](#audioPlayer-structure)\n\n- [Dll Import](#dll-import)\n \n [Adding Sounds](#adding-sounds)\n \n- [Sounds Array](#sounds-array)\n \n- [AddSound Method](#addSound-method)\n\n [Setting Volume](#setting-volume)\n \n [Looping Sounds](#looping-sounds)\n \n [Playing Sounds](#playing-sounds)\n \n [Pausing Sounds](#pausing-sounds)\n \n [Managing Overlapping Sounds](#managing-overlapping-sounds)\n \n [Sending MCI Commands](#sending-mci-commands)\n \n [Getting Sound Status](#getting-sound-status)\n \n [Closing Sounds](#closing-sounds)\n \n [Form Class and Event Handlers](#form-class-and-event-handlers)\n \n [Creating Sound Files](#creating-sound-files)\n\n [Adding Resources](#adding-resources)\n\n\n---\n\n\nThis code provides a comprehensive example of how to create an audio playback application in C#. We covered everything from adding sounds to managing their playback and volume. By understanding each part of this code, you can build a solid foundation for working with audio in your applications.\n\nFeel free to experiment with the code and modify it to enhance your learning experience!\n\n\n\n\n\n---\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjoelumbley%2Faudio-playback-cs","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fjoelumbley%2Faudio-playback-cs","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjoelumbley%2Faudio-playback-cs/lists"}