Version 0.5 preview

General discussion about tracking, help and support.
User avatar
HertzDevil
Posts: 475
Joined: Thu Apr 23, 2015 7:39 pm
Location: Hong Kong SAR
Contact:

Re: Version 0.5 preview

Postby HertzDevil » Sun Jul 05, 2015 1:26 am

In exported NSFs from FamiTracker 0.5.0 beta 1 to beta 4, the VRC7 Hxx and Ixx effects take effect as soon as they are read, but effects precede notes in NSFs, so notes that overwrite the VRC7 custom patch will render effects on the same row useless. For example, this will not work if instrument 00 uses patch #0:

Code: Select all

C-3 00 . H02 I00

The current workaround is to move these effects to a channel to the right of all channels that require the custom patch, since channel processing works from the left to the right (skipping over DPCM), but this is not possible if all channels use the custom patch simultaneously. Furthermore, although these effects have global scope for the VRC7, in FamiTracker they rarely work outside VRC7 channel 1 (especially when there is no note appearing on the same row as the Ixx effect), so while the following works in exported NSFs, it does not in FamiTracker unless instrument 01 also uses a custom patch, but then the exported NSF will not work:

Code: Select all

C-3 00 . ...        F-3 01 . H02 I00

A possible solution is to create a separate variable in the NSF driver so that, when the Ixx effect is read, the driver sets up a flag telling that the VRC7 has to update the custom patch after everything else:

Code: Select all

var_ch_vrc7_Hxx = $03EB
var_ch_vrc7_Ixx: .res 1

ft_cmd_vrc7_Ixx: ; $874D in bankswitched NSFs, whatever it is named by ft_command_table
    jsr ft_get_pattern_byte
    sta var_ch_vrc7_Ixx ; do not enter ft_custom_patch_vrc7 here
    lda var_ch_vrc7_Hxx
    ora #$80
    sta var_ch_vrc7_Hxx
    jmp ft_read_note

ft_update_vrc7:
    ; ...
@NextChan:
    inx
    cpx #$06
    beq :+
    jmp @LoopChannels
:
ft_custom_patch_vrc7: ; $97B9 in backswitched NSFs, relocated to remove single tail call
    lda var_ch_vrc7_Hxx
    bpl :+
    and #$7F
    sta var_ch_vrc7_Hxx
    sta $9010
    jsr ft_vrc7_delay
    lda var_ch_vrc7_Ixx
    sta $9030
    ;jsr ft_vrc7_delay not required since this is the last write to the VRC7 within an engine cycle
:   rts

However, this means only the last of multiple Ixx assignments to different addresses will not work, so the modulator level would not be altered at all in this case:

Code: Select all

C-3 00 . H02 I00 H01 I08

A more complete solution is to use a separate bitmask to keep track of which registers have to overwrite the custom patch, since there are conveniently only 8 registers for that, such as:

Code: Select all

var_ch_vrc7_Hxx = $03EB
var_ch_vrc7_flag: .res 1
var_ch_vrc7_custom: .res 8
bit_mask: ; this could leverage ft_channel_mask
    .byte $01, $02, $04, $08, $10, $20, $40, $80

ft_cmd_vrc7_Ixx:
    txa
    pha
    ldx var_ch_vrc7_Hxx
    jsr ft_get_pattern_byte
    sta var_ch_vrc7_custom, x
    lda var_ch_vrc7_flag
    ora bit_mask, x
    sta var_ch_vrc7_flag
    pla
    tax
    jmp ft_read_note

ft_update_vrc7:
    ; as above
ft_custom_patch_vrc7:
    ldx #$07
:   lda var_ch_vrc7_flag
    and bit_mask, x
    beq :+
    stx $9010
    jsr ft_vrc7_delay
    lda var_ch_vrc7_custom, x
    stx $9030
    jsr ft_vrc7_delay
:   dex
    bpl :--
    lda #$00
    sta var_ch_vrc7_flag
    rts

