Skip to content

VGMPlay / in_vgm

Last update: 2023-12-31 (v0.51.1)

Technical discussion about the VGM format, and all the software you need to handle VGM files.

Moderator: Staff

  • muteKi Offline
  • Posts: 17
  • Joined: 2012-07-10, 3:53:51

Post by muteKi »

No, it was something (quite clear from going over my large personal VGM collection the other day, since I like using an FM channel over the PSG noise channel for cymbal voices) that I've noticed as well -- the left and right output on some of the more 'static-y'/overdriven voices like that don't have consistent output on the left and right channels (giving these voices a weird stereo-chorus sort of effect to them), which doesn't make sense given the limited capabilities of the chip.

Couldn't tell ya for sure why it's a problem (what caused this bug I mean), naturally, but it's pretty obviously wrong.
Last edited by muteKi on 2012-08-16, 0:44:22, edited 1 time in total.
  • User avatar
  • ValleyBell Offline
  • Posts: 4767
  • Joined: 2011-12-01, 20:20:07
  • Location: Germany

Post by ValleyBell »

The difference between the cymbal on hardware and in VGMPlay could very well be caused by a low-pass filter.

The thing about left and right channel being different is a valid point, though.

I did a small mod to the YM2612 core when I added the DAC test mode, because:
Sik wrote:
ValleyBell wrote:The YM2612 itself has a clock divider of 72, so I get a sample rate of 106 534.08 Hz.
The output waveform is updated at half that rate though (~53KHz), so that'd be the real sample rate.
and I mean to have read that the chip alternates between updating the left and right channels. So this is what it does, ATM.
That feature is disabled, if the chip's sample rate goes lower than a certain value. So if you set Chip Sample Rate to 53267 (and force it to use that rate), it should sound like in earlier builds.

I'll make that an optional feature in the next build.

But well, that's all I intend to do with the YM2612.
  • User avatar
  • Raijin Offline
  • Posts: 41
  • Joined: 2012-08-15, 6:24:35

Post by Raijin »

Yeah, it's as muteKi says. You can definately tell it's wrong, especially the very start of the Alien Soldier track I mentioned before, because it's extremely distorted. I heard it on a real Genesis before and it definately wasn't distorted like that at all.
I'm not really technical enough to understand how to get around that though. I did play with sample rates, though it didn't help. I'm not going to bug you about that anymore, because it probably isn't too big of a deal, I guess.
By the way, while I am at it, I might as well ask. Can you explain what exactly makes Gens emulation so bad? It sounds fine for the most part as far as I can tell, but I'll bet maybe a more detailed explanation will help me understand better.
  • User avatar
  • ValleyBell Offline
  • Posts: 4767
  • Joined: 2011-12-01, 20:20:07
  • Location: Germany

Post by ValleyBell »

Sorry, but I didn't write any of the sound cores used in VGMPlay (except for the 2 OPL mappers for SN76489 and YM2413), so I don't know very little about their internal working.
The only thing I know about the Gens emulation is, that it's amost 10 years old and lacks SSG-EG support. (used in Asterix and the Great Rescue, for example)


Checked the Alien Soldier song: MESS 0.144 and VGMPlay (with the VGM recorded by MESS) sound different, although the tiny mods I did to the code were affect features the song doesn't use.
I give up and will leave it how it is. Period.
  • User avatar
  • Raijin Offline
  • Posts: 41
  • Joined: 2012-08-15, 6:24:35

Post by Raijin »

Well, you certainly don't seem like you're in a good mood about this, so again, I will just leave it at that and forget about it. It's not that big a deal, although I wish I knew enough to be able to help with this sort of thing. Sorry to bother you.
  • User avatar
  • Delek Offline
  • Posts: 41
  • Joined: 2012-05-05, 16:39:51

Post by Delek »

I'm adding NES Support to DefleMask and I find a bug in the noise channel lookup table of the NES Emulator used by in_vgm and VGMPlay:
The latest note:
static const int noise_freq[16] =
{
4, 8, 16, 32, 64, 96, 128, 160, 202, 254, 380, 508, 762, 1016, 2034, 2046
};

Should be:
static const int noise_freq[16] =
{
4, 8, 16, 32, 64, 96, 128, 160, 202, 254, 380, 508, 762, 1016, 2034, 4068
};


I've checked it using another emulators, and here I have a source that explains how should be the correct freq table:
http://wiki.nesdev.com/w/index.php/APU_Noise


You could check it by sending a 15 to the 0x02 reg of the noise channel, because you will hear almost the same that 14. And this is clearly wrong.
Last edited by Delek on 2012-08-19, 23:20:53, edited 2 times in total.
  • User avatar
  • ValleyBell Offline
  • Posts: 4767
  • Joined: 2011-12-01, 20:20:07
  • Location: Germany

Post by ValleyBell »

Thanks a lot. I've fixed it and it will be correct in the next release.
  • User avatar
  • Delek Offline
  • Posts: 41
  • Joined: 2012-05-05, 16:39:51

Post by Delek »

Awesome, you're welcome.

Btw, I discovered that the MESS core is very incomplete, it does not emulates correctly the Game Boy and it accept volume changes while a channel is sounding, and this is prohibited in Game Boy.

I modified the MESS emulation to be equal to the actual hardware, any write to the envelopes should be in this way:

case NR22: /* Envelope (R/W) */
gb->snd_2.env_direction = (data & 0x8) >> 3;
if(gb->snd_2.env_direction){
gb->snd_2.env_value++;
if(gb->snd_2.env_value>0x0F)gb->snd_2.env_value=0;
}
else{
gb->snd_2.env_value = data >> 4;
}
gb->snd_2.env_direction |= gb->snd_2.env_direction - 1;
gb->snd_2.env_length = gb->env_length_table[data & 0x7];

The volume channel can be changed while it is sounding by sending repeatedly 0x08 to the envelope register, this is explained in http://gbdev.gg8.se/wiki/articles/Gameb ... d_hardware
GBDev wrote: "Zombie" mode: the volume can be manually altered while a channel is playing by writing to NRx2. Behavior depends on the old and new values of NRx2, and whether the envlope has stopped automatic updates.

[...]

The only useful consistent behavior is using add mode with a period of zero in order to increment the volume by 1. That is, write $V8 to NRx2 to set the initial volume to V before triggering the channel, then write $08 to NRx2 to increment the volume as the sound plays (repeat 15 times to decrement the volume by 1). This allows manual volume control on all units tested.
Last edited by Delek on 2012-08-21, 18:28:32, edited 1 time in total.
  • User avatar
  • Delek Offline
  • Posts: 41
  • Joined: 2012-05-05, 16:39:51

Post by Delek »

Dudes, I find another bug in the NES Emulator, the notes from A0 to A1 in NES' Squares are unusable:

According to this table:
CODE wrote: /* frequency limit of square channels */
static const int freq_limit[8] =
{
0x3FF, 0x555, 0x666, 0x71C, 0x787, 0x7C1, 0x7E0, 0x7F0,
};
The limit freq at position zero should be 0x3FF... BUT, at the moment of the apu_square rendering, a wild condition appears:
CODE wrote: if ((0 == (chan->regs[1] & 8) && (chan->freq >> 16) > freq_limit[chan->regs[1] & 7])
|| (chan->freq >> 16) < 4)
return 0;
The interesting point is here:
(chan->freq >> 16) > freq_limit[chan->regs[1] & 7]

Why it is getting the information of the frequency limiter from the lower 3 bits of the APU Sweep (these 3 bits are the Shift count or speed of the sweep)?, and why it is getting from here always, even if the sweep is disabled!?.

This should be:
CODE wrote: if(chan->regs[1] & 0x80)freq_index=chan->regs[1] & 7; //If sweeping is enabled, I choose it as normal.
else freq_index=7; //If sweeping is disabled, I choose the lower limit.

if ((0 == (chan->regs[1] & 8) && (chan->freq >> 16) > freq_limit[freq_index])
|| (chan->freq >> 16) < 4)
return 0;
Now we can hear lower notes than A-1, but there is another thing, the full range of the NES is from A-0 to B-7 (not A-1 to B-7 as it was previously configured), but with this fix we cannot use A-0 yet. So this emulator needs another fix, and it is here:
CODE wrote: /* frequency limit of square channels */
static const int freq_limit[8] =
{
0x3FF, 0x555, 0x666, 0x71C, 0x787, 0x7C1, 0x7E0, 0x7F0,
};
The latest limit is wrong, I don't know the exact value for the limit, but the first value when the A-0 becomes audible is 0x7F2, so:
CODE wrote: /* frequency limit of square channels */
static const int freq_limit[8] =
{
0x3FF, 0x555, 0x666, 0x71C, 0x787, 0x7C1, 0x7E0, 0x7F2,
};

You could check in Famitracker easily that the NES could reach lower notes than A-1 and even A-0, and you can check that the current emulator used by in_vgm/VGMPlay could not reach those notes by listening to the next examples (they play A1 G1 F1 E1 D1 C1 B0 A0):
A VGM example done in DefleMask (you will hear only one note, A1, and then silence)
A WAVE Rendering of DefleMask
A WAVE Rendering of Famitracker
And a NSF that you can test with different emulators:

http://www.delek.com.ar/A0Test.vgm
http://www.delek.com.ar/A0Test_DefleMask.wav
http://www.delek.com.ar/A0Test_Famitracker.wav
http://www.delek.com.ar/A0Test_NSF.nsf

Regards.
Last edited by Delek on 2012-08-22, 2:40:49, edited 13 times in total.
  • User avatar
  • ValleyBell Offline
  • Posts: 4767
  • Joined: 2011-12-01, 20:20:07
  • Location: Germany

Post by ValleyBell »

Thanks, this works like a charm.
  • User avatar
  • dissident93 Offline
  • Posts: 204
  • Joined: 2012-02-17, 5:54:01
  • Location: USA

Post by dissident93 »

Excuse my ignorance, but the SEGA PCM tab is the YM3012?

Post by Sonic of 8! »

No. The YM3012 is a DAC chip for YM2151.
オモいカルチャーをオモチャーと言う - 細野晴臣
  • User avatar
  • RichterEX2 Offline
  • Posts: 191
  • Joined: 2012-03-30, 9:28:37
  • Location: Georgia, USA

Post by RichterEX2 »

I've got a question. I notice that each chip has its own panning menu in the settings, but all of them are greyed out. Will stereo panning be added for these chips in the future? Because it would really make the many mono sound arcade games sound better.
  • User avatar
  • ValleyBell Offline
  • Posts: 4767
  • Joined: 2011-12-01, 20:20:07
  • Location: Germany

Post by ValleyBell »

For now I don't plan do to add panning support to any other chips (except for YM3812, mabye).
  • User avatar
  • Delek Offline
  • Posts: 41
  • Joined: 2012-05-05, 16:39:51

Post by Delek »

Another bug in the NES Emulation, I discovered because my NSFs were doing a lot of plop sounds while changing the frequency, and not in DefleMask.

The write to the higher 3bits of the frequency in the Squares should reset the phase of the square, so:

case APU_WRA3:
case APU_WRB3:
info->APU.squ[chan].regs[3] = value;

if (info->APU.squ[chan].enabled)
{
info->APU.squ[chan].adder=0; <<<<NEW LINE
info->APU.squ[chan].vbl_length = info->vbl_times[value >> 3];
info->APU.squ[chan].env_vol = 0;
info->APU.squ[chan].freq = ((((value & 7) << 8) + info->APU.squ[chan].regs[2]) + 1) << 16;
}
That's how the NES have those plops on A-3 in Mega Man. (The fix in DefleMask was done avoiding write the high 3 bits on a portamento/vibrato).

SOURCE:

http://wiki.nesdev.com/w/index.php/APU
"Writing to $4003/4007 reloads the length counter, restarts the envelope, and resets the phase of the pulse generator. Because it resets phase, vibrato should only write the low timer register to avoid a phase reset click. At some pitches, particularly near A440, wide vibrato should normally be avoided (e.g. this flaw is heard throughout the Mega Man 2 ending)."


Also:
http://forums.nesdev.com/viewtopic.php?t=231
Post Reply