MVE: Initial sound support

Sound supported by SDL backend.
This commit is contained in:
Azamat H. Hackimov 2024-05-05 18:36:16 +03:00
parent a8784ee524
commit afd7c1a636
4 changed files with 45 additions and 56 deletions

View File

@ -23,8 +23,8 @@
// Max&Min values for settings
#define LNXSND_VOLUME_MAX 0
#define LNXSND_VOLUME_MIN -10000
#define LNXSND_PAN_LEFT -10000
#define LNXSND_VOLUME_MIN (-10000)
#define LNXSND_PAN_LEFT (-10000)
#define LNXSND_PAN_RIGHT 10000
// Status/Buffer flags

View File

@ -16,26 +16,17 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <assert.h>
#include <errno.h>
#include <sys/types.h>
#include <cassert>
#ifdef __LINUX__
#include <sys/time.h>
#include <sys/fcntl.h>
#include <unistd.h>
#include <sched.h>
#include <cstdlib>
#include <cstring>
#include <cmath>
#endif
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <math.h>
#include <memory.h>
#include "lnxdsound.h"
#include <SDL_audio.h>
#include "args.h"
#include "SDL.h"
#include "SDL_audio.h"
#include "lnxdsound.h"
#define FRAGMENT_LENGTH (LnxBuffers[0]->bps >> 4)
#define FREQUENCY_SHIFT (14)
@ -56,9 +47,9 @@ static uint32_t LinuxSoundMixInMainBuffer(LnxSoundBuffer *dsb, int len);
static void LinuxSoundMixBuffersIntoMain(int len);
static void LinuxSoundThreadHandler(void *unused, Uint8 *stream, int len);
static inline void enter_critical(void) { SDL_LockAudio(); }
static inline void enter_critical() { SDL_LockAudio(); }
static inline void exit_critical(void) { SDL_UnlockAudio(); }
static inline void exit_critical() { SDL_UnlockAudio(); }
///////////////////////////////
// LnxSound_CreateSoundBuffer
@ -113,7 +104,7 @@ int LnxSound_CreateSoundBuffer(LnxSoundDevice *dev, LnxBufferDesc *lbdesc, LnxSo
(*lsndb)->buffer_len = dev->bps;
(*lsndb)->freq = dev->freq;
(*lsndb)->bps = dev->bps;
(*lsndb)->buffer = NULL;
(*lsndb)->buffer = nullptr;
} else {
(*lsndb)->buffer_len = lbdesc->dwBufferBytes;
(*lsndb)->freq = lbdesc->lpwfxFormat->nSamplesPerSec;
@ -121,7 +112,7 @@ int LnxSound_CreateSoundBuffer(LnxSoundDevice *dev, LnxBufferDesc *lbdesc, LnxSo
(*lsndb)->buffer = (uint8_t *)malloc((*lsndb)->buffer_len);
if (!(*lsndb)->buffer) {
free(*lsndb);
*lsndb = NULL;
*lsndb = nullptr;
return -2;
}
memset((*lsndb)->buffer, 0, (*lsndb)->buffer_len);
@ -197,7 +188,7 @@ int LnxSoundBuffer_Release(LnxSoundBuffer *buff) {
ShutdownSoundSystem();
LnxNumBuffers = 0;
LnxBuffers = NULL;
LnxBuffers = nullptr;
} else {
// wait until it is ok (our thread is in a good position)
enter_critical();
@ -450,7 +441,7 @@ int LnxSoundBuffer_Lock(LnxSoundBuffer *buff, uint32_t pos, uint32_t numbytes, v
*(uint8_t **)ptr1 = buff->buffer + pos;
*numbytes1 = numbytes;
if (ptr2)
*(uint8_t **)ptr2 = NULL;
*(uint8_t **)ptr2 = nullptr;
if (numbytes2)
*numbytes2 = 0;
} else {
@ -513,7 +504,7 @@ static bool StartupSoundSystem(LnxSoundDevice *dev) {
spec.samples = sampleCount;
spec.callback = LinuxSoundThreadHandler;
if (SDL_OpenAudio(&spec, NULL) < 0) {
if (SDL_OpenAudio(&spec, nullptr) < 0) {
return false;
}
SDL_PauseAudio(0);
@ -521,7 +512,7 @@ static bool StartupSoundSystem(LnxSoundDevice *dev) {
}
// Shutsdown the sound processing thread
static void ShutdownSoundSystem(void) { SDL_CloseAudio(); }
static void ShutdownSoundSystem() { SDL_CloseAudio(); }
static inline void GetValues(const LnxSoundBuffer *dsb, uint8_t *buf, uint32_t *fl, uint32_t *fr) {
int16_t *bufs = (int16_t *)buf;
@ -553,7 +544,6 @@ static inline void GetValues(const LnxSoundBuffer *dsb, uint8_t *buf, uint32_t *
*fr = *bufs;
return;
}
return;
}
static inline void SetValues(uint8_t *buf, uint32_t fl, uint32_t fr) {
@ -584,7 +574,6 @@ static inline void SetValues(uint8_t *buf, uint32_t fl, uint32_t fr) {
*bufs = (fl + fr) >> 1;
return;
}
return;
}
static void LinuxSoundMixWithVolume(LnxSoundBuffer *dsb, uint8_t *buf, uint32_t len) {
@ -676,7 +665,7 @@ int DoMulDiv(int nNumber, int nNumerator, int nDenominator) {
return ret;
}
static void *TempSoundBuffer = NULL;
static void *TempSoundBuffer = nullptr;
static int TempSoundBufferLen = 0;
static uint32_t LinuxSoundMixInMainBuffer(LnxSoundBuffer *dsb, int len) {
uint32_t i, ilen, advance = (LnxBuffers[0]->wfx.wBitsPerSample >> 3);
@ -786,5 +775,5 @@ static void LinuxSoundThreadHandler(void *unused, Uint8 *stream, int len) {
LinuxSoundMixBuffersIntoMain(len);
LnxBuffers[0]->buffer = NULL;
LnxBuffers[0]->buffer = nullptr;
}

View File

@ -16,7 +16,7 @@
*/
// TODO
//#define AUDIO
#define AUDIO
#include <cstring>
#ifdef _WIN32
@ -28,7 +28,6 @@
#if defined(AUDIO)
#include <SDL.h>
#include "SDL_mixer.h"
#endif
#include "decoders.h"
@ -63,7 +62,7 @@ int g_spdFactorNum = 0;
static int g_spdFactorDenom = 10;
static int g_frameUpdated = 0;
static ISoundDevice *snd_ds = NULL;
static ISoundDevice *snd_ds = nullptr;
static short get_short(unsigned char *data) {
short value;
@ -130,7 +129,7 @@ unsigned long int timer_getmicroseconds() {
struct timeval tv;
static time_t starttime = 0;
gettimeofday(&tv, NULL);
gettimeofday(&tv, nullptr);
if (!starttime)
starttime = tv.tv_sec;
@ -149,7 +148,7 @@ void timer_sleepmicroseconds(unsigned long int usec) {
struct timespec ts;
ts.tv_sec = usec / 1000000;
ts.tv_nsec = usec % 1000000 * 1000;
nanosleep(&ts, NULL);
nanosleep(&ts, nullptr);
#endif
}
@ -177,18 +176,18 @@ static int create_timer_handler(unsigned char major, unsigned char minor, unsign
return 1;
}
static void timer_stop(void) {
static void timer_stop() {
timer_expire = 0;
timer_started = 0;
}
static void timer_start(void) {
static void timer_start() {
timer_expire = timer_getmicroseconds();
timer_expire += micro_frame_delay;
timer_started = 1;
}
static void do_timer_wait(void) {
static void do_timer_wait() {
unsigned long int ts;
unsigned long int tv;
@ -211,12 +210,10 @@ end:
* audio handlers
*************************/
static int mve_audio_enabled = 0;
#ifdef AUDIO
#define TOTAL_AUDIO_BUFFERS 64
static int audiobuf_created = 0;
static void mve_audio_callback(void *userdata, unsigned char *stream, int len);
static short *mve_audio_buffers[TOTAL_AUDIO_BUFFERS];
static int mve_audio_buflens[TOTAL_AUDIO_BUFFERS];
static int mve_audio_curbuf_curpos = 0;
@ -295,7 +292,6 @@ static int create_audiobuf_handler(unsigned char major, unsigned char minor, uns
int stereo;
int bitsize;
int compressed;
int format;
@ -314,16 +310,13 @@ static int create_audiobuf_handler(unsigned char major, unsigned char minor, uns
stereo = (flags & MVE_AUDIO_FLAGS_STEREO) ? 1 : 0;
bitsize = (flags & MVE_AUDIO_FLAGS_16BIT) ? 1 : 0;
if (minor > 0) {
compressed = flags & MVE_AUDIO_FLAGS_COMPRESSED ? 1 : 0;
} else {
compressed = 0;
mve_audio_compressed = 0;
if (minor > 0 && (flags & MVE_AUDIO_FLAGS_COMPRESSED)) {
mve_audio_compressed = 1;
}
mve_audio_compressed = compressed;
if (bitsize == 1) {
#ifdef WORDS_BIGENDIAN
#ifdef OUTRAGE_BIG_ENDIAN
format = AUDIO_S16MSB;
#else
format = AUDIO_S16LSB;
@ -334,17 +327,23 @@ static int create_audiobuf_handler(unsigned char major, unsigned char minor, uns
fprintf(stderr, "creating audio buffers:\n");
fprintf(stderr, "sample rate = %d, stereo = %d, bitsize = %d, compressed = %d\n", sample_rate, stereo,
bitsize ? 16 : 8, compressed);
bitsize ? 16 : 8, mve_audio_compressed);
if (Mix_OpenAudio(sample_rate, format, stereo ? 2 : 1, 4096) == 0) {
SDL_AudioSpec spec {
.freq = sample_rate,
.format = (unsigned short)format,
.channels = (unsigned char)(stereo ? 2 : 1),
.size = (unsigned int)desired_buffer,
.callback = mve_audio_callback,
};
if (SDL_OpenAudio(&spec, nullptr) == 0) {
fprintf(stderr, " success\n");
mve_audio_canplay = 1;
} else {
fprintf(stderr, " failure : %s\n", Mix_GetError());
fprintf(stderr, " failure : %s\n", SDL_GetError());
mve_audio_canplay = 0;
}
Mix_SetPostMix(mve_audio_callback, NULL);
mve_audio_canplay = 1;
memset(mve_audio_buffers, 0, sizeof(mve_audio_buffers));
@ -357,7 +356,7 @@ static int create_audiobuf_handler(unsigned char major, unsigned char minor, uns
static int play_audio_handler(unsigned char major, unsigned char minor, unsigned char *data, int len, void *context) {
#ifdef AUDIO
if (mve_audio_canplay && !mve_audio_playing && mve_audio_bufhead != mve_audio_buftail) {
Mix_Resume(-1);
SDL_PauseAudio(0);
mve_audio_playing = 1;
}
#endif
@ -650,7 +649,7 @@ void MVE_rmEndMovie(MVESTREAM *mve) {
#ifdef AUDIO
if (mve_audio_canplay) {
// only close audio if we opened it
Mix_CloseAudio();
SDL_CloseAudio();
mve_audio_canplay = 0;
}
for (int i = 0; i < TOTAL_AUDIO_BUFFERS; i++)

View File

@ -222,7 +222,7 @@ public:
ISysSoundBuffer *p = (ISysSoundBuffer *)new MovieSoundBuffer(sb);
*lsndb = p;
} else {
lsndb = NULL;
lsndb = nullptr;
}
return ret;
}
@ -692,6 +692,7 @@ bool mve_InitSound(oeApplication *app, MovieSoundDevice &device) {
device.SetDirectSound(snddev);
MVE_sndInit(&device);
MVE_sndInit(1);
return true;
}