Skip to content
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

Make audio buffer size configurable #56

Merged
merged 4 commits into from
Oct 14, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions doc/en/sidplayfp.ini.pod
Original file line number Diff line number Diff line change
Expand Up @@ -162,6 +162,12 @@ Number of bits ber sample, used only for wav/au output. Using
values other than the ones specified will produce invalid
output.

=item B<BufferLength>=I<< <number> >>

Length of the buffer in milliseconds, default is 250.
Increase if you experience audio problems or reduce to
improve latency.

=back


Expand Down
3 changes: 3 additions & 0 deletions src/IniConfig.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,7 @@ void IniConfig::clear()
audio_s.frequency = SidConfig::DEFAULT_SAMPLING_FREQ;
audio_s.channels = 0;
audio_s.precision = 16;
audio_s.bufLength = 250;

emulation_s.modelDefault = SidConfig::PAL;
emulation_s.modelForced = false;
Expand Down Expand Up @@ -376,6 +377,8 @@ void IniConfig::readAudio(iniHandler &ini)
readInt(ini, TEXT("Channels"), audio_s.channels);

readInt(ini, TEXT("BitsPerSample"), audio_s.precision);

readInt(ini, TEXT("BufferLength"), audio_s.bufLength);
}


Expand Down
8 changes: 5 additions & 3 deletions src/IniConfig.h
Original file line number Diff line number Diff line change
Expand Up @@ -63,9 +63,11 @@ class IniConfig

struct audio_section
{ // INI Section - [Audio]
int frequency;
int channels;
int precision;
int frequency; // sample rate
int channels; // number of channels
int precision; // sample precision in bits
int bufLength; // buffer length in milliseconds
int getBufSize() const { return (bufLength * frequency) / 1000; }
};

struct emulation_section
Expand Down
4 changes: 1 addition & 3 deletions src/audio/AudioConfig.h
Original file line number Diff line number Diff line change
Expand Up @@ -29,15 +29,13 @@ class AudioConfig
uint_least32_t frequency;
int precision;
int channels;
uint_least32_t bufSize; // sample buffer size
uint_least32_t bufSize; // sample buffer size measured in frames

AudioConfig() :
frequency(48000),
precision(16),
channels(1),
bufSize(0) {}

uint_least32_t bytesPerMillis() const { return (precision/8 * channels * frequency) / 1000; }
};

#endif // AUDIOCONFIG_H
3 changes: 3 additions & 0 deletions src/audio/AudioDrv.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,8 @@
# define HAVE_NULL
#endif

#include <iostream>

bool audioDrv::open(AudioConfig &cfg)
{
bool res = false;
Expand All @@ -69,6 +71,7 @@ bool audioDrv::open(AudioConfig &cfg)
{
audio.reset(new Audio_ALSA());
res = audio->open(cfg);
if (res) std::cerr << "ALSA" << std::endl;
}
#endif
#ifdef HAVE_OSS
Expand Down
2 changes: 1 addition & 1 deletion src/audio/AudioDrv.h
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ class audioDrv : public IAudio

bool open(AudioConfig &cfg) override;
void reset() override { audio->reset(); }
bool write(uint_least32_t size) override { return audio->write(size); }
bool write(uint_least32_t frames) override { return audio->write(frames); }
void close() override { audio->close(); }
void pause() override { audio->pause(); }
short *buffer() const override { return audio->buffer(); }
Expand Down
2 changes: 1 addition & 1 deletion src/audio/IAudio.h
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ class IAudio

virtual bool open(AudioConfig &cfg) = 0;
virtual void reset() = 0;
virtual bool write(uint_least32_t size) = 0;
virtual bool write(uint_least32_t frames) = 0;
virtual void close() = 0;
virtual void pause() = 0;
virtual short *buffer() const = 0;
Expand Down
6 changes: 3 additions & 3 deletions src/audio/alsa/audiodrv.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ bool Audio_ALSA::open(AudioConfig &cfg)
tmpCfg.frequency = rate;
}

snd_pcm_uframes_t buffer_size = tmpCfg.frequency / 5;
snd_pcm_uframes_t buffer_size = tmpCfg.bufSize;
checkResult(snd_pcm_hw_params_set_buffer_size_near(_audioHandle, hw_params, &buffer_size));
tmpCfg.bufSize = buffer_size;

Expand Down Expand Up @@ -136,15 +136,15 @@ void Audio_ALSA::close()
}
}

