openMSX
Classes | Public Member Functions | Static Public Attributes | Protected Member Functions | Static Protected Member Functions | List of all members
openmsx::SoundDevice Class Referenceabstract

#include <SoundDevice.hh>

Inheritance diagram for openmsx::SoundDevice:
Inheritance graph
[legend]

Classes

struct  AmplificationFactors
 Gets this device its 'amplification factor'. More...
 

Public Member Functions

 SoundDevice (const SoundDevice &)=delete
 
 SoundDevice (SoundDevice &&)=delete
 
SoundDeviceoperator= (const SoundDevice &)=delete
 
SoundDeviceoperator= (SoundDevice &&)=delete
 
const std::string & getName () const
 Get the unique name that identifies this sound device.
 
std::string_view getDescription () const
 Gets a description of this sound device, to be presented to the user.
 
unsigned getNumChannels () const
 How many channels does this device have?
 
bool hasStereoChannels () const
 Are the individual channels of this device stereo?
 
bool isStereo () const
 Is the full output of this device stereo?
 
AmplificationFactors getAmplificationFactor () const
 
void setSoftwareVolume (float volume, EmuTime::param time)
 Change the 'software volume' of this sound device.
 
void setSoftwareVolume (float left, float right, EmuTime::param time)
 
void recordChannel (unsigned channel, const Filename &filename)
 
void muteChannel (unsigned channel, bool muted)
 
std::span< const float > getLastBuffer (unsigned channel)
 Query the last generated audio signal for a specific channel.
 
unsigned getLastBufferSize () const
 getLastBuffer() with return buffers containing this many samples.
 
virtual void setOutputRate (unsigned hostSampleRate, double speed)=0
 When a SoundDevice registers itself with the Mixer, the Mixer sets the required sampleRate through this method.
 
virtual bool updateBuffer (size_t length, float *buffer, EmuTime::param time)=0
 Generate sample data.
 

Static Public Attributes

static constexpr unsigned MAX_CHANNELS = 24
 

Protected Member Functions

 SoundDevice (MSXMixer &mixer, std::string_view name, static_string_view description, unsigned numChannels, unsigned inputRate, bool stereo)
 Constructor.
 
 ~SoundDevice ()
 
virtual float getAmplificationFactorImpl () const
 Get amplification/attenuation factor for this device.
 
void registerSound (const DeviceConfig &config)
 Registers this sound device with the Mixer.
 
void unregisterSound ()
 Unregisters this sound device with the Mixer.
 
void updateStream (EmuTime::param time)
 
void setInputRate (unsigned sampleRate)
 
unsigned getInputRate () const
 
virtual void generateChannels (std::span< float * > buffers, unsigned num)=0
 Abstract method to generate the actual sound data.
 
bool mixChannels (float *dataOut, size_t samples)
 Calls generateChannels() and combines the output to a single channel.
 
const DynamicClockgetHostSampleClock () const
 See MSXMixer::getHostSampleClock().
 
double getEffectiveSpeed () const
 

Static Protected Member Functions

static void addFill (float *&buffer, float value, unsigned num)
 Adds a number of samples that all have the same value.
 

Detailed Description

Definition at line 19 of file SoundDevice.hh.

Constructor & Destructor Documentation

◆ SoundDevice() [1/3]

openmsx::SoundDevice::SoundDevice ( const SoundDevice )
delete

◆ SoundDevice() [2/3]

openmsx::SoundDevice::SoundDevice ( SoundDevice &&  )
delete

◆ SoundDevice() [3/3]

openmsx::SoundDevice::SoundDevice ( MSXMixer mixer,
std::string_view  name,
static_string_view  description,
unsigned  numChannels,
unsigned  inputRate,
bool  stereo 
)
protected

Constructor.

Parameters
mixerThe Mixer object
nameName for this device, will be made unique
descriptionDescription for this sound device
numChannelsThe number of channels for this device
inputRateThe sample rate of this sound device
stereoIs this a stereo device

Definition at line 48 of file SoundDevice.cc.

References ranges::fill(), MAX_CHANNELS, and setInputRate().

◆ ~SoundDevice()

openmsx::SoundDevice::~SoundDevice ( )
protecteddefault

Member Function Documentation

◆ addFill()

void openmsx::SoundDevice::addFill ( float *&  buffer,
float  value,
unsigned  num 
)
staticprotected

Adds a number of samples that all have the same value.

Can be used to synthesize segments of a square wave.

Parameters
bufferPointer to the position in a sample buffer where the samples should be added. This pointer is updated to the position right after the written samples.
valueSample value (amplitude).
numThe number of samples.

