Final updates to the sound code (resampling seems to be working fine).

git-svn-id: svn://svn.code.sf.net/p/stella/code/trunk@2585 8b62c5a3-ac7e-4cc8-8f21-d9a121418aba
This commit is contained in:
stephena 2013-01-27 15:08:04 +00:00
parent b7df9deeb6
commit a5cb67551f
12 changed files with 58 additions and 144 deletions

View File

@ -12,16 +12,17 @@
Release History Release History
=========================================================================== ===========================================================================
3.7.5 to 3.8: (January xx, 2013) 3.7.5 to 3.8: (February xx, 2013)
* Huge changes to the sound system: * Huge changes to the sound system:
- The sound code now uses signed 16-bit samples instead of unsigned - The sound code now uses 16-bit signed samples instead of 8-bit
8-bit samples, making it more compatible with a wider variety of unsigned samples, making it more compatible with a wider variety of
systems. systems.
- Improved sound output for several ROMs, including "Space Rocks" - Improved sound output for several ROMs, including "Space Rocks"
(the 'heartbeat' sound can now be clearly heard). (the 'heartbeat' sound can now be clearly heard).
- The 'volume clipping' option has been removed, since in 16-bit - The 'volume clipping' option has been removed, since in 16-bit
mode it's no longer needed. mode it's no longer needed.
- The 'Tia freq' option has been removed.
* Improved bankswitch autodetection for X07 ROMs (although there's only * Improved bankswitch autodetection for X07 ROMs (although there's only
two known ROMs in existence, so the detection probably isn't robust). two known ROMs in existence, so the detection probably isn't robust).
@ -69,7 +70,7 @@
reading from TIMINT. Also, D6 of the Interrupt Flag register is now reading from TIMINT. Also, D6 of the Interrupt Flag register is now
properly set on active transition of the PA7 pin. properly set on active transition of the PA7 pin.
* Fixed bug in DPC+ bankswitch scheme; the music in "Stay Frosty 2" * Fixed bug in DPC+ bankswitch scheme; the music several DPC+ ROMS
wasn't playing correctly. wasn't playing correctly.
* The ROM properties database now uses 'Auto' instead of 'Auto-select' * The ROM properties database now uses 'Auto' instead of 'Auto-select'

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.5 KiB

After

Width:  |  Height:  |  Size: 3.1 KiB

View File

@ -10,7 +10,7 @@
<br><br> <br><br>
<center><h2><b>A multi-platform Atari 2600 VCS emulator</b></h2></center> <center><h2><b>A multi-platform Atari 2600 VCS emulator</b></h2></center>
<center><h4><b>Release 3.7.5</b></h4></center> <center><h4><b>Release 3.8</b></h4></center>
<br><br> <br><br>
<center><h2><b>User's Guide</b></h2></center> <center><h2><b>User's Guide</b></h2></center>
@ -54,7 +54,7 @@
<br><br><br> <br><br><br>
<center><b>February 1999 - December 2012</b></center> <center><b>February 1999 - February 2013</b></center>
<center><b>The Stella Team</b></center> <center><b>The Stella Team</b></center>
<center><b><a href="http://stella.sourceforge.net">Stella Homepage</a></b></center> <center><b><a href="http://stella.sourceforge.net">Stella Homepage</a></b></center>
@ -1995,14 +1995,7 @@
<tr> <tr>
<td><pre>-freq &lt;number&gt;</pre></td> <td><pre>-freq &lt;number&gt;</pre></td>
<td>Set sound sample output frequency (0 - 48000). <td>Set sound sample output frequency (11025,22050,31400,44100,48000)
Default is 31400. Do not change unless you experience sound
issues.</td>
</tr>
<tr>
<td><pre>-tiafreq &lt;number&gt;</pre></td>
<td>Set sound sample generation frequency (0 - 48000).
Default is 31400. Do not change unless you experience sound Default is 31400. Do not change unless you experience sound
issues.</td> issues.</td>
</tr> </tr>
@ -2494,9 +2487,7 @@
<tr><th>Item</th><th>Brief description</th><th>For more information,<br>see <a href="#CommandLine">CommandLine</a></th></tr> <tr><th>Item</th><th>Brief description</th><th>For more information,<br>see <a href="#CommandLine">CommandLine</a></th></tr>
<tr><td>Volume</td><td>self-explanatory</td><td>-volume</td></tr> <tr><td>Volume</td><td>self-explanatory</td><td>-volume</td></tr>
<tr><td>Sample size (*)</td><td>set size of audio buffers</td><td>-fragsize</td></tr> <tr><td>Sample size (*)</td><td>set size of audio buffers</td><td>-fragsize</td></tr>
<tr><td>Output freq (*)</td><td>change sound output frequency (advanced)</td><td>-freq</td></tr> <tr><td>Frequency (*)</td><td>change sound output frequency</td><td>-freq</td></tr>
<tr><td>TIA freq</td><td>change TIA output frequency (advanced)</td><td>-tiafreq</td></tr>
<tr><td>Clip volume</td><td>Eliminate popping in sound generation (advanced)</td><td>-clipvol</td></tr>
<tr><td>Enable sound</td><td>self-explanatory</td><td>-sound</td></tr> <tr><td>Enable sound</td><td>self-explanatory</td><td>-sound</td></tr>
</table> </table>
</td> </td>