bool Audio_ALSA::write(uint_least32_t size)
bool Audio_ALSA::write(uint_least32_t frames)
{
if (_audioHandle == nullptr)
{
setError("Device not open.");
return false;
}

int err = snd_pcm_writei(_audioHandle, _sampleBuffer, size);
int err = snd_pcm_writei(_audioHandle, _sampleBuffer, frames);
if (err < 0)
{
err = snd_pcm_recover(_audioHandle, err, 0);
Expand Down
2 changes: 1 addition & 1 deletion src/audio/alsa/audiodrv.h
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ class Audio_ALSA: public AudioBase
bool open (AudioConfig &cfg) override;
void close () override;
void reset () override {}
bool write (uint_least32_t size) override;
bool write (uint_least32_t frames) override;
void pause () override {}
};

Expand Down
18 changes: 10 additions & 8 deletions src/audio/au/auFile.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -186,20 +186,21 @@ auFile::auFile(const std::string &name) :
auHdr(defaultAuHdr),
file(nullptr),
headerWritten(false),
precision(32)
m_precision(32)
{}

bool auFile::open(AudioConfig &cfg)
{
precision = cfg.precision;
m_precision = cfg.precision;
m_channels = cfg.channels;

unsigned short bits = precision;
unsigned long format = (precision == 16) ? 3 : 6;
unsigned long channels = cfg.channels;
unsigned short bits = m_precision;
unsigned long format = (m_precision == 16) ? 3 : 6;
unsigned long channels = m_channels;
unsigned long freq = cfg.frequency;
unsigned short blockAlign = (bits>>3)*channels;
unsigned long bufSize = freq * blockAlign;
cfg.bufSize = bufSize;
cfg.bufSize = freq;

if (name.empty())
return false;
Expand Down Expand Up @@ -238,18 +239,19 @@ bool auFile::open(AudioConfig &cfg)
return true;
}

bool auFile::write(uint_least32_t size)
bool auFile::write(uint_least32_t frames)
{
if (file && !file->fail())
{
uint_least32_t size = frames * m_channels;
unsigned long int bytes = size;
if (!headerWritten)
{
file->write((char*)&auHdr, sizeof(auHeader));
headerWritten = true;
}

if (precision == 16)
if (m_precision == 16)
{
std::vector<uint_least16_t> buffer(size);
bytes *= 2;
Expand Down
3 changes: 2 additions & 1 deletion src/audio/au/auFile.h
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,8 @@ class auFile: public AudioBase

std::ostream *file;
bool headerWritten;
int precision;
int m_precision;
int m_channels;

public:
auFile(const std::string &name);
Expand Down
12 changes: 6 additions & 6 deletions src/audio/directx/audiodrv.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -131,8 +131,7 @@ bool Audio_DirectX::open (AudioConfig &cfg, HWND hwnd)
}
lpDsbPrimary->Release ();

// Buffer size reduced to 2 blocks of 500ms
bufSize = wfm.nSamplesPerSec / 2 * wfm.nBlockAlign;
bufSize = cfg.bufSize * wfm.nBlockAlign;

// Allocate secondary buffers
memset (&dsbdesc, 0, sizeof(DSBUFFERDESC));
Expand Down Expand Up @@ -182,7 +181,7 @@ bool Audio_DirectX::open (AudioConfig &cfg, HWND hwnd)
}

// Update the users settings
cfg.bufSize = bufSize / 2;
m_frameSize = wfm.nBlockAlign;
_settings = cfg;
isPlaying = false;
_sampleBuffer = (short*)lpvData;
Expand All @@ -198,15 +197,16 @@ bool Audio_DirectX::open (AudioConfig &cfg, HWND hwnd)
}
}

bool Audio_DirectX::write (uint_least32_t size)
bool Audio_DirectX::write (uint_least32_t frames)
{
if (!isOpen)
{
setError("Device not open.");
return false;
}

size *= 2;

// get the number of bytes
DWORD size = frames * m_frameSize;

// Unlock the current buffer for playing
lpDsb->Unlock (lpvData, size, NULL, 0);
Expand Down
4 changes: 3 additions & 1 deletion src/audio/directx/audiodrv.h
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,8 @@ class Audio_DirectX: public AudioBase
HANDLE rghEvent[AUDIO_DIRECTX_BUFFERS];
DWORD bufSize;

int m_frameSize;

bool isOpen;
bool isPlaying;

Expand All @@ -75,7 +77,7 @@ class Audio_DirectX: public AudioBase
bool open (AudioConfig &cfg, HWND hwnd);
void close () override;
void reset () override;
bool write (uint_least32_t size) override;
bool write (uint_least32_t frames) override;
void pause () override;
};

