-
Notifications
You must be signed in to change notification settings - Fork 0
Audio setup with WAV file loading #35
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Draft
nrbyte
wants to merge
5
commits into
main
Choose a base branch
from
audio
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Draft
Changes from all commits
Commits
Show all changes
5 commits
Select commit
Hold shift + click to select a range
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,29 @@ | ||
| using OpenTK.Audio.OpenAL; | ||
|
|
||
| using rasdaq.Logging; | ||
|
|
||
| namespace rasdaq.Audio; | ||
|
|
||
| public class Audio : IDisposable | ||
| { | ||
| public int Handle; | ||
|
|
||
| public Audio() | ||
| { | ||
| Handle = AL.GenBuffer(); | ||
| // Check for errors | ||
| ALError error = AL.GetError(); | ||
| if (error != ALError.NoError) | ||
| { | ||
| string err = $"OpenAL error while trying to create audio buffer: {error}"; | ||
|
|
||
| Log.Error(err); | ||
| throw new Exception(err); | ||
| } | ||
| } | ||
|
|
||
| public void Dispose() | ||
| { | ||
| AL.DeleteBuffer(Handle); | ||
| } | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,159 @@ | ||
| using OpenTK.Audio.OpenAL; | ||
|
|
||
| using rasdaq.Logging; | ||
|
|
||
| namespace rasdaq.Audio; | ||
|
|
||
| public class AudioManager | ||
| { | ||
| private static void CheckALCError(ALDevice device) | ||
| { | ||
| AlcError error = ALC.GetError(device); | ||
| if (error != AlcError.NoError) | ||
| { | ||
| string err = $"OpenAL error: {error}"; | ||
| Log.Error(err); | ||
| throw new Exception(err); | ||
| } | ||
| } | ||
|
|
||
| private static void CheckALError() | ||
| { | ||
| ALError error = AL.GetError(); | ||
| if (error != ALError.NoError) | ||
| { | ||
| string err = $"OpenAL error: {error}"; | ||
| Log.Error(err); | ||
| throw new Exception(err); | ||
| } | ||
| } | ||
|
|
||
| /// <summary> | ||
| /// Initialize Audio for the Application, using the default audio device. | ||
| /// </summary> | ||
| /// <exception cref="Exception"></exception> | ||
| public AudioManager() | ||
| { | ||
| // Open the default audio device. | ||
| ALDevice device = ALC.OpenDevice(null); | ||
| if (device == ALDevice.Null) | ||
| { | ||
| string err = "Failed to open the default audio device."; | ||
| Log.Error(err); | ||
| throw new Exception(err); | ||
| } | ||
|
|
||
| // Create a context for the device. | ||
| ALContext context = ALC.CreateContext(device, new ALContextAttributes(null, null, null, null, null)); | ||
| if (context == ALContext.Null) | ||
| { | ||
| ALC.CloseDevice(device); | ||
| string err = "Failed to create an OpenAL context."; | ||
| Log.Error(err); | ||
| throw new Exception(err); | ||
| } | ||
|
|
||
| // Check if we have any errors. | ||
| AlcError error = ALC.GetError(device); | ||
| CheckALCError(device); | ||
| // If no errors, make the context current. | ||
| ALC.MakeContextCurrent(context); | ||
| } | ||
|
|
||
| /// <summary> | ||
| /// Load a WAV file that contains PCM data only. | ||
| /// </summary> | ||
| /// <param name="path">Path to WAV file</param> | ||
| /// <returns>A integer handle referring to the loaded audio</returns> | ||
| /// <exception cref="Exception"></exception> | ||
| public Audio LoadAudio(string path) | ||
| { | ||
| // Create an OpenAL buffer for the data to go in. | ||
| Audio audio = new Audio(); | ||
|
|
||
| // Load the WAV file | ||
| WAVLoader.WAVData wavData = WAVLoader.LoadWav(path); | ||
|
|
||
| // Discern the format of the audio data based on number of channels and bits per sample. | ||
| ALFormat format; | ||
| if (wavData.Format.NumChannels == 1) | ||
| { | ||
| if (wavData.Format.BitsPerSample == 8) | ||
| { | ||
| format = ALFormat.Mono8; | ||
| } | ||
| else if (wavData.Format.BitsPerSample == 16) | ||
| { | ||
| format = ALFormat.Mono16; | ||
| } | ||
| else | ||
| { | ||
| string err = $"Unsupported bits per sample: {wavData.Format.BitsPerSample}"; | ||
| Log.Error(err); | ||
| throw new Exception(err); | ||
| } | ||
| } | ||
| else if (wavData.Format.NumChannels == 2) | ||
| { | ||
| if (wavData.Format.BitsPerSample == 8) | ||
| { | ||
| format = ALFormat.Stereo8; | ||
| } | ||
| else if (wavData.Format.BitsPerSample == 16) | ||
| { | ||
| format = ALFormat.Stereo16; | ||
| } | ||
| else | ||
| { | ||
| string err = $"Unsupported bits per sample: {wavData.Format.BitsPerSample}"; | ||
| Log.Error(err); | ||
| throw new Exception(err); | ||
| } | ||
| } | ||
| else | ||
| { | ||
| string err = $"Unsupported number of channels: {wavData.Format.NumChannels}"; | ||
| Log.Error(err); | ||
| throw new Exception(err); | ||
| } | ||
|
|
||
| // Load the audio data into the OpenAL buffer. | ||
| AL.BufferData(audio.Handle, format, wavData.Data.Data, (int)wavData.Format.SampleRate); | ||
|
|
||
| // Check if we have any errors from trying to load the audio data. | ||
| CheckALError(); | ||
|
|
||
| return audio; | ||
| } | ||
|
|
||
| /// <summary> | ||
| /// Add a loaded audio file to an audio source, so that it can be played. | ||
| /// </summary> | ||
| /// <param name="audio">Audio file</param> | ||
| /// <param name="audioSource">Audio source</param> | ||
| public void AttachAudioToSource(Audio audio, AudioSource audioSource) | ||
| { | ||
| AL.Source(audioSource.Handle, ALSourcei.Buffer, audio.Handle); | ||
| CheckALError(); | ||
| } | ||
|
|
||
| /// <summary> | ||
| /// Play back an audio source that has audio attached to it. | ||
| /// </summary> | ||
| /// <param name="source"></param> | ||
| public void PlaySource(AudioSource audioSource) | ||
|
Owner
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. would it not make sense to have the Play function be directly on the AudioSource component? Then you can do something like Entity.GetComponent().Play() |
||
| { | ||
| AL.SourcePlay(audioSource.Handle); | ||
| CheckALError(); | ||
| } | ||
|
|
||
| /// <summary> | ||
| /// Stop playback of an audio source. | ||
| /// </summary> | ||
| /// <param name="source"></param> | ||
| public void StopSource(AudioSource audioSource) | ||
| { | ||
| AL.SourceStop(audioSource.Handle); | ||
| CheckALError(); | ||
| } | ||
| } | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,29 @@ | ||
| using OpenTK.Audio.OpenAL; | ||
|
|
||
| using rasdaq.Logging; | ||
|
|
||
| namespace rasdaq.Audio; | ||
|
|
||
| public class AudioSource : IDisposable | ||
| { | ||
| public int Handle; | ||
|
|
||
| public AudioSource() | ||
| { | ||
| Handle = AL.GenSource(); | ||
| // Check for errors | ||
| ALError error = AL.GetError(); | ||
| if (error != ALError.NoError) | ||
| { | ||
| string err = $"OpenAL error while trying to create audio source: {error}"; | ||
|
|
||
| Log.Error(err); | ||
| throw new Exception("OpenAL error while trying to create audio source: " + error); | ||
| } | ||
| } | ||
|
|
||
| public void Dispose() | ||
| { | ||
| AL.DeleteSource(Handle); | ||
| } | ||
| } |
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
should add something in the pong sample to show using audio