View File

@ -1,74 +0,0 @@
//============================================================================
//
// SSSS tt lll lll
// SS SS tt ll ll
// SS tttttt eeee ll ll aaaa
// SSSS tt ee ee ll ll aa
// SS tt eeeeee ll ll aaaaa -- "An Atari 2600 VCS Emulator"
// SS SS tt ee ll ll aa aa
// SSSS ttt eeeee llll llll aaaaa
//
// Copyright (c) 1995-2013 by Bradford W. Mott, Stephen Anthony
// and the Stella Team
//
// See the file "License.txt" for information on usage and redistribution of
// this file, and for a DISCLAIMER OF ALL WARRANTIES.
//
// $Id$
//============================================================================
#include "bspf.hxx"
#include "OSystem.hxx"
#include "Settings.hxx"
#include "SoundNull.hxx"
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
SoundNull::SoundNull(OSystem* osystem)
: Sound(osystem)
{
myOSystem->logMessage("Sound disabled.\n", 1);
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
SoundNull::~SoundNull()
{
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
bool SoundNull::load(Serializer& in)
{
if(in.getString() != "TIASound")
return false;
// Read sound registers and discard
in.getByte();
in.getByte();
in.getByte();
in.getByte();
in.getByte();
in.getByte();
// myLastRegisterSetCycle
in.getInt();
return true;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
bool SoundNull::save(Serializer& out) const
{
out.putString("TIASound");
out.putByte(0);
out.putByte(0);
out.putByte(0);
out.putByte(0);
out.putByte(0);
out.putByte(0);
// myLastRegisterSetCycle
out.putInt(0);
return true;
}

View File

@ -24,6 +24,7 @@ class OSystem;
#include "bspf.hxx" #include "bspf.hxx"
#include "Sound.hxx" #include "Sound.hxx"
#include "OSystem.hxx"
/** /**
This class implements a Null sound object, where-by sound generation This class implements a Null sound object, where-by sound generation
@ -39,7 +40,10 @@ class SoundNull : public Sound
Create a new sound object. The init method must be invoked before Create a new sound object. The init method must be invoked before
using the object. using the object.
*/ */
SoundNull(OSystem* osystem); SoundNull(OSystem* osystem) : Sound(osystem)
{
myOSystem->logMessage("Sound disabled.\n", 1);
}
/** /**
Destructor Destructor
@ -128,14 +132,25 @@ class SoundNull : public Sound
*/ */
void adjustVolume(Int8 direction) { } void adjustVolume(Int8 direction) { }
public: public:
/** /**
Saves the current state of this device to the given Serializer. Saves the current state of this device to the given Serializer.
@param out The serializer device to save to. @param out The serializer device to save to.
@return The result of the save. True on success, false on failure. @return The result of the save. True on success, false on failure.
*/ */
bool save(Serializer& out) const; bool save(Serializer& out) const
{
out.putString("TIASound");
for(int = 0; i < 6; ++i)
out.putByte(0);
// myLastRegisterSetCycle
out.putInt(0);
return true;
}
/** /**
Loads the current state of this device from the given Serializer. Loads the current state of this device from the given Serializer.
@ -143,7 +158,20 @@ public:
@param in The Serializer device to load from. @param in The Serializer device to load from.
@return The result of the load. True on success, false on failure. @return The result of the load. True on success, false on failure.
*/ */
bool load(Serializer& in); bool load(Serializer& in)
{
if(in.getString() != "TIASound")
return false;
// Read sound registers and discard
for(int = 0; i < 6; ++i)
in.getByte();
// myLastRegisterSetCycle
in.getInt();
return true;
}
/** /**
Get a descriptor for this console class (used in error checking). Get a descriptor for this console class (used in error checking).

View File

@ -125,9 +125,7 @@ void SoundSDL::open()
} }
// Now initialize the TIASound object which will actually generate sound // Now initialize the TIASound object which will actually generate sound
int tiafreq = myOSystem->settings().getInt("tiafreq");
myTIASound.outputFrequency(myHardwareSpec.freq); myTIASound.outputFrequency(myHardwareSpec.freq);
myTIASound.tiaFrequency(tiafreq);
const string& chanResult = const string& chanResult =
myTIASound.channels(myHardwareSpec.channels, myNumChannels == 2); myTIASound.channels(myHardwareSpec.channels, myNumChannels == 2);

View File

@ -2,7 +2,6 @@ MODULE := src/common
MODULE_OBJS := \ MODULE_OBJS := \
src/common/mainSDL.o \ src/common/mainSDL.o \
src/common/SoundNull.o \
src/common/SoundSDL.o \ src/common/SoundSDL.o \
src/common/FrameBufferSoft.o \ src/common/FrameBufferSoft.o \
src/common/FrameBufferGL.o \ src/common/FrameBufferGL.o \

View File

@ -79,7 +79,6 @@ Settings::Settings(OSystem* osystem)
setInternal("sound", "true"); setInternal("sound", "true");
setInternal("fragsize", "512"); setInternal("fragsize", "512");
setInternal("freq", "31400"); setInternal("freq", "31400");
setInternal("tiafreq", "31400");
setInternal("volume", "100"); setInternal("volume", "100");
// Input event options // Input event options
@ -285,9 +284,8 @@ void Settings::validate()
i = getInt("volume"); i = getInt("volume");
if(i < 0 || i > 100) setInternal("volume", "100"); if(i < 0 || i > 100) setInternal("volume", "100");
i = getInt("freq"); i = getInt("freq");
if(i < 0 || i > 48000) setInternal("freq", "31400"); if(!(i == 11025 || i == 22050 || i == 31400 || i == 44100 || i == 48000))
i = getInt("tiafreq"); setInternal("freq", "31400");
if(i < 0 || i > 48000) setInternal("tiafreq", "31400");
#endif #endif
i = getInt("joydeadzone"); i = getInt("joydeadzone");
@ -382,8 +380,7 @@ void Settings::usage()
#ifdef SOUND_SUPPORT #ifdef SOUND_SUPPORT
<< " -sound <1|0> Enable sound generation\n" << " -sound <1|0> Enable sound generation\n"
<< " -fragsize <number> The size of sound fragments (must be a power of two)\n" << " -fragsize <number> The size of sound fragments (must be a power of two)\n"
<< " -freq <number> Set sound sample output frequency (0 - 48000)\n" << " -freq <number> Set sound sample output frequency (11025|22050|31400|44100|48000)\n"
<< " -tiafreq <number> Set sound sample generation frequency (0 - 48000)\n"
<< " -volume <number> Set the volume (0 - 100)\n" << " -volume <number> Set the volume (0 - 100)\n"
<< " -clipvol <1|0> Enable volume clipping (eliminates popping)\n" << " -clipvol <1|0> Enable volume clipping (eliminates popping)\n"
<< endl << endl

View File

@ -21,10 +21,9 @@
#include "TIASnd.hxx" #include "TIASnd.hxx"
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
TIASound::TIASound(Int32 outputFrequency, Int32 tiaFrequency) TIASound::TIASound(Int32 outputFrequency)
: myChannelMode(Hardware2Stereo), : myChannelMode(Hardware2Stereo),
myOutputFrequency(outputFrequency), myOutputFrequency(outputFrequency),
myTIAFrequency(tiaFrequency),
myOutputCounter(0), myOutputCounter(0),
myVolumePercentage(100) myVolumePercentage(100)
{ {
@ -68,12 +67,6 @@ void TIASound::outputFrequency(Int32 freq)
myOutputFrequency = freq; myOutputFrequency = freq;
} }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void TIASound::tiaFrequency(Int32 freq)
{
myTIAFrequency = freq;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
string TIASound::channels(uInt32 hardware, bool stereo) string TIASound::channels(uInt32 hardware, bool stereo)
{ {
@ -352,31 +345,31 @@ void TIASound::process(Int16* buffer, uInt32 samples)
switch(myChannelMode) switch(myChannelMode)
{ {
case Hardware2Mono: // mono sampling with 2 hardware channels case Hardware2Mono: // mono sampling with 2 hardware channels
while((samples > 0) && (myOutputCounter >= myTIAFrequency)) while((samples > 0) && (myOutputCounter >= 31400))
{ {
Int16 byte = v0 + v1; Int16 byte = v0 + v1;
*(buffer++) = byte; *(buffer++) = byte;
*(buffer++) = byte; *(buffer++) = byte;
myOutputCounter -= myTIAFrequency; myOutputCounter -= 31400;
samples--; samples--;
} }
break; break;
case Hardware2Stereo: // stereo sampling with 2 hardware channels case Hardware2Stereo: // stereo sampling with 2 hardware channels
while((samples > 0) && (myOutputCounter >= myTIAFrequency)) while((samples > 0) && (myOutputCounter >= 31400))
{ {
*(buffer++) = v0; *(buffer++) = v0;
*(buffer++) = v1; *(buffer++) = v1;
myOutputCounter -= myTIAFrequency; myOutputCounter -= 31400;
samples--; samples--;
} }
break; break;
case Hardware1: // mono/stereo sampling with only 1 hardware channel case Hardware1: // mono/stereo sampling with only 1 hardware channel
while((samples > 0) && (myOutputCounter >= myTIAFrequency)) while((samples > 0) && (myOutputCounter >= 31400))
{ {
*(buffer++) = v0 + v1; *(buffer++) = v0 + v1;
myOutputCounter -= myTIAFrequency; myOutputCounter -= 31400;
samples--; samples--;
} }
break; break;

View File

@ -26,6 +26,9 @@
This class implements a fairly accurate emulation of the TIA sound This class implements a fairly accurate emulation of the TIA sound
hardware. This class uses code/ideas from z26 and MESS. hardware. This class uses code/ideas from z26 and MESS.
Currently, the sound generation routines work at 31400Hz only.
Resampling can be done by passing in a different output frequency.
@author Bradford W. Mott, Stephen Anthony, z26 and MESS teams @author Bradford W. Mott, Stephen Anthony, z26 and MESS teams
@version $Id$ @version $Id$
*/ */
@ -35,7 +38,7 @@ class TIASound
/** /**
Create a new TIA Sound object using the specified output frequency Create a new TIA Sound object using the specified output frequency
*/ */
TIASound(Int32 outputFrequency = 31400, Int32 tiaFrequency = 31400); TIASound(Int32 outputFrequency = 31400);
/** /**
Destructor Destructor
@ -53,11 +56,6 @@ class TIASound
*/ */
void outputFrequency(Int32 freq); void outputFrequency(Int32 freq);
/**
Set the frequency the of the TIA device
*/
void tiaFrequency(Int32 freq);
/** /**
Selects the number of audio channels per sample. There are two factors Selects the number of audio channels per sample. There are two factors
to consider: hardware capability and desired mixing. to consider: hardware capability and desired mixing.
@ -159,7 +157,6 @@ class TIASound
ChannelMode myChannelMode; ChannelMode myChannelMode;
Int32 myOutputFrequency; Int32 myOutputFrequency;
Int32 myTIAFrequency;
Int32 myOutputCounter; Int32 myOutputCounter;
uInt32 myVolumePercentage; uInt32 myVolumePercentage;

View File

@ -55,7 +55,7 @@ AudioDialog::AudioDialog(OSystem* osystem, DialogContainer* parent,
// Set real dimensions // Set real dimensions
_w = 35 * fontWidth + 10; _w = 35 * fontWidth + 10;
_h = 8 * (lineHeight + 4) + 10; _h = 7 * (lineHeight + 4) + 10;
// Volume // Volume
xpos = 3 * fontWidth; ypos = 10; xpos = 3 * fontWidth; ypos = 10;
@ -95,20 +95,13 @@ AudioDialog::AudioDialog(OSystem* osystem, DialogContainer* parent,
items.push_back("48000 Hz", "48000"); items.push_back("48000 Hz", "48000");
myFreqPopup = new PopUpWidget(this, font, xpos, ypos, myFreqPopup = new PopUpWidget(this, font, xpos, ypos,
pwidth + myVolumeLabel->getWidth() - 4, lineHeight, pwidth + myVolumeLabel->getWidth() - 4, lineHeight,
items, "Output freq (*): ", lwidth); items, "Frequency (*): ", lwidth);
wid.push_back(myFreqPopup); wid.push_back(myFreqPopup);
ypos += lineHeight + 4; ypos += lineHeight + 4;
// TIA frequency
// ... use same items as above
myTiaFreqPopup = new PopUpWidget(this, font, xpos, ypos,
pwidth + myVolumeLabel->getWidth() - 4, lineHeight,
items, "TIA freq: ", lwidth);
wid.push_back(myTiaFreqPopup);
ypos += lineHeight + 4;
// Enable sound // Enable sound
xpos = (_w - (font.getStringWidth("Enable sound") + 10)) / 2; xpos = (_w - (font.getStringWidth("Enable sound") + 10)) / 2;
ypos += 4;
mySoundEnableCheckbox = new CheckboxWidget(this, font, xpos, ypos, mySoundEnableCheckbox = new CheckboxWidget(this, font, xpos, ypos,
"Enable sound", kSoundEnableChanged); "Enable sound", kSoundEnableChanged);
wid.push_back(mySoundEnableCheckbox); wid.push_back(mySoundEnableCheckbox);
@ -148,9 +141,6 @@ void AudioDialog::loadConfig()
// Output frequency // Output frequency
myFreqPopup->setSelected(instance().settings().getString("freq"), "31400"); myFreqPopup->setSelected(instance().settings().getString("freq"), "31400");
// TIA frequency
myTiaFreqPopup->setSelected(instance().settings().getString("tiafreq"), "31400");
// Enable sound // Enable sound
bool b = instance().settings().getBool("sound"); bool b = instance().settings().getBool("sound");
mySoundEnableCheckbox->setState(b); mySoundEnableCheckbox->setState(b);
@ -174,9 +164,6 @@ void AudioDialog::saveConfig()
// Output frequency // Output frequency
settings.setString("freq", myFreqPopup->getSelectedTag()); settings.setString("freq", myFreqPopup->getSelectedTag());
// TIA frequency
settings.setString("tiafreq", myTiaFreqPopup->getSelectedTag());
// Enable/disable sound (requires a restart to take effect) // Enable/disable sound (requires a restart to take effect)
instance().sound().setEnabled(mySoundEnableCheckbox->getState()); instance().sound().setEnabled(mySoundEnableCheckbox->getState());
@ -194,7 +181,6 @@ void AudioDialog::setDefaults()
myFragsizePopup->setSelected("512", ""); myFragsizePopup->setSelected("512", "");
myFreqPopup->setSelected("31400", ""); myFreqPopup->setSelected("31400", "");
myTiaFreqPopup->setSelected("31400", "");
mySoundEnableCheckbox->setState(true); mySoundEnableCheckbox->setState(true);
@ -211,7 +197,6 @@ void AudioDialog::handleSoundEnableChange(bool active)
myVolumeLabel->setEnabled(active); myVolumeLabel->setEnabled(active);
myFragsizePopup->setEnabled(active); myFragsizePopup->setEnabled(active);
myFreqPopup->setEnabled(active); myFreqPopup->setEnabled(active);
myTiaFreqPopup->setEnabled(active);
} }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

View File

@ -45,7 +45,6 @@ class AudioDialog : public Dialog
StaticTextWidget* myVolumeLabel; StaticTextWidget* myVolumeLabel;
PopUpWidget* myFragsizePopup; PopUpWidget* myFragsizePopup;
PopUpWidget* myFreqPopup; PopUpWidget* myFreqPopup;
PopUpWidget* myTiaFreqPopup;
CheckboxWidget* mySoundEnableCheckbox; CheckboxWidget* mySoundEnableCheckbox;
private: private: