summaryrefslogtreecommitdiffhomepage
path: root/src/raudio.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/raudio.c')
-rw-r--r--src/raudio.c72
1 files changed, 64 insertions, 8 deletions
diff --git a/src/raudio.c b/src/raudio.c
index 67510dc2..57f4294f 100644
--- a/src/raudio.c
+++ b/src/raudio.c
@@ -317,6 +317,7 @@ struct rAudioBuffer {
float volume; // Audio buffer volume
float pitch; // Audio buffer pitch
+ float pan; // Audio buffer pan (0 to 1)
bool playing; // Audio buffer state: AUDIO_PLAYING
bool paused; // Audio buffer state: AUDIO_PAUSED
@@ -373,7 +374,7 @@ static AudioData AUDIO = { // Global AUDIO context
//----------------------------------------------------------------------------------
static void OnLog(ma_context *pContext, ma_device *pDevice, ma_uint32 logLevel, const char *message);
static void OnSendAudioDataToDevice(ma_device *pDevice, void *pFramesOut, const void *pFramesInput, ma_uint32 frameCount);
-static void MixAudioFrames(float *framesOut, const float *framesIn, ma_uint32 frameCount, float localVolume);
+static void MixAudioFrames(float *framesOut, const float *framesIn, ma_uint32 frameCount, AudioBuffer *buffer);
#if defined(RAUDIO_STANDALONE)
static bool IsFileExtension(const char *fileName, const char *ext); // Check file extension
@@ -397,6 +398,7 @@ void StopAudioBuffer(AudioBuffer *buffer);
void PauseAudioBuffer(AudioBuffer *buffer);
void ResumeAudioBuffer(AudioBuffer *buffer);
void SetAudioBufferVolume(AudioBuffer *buffer, float volume);
+void SetAudioBufferPan(AudioBuffer *buffer, float pan);
void SetAudioBufferPitch(AudioBuffer *buffer, float pitch);
void TrackAudioBuffer(AudioBuffer *buffer);
void UntrackAudioBuffer(AudioBuffer *buffer);
@@ -553,6 +555,8 @@ AudioBuffer *LoadAudioBuffer(ma_format format, ma_uint32 channels, ma_uint32 sam
// Init audio buffer values
audioBuffer->volume = 1.0f;
audioBuffer->pitch = 1.0f;
+ audioBuffer->pan = 0.5f;
+
audioBuffer->playing = false;
audioBuffer->paused = false;
audioBuffer->looping = false;
@@ -641,6 +645,12 @@ void SetAudioBufferVolume(AudioBuffer *buffer, float volume)
if (buffer != NULL) buffer->volume = volume;
}
+// Set pan for an audio buffer
+void SetAudioBufferPan(AudioBuffer *buffer, float pan)
+{
+ if (buffer != NULL) buffer->pan = pan;
+}
+
// Set pitch for an audio buffer
void SetAudioBufferPitch(AudioBuffer *buffer, float pitch)
{
@@ -1048,6 +1058,8 @@ void PlaySoundMulti(Sound sound)
SetAudioBufferVolume(AUDIO.MultiChannel.pool[index], sound.stream.buffer->volume);
SetAudioBufferPitch(AUDIO.MultiChannel.pool[index], sound.stream.buffer->pitch);
+ SetAudioBufferPan(AUDIO.MultiChannel.pool[index], sound.stream.buffer->pan);
+
AUDIO.MultiChannel.pool[index]->looping = sound.stream.buffer->looping;
AUDIO.MultiChannel.pool[index]->usage = sound.stream.buffer->usage;
AUDIO.MultiChannel.pool[index]->isSubBufferProcessed[0] = false;
@@ -1113,6 +1125,12 @@ void SetSoundPitch(Sound sound, float pitch)
SetAudioBufferPitch(sound.stream.buffer, pitch);
}
+// Set pan for a sound
+void SetSoundPan(Sound sound, float pan)
+{
+ SetAudioBufferPan(sound.stream.buffer, pan);
+}
+
// Convert wave data to desired format
void WaveFormat(Wave *wave, int sampleRate, int sampleSize, int channels)
{
@@ -1809,6 +1827,12 @@ void SetMusicPitch(Music music, float pitch)
SetAudioBufferPitch(music.stream.buffer, pitch);
}
+// Set pan for a music
+void SetMusicPan(Music music, float pan)
+{
+ SetAudioBufferPan(music.stream.buffer, pan);
+}
+
// Get music time length (in seconds)
float GetMusicTimeLength(Music music)
{
@@ -1989,6 +2013,14 @@ void SetAudioStreamPitch(AudioStream stream, float pitch)
SetAudioBufferPitch(stream.buffer, pitch);
}
+// Set pan for audio stream
+void SetAudioStreamPan(AudioStream stream, float pan)
+{
+ if (pan < 0.0f) pan = 0.0f; else if (pan > 1.0f) pan = 1.0f;
+ SetAudioBufferPan(stream.buffer, pan);
+}
+
+
// Default size for new audio streams
void SetAudioStreamBufferSizeDefault(int size)
{
@@ -2184,7 +2216,7 @@ static void OnSendAudioDataToDevice(ma_device *pDevice, void *pFramesOut, const
float *framesOut = (float *)pFramesOut + (framesRead*AUDIO.System.device.playback.channels);
float *framesIn = tempBuffer;
- MixAudioFrames(framesOut, framesIn, framesJustRead, audioBuffer->volume);
+ MixAudioFrames(framesOut, framesIn, framesJustRead, audioBuffer);
framesToRead -= framesJustRead;
framesRead += framesJustRead;
@@ -2226,16 +2258,40 @@ static void OnSendAudioDataToDevice(ma_device *pDevice, void *pFramesOut, const
// This is the main mixing function. Mixing is pretty simple in this project - it's just an accumulation.
// NOTE: framesOut is both an input and an output. It will be initially filled with zeros outside of this function.
-static void MixAudioFrames(float *framesOut, const float *framesIn, ma_uint32 frameCount, float localVolume)
+static void MixAudioFrames(float *framesOut, const float *framesIn, ma_uint32 frameCount, AudioBuffer *buffer)
{
- for (ma_uint32 iFrame = 0; iFrame < frameCount; ++iFrame)
+ const float localVolume = buffer->volume;
+
+ const ma_uint32 nChannels = AUDIO.System.device.playback.channels;
+ if (nChannels == 2)
+ {
+ const float left = buffer->pan;
+ const float right = 1.0f - left;
+
+ // fast sine approximation in [0..1] for pan law: y = 0.5f * x * (3 - x * x);
+ const float levels[2] = { localVolume*0.5f*left*(3.0f-left*left), localVolume*0.5f*right*(3.0f-right*right) };
+
+ float *frameOut = framesOut;
+ const float *frameIn = framesIn;
+ for (ma_uint32 iFrame = 0; iFrame < frameCount; ++iFrame)
+ {
+ frameOut[0] += (frameIn[0]*levels[0]);
+ frameOut[1] += (frameIn[1]*levels[1]);
+ frameOut += 2;
+ frameIn += 2;
+ }
+ }
+ else // pan is kinda meaningless
{
- for (ma_uint32 iChannel = 0; iChannel < AUDIO.System.device.playback.channels; ++iChannel)
+ for (ma_uint32 iFrame = 0; iFrame < frameCount; ++iFrame)
{
- float *frameOut = framesOut + (iFrame*AUDIO.System.device.playback.channels);
- const float *frameIn = framesIn + (iFrame*AUDIO.System.device.playback.channels);
+ for (ma_uint32 iChannel = 0; iChannel < nChannels; ++iChannel)
+ {
+ float *frameOut = framesOut + (iFrame * nChannels);
+ const float *frameIn = framesIn + (iFrame * nChannels);
- frameOut[iChannel] += (frameIn[iChannel]*localVolume);
+ frameOut[iChannel] += (frameIn[iChannel] * localVolume);
+ }
}
}
}