The NSF driver should have sufficient space for this; apart from the bug where Ixx rarely works outside VRC7 channel 1, in any case the implementation of Hxx and Ixx should not require changes in FamiTracker at all. One more solution is to use an extra internal command to signify that a specified number of effect bytes must be read after the driver has finished processing the note length, then the VRC7 Hxx/Ixx effects will work as expected without any modification, but that requires significantly more work for both the NSF driver and the CPatternCompiler class.

On the other hand, the status bar's effect hints for these effects have not been updated:
  • HXY - VRC7 custom patch modulator settings
  • IXY - VRC7 custom patch carrier settings
In other words the H effect command for the VRC7 was going to have orthogonal control over each aspect of the VRC7 custom patch, as shown in this commented out code from CChannelHandlerVRC7::HandleCustomEffects(int, int) since 0.4.1: (Jxx would be used to control the modulator and feedback levels as indicated by EFF_CHAR[]. This is also the last FamiTracker version that featured the VRC7 Vxx effect.)

Code: Select all

case EF_VRC7_MODULATOR:
   switch (EffParam & 0xF0) {
      case 0x00:   // Amplitude modulation on/off
         break;
      case 0x10:   // Vibrato on/off
         break;
      case 0x20:   // Sustain on/off
         break;
      case 0x30:   // Wave rectification on/off
         break;
      case 0x40:   // Key rate scaling on/off
         break;
      case 0x50:   // Key rate level
         break;
      case 0x60:   // Mult factor
         break;
      case 0x70:   // Attack
         break;
      case 0x80:   // Decay
         break;
      case 0x90:   // Sustain
         break;
      case 0xA0:   // Release
         break;
   }
   break;
   case EF_VRC7_CARRIER:
      break;
   case EF_VRC7_LEVELS:
      if (EffParam & 0x80)   // Feedback
         m_iRegs[0x03] = (m_iRegs[0x03] & 0xF8) | (EffParam & 0x07);
      else
         m_iRegs[0x02] = (m_iRegs[0x02] & 0xC0) | (EffParam & 0x3F);
      m_bRegsDirty = true;
      break;

Other FamiTracker users may find this alternative implementation worth considering, but clearly this implementation would require much more ASM code than simply allowing a single byte to be written (do not even try to evaluate the corresponding custom patch bytes during NSF compile-time).

As a final word, when can we expect the Vxx effect for VRC7 to come back if the corresponding ASM code is still remaining in the NSF driver?
refactoring 0cc-famitracker

User avatar
ollaxe
Posts: 736
Joined: Mon Apr 20, 2015 7:07 pm
Location: Sweden
Contact:

Re: Version 0.5 preview

Postby ollaxe » Mon Jul 06, 2015 5:57 pm

https://youtu.be/HdWRTleizFU?t=15m24s

glitch.ftm
In the beta, the beginning V01-effect doesn't work.

Warning: This is an old, abandoned loop that sucks.
(4.1 KiB) Downloaded 54 times


Edit: It appears this was fixed in the 0.5.0 beta 3 or 4. I still had the beta 2 when I found this. Sorry!
Last edited by ollaxe on Thu Jul 09, 2015 9:34 am, edited 1 time in total.
Hi! I'm not really active here anymore but I still make music. Nowadays I mostly make dubstep with emphasis on good melodies and chord progressions.
SoundCloud: soundcloud.com/ollaxe
Twitter: twitter.com/ollaxe
Discord server: dis.gd/tK7uRnc
I'm also on Spotify. Search "OllAxe" and you'll find me.

User avatar
za909
Posts: 79
Joined: Tue May 12, 2015 12:10 pm
Location: Hungary

Re: Version 0.5 preview

Postby za909 » Wed Jul 08, 2015 6:29 pm

