Update to v101r30 release.
byuu says:
Changelog:
- SMS: added cartridge ROM/RAM mirroring (fixes Alex Kidd)
- SMS: fixed 8x16 sprite mode (fixes Wonder Boy, Ys graphics)
- Z80: emulated "ex (sp),hl" instruction
- Z80: fixed INx NF (should be set instead of cleared)
- Z80: fixed loop condition check for CPxR, INxR, LDxR, OTxR (fixes
walking in Wonder Boy)
- SFC: removed Debugger and sfc/debugger.hpp
- icarus: connected MS, GG, MD importing to the scan dialog
- PCE: added emulation skeleton to higan and icarus
At this point, Master System games are fairly highly compatible, sans
audio. Game Gear games are running, but I need to crop the resolution
and support the higher color palette that they can utilize. It's really
something else the way they handled the resolution shrink on that thing.
The last change is obviously going to be the biggest news.
I'm very well aware it's not an ideal time to start on a new emulation
core, with the MS and MD cores only just now coming to life with no
audio support.
But, for whatever reason, my heart's really set on working on the PC
Engine. I wanted to write the final higan skeleton core, and get things
ready so that whenever I'm in the mood to work on the PCE, I can do so.
The skeleton is far and away the most tedious and obnoxious part of the
emulator development, because it's basically all just lots of
boilerplate templated code, lots of new files to create, etc.
I really don't know how things are going to proceed ... but I can say
with 99.9% certainty that this will be the final brand new core ever
added to higan -- at least one written by me, that is. This was
basically the last system from my childhood that I ever cared about.
It's the last 2D system with games that I really enjoy playing. No other
system is worth dividing my efforts and reducing the quality and amount
of time to work on the systems I have.
In the future, there will be potential for FDS, Mega CD and PCE-CD
support. But those will all be add-ons, and they'll all be really
difficult and challenge the entire design of higan's UI (it's entirely
cartridge-driven at this time.) None of them will be entirely new cores
like this one.
2017-01-11 20:27:30 +00:00
|
|
|
#include <pce/pce.hpp>
|
|
|
|
|
|
|
|
namespace PCEngine {
|
|
|
|
|
|
|
|
PSG psg;
|
Update to v102r05 release.
byuu says:
Changelog:
- higan: added Makefile option,
`build=(release|debug|instrument|optimize)` , defaults to release
- PCE: added preliminary PSG (sound) emulation
The Makefile thing is just to make it easier to build debug releases
without having to hand-edit the Makefile. Just say "gmake build=debug"
and you'll get -g, otherwise you'll get -O3 -s. I'll probably start
adding these build= blocks to my other projects. Or maybe I'll put it
into nall, in which case release will need a different name ... a stable
-01, and a fast -03 mode. I also want to add a mode to generate
profiling information (via gprof.)
Unfortunately, the existing documentation on the PCE's PSG is as
barebones as humanly possible.
Right now, I support waveform mode, direct D/A mode, and noise
generation mode. However for noise, I'm not actually generating a proper
square wave, and I don't know the PRNG algorithm used for choosing the
random values. So for now, I'm just feeding in nall::random() values to
it.
I'm also not sure about the noise mode's frequency counter. Magic Kit is
implying it's 64*~frequency, but that results in an 11-bit period. It
seems only logical that we'd want a 12-bit period. So my guess is that
it's actually 12-bit, and halfway through it alternates between two
randomly generated values every 32 samples, and the two values are
generated every time the period hits zero.
Next up, it's not clear when the period counter is reloaded, either for
the waveform or the noise mode. So for now, when enabling the channel, I
reload the waveform period. And when enabling noise mode, I reload the
noise period. I don't know if you need to do it when writing to the
frequency registers or not.
Next, it's not clear whether the period is a decrement-and-compare, or a
compare-and-decrement, and whether we reload with frequency,
frequency-1, or frequency+1. There's this cryptic note in
pcetext.txt:
> The PSG channel frequency is 12 bits, $001 is the highest frequency,
> $FFF is the next to lowest frequency, and $000 is the lowest frequency.
As best I can tell, he's trying to say that it's decrement-and-compare.
Whatever the case, there's periodic popping noises every few seconds. I
thought it might be because this is the first system with a fractional
sampling rate (~3.57MHz), but rounding the frequency to a whole number
doesn't help at all, and emulator/audio should be able to handle
fractional resampling rates anyway.
The popping noises could also be due to PSG writes being cycle-timed,
and my HuC6280 cycle timings not being very great yet. The PSG has no
kind of interrupts, so I think careful timing is the only way to do
certain things, especially D/A mode.
Next up, I really don't understand the frequency modulation mode at all.
I don't have any idea whatsoever how to support that. It also has a
frequency value that we'll need to understand how the period works and
reloads. Basic idea though is the channel 1 output turns into a value to
modulate channel 0's frequency by, and channel 1's output gets muted.
Next up, I don't know how the volume controls work at all. There's a
master volume left+right, per-channel volume left+right, and per-channel
overall volume. The documentation lists their effects in terms of
decibels. I have no fucking clue how to turn decibels into multiply-by
values. Let alone how to stack THREE levels of audio volume controls
>_>
Next, it looks like the output is always 5-bit unsigned per-channel, but
there's also all the volume adjustments. So I don't know the final
bit-depth of the final output to normalize the value into a signed
floating point value between -1.0 and +1.0. So for now, half the
potential speaker range (anything below zero) isn't used in the
generated output.
As bad as all this sounds, and it is indeed bad ... the audio's about
~75% correct, so you can definitely play games like this, it just won't
be all that much fun.
2017-02-09 20:10:38 +00:00
|
|
|
#include "io.cpp"
|
|
|
|
#include "channel.cpp"
|
2017-02-12 23:09:03 +00:00
|
|
|
#include "serialization.cpp"
|
Update to v101r30 release.
byuu says:
Changelog:
- SMS: added cartridge ROM/RAM mirroring (fixes Alex Kidd)
- SMS: fixed 8x16 sprite mode (fixes Wonder Boy, Ys graphics)
- Z80: emulated "ex (sp),hl" instruction
- Z80: fixed INx NF (should be set instead of cleared)
- Z80: fixed loop condition check for CPxR, INxR, LDxR, OTxR (fixes
walking in Wonder Boy)
- SFC: removed Debugger and sfc/debugger.hpp
- icarus: connected MS, GG, MD importing to the scan dialog
- PCE: added emulation skeleton to higan and icarus
At this point, Master System games are fairly highly compatible, sans
audio. Game Gear games are running, but I need to crop the resolution
and support the higher color palette that they can utilize. It's really
something else the way they handled the resolution shrink on that thing.
The last change is obviously going to be the biggest news.
I'm very well aware it's not an ideal time to start on a new emulation
core, with the MS and MD cores only just now coming to life with no
audio support.
But, for whatever reason, my heart's really set on working on the PC
Engine. I wanted to write the final higan skeleton core, and get things
ready so that whenever I'm in the mood to work on the PCE, I can do so.
The skeleton is far and away the most tedious and obnoxious part of the
emulator development, because it's basically all just lots of
boilerplate templated code, lots of new files to create, etc.
I really don't know how things are going to proceed ... but I can say
with 99.9% certainty that this will be the final brand new core ever
added to higan -- at least one written by me, that is. This was
basically the last system from my childhood that I ever cared about.
It's the last 2D system with games that I really enjoy playing. No other
system is worth dividing my efforts and reducing the quality and amount
of time to work on the systems I have.
In the future, there will be potential for FDS, Mega CD and PCE-CD
support. But those will all be add-ons, and they'll all be really
difficult and challenge the entire design of higan's UI (it's entirely
cartridge-driven at this time.) None of them will be entirely new cores
like this one.
2017-01-11 20:27:30 +00:00
|
|
|
|
|
|
|
auto PSG::Enter() -> void {
|
|
|
|
while(true) scheduler.synchronize(), psg.main();
|
|
|
|
}
|
|
|
|
|
|
|
|
auto PSG::main() -> void {
|
2017-02-12 23:09:03 +00:00
|
|
|
static const uint5 volumeScale[16] = {
|
|
|
|
0x00, 0x03, 0x05, 0x07, 0x09, 0x0b, 0x0d, 0x0f,
|
|
|
|
0x10, 0x13, 0x15, 0x17, 0x19, 0x1b, 0x1d, 0x1f,
|
|
|
|
};
|
|
|
|
|
|
|
|
uint5 lmal = volumeScale[io.volumeLeft];
|
|
|
|
uint5 rmal = volumeScale[io.volumeRight];
|
|
|
|
|
|
|
|
double outputLeft = 0.0;
|
|
|
|
double outputRight = 0.0;
|
Update to v102r05 release.
byuu says:
Changelog:
- higan: added Makefile option,
`build=(release|debug|instrument|optimize)` , defaults to release
- PCE: added preliminary PSG (sound) emulation
The Makefile thing is just to make it easier to build debug releases
without having to hand-edit the Makefile. Just say "gmake build=debug"
and you'll get -g, otherwise you'll get -O3 -s. I'll probably start
adding these build= blocks to my other projects. Or maybe I'll put it
into nall, in which case release will need a different name ... a stable
-01, and a fast -03 mode. I also want to add a mode to generate
profiling information (via gprof.)
Unfortunately, the existing documentation on the PCE's PSG is as
barebones as humanly possible.
Right now, I support waveform mode, direct D/A mode, and noise
generation mode. However for noise, I'm not actually generating a proper
square wave, and I don't know the PRNG algorithm used for choosing the
random values. So for now, I'm just feeding in nall::random() values to
it.
I'm also not sure about the noise mode's frequency counter. Magic Kit is
implying it's 64*~frequency, but that results in an 11-bit period. It
seems only logical that we'd want a 12-bit period. So my guess is that
it's actually 12-bit, and halfway through it alternates between two
randomly generated values every 32 samples, and the two values are
generated every time the period hits zero.
Next up, it's not clear when the period counter is reloaded, either for
the waveform or the noise mode. So for now, when enabling the channel, I
reload the waveform period. And when enabling noise mode, I reload the
noise period. I don't know if you need to do it when writing to the
frequency registers or not.
Next, it's not clear whether the period is a decrement-and-compare, or a
compare-and-decrement, and whether we reload with frequency,
frequency-1, or frequency+1. There's this cryptic note in
pcetext.txt:
> The PSG channel frequency is 12 bits, $001 is the highest frequency,
> $FFF is the next to lowest frequency, and $000 is the lowest frequency.
As best I can tell, he's trying to say that it's decrement-and-compare.
Whatever the case, there's periodic popping noises every few seconds. I
thought it might be because this is the first system with a fractional
sampling rate (~3.57MHz), but rounding the frequency to a whole number
doesn't help at all, and emulator/audio should be able to handle
fractional resampling rates anyway.
The popping noises could also be due to PSG writes being cycle-timed,
and my HuC6280 cycle timings not being very great yet. The PSG has no
kind of interrupts, so I think careful timing is the only way to do
certain things, especially D/A mode.
Next up, I really don't understand the frequency modulation mode at all.
I don't have any idea whatsoever how to support that. It also has a
frequency value that we'll need to understand how the period works and
reloads. Basic idea though is the channel 1 output turns into a value to
modulate channel 0's frequency by, and channel 1's output gets muted.
Next up, I don't know how the volume controls work at all. There's a
master volume left+right, per-channel volume left+right, and per-channel
overall volume. The documentation lists their effects in terms of
decibels. I have no fucking clue how to turn decibels into multiply-by
values. Let alone how to stack THREE levels of audio volume controls
>_>
Next, it looks like the output is always 5-bit unsigned per-channel, but
there's also all the volume adjustments. So I don't know the final
bit-depth of the final output to normalize the value into a signed
floating point value between -1.0 and +1.0. So for now, half the
potential speaker range (anything below zero) isn't used in the
generated output.
As bad as all this sounds, and it is indeed bad ... the audio's about
~75% correct, so you can definitely play games like this, it just won't
be all that much fun.
2017-02-09 20:10:38 +00:00
|
|
|
|
|
|
|
for(auto C : range(6)) {
|
2017-02-12 23:09:03 +00:00
|
|
|
uint5 al = channel[C].io.volume;
|
|
|
|
uint5 lal = volumeScale[channel[C].io.volumeLeft];
|
|
|
|
uint5 ral = volumeScale[channel[C].io.volumeRight];
|
|
|
|
|
|
|
|
uint5 volumeLeft = min(0x1f, (0x1f - lmal) + (0x1f - lal) + (0x1f - al));
|
|
|
|
uint5 volumeRight = min(0x1f, (0x1f - rmal) + (0x1f - ral) + (0x1f - al));
|
|
|
|
|
Update to v102r05 release.
byuu says:
Changelog:
- higan: added Makefile option,
`build=(release|debug|instrument|optimize)` , defaults to release
- PCE: added preliminary PSG (sound) emulation
The Makefile thing is just to make it easier to build debug releases
without having to hand-edit the Makefile. Just say "gmake build=debug"
and you'll get -g, otherwise you'll get -O3 -s. I'll probably start
adding these build= blocks to my other projects. Or maybe I'll put it
into nall, in which case release will need a different name ... a stable
-01, and a fast -03 mode. I also want to add a mode to generate
profiling information (via gprof.)
Unfortunately, the existing documentation on the PCE's PSG is as
barebones as humanly possible.
Right now, I support waveform mode, direct D/A mode, and noise
generation mode. However for noise, I'm not actually generating a proper
square wave, and I don't know the PRNG algorithm used for choosing the
random values. So for now, I'm just feeding in nall::random() values to
it.
I'm also not sure about the noise mode's frequency counter. Magic Kit is
implying it's 64*~frequency, but that results in an 11-bit period. It
seems only logical that we'd want a 12-bit period. So my guess is that
it's actually 12-bit, and halfway through it alternates between two
randomly generated values every 32 samples, and the two values are
generated every time the period hits zero.
Next up, it's not clear when the period counter is reloaded, either for
the waveform or the noise mode. So for now, when enabling the channel, I
reload the waveform period. And when enabling noise mode, I reload the
noise period. I don't know if you need to do it when writing to the
frequency registers or not.
Next, it's not clear whether the period is a decrement-and-compare, or a
compare-and-decrement, and whether we reload with frequency,
frequency-1, or frequency+1. There's this cryptic note in
pcetext.txt:
> The PSG channel frequency is 12 bits, $001 is the highest frequency,
> $FFF is the next to lowest frequency, and $000 is the lowest frequency.
As best I can tell, he's trying to say that it's decrement-and-compare.
Whatever the case, there's periodic popping noises every few seconds. I
thought it might be because this is the first system with a fractional
sampling rate (~3.57MHz), but rounding the frequency to a whole number
doesn't help at all, and emulator/audio should be able to handle
fractional resampling rates anyway.
The popping noises could also be due to PSG writes being cycle-timed,
and my HuC6280 cycle timings not being very great yet. The PSG has no
kind of interrupts, so I think careful timing is the only way to do
certain things, especially D/A mode.
Next up, I really don't understand the frequency modulation mode at all.
I don't have any idea whatsoever how to support that. It also has a
frequency value that we'll need to understand how the period works and
reloads. Basic idea though is the channel 1 output turns into a value to
modulate channel 0's frequency by, and channel 1's output gets muted.
Next up, I don't know how the volume controls work at all. There's a
master volume left+right, per-channel volume left+right, and per-channel
overall volume. The documentation lists their effects in terms of
decibels. I have no fucking clue how to turn decibels into multiply-by
values. Let alone how to stack THREE levels of audio volume controls
>_>
Next, it looks like the output is always 5-bit unsigned per-channel, but
there's also all the volume adjustments. So I don't know the final
bit-depth of the final output to normalize the value into a signed
floating point value between -1.0 and +1.0. So for now, half the
potential speaker range (anything below zero) isn't used in the
generated output.
As bad as all this sounds, and it is indeed bad ... the audio's about
~75% correct, so you can definitely play games like this, it just won't
be all that much fun.
2017-02-09 20:10:38 +00:00
|
|
|
channel[C].run();
|
|
|
|
if(C == 1 && io.lfoEnable) {
|
|
|
|
//todo: frequency modulation of channel 0 using channel 1's output
|
|
|
|
} else {
|
2017-02-12 23:09:03 +00:00
|
|
|
outputLeft += channel[C].io.output * volumeScalar[volumeLeft];
|
|
|
|
outputRight += channel[C].io.output * volumeScalar[volumeRight];
|
Update to v102r05 release.
byuu says:
Changelog:
- higan: added Makefile option,
`build=(release|debug|instrument|optimize)` , defaults to release
- PCE: added preliminary PSG (sound) emulation
The Makefile thing is just to make it easier to build debug releases
without having to hand-edit the Makefile. Just say "gmake build=debug"
and you'll get -g, otherwise you'll get -O3 -s. I'll probably start
adding these build= blocks to my other projects. Or maybe I'll put it
into nall, in which case release will need a different name ... a stable
-01, and a fast -03 mode. I also want to add a mode to generate
profiling information (via gprof.)
Unfortunately, the existing documentation on the PCE's PSG is as
barebones as humanly possible.
Right now, I support waveform mode, direct D/A mode, and noise
generation mode. However for noise, I'm not actually generating a proper
square wave, and I don't know the PRNG algorithm used for choosing the
random values. So for now, I'm just feeding in nall::random() values to
it.
I'm also not sure about the noise mode's frequency counter. Magic Kit is
implying it's 64*~frequency, but that results in an 11-bit period. It
seems only logical that we'd want a 12-bit period. So my guess is that
it's actually 12-bit, and halfway through it alternates between two
randomly generated values every 32 samples, and the two values are
generated every time the period hits zero.
Next up, it's not clear when the period counter is reloaded, either for
the waveform or the noise mode. So for now, when enabling the channel, I
reload the waveform period. And when enabling noise mode, I reload the
noise period. I don't know if you need to do it when writing to the
frequency registers or not.
Next, it's not clear whether the period is a decrement-and-compare, or a
compare-and-decrement, and whether we reload with frequency,
frequency-1, or frequency+1. There's this cryptic note in
pcetext.txt:
> The PSG channel frequency is 12 bits, $001 is the highest frequency,
> $FFF is the next to lowest frequency, and $000 is the lowest frequency.
As best I can tell, he's trying to say that it's decrement-and-compare.
Whatever the case, there's periodic popping noises every few seconds. I
thought it might be because this is the first system with a fractional
sampling rate (~3.57MHz), but rounding the frequency to a whole number
doesn't help at all, and emulator/audio should be able to handle
fractional resampling rates anyway.
The popping noises could also be due to PSG writes being cycle-timed,
and my HuC6280 cycle timings not being very great yet. The PSG has no
kind of interrupts, so I think careful timing is the only way to do
certain things, especially D/A mode.
Next up, I really don't understand the frequency modulation mode at all.
I don't have any idea whatsoever how to support that. It also has a
frequency value that we'll need to understand how the period works and
reloads. Basic idea though is the channel 1 output turns into a value to
modulate channel 0's frequency by, and channel 1's output gets muted.
Next up, I don't know how the volume controls work at all. There's a
master volume left+right, per-channel volume left+right, and per-channel
overall volume. The documentation lists their effects in terms of
decibels. I have no fucking clue how to turn decibels into multiply-by
values. Let alone how to stack THREE levels of audio volume controls
>_>
Next, it looks like the output is always 5-bit unsigned per-channel, but
there's also all the volume adjustments. So I don't know the final
bit-depth of the final output to normalize the value into a signed
floating point value between -1.0 and +1.0. So for now, half the
potential speaker range (anything below zero) isn't used in the
generated output.
As bad as all this sounds, and it is indeed bad ... the audio's about
~75% correct, so you can definitely play games like this, it just won't
be all that much fun.
2017-02-09 20:10:38 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
Update to v102r15 release.
byuu says:
Changelog:
- nall: added DSP::IIR::OnePole (which is a first-order IIR filter)
- FC/APU: removed strong highpass, weak hipass filters (and the
dummied out lowpass filter)
- MS,GG,MD/PSG: removed lowpass filter
- MS,GG,MD/PSG: audio was not being centered properly; removed
centering for now
- MD/YM2612: fixed clipping of accumulator from 18 signed bits to 14
signed bits (-0x2000 to +0x1fff) [Cydrak]
- MD/YM2612: removed lowpass filter
- PCE/PSG: audio was not being centered properly; removed centering
for now
First thing is that I've removed all of the ad-hoc audio filtering.
Emulator::Stream intrinsically provides a three-pass, second-order
biquad IIR butterworth lowpass filter that clips frequencies above 20KHz
with very good attenuation (as good as IIR gets, anyway.)
It doesn't really make sense to have the various cores running
additional lowpass filters. If we want to filter frequencies below
20KHz, then I can adapt Emulator::Audio::createStream() to take a cutoff
frequency value, and we can do it all at once, with much better quality.
Right now, I don't know what frequencies are best to cut off the various
other audio cores, so they're just gone for now.
As for the highpass filters for the Famicom core, well ... you don't get
aliasing from resampling low frequencies. And generally speaking, too
low a frequency will be inaudible anyway. All these were doing was
killing possible bass (if they were too strong.) We can add them again,
but only if someone can convert Ryphecha's ad-hoc magic integers into a
frequency cutoff. In which case, I'll use my biquad IIR filter to do it
even better. On this note, it may prove useful to do this for the MD PSG
as well, to try and head off unnecessary clamping when mixing with the
YM2612.
Finally, there was the audio centering issue that affected the
MS,GG,MD,PCE,SG cores. It was flooring the "silent" audio level, which
was resulting in extremely heavy distortion if you tried listening to
higan and, say, audacious at the same time. Without the botched
centering, this distortion is completely gone now.
However, without any centering, we've halved the potential volume range.
This means the audio slider in higan's audio settings panel will start
clamping twice as quickly. So ultimately, we need to figure out how to
fix the centering. This isn't as simple as just subtracting less. We
will probably have to center every individual audio channel before
summing them to do this properly.
Results:
On the Mega Drive, Altered Beast sounds quite a bit better, a lot less
distortion now. But it's still not perfect, especially sound effects.
Further, Bare Knuckle / Streets of Rage still has really bad sound
effects. It looks like I broke something in Cydrak's code when trying to
adapt it to my style =(
2017-03-06 20:23:22 +00:00
|
|
|
stream->sample(sclamp<16>(outputLeft) / 32768.0, sclamp<16>(outputRight) / 32768.0);
|
Update to v101r30 release.
byuu says:
Changelog:
- SMS: added cartridge ROM/RAM mirroring (fixes Alex Kidd)
- SMS: fixed 8x16 sprite mode (fixes Wonder Boy, Ys graphics)
- Z80: emulated "ex (sp),hl" instruction
- Z80: fixed INx NF (should be set instead of cleared)
- Z80: fixed loop condition check for CPxR, INxR, LDxR, OTxR (fixes
walking in Wonder Boy)
- SFC: removed Debugger and sfc/debugger.hpp
- icarus: connected MS, GG, MD importing to the scan dialog
- PCE: added emulation skeleton to higan and icarus
At this point, Master System games are fairly highly compatible, sans
audio. Game Gear games are running, but I need to crop the resolution
and support the higher color palette that they can utilize. It's really
something else the way they handled the resolution shrink on that thing.
The last change is obviously going to be the biggest news.
I'm very well aware it's not an ideal time to start on a new emulation
core, with the MS and MD cores only just now coming to life with no
audio support.
But, for whatever reason, my heart's really set on working on the PC
Engine. I wanted to write the final higan skeleton core, and get things
ready so that whenever I'm in the mood to work on the PCE, I can do so.
The skeleton is far and away the most tedious and obnoxious part of the
emulator development, because it's basically all just lots of
boilerplate templated code, lots of new files to create, etc.
I really don't know how things are going to proceed ... but I can say
with 99.9% certainty that this will be the final brand new core ever
added to higan -- at least one written by me, that is. This was
basically the last system from my childhood that I ever cared about.
It's the last 2D system with games that I really enjoy playing. No other
system is worth dividing my efforts and reducing the quality and amount
of time to work on the systems I have.
In the future, there will be potential for FDS, Mega CD and PCE-CD
support. But those will all be add-ons, and they'll all be really
difficult and challenge the entire design of higan's UI (it's entirely
cartridge-driven at this time.) None of them will be entirely new cores
like this one.
2017-01-11 20:27:30 +00:00
|
|
|
step(1);
|
|
|
|
}
|
|
|
|
|
|
|
|
auto PSG::step(uint clocks) -> void {
|
|
|
|
Thread::step(clocks);
|
|
|
|
synchronize(cpu);
|
|
|
|
}
|
|
|
|
|
|
|
|
auto PSG::power() -> void {
|
Update to v102r05 release.
byuu says:
Changelog:
- higan: added Makefile option,
`build=(release|debug|instrument|optimize)` , defaults to release
- PCE: added preliminary PSG (sound) emulation
The Makefile thing is just to make it easier to build debug releases
without having to hand-edit the Makefile. Just say "gmake build=debug"
and you'll get -g, otherwise you'll get -O3 -s. I'll probably start
adding these build= blocks to my other projects. Or maybe I'll put it
into nall, in which case release will need a different name ... a stable
-01, and a fast -03 mode. I also want to add a mode to generate
profiling information (via gprof.)
Unfortunately, the existing documentation on the PCE's PSG is as
barebones as humanly possible.
Right now, I support waveform mode, direct D/A mode, and noise
generation mode. However for noise, I'm not actually generating a proper
square wave, and I don't know the PRNG algorithm used for choosing the
random values. So for now, I'm just feeding in nall::random() values to
it.
I'm also not sure about the noise mode's frequency counter. Magic Kit is
implying it's 64*~frequency, but that results in an 11-bit period. It
seems only logical that we'd want a 12-bit period. So my guess is that
it's actually 12-bit, and halfway through it alternates between two
randomly generated values every 32 samples, and the two values are
generated every time the period hits zero.
Next up, it's not clear when the period counter is reloaded, either for
the waveform or the noise mode. So for now, when enabling the channel, I
reload the waveform period. And when enabling noise mode, I reload the
noise period. I don't know if you need to do it when writing to the
frequency registers or not.
Next, it's not clear whether the period is a decrement-and-compare, or a
compare-and-decrement, and whether we reload with frequency,
frequency-1, or frequency+1. There's this cryptic note in
pcetext.txt:
> The PSG channel frequency is 12 bits, $001 is the highest frequency,
> $FFF is the next to lowest frequency, and $000 is the lowest frequency.
As best I can tell, he's trying to say that it's decrement-and-compare.
Whatever the case, there's periodic popping noises every few seconds. I
thought it might be because this is the first system with a fractional
sampling rate (~3.57MHz), but rounding the frequency to a whole number
doesn't help at all, and emulator/audio should be able to handle
fractional resampling rates anyway.
The popping noises could also be due to PSG writes being cycle-timed,
and my HuC6280 cycle timings not being very great yet. The PSG has no
kind of interrupts, so I think careful timing is the only way to do
certain things, especially D/A mode.
Next up, I really don't understand the frequency modulation mode at all.
I don't have any idea whatsoever how to support that. It also has a
frequency value that we'll need to understand how the period works and
reloads. Basic idea though is the channel 1 output turns into a value to
modulate channel 0's frequency by, and channel 1's output gets muted.
Next up, I don't know how the volume controls work at all. There's a
master volume left+right, per-channel volume left+right, and per-channel
overall volume. The documentation lists their effects in terms of
decibels. I have no fucking clue how to turn decibels into multiply-by
values. Let alone how to stack THREE levels of audio volume controls
>_>
Next, it looks like the output is always 5-bit unsigned per-channel, but
there's also all the volume adjustments. So I don't know the final
bit-depth of the final output to normalize the value into a signed
floating point value between -1.0 and +1.0. So for now, half the
potential speaker range (anything below zero) isn't used in the
generated output.
As bad as all this sounds, and it is indeed bad ... the audio's about
~75% correct, so you can definitely play games like this, it just won't
be all that much fun.
2017-02-09 20:10:38 +00:00
|
|
|
create(PSG::Enter, system.colorburst());
|
Update to v102r16 release.
byuu says:
Changelog:
- Emulator::Stream now allows adding low-pass and high-pass filters
dynamically
- also accepts a pass# count; each pass is a second-order biquad
butterworth IIR filter
- Emulator::Stream no longer automatically filters out >20KHz
frequencies for all streams
- FC: added 20Hz high-pass filter; 20KHz low-pass filter
- GB: removed simple 'magic constant' high-pass filter of unknown
cutoff frequency (missed this one in the last WIP)
- GB,SGB,GBC: added 20Hz high-pass filter; 20KHz low-pass filter
- MS,GG,MD/PSG: added 20Hz high-pass filter; 20KHz low-pass filter
- MD: added save state support (but it's completely broken for now;
sorry)
- MD/YM2612: fixed Voice#3 per-operator pitch support (fixes sound
effects in Streets of Rage, etc)
- PCE: added 20Hz high-pass filter; 20KHz low-pass filter
- WS,WSC: added 20Hz high-pass filter; 20KHz low-pass filter
So, the point of the low-pass filters is to remove frequencies above
human hearing. If we don't do this, then resampling will introduce
aliasing that results in sounds that are audible to the human ear. Which
basically an annoying buzzing sound. You'll definitely hear the
improvement from these in games like Mega Man 2 on the NES. Of course,
these already existed before, so this WIP won't sound better than
previous WIPs.
The high-pass filters are a little more complicated. Their main role is
to remove DC bias and help to center the audio stream. I don't
understand how they do this at all, but ... that's what everyone who
knows what they're talking about says, thus ... so be it.
I have set all of the high-pass filters to 20Hz, which is below the
limit of human hearing. Now this is where it gets really interesting ...
technically, some of these systems actually cut off a lot of range. For
instance, the GBA should technically use an 800Hz high-pass filter when
output is done through the system's speakers. But of course, if you plug
in headphones, you can hear the lower frequencies.
Now 800Hz ... you definitely can hear. At that level, nearly all of the
bass is stripped out and the audio is very tinny. Just like the real
system. But for now, I don't want to emulate the audio being crushed
that badly.
I'm sticking with 20Hz everywhere since it won't negatively affect audio
quality. In fact, you should not be able to hear any difference between
this WIP and the previous WIP. But theoretically, DC bias should mostly
be removed as a result of these new filters. It may be that we need to
raise the values on some cores in the future, but I don't want to do
that until we know for certain that we have to.
What I can say is that compared to even older WIPs than r15 ... the
removal of the simple one-pole low-pass and high-pass filters with the
newer three-pass, second-order filters should result in much better
attenuation (less distortion of audible frequencies.) Probably not
enough to be noticeable in a blind test, though.
2017-03-08 20:20:40 +00:00
|
|
|
stream = Emulator::audio.createStream(2, frequency());
|
Update to v103r01 release.
byuu says:
Changelog:
- nall/dsp: improve one pole coefficient calculations [Fatbag]
- higan/audio: reworked filters to support selection of either one
pole (first-order) or biquad (second-order) filters
- note: the design is not stable yet; so forks should not put too
much effort into synchronizing with this change yet
- fc: added first-order filters as per NESdev wiki (90hz lowpass +
440hz lowpass + 14khz highpass)
- fc: created separate NTSC-J and NTSC-U regions
- NESdev wiki says the Japanese Famicom uses a separate audio
filtering strategy, but details are fuzzy
- there's also cartridge audio output being disabled on NES units;
and differences with controllers
- this stuff will be supported in the future, just adding the
support for it now
- gba: corrected serious bugs in PSG wave channel emulation [Cydrak]
- note that if there are still bugs here, it's my fault
- md/psg,ym2612: added first-order low-pass 2840hz filter to match
VA3-VA6 Mega Drives
- md/psg: lowered volume relative to the YM2612
- using 0x1400; multiple people agreed it was the closest to the
hardware recordings against a VA6
- ms,md/psg: don't serialize the volume levels array
- md/vdp: Hblank bit acts the same during Vblank as outside of it (it
isn't always set during Vblank)
- md/vdp: return isPAL in bit 0 of control port reads
- tomoko: change command-line option separator from : to |
- [Editor's note: This change was present in the public v103,
but it's in this changelog because it was made after the v103 WIP]
- higan/all: change the 20hz high-pass filters from second-order
three-pass to first-order one-pass
- these filters are meant to remove DC bias, but I honestly can't
hear a difference with or without them
- so there's really no sense wasting CPU power with an extremely
powerful filter here
Things I did not do:
- change icarus install rule
- work on 8-bit Mega Drive SRAM
- work on Famicom or Mega Drive region detection heuristics in icarus
My long-term dream plan is to devise a special user-configurable
filtering system where you can set relative volumes and create your own
list of filters (any number of them in any order at any frequency), that
way people can make the systems sound however they want.
Right now, the sanest place to put this information is inside the
$system.sys/manifest.bml files. But that's not very user friendly, and
upgrading to new versions will lose these changes if you don't copy them
over manually. Of course, cluttering the GUI with a fancy filter editor
is probably supreme overkill for 99% of users, so maybe that's fine.
2017-06-26 01:41:58 +00:00
|
|
|
stream->addFilter(Emulator::Filter::Order::First, Emulator::Filter::Type::HighPass, 20.0);
|
|
|
|
stream->addFilter(Emulator::Filter::Order::Second, Emulator::Filter::Type::LowPass, 20000.0, 3);
|
Update to v102r05 release.
byuu says:
Changelog:
- higan: added Makefile option,
`build=(release|debug|instrument|optimize)` , defaults to release
- PCE: added preliminary PSG (sound) emulation
The Makefile thing is just to make it easier to build debug releases
without having to hand-edit the Makefile. Just say "gmake build=debug"
and you'll get -g, otherwise you'll get -O3 -s. I'll probably start
adding these build= blocks to my other projects. Or maybe I'll put it
into nall, in which case release will need a different name ... a stable
-01, and a fast -03 mode. I also want to add a mode to generate
profiling information (via gprof.)
Unfortunately, the existing documentation on the PCE's PSG is as
barebones as humanly possible.
Right now, I support waveform mode, direct D/A mode, and noise
generation mode. However for noise, I'm not actually generating a proper
square wave, and I don't know the PRNG algorithm used for choosing the
random values. So for now, I'm just feeding in nall::random() values to
it.
I'm also not sure about the noise mode's frequency counter. Magic Kit is
implying it's 64*~frequency, but that results in an 11-bit period. It
seems only logical that we'd want a 12-bit period. So my guess is that
it's actually 12-bit, and halfway through it alternates between two
randomly generated values every 32 samples, and the two values are
generated every time the period hits zero.
Next up, it's not clear when the period counter is reloaded, either for
the waveform or the noise mode. So for now, when enabling the channel, I
reload the waveform period. And when enabling noise mode, I reload the
noise period. I don't know if you need to do it when writing to the
frequency registers or not.
Next, it's not clear whether the period is a decrement-and-compare, or a
compare-and-decrement, and whether we reload with frequency,
frequency-1, or frequency+1. There's this cryptic note in
pcetext.txt:
> The PSG channel frequency is 12 bits, $001 is the highest frequency,
> $FFF is the next to lowest frequency, and $000 is the lowest frequency.
As best I can tell, he's trying to say that it's decrement-and-compare.
Whatever the case, there's periodic popping noises every few seconds. I
thought it might be because this is the first system with a fractional
sampling rate (~3.57MHz), but rounding the frequency to a whole number
doesn't help at all, and emulator/audio should be able to handle
fractional resampling rates anyway.
The popping noises could also be due to PSG writes being cycle-timed,
and my HuC6280 cycle timings not being very great yet. The PSG has no
kind of interrupts, so I think careful timing is the only way to do
certain things, especially D/A mode.
Next up, I really don't understand the frequency modulation mode at all.
I don't have any idea whatsoever how to support that. It also has a
frequency value that we'll need to understand how the period works and
reloads. Basic idea though is the channel 1 output turns into a value to
modulate channel 0's frequency by, and channel 1's output gets muted.
Next up, I don't know how the volume controls work at all. There's a
master volume left+right, per-channel volume left+right, and per-channel
overall volume. The documentation lists their effects in terms of
decibels. I have no fucking clue how to turn decibels into multiply-by
values. Let alone how to stack THREE levels of audio volume controls
>_>
Next, it looks like the output is always 5-bit unsigned per-channel, but
there's also all the volume adjustments. So I don't know the final
bit-depth of the final output to normalize the value into a signed
floating point value between -1.0 and +1.0. So for now, half the
potential speaker range (anything below zero) isn't used in the
generated output.
As bad as all this sounds, and it is indeed bad ... the audio's about
~75% correct, so you can definitely play games like this, it just won't
be all that much fun.
2017-02-09 20:10:38 +00:00
|
|
|
|
|
|
|
memory::fill(&io, sizeof(IO));
|
2017-02-10 23:56:42 +00:00
|
|
|
for(auto C : range(6)) channel[C].power(C);
|
2017-02-12 23:09:03 +00:00
|
|
|
|
Update to v102r15 release.
byuu says:
Changelog:
- nall: added DSP::IIR::OnePole (which is a first-order IIR filter)
- FC/APU: removed strong highpass, weak hipass filters (and the
dummied out lowpass filter)
- MS,GG,MD/PSG: removed lowpass filter
- MS,GG,MD/PSG: audio was not being centered properly; removed
centering for now
- MD/YM2612: fixed clipping of accumulator from 18 signed bits to 14
signed bits (-0x2000 to +0x1fff) [Cydrak]
- MD/YM2612: removed lowpass filter
- PCE/PSG: audio was not being centered properly; removed centering
for now
First thing is that I've removed all of the ad-hoc audio filtering.
Emulator::Stream intrinsically provides a three-pass, second-order
biquad IIR butterworth lowpass filter that clips frequencies above 20KHz
with very good attenuation (as good as IIR gets, anyway.)
It doesn't really make sense to have the various cores running
additional lowpass filters. If we want to filter frequencies below
20KHz, then I can adapt Emulator::Audio::createStream() to take a cutoff
frequency value, and we can do it all at once, with much better quality.
Right now, I don't know what frequencies are best to cut off the various
other audio cores, so they're just gone for now.
As for the highpass filters for the Famicom core, well ... you don't get
aliasing from resampling low frequencies. And generally speaking, too
low a frequency will be inaudible anyway. All these were doing was
killing possible bass (if they were too strong.) We can add them again,
but only if someone can convert Ryphecha's ad-hoc magic integers into a
frequency cutoff. In which case, I'll use my biquad IIR filter to do it
even better. On this note, it may prove useful to do this for the MD PSG
as well, to try and head off unnecessary clamping when mixing with the
YM2612.
Finally, there was the audio centering issue that affected the
MS,GG,MD,PCE,SG cores. It was flooring the "silent" audio level, which
was resulting in extremely heavy distortion if you tried listening to
higan and, say, audacious at the same time. Without the botched
centering, this distortion is completely gone now.
However, without any centering, we've halved the potential volume range.
This means the audio slider in higan's audio settings panel will start
clamping twice as quickly. So ultimately, we need to figure out how to
fix the centering. This isn't as simple as just subtracting less. We
will probably have to center every individual audio channel before
summing them to do this properly.
Results:
On the Mega Drive, Altered Beast sounds quite a bit better, a lot less
distortion now. But it's still not perfect, especially sound effects.
Further, Bare Knuckle / Streets of Rage still has really bad sound
effects. It looks like I broke something in Cydrak's code when trying to
adapt it to my style =(
2017-03-06 20:23:22 +00:00
|
|
|
double level = 32767.0 / 6.0 / 32.0; //max volume / channels / steps
|
2017-02-12 23:09:03 +00:00
|
|
|
double step = 48.0 / 32.0; //48dB volume range spread over 32 steps
|
|
|
|
for(uint n : range(31)) {
|
|
|
|
volumeScalar[n] = level;
|
|
|
|
level /= pow(10.0, step / 20.0);
|
|
|
|
}
|
|
|
|
volumeScalar[31] = 0.0;
|
Update to v101r30 release.
byuu says:
Changelog:
- SMS: added cartridge ROM/RAM mirroring (fixes Alex Kidd)
- SMS: fixed 8x16 sprite mode (fixes Wonder Boy, Ys graphics)
- Z80: emulated "ex (sp),hl" instruction
- Z80: fixed INx NF (should be set instead of cleared)
- Z80: fixed loop condition check for CPxR, INxR, LDxR, OTxR (fixes
walking in Wonder Boy)
- SFC: removed Debugger and sfc/debugger.hpp
- icarus: connected MS, GG, MD importing to the scan dialog
- PCE: added emulation skeleton to higan and icarus
At this point, Master System games are fairly highly compatible, sans
audio. Game Gear games are running, but I need to crop the resolution
and support the higher color palette that they can utilize. It's really
something else the way they handled the resolution shrink on that thing.
The last change is obviously going to be the biggest news.
I'm very well aware it's not an ideal time to start on a new emulation
core, with the MS and MD cores only just now coming to life with no
audio support.
But, for whatever reason, my heart's really set on working on the PC
Engine. I wanted to write the final higan skeleton core, and get things
ready so that whenever I'm in the mood to work on the PCE, I can do so.
The skeleton is far and away the most tedious and obnoxious part of the
emulator development, because it's basically all just lots of
boilerplate templated code, lots of new files to create, etc.
I really don't know how things are going to proceed ... but I can say
with 99.9% certainty that this will be the final brand new core ever
added to higan -- at least one written by me, that is. This was
basically the last system from my childhood that I ever cared about.
It's the last 2D system with games that I really enjoy playing. No other
system is worth dividing my efforts and reducing the quality and amount
of time to work on the systems I have.
In the future, there will be potential for FDS, Mega CD and PCE-CD
support. But those will all be add-ons, and they'll all be really
difficult and challenge the entire design of higan's UI (it's entirely
cartridge-driven at this time.) None of them will be entirely new cores
like this one.
2017-01-11 20:27:30 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
}
|