Definition at line 35 of file SoundDevice.cc.

◆ generateChannels()

virtual void openmsx::SoundDevice::generateChannels ( std::span< float * >  buffers,
unsigned  num 
)
protectedpure virtual

Abstract method to generate the actual sound data.

Parameters
buffersAn array of pointer to buffers. Each buffer must be big enough to hold 'num' samples.
numThe number of samples.

This method should fill each buffer with sound data that corresponds to one channel of the sound device. The same channel should each time be written to the same buffer (needed for record).

If a certain channel is muted it is allowed to set the buffer pointer to nullptr. This has exactly the same effect as filling the buffer completely with zeros, but it can be more efficient.

Implemented in openmsx::CassettePlayer, and openmsx::SN76489.

Referenced by mixChannels().

◆ getAmplificationFactor()

AmplificationFactors openmsx::SoundDevice::getAmplificationFactor ( ) const
inline

Definition at line 71 of file SoundDevice.hh.

References getAmplificationFactorImpl().

Referenced by mixChannels().

◆ getAmplificationFactorImpl()

float openmsx::SoundDevice::getAmplificationFactorImpl ( ) const
protectedvirtual

Get amplification/attenuation factor for this device.

Normally the outputBuffer() method should scale the output to the range [-1.0..+1.0]. But sometimes it's more convenient to generate another output range. In later stages the output is anyway still multiplied by some factor. This method tells which factor should be used to scale the output to the correct range. The default implementation returns '1.0 / 32768.0'.

Reimplemented in openmsx::CassettePlayer.

Definition at line 68 of file SoundDevice.cc.

Referenced by getAmplificationFactor().

◆ getDescription()

std::string_view openmsx::SoundDevice::getDescription ( ) const
inline

Gets a description of this sound device, to be presented to the user.

Definition at line 37 of file SoundDevice.hh.

◆ getEffectiveSpeed()

double openmsx::SoundDevice::getEffectiveSpeed ( ) const
protected

Definition at line 364 of file SoundDevice.cc.

Referenced by openmsx::ResampledSoundDevice::createResampler().

◆ getHostSampleClock()

const DynamicClock & openmsx::SoundDevice::getHostSampleClock ( ) const
protected

◆ getInputRate()

unsigned openmsx::SoundDevice::getInputRate ( ) const
inlineprotected

Definition at line 160 of file SoundDevice.hh.

Referenced by openmsx::ResampledSoundDevice::createResampler().

◆ getLastBuffer()

std::span< const float > openmsx::SoundDevice::getLastBuffer ( unsigned  channel)

Query the last generated audio signal for a specific channel.

The length of this buffer is fixed (for a specific sound device), see getLastBufferSize(). It's possible that no data is available yet. In that case an empty buffer will be returned. For example this will be the case the first time you call this method. Collecting this data is not free, so by default we don't do it. Requesting this data will automatically start the collecting-process. So, some time later, when you call this method again, there is a good chance that it will succeed. And similarly, if you stop calling this method for some time, we will automatically stop collecting this data. This method is meant to be used by the GUI. There it's acceptable that the first few frames no data is available yet.

Definition at line 175 of file SoundDevice.cc.

References getLastBufferSize().

◆ getLastBufferSize()

unsigned openmsx::SoundDevice::getLastBufferSize ( ) const
inline

getLastBuffer() with return buffers containing this many samples.

This number depends on the native-sample-rate of the device. For all devices it will be (approximately) represent the same time duration.

Definition at line 113 of file SoundDevice.hh.

Referenced by getLastBuffer(), and mixChannels().

◆ getName()

const std::string & openmsx::SoundDevice::getName ( ) const
inline

Get the unique name that identifies this sound device.

Used to create setting names.

Definition at line 32 of file SoundDevice.hh.

Referenced by openmsx::paintSCC(), openmsx::MSXMixer::registerSound(), and openmsx::MSXMixer::unregisterSound().

◆ getNumChannels()

unsigned openmsx::SoundDevice::getNumChannels ( ) const
inline

How many channels does this device have?

Definition at line 41 of file SoundDevice.hh.

◆ hasStereoChannels()

bool openmsx::SoundDevice::hasStereoChannels ( ) const
inline

Are the individual channels of this device stereo?

Definition at line 45 of file SoundDevice.hh.

Referenced by isStereo().

◆ isStereo()

bool openmsx::SoundDevice::isStereo ( ) const
inline

Is the full output of this device stereo?

Definition at line 51 of file SoundDevice.hh.

References hasStereoChannels().