Any VRC7 module exported seems to instantly silence channels in the NSF when an Sxx effect is used. This existed in beta 2 as well, but I don't know when it was introduced. I'm not very familiar with the register layout but I checked a possible problem with the $30-$36 register writes, and one of the problematic channels in my song kept receiving the expected $E4 byte, so at least I know the problem is not there.

User avatar
HertzDevil
Posts: 475
Joined: Thu Apr 23, 2015 7:39 pm
Location: Hong Kong SAR
Contact:

Re: Version 0.5 preview

Postby HertzDevil » Thu Jul 09, 2015 3:11 am

I cannot reproduce the V01 bug on beta 3 or above.

The Sxx effect always resets the channel's period / frequency to 0 immediately, and sets the note number to 0x00 (no note); for VRC7 it also sets a corresponding "command" byte that determines whether the channel's instrument would sustain or release. The VRC7 channels have their own frequency variables, that are updated only when the current channel is active. Since 0.5.0 beta 1, however, the VRC7 skips the check for note number:

Code: Select all

@UpdateChannel:
    ; Load and cache period if there is an active note
    lda var_ch_Note + VRC7_CHANNEL, x
    ; this line is absent since 0.5.0 beta 1
    ; beq @SkipPeriod
    lda var_ch_PeriodCalcLo + VRC7_CHANNEL, x
    sta var_ch_vrc7_FnumLo, x
    lda var_ch_PeriodCalcHi + VRC7_CHANNEL, x
    and #$07
    sta var_ch_vrc7_FnumHi, x
@SkipPeriod:

In other words, even when var_ch_vrc7_Command is appropriately set by the Sxx command in ft_skip_row_update@BeginCut, the VRC7 channel can still write the zero frequency as soon as Sxx takes effect. Although the note cut and Sxx should perform the same action, for VRC7 their different behaviour might actually be preferable, because the built-in VRC7 patches do not even have a way to immediately issue a note cut until now (remember that volume 0 is audible for VRC7). In other words this might have been a new feature and a bug for the FamiTracker player side; to fix this, one could simply add another constant in vrc7_command_t, say CMD_NOTE_SXX, which behaves identically to the current CMD_NOTE_HALT except that this would reset the frequency to 0 before updating the VRC7 registers:

Code: Select all

void CChannelHandlerVRC7::HandleCut()
{
   m_iCommand = CMD_NOTE_SXX; // not CMD_NOTE_HALT
   m_iPortaTo = 0;
   RegisterKeyState(-1);
}

void CVRC7Channel::RefreshChannel()
{
   // ...
   int Fnum = (m_iPeriod >> 2) - GetVibrato() - GetFinePitch();// (m_iFinePitch - 0x80);
   if (m_iCommand == CMD_NOTE_SXX) // add these two lines
      Fnum = 0;
   // ...
   switch (m_iCommand) {
      case CMD_NOTE_TRIGGER:
         // ...
      case CMD_NOTE_ON:
         // ...
      case CMD_NOTE_HALT:
      case CMD_NOTE_SXX: // add this line
         Cmd = 0;
refactoring 0cc-famitracker

User avatar
ollaxe
Posts: 736
Joined: Mon Apr 20, 2015 7:07 pm
Location: Sweden
Contact:

Re: Version 0.5 preview

Postby ollaxe » Thu Jul 09, 2015 9:32 am

HertzDevil wrote:I cannot reproduce the V01 bug on beta 3 or above.


Oh, completely forgot to test it in a newer version... Sorry!
Hi! I'm not really active here anymore but I still make music. Nowadays I mostly make dubstep with emphasis on good melodies and chord progressions.
SoundCloud: soundcloud.com/ollaxe
Twitter: twitter.com/ollaxe
Discord server: dis.gd/tK7uRnc
I'm also on Spotify. Search "OllAxe" and you'll find me.

User avatar
ollaxe
Posts: 736
Joined: Mon Apr 20, 2015 7:07 pm
Location: Sweden
Contact:

Re: Version 0.5 preview

Postby ollaxe » Fri Jul 10, 2015 3:42 pm

Found yet another glitch - this time on the actual latest beta version...

The FDS-channel is not changing sample when changing instrument in the frame editor without a new note next to it. This was not present in the second beta and version 0.4.6

Example FTM:
Attachments
Short dubstep-ish loop.ftm
(6.41 KiB) Downloaded 51 times
Hi! I'm not really active here anymore but I still make music. Nowadays I mostly make dubstep with emphasis on good melodies and chord progressions.
SoundCloud: soundcloud.com/ollaxe
Twitter: twitter.com/ollaxe
Discord server: dis.gd/tK7uRnc
I'm also on Spotify. Search "OllAxe" and you'll find me.

jsr
Site Admin
Posts: 112
Joined: Tue Jan 06, 2015 1:25 pm

Re: Version 0.5 preview

Postby jsr » Sun Jul 12, 2015 11:09 pm

Thanks again for your reports. I'll upload a new build with the latest fixes soon, there's a few minor issues still remaining.

TheMudkipMaster12 wrote:Trying to use the edit function for DPCM samples crashes FamiTracker. I added the .dmp if you need it even though the crash is easy to do.

Thanks for the dump, I've tried to fix that.

8BitZtunerYT wrote:The NSF DatAdam - 700 Main St 0.5 Beta fails to compile correctly, the notes have switched places in the 2A03, the 5B is unaffected, the FTM sounds fine.

Wrong period table is used for 2a03 when Sunsoft is enabled, I messed up. It will be fixed.

HertzDevil wrote:Note that the 2A03 and 5B period tables are identical, so a separate table should not be required in the NSF driver in the same way MMC5 and VRC6 pulses do not.

That's true the other table can be removed. There should be an offset of one between 2a03 and YM though, this will be corrected in the next build.

HertzDevil wrote:Furthermore, although these effects have global scope for the VRC7, in FamiTracker they rarely work outside VRC7 channel 1

This was fixed by making the register buffer shared. I'll add some way to handle the priority issues as well.

HertzDevil wrote:Other FamiTracker users may find this alternative implementation worth considering, but clearly this implementation would require much more ASM code than simply allowing a single byte to be written

That's the reason it was scrapped. The current way will be explained in the help files and hopefully still useful.

HertzDevil wrote:As a final word, when can we expect the Vxx effect for VRC7 to come back if the corresponding ASM code is still remaining in the NSF driver?

A neglected feature, shouldn't take long to fix.

ollaxe wrote:The FDS-channel is not changing sample when changing instrument in the frame editor without a new note next to it. This was not present in the second beta and version 0.4.6

That's correct, I'll fix this too.
Famitracker developer

User avatar
MovieMovies1
Posts: 98
Joined: Mon Apr 20, 2015 6:20 pm
Location: Norway
Contact:

Re: Version 0.5 preview

Postby MovieMovies1 » Mon Jul 13, 2015 12:10 am

Copying a 2A03 instrument removes D Counter values. This occurs in both 0.4.6 and 0.5 beta from what I have tested

Video
[INSERT SIGNATURE HERE]

jsr
Site Admin
Posts: 112
Joined: Tue Jan 06, 2015 1:25 pm

Re: Version 0.5 preview

Postby jsr » Mon Jul 13, 2015 8:12 pm

I've fixed that now, MovieMovies1.

The latest build has been uploaded to the first post along with a change log.

The YM emulation has been rewritten and should now be on par with other chips regarding audio quality. Next step is to check the actual mixing levels.
Famitracker developer

8BitZtunerYT
Posts: 379
Joined: Thu Apr 23, 2015 7:20 pm
Location: Somewhere stuck in Winamp

Re: Version 0.5 preview

Postby 8BitZtunerYT » Mon Jul 13, 2015 8:51 pm

This sounds so promising, will test tomorrow.
slowly ceasing to exist.
"8BitZ caresses his keyboard as he orgasms to the sounds of Winamp."
-retrodpc, 2015