Expand Down
11 changes: 7 additions & 4 deletions src/audio/mmsystem/audiodrv.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -113,11 +113,10 @@ bool Audio_MMSystem::open(AudioConfig &cfg)
wfm.cbSize = 0;

// Rev 1.3 (saw) - Calculate buffer to hold 250ms of data
bufSize = wfm.nSamplesPerSec / 4 * wfm.nBlockAlign;
bufSize = cfg.bufSize * wfm.nBlockAlign;

try
{
cfg.bufSize = bufSize / 2;
checkResult(waveOutOpen(&waveHandle, WAVE_MAPPER, &wfm, 0, 0, 0));

_settings = cfg;
Expand Down Expand Up @@ -160,6 +159,7 @@ bool Audio_MMSystem::open(AudioConfig &cfg)
header->dwFlags = WHDR_DONE; /* mark the block is done */
}

m_frameSize = wfm.nBlockAlign;
blockNum = 0;
_sampleBuffer = blocks[blockNum];
return true;
Expand All @@ -173,17 +173,20 @@ bool Audio_MMSystem::open(AudioConfig &cfg)
}
}

bool Audio_MMSystem::write(uint_least32_t size)
bool Audio_MMSystem::write(uint_least32_t frames)
{
if (!isOpen)
{
setError("Device not open.");
return false;
}

// get the number of bytes
DWORD size = frames * m_frameSize;

/* Reset wave header fields: */
blockHeaders[blockNum]->dwFlags = 0;
blockHeaders[blockNum]->dwBufferLength = size * 2;
blockHeaders[blockNum]->dwBufferLength = size;

/* Prepare block header: */
checkResult(waveOutPrepareHeader(waveHandle, blockHeaders[blockNum], sizeof(WAVEHDR)));
Expand Down
4 changes: 3 additions & 1 deletion src/audio/mmsystem/audiodrv.h
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,8 @@ class Audio_MMSystem: public AudioBase
HGLOBAL blockHeaderHandles[MAXBUFBLOCKS];
int blockNum;
int bufSize;
int m_frameSize;

bool isOpen;

private:
Expand All @@ -66,7 +68,7 @@ class Audio_MMSystem: public AudioBase
bool open (AudioConfig &cfg) override;
void close () override;
void reset () override;
bool write (uint_least32_t size) override;
bool write (uint_least32_t frames) override;
void pause () override {}
};

Expand Down
2 changes: 1 addition & 1 deletion src/audio/null/null.h
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ class Audio_Null: public AudioBase
bool open (AudioConfig &cfg) override;
void close () override;
void reset () override {}
bool write (uint_least32_t size) override;
bool write (uint_least32_t frames) override;
void pause () override {}
};

Expand Down
6 changes: 4 additions & 2 deletions src/audio/oss/audiodrv.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,7 @@ bool Audio_OSS::open (AudioConfig &cfg)
}

// Setup internal Config
m_frameSize = 2 * cfg.channels;
_settings = cfg;
return true;
}
Expand Down Expand Up @@ -155,15 +156,16 @@ void Audio_OSS::reset ()
}
}

bool Audio_OSS::write (uint_least32_t size)
bool Audio_OSS::write (uint_least32_t frames)
{
if (_audiofd == -1)
{
setError("Device not open.");
return false;
}

::write (_audiofd, _sampleBuffer, 2 * size);
size_t const bytes = static_cast<size_t>(frames) * m_frameSize;
::write (_audiofd, _sampleBuffer, bytes);
return true;
}

Expand Down
5 changes: 4 additions & 1 deletion src/audio/oss/audiodrv.h
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,9 @@ class Audio_OSS: public AudioBase
static const char AUDIODEVICE[];
volatile int _audiofd;

int m_frameSize;

private:
void outOfOrder ();

public: // --------------------------------------------------------- public
Expand All @@ -68,7 +71,7 @@ class Audio_OSS: public AudioBase
bool open (AudioConfig &cfg) override;
void close () override;
void reset () override;
bool write (uint_least32_t size) override;
bool write (uint_least32_t frames) override;
void pause () override {}
};

Expand Down
Loading
Loading