Referenced by openmsx::ResampledSoundDevice::createResampler(), and mixChannels().

◆ mixChannels()

bool openmsx::SoundDevice::mixChannels ( float *  dataOut,
size_t  samples 
)
protected

Calls generateChannels() and combines the output to a single channel.

Parameters
dataOutOutput buffer, must be big enough to hold 'samples' number of samples
samplesThe number of samples
Returns
true iff at least one channel was unmuted

Note: To enable various optimizations (like SSE), this method can fill the output buffer with up to 3 extra samples. Those extra samples should be ignored, though the caller must make sure the buffer has enough space to hold them.

Definition at line 187 of file SoundDevice.cc.

References ranges::any_of(), ranges::fill(), generateChannels(), getAmplificationFactor(), getLastBufferSize(), isStereo(), subspan(), VLA, and xrange().

Referenced by openmsx::ResampledSoundDevice::generateInput().

◆ muteChannel()

void openmsx::SoundDevice::muteChannel ( unsigned  channel,
bool  muted 
)

Definition at line 169 of file SoundDevice.cc.

◆ operator=() [1/2]

SoundDevice & openmsx::SoundDevice::operator= ( const SoundDevice )
delete

◆ operator=() [2/2]

SoundDevice & openmsx::SoundDevice::operator= ( SoundDevice &&  )
delete

◆ recordChannel()

void openmsx::SoundDevice::recordChannel ( unsigned  channel,
const Filename filename 
)

Definition at line 141 of file SoundDevice.cc.

References openmsx::Filename::empty().

◆ registerSound()

void openmsx::SoundDevice::registerSound ( const DeviceConfig config)
protected

◆ setInputRate()

void openmsx::SoundDevice::setInputRate ( unsigned  sampleRate)
inlineprotected

Definition at line 159 of file SoundDevice.hh.

Referenced by SoundDevice().

◆ setOutputRate()

virtual void openmsx::SoundDevice::setOutputRate ( unsigned  hostSampleRate,
double  speed 
)
pure virtual

When a SoundDevice registers itself with the Mixer, the Mixer sets the required sampleRate through this method.

All sound devices share a common sampleRate.

Implemented in openmsx::ResampledSoundDevice.

Referenced by openmsx::MSXMixer::registerSound().

◆ setSoftwareVolume() [1/2]

void openmsx::SoundDevice::setSoftwareVolume ( float  left,
float  right,
EmuTime::param  time 
)

Definition at line 133 of file SoundDevice.cc.

References updateStream().

◆ setSoftwareVolume() [2/2]

void openmsx::SoundDevice::setSoftwareVolume ( float  volume,
EmuTime::param  time 
)

Change the 'software volume' of this sound device.

Some devices like 'Carnivore2' include sound chips (e.g. SCC and fm-pac) and allow the MSX software to configure the volume of those chips. To be clear: these are not the regular per channel volume registers of the SCC/YM2413 sound chips, but another register that controls the total output of those chips.

This method allows to change that per-chip volume.

Definition at line 128 of file SoundDevice.cc.

References setSoftwareVolume().

Referenced by openmsx::DACSound8U::DACSound8U(), openmsx::YMF262::setMixLevel(), openmsx::YMF278::setMixLevel(), setSoftwareVolume(), and openmsx::ReproCartridgeV2::setVolume().

◆ unregisterSound()

void openmsx::SoundDevice::unregisterSound ( )
protected

◆ updateBuffer()

virtual bool openmsx::SoundDevice::updateBuffer ( size_t  length,
float *  buffer,
EmuTime::param  time 
)
pure virtual

Generate sample data.

Parameters
lengthThe number of required samples
bufferThis buffer should be filled
timecurrent time
Returns
false iff the output is empty. IOW filling the buffer with zeros or returning false has the same effect, but the latter can be more efficient

This method is regularly called from the Mixer, it should return a pointer to a buffer filled with the required number of samples. Samples are always floats, later they are converted to the systems native format (e.g. 16-bit signed).

Note: To enable various optimizations (like SSE), this method can fill the output buffer with up to 3 extra samples. Those extra samples should be ignored, though the caller must make sure the buffer has enough space to hold them.

Implemented in openmsx::ResampledSoundDevice.

◆ updateStream()

void openmsx::SoundDevice::updateStream ( EmuTime::param  time)
protected

Member Data Documentation

◆ MAX_CHANNELS

constexpr unsigned openmsx::SoundDevice::MAX_CHANNELS = 24
staticconstexpr

Definition at line 22 of file SoundDevice.hh.

Referenced by SoundDevice().


The documentation for this class was generated from the following files: