mirror of
https://github.com/kevinbentley/Descent3.git
synced 2025-01-22 11:28:56 +00:00
Update MVE playback on Windows
There only one problem still persist on playback - slow filling sound buffer from std::deque on MSVC Debug mode due extremely slow performance of STL containers on that mode. On Release and RelWithDebInfo playback is fine.
This commit is contained in:
parent
8fd119bd3d
commit
9672475f70
@ -2,12 +2,12 @@ set(CPPS
|
|||||||
# mveasm.cpp
|
# mveasm.cpp
|
||||||
# mvelibl.cpp
|
# mvelibl.cpp
|
||||||
# platform.cpp
|
# platform.cpp
|
||||||
lnxdsound.cpp
|
# lnxdsound.cpp
|
||||||
lnx_sound.cpp
|
|
||||||
|
|
||||||
# d2x implementation
|
# d2x implementation
|
||||||
decoder8.cpp
|
decoder8.cpp
|
||||||
decoder16.cpp
|
decoder16.cpp
|
||||||
|
lnx_sound.cpp
|
||||||
mve_audio.cpp
|
mve_audio.cpp
|
||||||
mvelib.cpp
|
mvelib.cpp
|
||||||
mveplay.cpp
|
mveplay.cpp
|
||||||
|
@ -26,23 +26,22 @@ void MovieSoundDevice::SDLAudioCallback(void *userdata, unsigned char *stream, i
|
|||||||
for (int i = 0; i < len; i += 2) {
|
for (int i = 0; i < len; i += 2) {
|
||||||
int16_t sample = device->m_sound_buffer->front();
|
int16_t sample = device->m_sound_buffer->front();
|
||||||
device->m_sound_buffer->pop_front();
|
device->m_sound_buffer->pop_front();
|
||||||
stream[i] = sample & 0xff;
|
memcpy(&stream[i], &sample, 2);
|
||||||
stream[i + 1] = sample >> 8;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
MovieSoundDevice::MovieSoundDevice(int sample_rate, uint16_t sample_size, uint8_t channels, uint32_t buf_size,
|
MovieSoundDevice::MovieSoundDevice(int sample_rate, uint16_t sample_size, uint8_t channels, uint32_t buf_size,
|
||||||
bool is_compressed) {
|
bool is_compressed) {
|
||||||
SDL_AudioFormat format = (sample_size == 2) ? AUDIO_S16LSB : AUDIO_U8;
|
SDL_AudioFormat format = (sample_size == 2) ? AUDIO_S16LSB : AUDIO_U8;
|
||||||
SDL_AudioSpec spec{
|
SDL_AudioSpec spec;
|
||||||
.freq = sample_rate,
|
spec.freq = sample_rate;
|
||||||
.format = format,
|
spec.format = format;
|
||||||
.channels = channels,
|
spec.channels = channels;
|
||||||
.size = buf_size,
|
spec.size = 4096;
|
||||||
.callback = &MovieSoundDevice::SDLAudioCallback,
|
spec.callback = &MovieSoundDevice::SDLAudioCallback;
|
||||||
.userdata = this,
|
spec.userdata = this;
|
||||||
};
|
|
||||||
m_device_id = SDL_OpenAudioDevice(nullptr, 0, &spec, nullptr, SDL_AUDIO_ALLOW_ANY_CHANGE);
|
m_device_id = SDL_OpenAudioDevice(nullptr, 0, &spec, nullptr, 0);
|
||||||
m_is_compressed = is_compressed;
|
m_is_compressed = is_compressed;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -33,7 +33,7 @@ public:
|
|||||||
MovieSoundDevice(int sample_rate, uint16_t sample_size, uint8_t channels, uint32_t buf_size, bool is_compressed);
|
MovieSoundDevice(int sample_rate, uint16_t sample_size, uint8_t channels, uint32_t buf_size, bool is_compressed);
|
||||||
~MovieSoundDevice();
|
~MovieSoundDevice();
|
||||||
|
|
||||||
[[nodiscard]] bool IsInitialized() const { return m_device_id > 0 ? true : false; }
|
[[nodiscard]] bool IsInitialized() const { return m_device_id > 0; }
|
||||||
|
|
||||||
void static SDLAudioCallback(void *userdata, unsigned char *stream, int len);
|
void static SDLAudioCallback(void *userdata, unsigned char *stream, int len);
|
||||||
|
|
||||||
|
@ -30,12 +30,8 @@
|
|||||||
#include "mve_audio.h"
|
#include "mve_audio.h"
|
||||||
|
|
||||||
#ifdef AUDIO
|
#ifdef AUDIO
|
||||||
#ifdef _WIN32
|
|
||||||
|
|
||||||
#else
|
|
||||||
#include "lnx_sound.h"
|
#include "lnx_sound.h"
|
||||||
#endif
|
#endif
|
||||||
#endif
|
|
||||||
|
|
||||||
#define MVE_OPCODE_ENDOFSTREAM 0x00 // mcmd_end
|
#define MVE_OPCODE_ENDOFSTREAM 0x00 // mcmd_end
|
||||||
#define MVE_OPCODE_ENDOFCHUNK 0x01 // mcmd_next
|
#define MVE_OPCODE_ENDOFCHUNK 0x01 // mcmd_next
|
||||||
@ -140,6 +136,13 @@ static void timer_start() {
|
|||||||
timer_started = 1;
|
timer_started = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef AUDIO
|
||||||
|
static std::unique_ptr<D3::MovieSoundDevice> snd_ds;
|
||||||
|
static int mve_audio_enabled = 1;
|
||||||
|
#else
|
||||||
|
static int mve_audio_enabled = 0;
|
||||||
|
#endif
|
||||||
|
|
||||||
static void do_timer_wait() {
|
static void do_timer_wait() {
|
||||||
uint64_t ts;
|
uint64_t ts;
|
||||||
uint64_t tv;
|
uint64_t tv;
|
||||||
@ -153,6 +156,7 @@ static void do_timer_wait() {
|
|||||||
|
|
||||||
ts = timer_expire - tv;
|
ts = timer_expire - tv;
|
||||||
|
|
||||||
|
//mprintf(0,"SLEEP for %llu us, buffer size is %d\n", ts, snd_ds->GetBuffer()->size());
|
||||||
timer_sleepmicroseconds(ts);
|
timer_sleepmicroseconds(ts);
|
||||||
|
|
||||||
end:
|
end:
|
||||||
@ -163,13 +167,6 @@ end:
|
|||||||
* audio handlers
|
* audio handlers
|
||||||
*************************/
|
*************************/
|
||||||
|
|
||||||
#ifdef AUDIO
|
|
||||||
static std::unique_ptr<D3::MovieSoundDevice> snd_ds;
|
|
||||||
static int mve_audio_enabled = 1;
|
|
||||||
#else
|
|
||||||
static int mve_audio_enabled = 0;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
static int create_audiobuf_handler(unsigned char major, unsigned char minor, unsigned char *data, int len,
|
static int create_audiobuf_handler(unsigned char major, unsigned char minor, unsigned char *data, int len,
|
||||||
void *context) {
|
void *context) {
|
||||||
#ifdef AUDIO
|
#ifdef AUDIO
|
||||||
@ -188,7 +185,7 @@ static int create_audiobuf_handler(unsigned char major, unsigned char minor, uns
|
|||||||
is_compressed = true;
|
is_compressed = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
snd_ds = std::make_unique<D3::MovieSoundDevice>(sample_rate, sample_size, channels, 4096, is_compressed);
|
snd_ds = std::make_unique<D3::MovieSoundDevice>(sample_rate, sample_size, channels, desired_buffer, is_compressed);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
|
155
libmve/win_sound.cpp
Normal file
155
libmve/win_sound.cpp
Normal file
@ -0,0 +1,155 @@
|
|||||||
|
/*
|
||||||
|
* Descent 3
|
||||||
|
* Copyright (C) 2024 Descent Developers
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "win_sound.h"
|
||||||
|
|
||||||
|
namespace D3 {
|
||||||
|
|
||||||
|
MovieSoundDevice::MovieSoundDevice(int sample_rate, uint16_t sample_size, uint8_t channels, uint32_t buf_size,
|
||||||
|
bool is_compressed) {
|
||||||
|
m_is_compressed = is_compressed;
|
||||||
|
|
||||||
|
m_lpDS = nullptr;
|
||||||
|
m_lpDSB = nullptr;
|
||||||
|
|
||||||
|
m_WFE.wFormatTag = WAVE_FORMAT_PCM;
|
||||||
|
m_WFE.nChannels = channels;
|
||||||
|
m_WFE.nSamplesPerSec = sample_rate;
|
||||||
|
m_WFE.nAvgBytesPerSec = sample_rate * channels * sample_size;
|
||||||
|
m_WFE.nBlockAlign = channels * sample_size;
|
||||||
|
m_WFE.wBitsPerSample = sample_size * 8;
|
||||||
|
|
||||||
|
// Initialize DSound
|
||||||
|
if (FAILED(DirectSoundCreate(nullptr, &m_lpDS, nullptr))) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// Set Cooperative Level
|
||||||
|
HWND hWnd = GetForegroundWindow();
|
||||||
|
if (hWnd == nullptr) {
|
||||||
|
hWnd = GetDesktopWindow();
|
||||||
|
}
|
||||||
|
if (FAILED(m_lpDS->SetCooperativeLevel(hWnd, DSSCL_EXCLUSIVE))) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create Primary Buffer
|
||||||
|
DSBUFFERDESC dsbd;
|
||||||
|
ZeroMemory(&dsbd, sizeof(dsbd));
|
||||||
|
dsbd.dwSize = sizeof(DSBUFFERDESC);
|
||||||
|
dsbd.dwFlags = DSBCAPS_PRIMARYBUFFER;
|
||||||
|
dsbd.dwBufferBytes = 0;
|
||||||
|
dsbd.lpwfxFormat = nullptr;
|
||||||
|
|
||||||
|
LPDIRECTSOUNDBUFFER lpDSB = nullptr;
|
||||||
|
if (FAILED(m_lpDS->CreateSoundBuffer(&dsbd, &lpDSB, nullptr))) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set Primary Buffer Format
|
||||||
|
if (FAILED(lpDSB->SetFormat(&m_WFE))) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create Second Sound Buffer
|
||||||
|
dsbd.dwFlags = DSBCAPS_CTRLPOSITIONNOTIFY | DSBCAPS_GLOBALFOCUS;
|
||||||
|
dsbd.dwBufferBytes = (buf_size + (buf_size >> 1)) & ~3;
|
||||||
|
dsbd.lpwfxFormat = &m_WFE;
|
||||||
|
|
||||||
|
if (FAILED(m_lpDS->CreateSoundBuffer(&dsbd, &m_lpDSB, nullptr))) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
MovieSoundDevice::~MovieSoundDevice() {
|
||||||
|
if (m_lpDSB != nullptr) {
|
||||||
|
m_lpDSB->Stop();
|
||||||
|
m_lpDSB->Release();
|
||||||
|
}
|
||||||
|
m_sound_buffer.reset();
|
||||||
|
}
|
||||||
|
|
||||||
|
void MovieSoundDevice::Play() {
|
||||||
|
if (!m_lpDSB)
|
||||||
|
return;
|
||||||
|
|
||||||
|
// Check if the DirectSound was created successfully
|
||||||
|
if (m_lpDS == nullptr) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
LPBYTE lpvAudio1 = nullptr, lpvAudio2 = nullptr;
|
||||||
|
DWORD dwBytesAudio1 = 0, dwBytesAudio2 = 0;
|
||||||
|
|
||||||
|
if (FAILED(m_lpDSB->Lock(0, (DWORD)GetBuffer()->size() * 2, reinterpret_cast<LPVOID *>(&lpvAudio1), &dwBytesAudio1,
|
||||||
|
reinterpret_cast<LPVOID *>(&lpvAudio2), &dwBytesAudio2, DSBLOCK_FROMWRITECURSOR)))
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (dwBytesAudio1 > 0) {
|
||||||
|
memset(lpvAudio1, 0, dwBytesAudio1);
|
||||||
|
auto limit = std::min(dwBytesAudio1 / 2, (DWORD)GetBuffer()->size());
|
||||||
|
for (int i = 0; i < limit; i += 2) {
|
||||||
|
int16_t sample = GetBuffer()->front();
|
||||||
|
GetBuffer()->pop_front();
|
||||||
|
lpvAudio1[i] = sample & 0xff;
|
||||||
|
lpvAudio1[i + 1] = sample >> 8;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (dwBytesAudio2 > 0) {
|
||||||
|
memset(lpvAudio2, 0, dwBytesAudio2);
|
||||||
|
auto limit = std::min(dwBytesAudio2 / 2, (DWORD)GetBuffer()->size());
|
||||||
|
for (int i = 0; i < limit; i += 2) {
|
||||||
|
int16_t sample = GetBuffer()->front();
|
||||||
|
GetBuffer()->pop_front();
|
||||||
|
lpvAudio2[i] = sample & 0xff;
|
||||||
|
lpvAudio2[i + 1] = sample >> 8;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
m_lpDSB->Unlock(lpvAudio1, dwBytesAudio1, lpvAudio2, dwBytesAudio2);
|
||||||
|
|
||||||
|
// Begin Play
|
||||||
|
m_lpDSB->Play(0, 0, DSBPLAY_LOOPING);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void MovieSoundDevice::Stop() {
|
||||||
|
if (m_lpDSB != nullptr) {
|
||||||
|
|
||||||
|
m_lpDSB->Stop();
|
||||||
|
|
||||||
|
// Empty the buffer
|
||||||
|
LPVOID lpvAudio1 = nullptr;
|
||||||
|
DWORD dwBytesAudio1 = 0;
|
||||||
|
HRESULT hr = m_lpDSB->Lock(0, 0, &lpvAudio1, &dwBytesAudio1, nullptr, nullptr, DSBLOCK_ENTIREBUFFER);
|
||||||
|
if (FAILED(hr)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
memset(lpvAudio1, 0, dwBytesAudio1);
|
||||||
|
m_lpDSB->Unlock(lpvAudio1, dwBytesAudio1, nullptr, 0);
|
||||||
|
|
||||||
|
// Move the current play position to begin
|
||||||
|
m_lpDSB->SetCurrentPosition(0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void MovieSoundDevice::Lock(){}
|
||||||
|
|
||||||
|
void MovieSoundDevice::Unlock(){}
|
||||||
|
|
||||||
|
} // namespace D3
|
55
libmve/win_sound.h
Normal file
55
libmve/win_sound.h
Normal file
@ -0,0 +1,55 @@
|
|||||||
|
/*
|
||||||
|
* Descent 3
|
||||||
|
* Copyright (C) 2024 Descent Developers
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef WIN_SOUND_H
|
||||||
|
#define WIN_SOUND_H
|
||||||
|
|
||||||
|
#include <windows.h>
|
||||||
|
#include <mmsystem.h>
|
||||||
|
|
||||||
|
#include "win/DirectX/dsound.h"
|
||||||
|
|
||||||
|
#include "sound_interface.h"
|
||||||
|
|
||||||
|
namespace D3 {
|
||||||
|
|
||||||
|
class MovieSoundDevice : ISoundDevice {
|
||||||
|
public:
|
||||||
|
MovieSoundDevice(int sample_rate, uint16_t sample_size, uint8_t channels, uint32_t buf_size, bool is_compressed);
|
||||||
|
~MovieSoundDevice();
|
||||||
|
|
||||||
|
[[nodiscard]] bool IsInitialized() const { return m_lpDS != nullptr; }
|
||||||
|
|
||||||
|
void Play() override;
|
||||||
|
void Stop() override;
|
||||||
|
void Lock() override;
|
||||||
|
void Unlock() override;
|
||||||
|
|
||||||
|
using ISoundDevice::GetBuffer;
|
||||||
|
using ISoundDevice::IsCompressed;
|
||||||
|
|
||||||
|
private:
|
||||||
|
WAVEFORMATEX m_WFE{};
|
||||||
|
LPDIRECTSOUND m_lpDS;
|
||||||
|
LPDIRECTSOUNDBUFFER m_lpDSB;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace D3
|
||||||
|
|
||||||
|
#endif // WIN_SOUND_H
|
@ -53,183 +53,6 @@ uint16_t CurrentPalette[256];
|
|||||||
int Movie_bm_handle = -1;
|
int Movie_bm_handle = -1;
|
||||||
uint32_t Movie_current_framenum = 0;
|
uint32_t Movie_current_framenum = 0;
|
||||||
bool Movie_looping = false;
|
bool Movie_looping = false;
|
||||||
|
|
||||||
#ifndef NO_MOVIES
|
|
||||||
|
|
||||||
class MovieSoundBuffer : public ISysSoundBuffer {
|
|
||||||
private:
|
|
||||||
LnxSoundBuffer *m_pBuffer;
|
|
||||||
|
|
||||||
public:
|
|
||||||
LnxSoundBuffer *GetLnxBuffer() { return m_pBuffer; }
|
|
||||||
MovieSoundBuffer(LnxSoundBuffer *buffer) : m_pBuffer(buffer) {}
|
|
||||||
|
|
||||||
////////////////////////////
|
|
||||||
// Release
|
|
||||||
////////////////////////////
|
|
||||||
// Releases the memory associated with a sound buffer. This pointer is
|
|
||||||
// no longer valid after return.
|
|
||||||
//
|
|
||||||
// Returns:
|
|
||||||
// -1 : Invalid Parameter
|
|
||||||
// 0 : Ok!
|
|
||||||
int Release() {
|
|
||||||
return LnxSoundBuffer_Release(m_pBuffer);
|
|
||||||
// m_pBuffer->Release();
|
|
||||||
delete this;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
//////////////////////////////
|
|
||||||
// SetVolume
|
|
||||||
//////////////////////////////
|
|
||||||
// Sets the volume of a buffer.
|
|
||||||
//
|
|
||||||
// Returns:
|
|
||||||
// 0 : no error
|
|
||||||
// -1 : Cannot set volume
|
|
||||||
// -2 : Invalid parameters
|
|
||||||
int SetVolume(int32_t vol) { return LnxSoundBuffer_SetVolume(m_pBuffer, vol); }
|
|
||||||
|
|
||||||
///////////////////////////
|
|
||||||
// SetPan
|
|
||||||
///////////////////////////
|
|
||||||
// Sets the pan of a buffer.
|
|
||||||
//
|
|
||||||
// Returns:
|
|
||||||
// 0 : no error
|
|
||||||
// -1 : Cannot set pan
|
|
||||||
// -2 : Invalid parameters
|
|
||||||
int SetPan(int32_t pan) { return LnxSoundBuffer_SetPan(m_pBuffer, pan); }
|
|
||||||
|
|
||||||
/////////////////////////
|
|
||||||
// Stop
|
|
||||||
/////////////////////////
|
|
||||||
// Stops a buffer from playing
|
|
||||||
//
|
|
||||||
// Returns:
|
|
||||||
// 0 : no error
|
|
||||||
// -1 : invalid parameters
|
|
||||||
int Stop() { return LnxSoundBuffer_Stop(m_pBuffer); }
|
|
||||||
|
|
||||||
/////////////////////////
|
|
||||||
// Play
|
|
||||||
/////////////////////////
|
|
||||||
// Starts a buffer playing (or changes the flags for a buffer currently
|
|
||||||
// playing).
|
|
||||||
//
|
|
||||||
// Returns:
|
|
||||||
// 0 : no error
|
|
||||||
// -1 : invalid parameters
|
|
||||||
int Play(uint32_t flags) {
|
|
||||||
uint32_t dsFlags = (flags & LNXSND_LOOPING) ? LNXSND_LOOPING : 0;
|
|
||||||
return LnxSoundBuffer_Play(m_pBuffer, dsFlags);
|
|
||||||
}
|
|
||||||
|
|
||||||
////////////////////////////
|
|
||||||
// GetCaps
|
|
||||||
////////////////////////////
|
|
||||||
// Get the capabilities of a sound buffer
|
|
||||||
//
|
|
||||||
// Returns:
|
|
||||||
// 0 : no error
|
|
||||||
// -1 : invalid parameters
|
|
||||||
int GetCaps(SysSoundCaps *caps) { return LnxSoundBuffer_GetCaps(m_pBuffer, (LinuxSoundCaps *)caps); }
|
|
||||||
|
|
||||||
//////////////////////////////
|
|
||||||
// GetStatus
|
|
||||||
//////////////////////////////
|
|
||||||
// Returns the status of a buffer
|
|
||||||
//
|
|
||||||
// Returns:
|
|
||||||
// 0 : no error
|
|
||||||
// -1 : invalid parameters
|
|
||||||
int GetStatus(uint32_t *status) { return LnxSoundBuffer_GetStatus(m_pBuffer, status); }
|
|
||||||
|
|
||||||
///////////////////////////////////////
|
|
||||||
// GetCurrentPosition
|
|
||||||
///////////////////////////////////////
|
|
||||||
// Returns the current play and write positions of the buffer
|
|
||||||
//
|
|
||||||
// Returns:
|
|
||||||
// 0 : no error
|
|
||||||
// -1 : invalid parameters
|
|
||||||
int GetCurrentPosition(uint32_t *ppos, uint32_t *wpos) {
|
|
||||||
|
|
||||||
return LnxSoundBuffer_GetCurrentPosition(m_pBuffer, ppos, wpos);
|
|
||||||
}
|
|
||||||
|
|
||||||
///////////////////////////////////////
|
|
||||||
// SetCurrentPosition
|
|
||||||
///////////////////////////////////////
|
|
||||||
// Sets the current play position of the buffer
|
|
||||||
//
|
|
||||||
// Returns:
|
|
||||||
// 0 : no error
|
|
||||||
// -1 : invalid parameters
|
|
||||||
int SetCurrentPosition(uint32_t pos) { return LnxSoundBuffer_SetCurrentPosition(m_pBuffer, pos); }
|
|
||||||
|
|
||||||
/////////////////////////
|
|
||||||
// Lock
|
|
||||||
/////////////////////////
|
|
||||||
// Locks the given buffer, returning pointer(s) to the buffer(s) along with
|
|
||||||
// available the size of the buffer(s) for writing.
|
|
||||||
//
|
|
||||||
// Returns:
|
|
||||||
// 0 : no error
|
|
||||||
// -1 : invalid parameters
|
|
||||||
int Lock(uint32_t pos, uint32_t numbytes, void **ptr1, uint32_t *numbytes1, void **ptr2,
|
|
||||||
uint32_t *numbytes2, uint32_t flags) {
|
|
||||||
return LnxSoundBuffer_Lock(m_pBuffer, pos, numbytes, ptr1, numbytes1, ptr2, numbytes2, flags);
|
|
||||||
}
|
|
||||||
|
|
||||||
///////////////////////////
|
|
||||||
// Unlock
|
|
||||||
///////////////////////////
|
|
||||||
// Unlocks a buffer.
|
|
||||||
//
|
|
||||||
// Returns:
|
|
||||||
// 0 : no error
|
|
||||||
// -1 : invalid parameters
|
|
||||||
int Unlock(void *ptr1, uint32_t num1, void *ptr2, uint32_t num2) {
|
|
||||||
return LnxSoundBuffer_Unlock(m_pBuffer, ptr1, num1, ptr2, num2);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
class MovieSoundDevice : public ISoundDevice {
|
|
||||||
private:
|
|
||||||
LnxSoundDevice m_ds;
|
|
||||||
|
|
||||||
public:
|
|
||||||
MovieSoundDevice() {}
|
|
||||||
|
|
||||||
void SetDirectSound(LnxSoundDevice ds) { m_ds = ds; }
|
|
||||||
|
|
||||||
LnxSoundDevice GetDirectSound() { return m_ds; }
|
|
||||||
|
|
||||||
///////////////////////////////
|
|
||||||
// CreateSoundBuffer
|
|
||||||
///////////////////////////////
|
|
||||||
// Creates a sound buffer to be used with mixing and output.
|
|
||||||
//
|
|
||||||
// Returns:
|
|
||||||
// -1 : Invalid Parameter
|
|
||||||
// -2 : Out of memory
|
|
||||||
// 0 : Ok!
|
|
||||||
int CreateSoundBuffer(SysSoundBufferDesc *lbdesc, ISysSoundBuffer **lsndb) {
|
|
||||||
LnxSoundBuffer *sb = NULL;
|
|
||||||
int ret = LnxSound_CreateSoundBuffer(&m_ds, (LnxBufferDesc *)lbdesc, (LnxSoundBuffer **)&sb);
|
|
||||||
if (ret == 0) {
|
|
||||||
ISysSoundBuffer *p = (ISysSoundBuffer *)new MovieSoundBuffer(sb);
|
|
||||||
*lsndb = p;
|
|
||||||
} else {
|
|
||||||
lsndb = nullptr;
|
|
||||||
}
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
#endif
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
static void *CallbackAlloc(uint32_t size);
|
static void *CallbackAlloc(uint32_t size);
|
||||||
@ -242,8 +65,8 @@ static void CallbackShowFrame(uint8_t *buf, uint32_t bufw, uint32_t bufh, uint32
|
|||||||
uint32_t hicolor);
|
uint32_t hicolor);
|
||||||
|
|
||||||
#ifndef NO_MOVIES
|
#ifndef NO_MOVIES
|
||||||
static bool mve_InitSound(oeApplication *app, MovieSoundDevice &device);
|
static bool mve_InitSound();
|
||||||
static void mve_CloseSound(MovieSoundDevice &device);
|
static void mve_CloseSound();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// sets the directory where movies are stored
|
// sets the directory where movies are stored
|
||||||
@ -329,8 +152,7 @@ int mve_PlayMovie(const char *pMovieName, oeApplication *pApp) {
|
|||||||
InitializePalette();
|
InitializePalette();
|
||||||
Movie_bm_handle = -1;
|
Movie_bm_handle = -1;
|
||||||
|
|
||||||
MovieSoundDevice soundDevice;
|
if (!mve_InitSound()) {
|
||||||
if (!mve_InitSound(pApp, soundDevice)) {
|
|
||||||
mprintf(0, "Failed to initialize sound\n");
|
mprintf(0, "Failed to initialize sound\n");
|
||||||
fclose(hFile);
|
fclose(hFile);
|
||||||
return MVELIB_INIT_ERROR;
|
return MVELIB_INIT_ERROR;
|
||||||
@ -340,7 +162,7 @@ int mve_PlayMovie(const char *pMovieName, oeApplication *pApp) {
|
|||||||
if (mve == nullptr) {
|
if (mve == nullptr) {
|
||||||
mprintf(0, "Failed to prepMovie %s\n", pMovieName);
|
mprintf(0, "Failed to prepMovie %s\n", pMovieName);
|
||||||
fclose(hFile);
|
fclose(hFile);
|
||||||
mve_CloseSound(soundDevice);
|
mve_CloseSound();
|
||||||
return MVELIB_INIT_ERROR;
|
return MVELIB_INIT_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -380,7 +202,7 @@ int mve_PlayMovie(const char *pMovieName, oeApplication *pApp) {
|
|||||||
MVE_rmEndMovie(mve);
|
MVE_rmEndMovie(mve);
|
||||||
|
|
||||||
// reset sound
|
// reset sound
|
||||||
mve_CloseSound(soundDevice);
|
mve_CloseSound();
|
||||||
|
|
||||||
// return out
|
// return out
|
||||||
return err;
|
return err;
|
||||||
@ -680,24 +502,13 @@ void mve_ClearRect(int16_t x1, int16_t y1, int16_t x2, int16_t y2) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#ifndef NO_MOVIES
|
#ifndef NO_MOVIES
|
||||||
bool mve_InitSound(oeApplication *app, MovieSoundDevice &device) {
|
bool mve_InitSound() {
|
||||||
|
|
||||||
LnxSoundDevice snddev;
|
|
||||||
bool use_22k_sound = false;
|
|
||||||
snddev.freq = use_22k_sound ? 22050 : 44100;
|
|
||||||
snddev.bit_depth = 16;
|
|
||||||
snddev.channels = 2;
|
|
||||||
snddev.bps = snddev.freq * snddev.channels * snddev.bit_depth / 8;
|
|
||||||
|
|
||||||
device.SetDirectSound(snddev);
|
|
||||||
|
|
||||||
MVE_sndInit(&device);
|
|
||||||
MVE_sndInit(1);
|
MVE_sndInit(1);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void mve_CloseSound(MovieSoundDevice &device) {
|
void mve_CloseSound() {
|
||||||
// TODO: close the driver out
|
// TODO: close the driver out
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user