Commit 1c268939 authored by David Reid's avatar David Reid

Add initial implementation of stereo panning to the ma_engine API.

This currently only supports f32, but support for more formats will be
coming soon.
parent f4b0b271
......@@ -35,14 +35,15 @@ int main(int argc, char** argv)
}
ma_engine_sound_set_pitch(&engine, &sound1, 0.75f);
ma_engine_sound_set_pan(&engine, &sound1, -1.0f);
ma_engine_sound_set_looping(&engine, &sound1, MA_TRUE);
ma_engine_sound_start(&engine, &sound1);
result = ma_engine_play_sound(&engine, argv[1], NULL);
/*result = ma_engine_play_sound(&engine, argv[1], NULL);
if (result != MA_SUCCESS) {
printf("ma_engine_play_sound() failed with: %s\n", ma_result_description(result));
}
}*/
}
......
......@@ -309,7 +309,7 @@ MA_API void ma_engine_uninit(ma_engine* pEngine);
MA_API ma_result ma_engine_start(ma_engine* pEngine);
MA_API ma_result ma_engine_stop(ma_engine* pEngine);
MA_API ma_result ma_engine_set_volume(ma_engine* pEngine, float volume);
MA_API ma_result me_engine_set_gain_db(ma_engine* pEngine, float gainDB);
MA_API ma_result ma_engine_set_gain_db(ma_engine* pEngine, float gainDB);
#ifndef MA_NO_RESOURCE_MANAGER
MA_API ma_result ma_engine_create_sound_from_file(ma_engine* pEngine, const char* pFilePath, ma_sound_group* pGroup, ma_sound* pSound);
......@@ -319,7 +319,8 @@ MA_API void ma_engine_delete_sound(ma_engine* pEngine, ma_sound* pSound);
MA_API ma_result ma_engine_sound_start(ma_engine* pEngine, ma_sound* pSound);
MA_API ma_result ma_engine_sound_stop(ma_engine* pEngine, ma_sound* pSound);
MA_API ma_result ma_engine_sound_set_volume(ma_engine* pEngine, ma_sound* pSound, float volume);
MA_API ma_result me_engine_sound_set_gain_db(ma_engine* pEngine, ma_sound* pSound, float gainDB);
MA_API ma_result ma_engine_sound_set_gain_db(ma_engine* pEngine, ma_sound* pSound, float gainDB);
MA_API ma_result ma_engine_sound_set_pan(ma_engine* pEngine, ma_sound* pSound, float pan);
MA_API ma_result ma_engine_sound_set_pitch(ma_engine* pEngine, ma_sound* pSound, float pitch);
MA_API ma_result ma_engine_sound_set_effect(ma_engine* pEngine, ma_sound* pSound, ma_effect* pEffect);
MA_API ma_result ma_engine_sound_set_position(ma_engine* pEngine, ma_sound* pSound, ma_vec3 position);
......@@ -505,14 +506,76 @@ MA_API ma_result ma_panner_init(const ma_panner_config* pConfig, ma_panner* pPan
return MA_SUCCESS;
}
static void ma_stereo_pan_pcm_frames_f32(float* pFramesOut, const float* pFramesIn, ma_uint64 frameCount, float pan)
{
float factorL0;
float factorR0;
float factorL1;
float factorR1;
ma_uint64 iFrame;
/* TODO: We can optimize this by removing some multiplies and adds. */
if (pan > 0) {
factorL0 = 1.0f - pan;
factorR0 = 0.0f;
factorL1 = 0.0f + pan;
factorR1 = 1.0f;
} else {
factorL0 = 1.0f;
factorR0 = 0.0f - pan;
factorL1 = 0.0f;
factorR1 = 1.0f + pan;
}
for (iFrame = 0; iFrame < frameCount; iFrame += 1) {
pFramesOut[iFrame*2 + 0] = (pFramesIn[iFrame*2 + 0] * factorL0) + (pFramesIn[iFrame*2 + 1] * factorR0);
pFramesOut[iFrame*2 + 1] = (pFramesIn[iFrame*2 + 0] * factorL1) + (pFramesIn[iFrame*2 + 1] * factorR1);
}
}
static void ma_stereo_pan_pcm_frames(void* pFramesOut, const void* pFramesIn, ma_uint64 frameCount, ma_format format, float pan)
{
if (pan == 0) {
/* Fast path. No panning required. */
if (pFramesOut == pFramesIn) {
/* No-op */
} else {
ma_copy_pcm_frames(pFramesOut, pFramesIn, frameCount, format, 2);
}
}
switch (format) {
case ma_format_f32: ma_stereo_pan_pcm_frames_f32(pFramesOut, pFramesIn, frameCount, pan); break;
/* Unknown format. Just copy. */
default:
{
ma_copy_pcm_frames(pFramesOut, pFramesIn, frameCount, format, 2);
} break;
}
}
MA_API ma_result ma_panner_process_pcm_frames(ma_panner* pPanner, void* pFramesOut, const void* pFramesIn, ma_uint64 frameCount)
{
if (pPanner == NULL || pFramesOut == NULL || pFramesIn) {
if (pPanner == NULL || pFramesOut == NULL || pFramesIn == NULL) {
return MA_INVALID_ARGS;
}
/* TODO: Implement me. Just copying for now. */
if (pPanner->channels == 2) {
/* Stereo case. For now assume channel 0 is left and channel right is 1, but should probably add support for a channel map. */
ma_stereo_pan_pcm_frames(pFramesOut, pFramesIn, frameCount, pPanner->format, pPanner->pan);
} else {
if (pPanner->channels == 1) {
/* Panning has no effect on mono streams. */
ma_copy_pcm_frames(pFramesOut, pFramesIn, frameCount, pPanner->format, pPanner->channels);
} else {
/* For now we're not going to support non-stereo set ups. Not sure how I want to handle this case just yet. */
ma_copy_pcm_frames(pFramesOut, pFramesIn, frameCount, pPanner->format, pPanner->channels);
}
}
return MA_SUCCESS;
}
......@@ -1023,7 +1086,7 @@ MA_API ma_result ma_engine_set_volume(ma_engine* pEngine, float volume)
return ma_device_set_master_volume(&pEngine->listener.device, volume);
}
MA_API ma_result me_engine_set_gain_db(ma_engine* pEngine, float gainDB)
MA_API ma_result ma_engine_set_gain_db(ma_engine* pEngine, float gainDB)
{
if (pEngine == NULL) {
return MA_INVALID_ARGS;
......@@ -1594,7 +1657,7 @@ MA_API ma_result ma_engine_sound_set_volume(ma_engine* pEngine, ma_sound* pSound
return MA_SUCCESS;
}
MA_API ma_result me_engine_sound_set_gain_db(ma_engine* pEngine, ma_sound* pSound, float gainDB)
MA_API ma_result ma_engine_sound_set_gain_db(ma_engine* pEngine, ma_sound* pSound, float gainDB)
{
if (pEngine == NULL || pSound == NULL) {
return MA_INVALID_ARGS;
......@@ -1614,6 +1677,15 @@ MA_API ma_result ma_engine_sound_set_pitch(ma_engine* pEngine, ma_sound* pSound,
return MA_SUCCESS;
}
MA_API ma_result ma_engine_sound_set_pan(ma_engine* pEngine, ma_sound* pSound, float pan)
{
if (pEngine == NULL || pSound == NULL) {
return MA_INVALID_ARGS;
}
return ma_panner_set_pan(&pSound->effect.panner, pan);
}
MA_API ma_result ma_engine_sound_set_effect(ma_engine* pEngine, ma_sound* pSound, ma_effect* pEffect)
{
if (pEngine == NULL || pSound == NULL) {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment