Help converting from Visual Basic

Just starting out? Need help? Post your questions and find answers here.
infratec
Always Here
Always Here
Posts: 6817
Joined: Sun Sep 07, 2008 12:45 pm
Location: Germany

Re: Help converting from Visual Basic

Post by infratec »

OPN_Write, writes to registers of an emulated YM2612 sound chip.

The registers are described here:

https://plutiedev.com/ym2612-registers

It has 3 channels

1. A4 A0
2. A5 A1
3. A6 A2

The third channel has also 'special functions'.

Hope this helps.
marcos.exe
User
User
Posts: 20
Joined: Fri Jan 17, 2020 8:20 pm

Re: Help converting from Visual Basic

Post by marcos.exe »

Looking quickly, I don't understand much. But with the codes in this post + the link you gave me, I believe it's just a matter of patience, and going deeper, to find the solution I need.

I am so grateful for the help!

I hope I can also contribute with what I learn.
When our generation/OS updates, we either update ourselves, or we are removed.
But we are never fully uninstalled.
SeregaZ
Enthusiast
Enthusiast
Posts: 617
Joined: Fri Feb 20, 2009 9:24 am
Location: Almaty (Kazakhstan. not Borat, but Triple G)
Contact:

Re: Help converting from Visual Basic

Post by SeregaZ »

not clear for me too :) will be nice to know what target you want.

i am use this dll from memory for my editor for old Sega Genesis \ Mega Drive 2 games. for sound part. but it is only one half. because this game console have two sound chips - YM2612 and PSG SNhowitnamesdontrememberthisdigits. this second one tone-noise-sound chip was converted into PB by wilbert, but i am not sure what topic it was, where he do that. so both part of sound i have in my project - one as PB, other as dll. i am use them with instruments editor. and early i use it for music play too, but my engine was not realy accurate... far far from original, but it was better than nothing.

so later one my comrade do dll version of GEMS audio driver player for PC. it need just send GEMS banks as memory into that dll and start play. that plays much more accurate, as real hardware do. so final result was awesome!
omnikam
User
User
Posts: 27
Joined: Sat Apr 15, 2017 10:58 am

Re: Help converting from Visual Basic

Post by omnikam »

Code: Select all

Function PasswordHash()

    ;Declarations
    Protected strInputString.s, strCode.s
    Protected intNameLength.i, intRnd.i

    strInputString = "abcdef0123456789" ;Characters to choose from to generate random string
    intNameLength = 16 ;Define length of random string

    Randomize()

    ;Generate the random string
    For intStep = 1 To intNameLength
        intRnd = Int((Len(strInputString) * Rnd()) + 1)
        strCode = strCode + Mid(strInputString, intRnd, 1)
    Next

    ;Return the string
    PasswordHash = strCode

EndFunction

Function ConvertBinary(strCode.s)

    ;Declarations
    Protected arrBinary.i(8), strStep.s
    Protected intCount.i

    ;Step through the randomly generated string of hex pairs by two and convert to binary
    ;while placing those binary values into an array
    For p = 0 To (Len(strCode) - 2) Step 2
        strStep = Mid(strCode, p + 1, 2)
        Protected b.i = Val("&H" + strStep)
        arrBinary(intCount) = b
        intCount = intCount + 1
    Next

    ;Return the populated array
    ConvertBinary = @arrBinary()

EndFunction
marcos.exe
User
User
Posts: 20
Joined: Fri Jan 17, 2020 8:20 pm

Re: Help converting from Visual Basic

Post by marcos.exe »

SeregaZ wrote: Wed Mar 22, 2023 4:17 pm not clear for me too :) will be nice to know what target you want.

i am use this dll from memory for my editor for old Sega Genesis \ Mega Drive 2 games. for sound part. but it is only one half. because this game console have two sound chips - YM2612 and PSG SNhowitnamesdontrememberthisdigits. this second one tone-noise-sound chip was converted into PB by wilbert, but i am not sure what topic it was, where he do that. so both part of sound i have in my project - one as PB, other as dll. i am use them with instruments editor. and early i use it for music play too, but my engine was not realy accurate... far far from original, but it was better than nothing.

so later one my comrade do dll version of GEMS audio driver player for PC. it need just send GEMS banks as memory into that dll and start play. that plays much more accurate, as real hardware do. so final result was awesome!
I created a virtual piano to play directly on the computer keyboard. It saves what I play to a midi file.
This piano uses windows midi sounds, as well as all VST that can be detected by windows drivers pickup system, such as the Yamaha S-YXG50e Roland SoundCanvas.
I also want it to sound sounds from the 2612 so that I have an idea of ​​how the final result will sound. Because then I can save in midi, and then convert to vgm or smps to play on the megadrive in some small projects.
Why not save directly to vgm? It would be a lot of work, and I don't have that much time for something that only I would use.
I know there are already programs that do this, but as I mentioned before, I'm totally blind, and my screen reader can't read the commands and buttons on these screens, like deflemask, fluitloops, etc.
The world is exclusively for the beholder, and so I must do my own thing. However, studying about it can be quite confusing for me, and my learning can be slower than that of a no-blind. So what for many of you seems simple to understand, for me can be a big puzzle.

Translated by google
When our generation/OS updates, we either update ourselves, or we are removed.
But we are never fully uninstalled.
SeregaZ
Enthusiast
Enthusiast
Posts: 617
Joined: Fri Feb 20, 2009 9:24 am
Location: Almaty (Kazakhstan. not Borat, but Triple G)
Contact:

Re: Help converting from Visual Basic

Post by SeregaZ »

for that opn.dll need to send registers values. i mean start core, then send that register values. at begin - set instruments registers and only then send key on, wait, key off commands. for your case can be problem with chords - becouse YM2612 have 6 channels and they need to set instruments to each of them and play key on individually. to understand more you can study this https://www.smspower.org/maxim/Documents/YM2612 and at the end it have some example for program, but not PB, just some idea. later i can add some example for PB.
marcos.exe
User
User
Posts: 20
Joined: Fri Jan 17, 2020 8:20 pm

Re: Help converting from Visual Basic

Post by marcos.exe »

SeregaZ wrote: Sat Apr 01, 2023 10:16 am for that opn.dll need to send registers values. i mean start core, then send that register values. at begin - set instruments registers and only then send key on, wait, key off commands. for your case can be problem with chords - becouse YM2612 have 6 channels and they need to set instruments to each of them and play key on individually. to understand more you can study this https://www.smspower.org/maxim/Documents/YM2612 and at the end it have some example for program, but not PB, just some idea. later i can add some example for PB.
I've learned a bit about the general view of how the 2612 works, but not enough to do what I want.
I saw that there are 6 sound channels, the sixth of which can be used as a DAC, in addition to the PSG sound, very similar to the MSX, (not the way to use it), which I still saw.
I played around with VGM Music Maker a bit, creating TFI instruments. But making music there? No way.
I've been using Basiegaxorz to insert music into a few things, but nothing that could be seriously usable.
Here, without vgm. Simply PSG and PSGVOL, because I didn't even know how to convert midi to VGM yet!
https://www.youtube.com/watch?v=sP65geY ... memusic%2B

Here, just one of several tests. I listened and tried to remake!
https://www.youtube.com/watch?v=51lc8Bf ... memusic%2B

I took a look at the link you posted. It doesn't seem like something I can learn in 3 months alone. But it's really valuable, and I'm already trying to get it inside my head.
I'm still studying all the scripts posted here, making changes and looking at manuals and links to learn a little more, however, still no progress different from what has already been posted by everyone.
So, despite all the help I've gotten here, if you could write an example, again I'd be very grateful, as it would save me a lot of headbanging.
Thank you very much in advance!

Translated by google
When our generation/OS updates, we either update ourselves, or we are removed.
But we are never fully uninstalled.
SeregaZ
Enthusiast
Enthusiast
Posts: 617
Joined: Fri Feb 20, 2009 9:24 am
Location: Almaty (Kazakhstan. not Borat, but Triple G)
Contact:

Re: Help converting from Visual Basic

Post by SeregaZ »

midi 2 vgm (but actually midi 2 deflemask, but later you can save it from deflemask to vgm from menu. use old deflemask version - it was free. now latest version is not free)
https://vgmrips.net/forum/download/file.php?id=2563

for windows.
SeregaZ
Enthusiast
Enthusiast
Posts: 617
Joined: Fri Feb 20, 2009 9:24 am
Location: Almaty (Kazakhstan. not Borat, but Triple G)
Contact:

Re: Help converting from Visual Basic

Post by SeregaZ »

very dirty example... and i didnt see how to attach files into this forum. need to attach opn.dll and instrument file for loading.

Code: Select all

Enumeration
  #Window
  
  #Canvas
  
  #CanvasBackImg
  
  #RawFileID
EndEnumeration

; structure and fill array with coordinates for fill area
Structure prsntstr
  x.u
  y.u
  t.a
EndStructure
Global Dim PressedNotes.prsntstr(5) ;{
PressedNotes(1)\x = 5
PressedNotes(1)\y = 75
PressedNotes(2)\x = 17
PressedNotes(2)\y = 5
PressedNotes(3)\x = 25
PressedNotes(3)\y = 75
PressedNotes(4)\x = 37
PressedNotes(4)\y = 5
PressedNotes(5)\x = 45
PressedNotes(5)\y = 75
;}

; paint green marks over keys
Procedure CanvasUpdate()
  
  SetGadgetAttribute(#Canvas, #PB_Canvas_Image, ImageID(#CanvasBackImg))
  
  If StartDrawing(CanvasOutput(#Canvas))
    
    For i = 1 To 5
      If PressedNotes(i)\t
        FillArea(PressedNotes(i)\x, PressedNotes(i)\y, RGB(1, 1, 1), RGB(0, 200, 0))
      EndIf
    Next
    
    StopDrawing()
  EndIf
  
EndProcedure

; paint base image for canvas
If CreateImage(#CanvasBackImg, 580, 140, 32, RGB(255, 255, 255)) ;{
  
  If StartDrawing(ImageOutput(#CanvasBackImg))
    
    Line(0, 90, 580, 1, RGB(1, 1, 1))
    Line(0, 90, 580, 1, RGB(1, 1, 1))
    
    Box(15, 0, 10, 60, RGB(1, 1, 1))
    Box(16, 0, 8, 59, RGB(0, 0, 0))
    
    Line(20, 60, 1, 30, RGB(1, 1, 1))
    
    Box(35, 0, 10, 60, RGB(1, 1, 1))
    Box(36, 0, 8, 59, RGB(0, 0, 0))
    
    Line(40, 60, 1, 30, RGB(1, 1, 1))
    
    Line(60, 0, 1, 90, RGB(1, 1, 1))
    
    StopDrawing()
  EndIf
  ;}
EndIf






;{ opn dll import
If OpenLibrary(OPNhdll, "OPN_DLL.dll")
  Prototype.l OpenDriver(chip.a)
  Prototype CloseDriver()
  Prototype OPNWrite(chip.a, register.u, value.u)  
  
  Global OpenOPNDriver.OpenDriver = GetFunction(OPNhdll, "OpenOPNDriver")
  Global CloseOPNDriver.CloseDriver = GetFunction(OPNhdll, "CloseOPNDriver")
  Global OPN_Write.OPNWrite = GetFunction(OPNhdll, "OPN_Write")
Else
  Debug "opn dll not found"
EndIf
;}


; procedure for setting instrument into some channel
;{ bits operations
Macro SetBit(Var, Bit) ;
  Var | (Bit)
EndMacro 
Macro ClearBit(Var, Bit) ;
  Var & (~(Bit))
EndMacro 
Macro TestBit(Var, Bit) ;
  Bool(Var & (Bit))
EndMacro
Macro NumToBit(Num) ;
  (1<<(Num))
EndMacro
Macro GetBits(Var, StartPos, EndPos)
  ((Var>>(StartPos))&(NumToBit((EndPos)-(StartPos)+1)-1))
EndMacro
;}
Global Dim Raw.l(39)
Procedure SetRegisterFromRaw(file$, vgmchannelforcode.i)
  
   Select vgmchannelforcode
     Case 0
       gcshift = 0
     Case 1
       gcshift = 1
     Case 2
       gcshift = 2
     Case 3
       gcshift = 256
     Case 4
       gcshift = 257
     Case 5
       gcshift = 258
   EndSelect
   
   If ReadFile(#RawFileID, file$)   ; if the file could be read, we continue...
    While Eof(#RawFileID) = 0           ; loop as long the 'end of file' isn't reached
      Number.a = ReadByte(#RawFileID)
      Select Loc(#RawFileID)
        Case 1 ; |??????tt| - type
          If Number <> 0
            MessageRequester("Attention | Внимание", "This file is unknown type of instrument.")
            Break
          Else
            Raw(1) = Number
          EndIf
        Case 2 ; |????ovvv| - LFO on, LFO value 
          Raw(2) = Number
          OPN_Write(0, $22, Number) ; global thing

        Case 3 ; |mm??????| - Channel 3 mode
          Raw(3) = Number          
          OPN_Write(0, $27, Number) ; global thing too         

        Case 4 ; |??fffaaa| - Feedback, Algorithm
          Raw(4) = Number
          OPN_Write(0, $B0+gcshift, Number)          

        Case 5 ; |lraa?fff| - Left/Right, AMS, FMS
          Raw(5) = Number
          OPN_Write(0, $B4+gcshift, Number)

        Case 6 ; |?dddmmmm| - Detune, Multiply 
          Raw(6) = Number
          OPN_Write(0, $30+gcshift, Number)

        Case 7 ; |?ttttttt| - TLevel
          Raw(7) = Number
          OPN_Write(0, $40+gcshift, Number)

        Case 8 ; |rr?aaaaa| - Rate Scale, Attack
          Raw(8) = Number
          OPN_Write(0, $50+gcshift, Number)

        Case 9 ; |a??ddddd| - AM, Decay 
          Raw(9) = Number
          OPN_Write(0, $60+gcshift, Number)

        Case 10 ; |???sssss| - Sustain
          Raw(10) = Number
          OPN_Write(0, $70+gcshift, Number)

        Case 11 ; |ssssrrrr| - Sustain Level, Release
          Raw(11) = Number
          OPN_Write(0, $80+gcshift, Number)

        Case 12 ; |?dddmmmm| - Detune, Multiply 
          Raw(12) = Number
          OPN_Write(0, $34+gcshift, Number)

        Case 13 ; |?ttttttt| - TLevel
          Raw(13) = Number
          OPN_Write(0, $44+gcshift, Number)

        Case 14 ; |rr?aaaaa| - Rate Scale, Attack
          Raw(14) = Number
          OPN_Write(0, $54+gcshift, Number)

        Case 15 ; |a??ddddd| - AM, Decay 
          Raw(15) = Number
          OPN_Write(0, $64+gcshift, Number)

        Case 16 ; |???sssss| - Sustain
          Raw(16) = Number
          OPN_Write(0, $74+gcshift, Number)

        Case 17 ; |ssssrrrr| - Sustain Level, Release
          Raw(17) = Number
          OPN_Write(0, $84+gcshift, Number)

        Case 18 ; |?dddmmmm| - Detune, Multiply 
          Raw(18) = Number
          OPN_Write(0, $38+gcshift, Number)

        Case 19 ; |?ttttttt| - TLevel
          Raw(19) = Number
          OPN_Write(0, $48+gcshift, Number)

        Case 20 ; |rr?aaaaa| - Rate Scale, Attack
          Raw(20) = Number
          OPN_Write(0, $58+gcshift, Number) 

        Case 21 ; |a??ddddd| - AM, Decay 
          Raw(21) = Number
          OPN_Write(0, $68+gcshift, Number)

        Case 22 ; |???sssss| - Sustain
          Raw(22) = Number
          OPN_Write(0, $78+gcshift, Number)

        Case 23 ; |ssssrrrr| - Sustain Level, Release
          Raw(23) = Number
          OPN_Write(0, $88+gcshift, Number)

        Case 24 ; |?dddmmmm| - Detune, Multiply 
          Raw(24) = Number
          OPN_Write(0, $3C+gcshift, Number)

        Case 25 ; |?ttttttt| - TLevel
          Raw(25) = Number
          OPN_Write(0, $4C+gcshift, Number)

        Case 26 ; |rr?aaaaa| - Rate Scale, Attack
          Raw(26) = Number
          OPN_Write(0, $5C+gcshift, Number)

        Case 27 ; |a??ddddd| - AM, Decay 
          Raw(27) = Number
          OPN_Write(0, $6C+gcshift, Number)

        Case 28 ; |???sssss| - Sustain
          Raw(28) = Number
          OPN_Write(0, $7C+gcshift, Number)

        Case 29 ; |ssssrrrr| - Sustain Level, Release
          Raw(29) = Number
          OPN_Write(0, $8C+gcshift, Number)

          
        Case 30
          Raw(30) = Number ;: Debug Hex(Number)
          OPN_Write(0, $A6, Number)
          
          Number = ReadByte(#RawFileID) ;: Debug Hex(Number)
          OPN_Write(0, $A2, Number)
          Raw(31) = Number

          
        Case 32
          Raw(32) = Number; : Debug Hex(Number)
          OPN_Write(0, $AC, Number)
          
          Number = ReadByte(#RawFileID); : Debug Hex(Number)
          OPN_Write(0, $A8, Number)
          Raw(33) = Number
          
        Case 34
          Raw(34) = Number; : Debug Hex(Number)
          OPN_Write(0, $AD, Number)
          
          Number = ReadByte(#RawFileID); : Debug Hex(Number)
          OPN_Write(0, $A9, Number)
          Raw(35) = Number

            
        Case 36
          Raw(36) = Number; : Debug Hex(Number)
          OPN_Write(0, $AE, Number)
          
          Number = ReadByte(#RawFileID); : Debug Hex(Number)
          OPN_Write(0, $AA, Number)
          Raw(37) = Number
          
          ;|??ffffffffffffff| - 14-bit frequency channel 3 mode operator 4 (A6, A2)
          ;
          ;|??ffffffffffffff| - 14-bit frequency channel 3 mode operator 3 (AC, A8)
          ;
          ;|??ffffffffffffff| - 14-bit frequency channel 3 mode operator 1 (AD, A9)
          ;
          ;|??ffffffffffffff| - 14-bit frequency channel 3 mode operator 2 (AE, AA)
          ;
          
        Case 38 ;{ keyon param
          Raw(38) = Number ;: Debug Bin(Number)
          ;}
 
          
      EndSelect

    Wend
    CloseFile(#RawFileID)               ; close the previously opened file
    
    OPN_Write(0, $90+gcshift, 0)
    OPN_Write(0, $94+gcshift, 0)
    OPN_Write(0, $98+gcshift, 0)
    OPN_Write(0, $9C+gcshift, 0)
  Else
    MessageRequester("Information","Couldn't open the raw file!")
  EndIf
  
EndProcedure ;}


; starting work opn core
OpenOPNDriver(1)

If OpenWindow(#Window, 100, 100, 600, 160, "", #PB_Window_MinimizeGadget | #PB_Window_ScreenCentered)
  
  CanvasGadget(#Canvas, 10, 10, 580, 140, #PB_Canvas_Keyboard)
  
  SetActiveGadget(#Canvas)
  
  CanvasUpdate()
  
  SetRegisterFromRaw("patch_34.raw", 0)
  SetRegisterFromRaw("patch_34.raw", 1)
  SetRegisterFromRaw("patch_34.raw", 2)
  SetRegisterFromRaw("patch_34.raw", 3)
  SetRegisterFromRaw("patch_34.raw", 4)
  
  OPN_Write(0, $A4, $1284 >> 8)  ; set notes values into registers of 1 ch
  OPN_Write(0, $A0, $1284 & $FF)
  
  OPN_Write(0, $A5, $12AA >> 8)  ; set notes values into registers of 2 ch
  OPN_Write(0, $A1, $12AA & $FF)
  
  OPN_Write(0, $A6, $12D3 >> 8)  ; set notes values into registers of 3 ch
  OPN_Write(0, $A2, $12D3 & $FF)
  
  OPN_Write(0, $A4 + 256, $12FE >> 8)  ; set notes values into registers of 4 ch
  OPN_Write(0, $A0 + 256, $12FE & $FF)
  
  OPN_Write(0, $A5 + 256, $132B >> 8)  ; set notes values into registers of 5 ch
  OPN_Write(0, $A1 + 256, $132B & $FF)
    
  Repeat
     Select WaitWindowEvent()

       Case #PB_Event_Gadget

         Select EventGadget()
           
           Case #Canvas
             Select EventType()
               Case #PB_EventType_KeyDown
                 Select GetGadgetAttribute(#Canvas, #PB_Canvas_Key) 
                   Case #PB_Shortcut_Z ; do ; 1284 ; Raw(38)
                     PressedNotes(1)\t = 1
                     CanvasUpdate()
                     OPN_Write(0, $28, (Raw(38) << 4))
                   Case #PB_Shortcut_S ;      12AA
                     PressedNotes(2)\t = 1
                     CanvasUpdate()
                     OPN_Write(0, $28, (Raw(38) << 4) + 1)
                   Case #PB_Shortcut_X ; re ; 12D3
                     PressedNotes(3)\t = 1
                     CanvasUpdate()
                     OPN_Write(0, $28, (Raw(38) << 4) + 2)
                   Case #PB_Shortcut_D ;      12FE
                     PressedNotes(4)\t = 1
                     CanvasUpdate()
                     OPN_Write(0, $28, (Raw(38) << 4) + 4)
                   Case #PB_Shortcut_C ; mi ; 132B
                     PressedNotes(5)\t = 1
                     CanvasUpdate()
                     OPN_Write(0, $28, (Raw(38) << 4) + 5)
                 EndSelect
               Case #PB_EventType_KeyUp 
                 Select GetGadgetAttribute(#Canvas, #PB_Canvas_Key)
                   Case #PB_Shortcut_Z ; do
                     PressedNotes(1)\t = 0
                     CanvasUpdate()
                     OPN_Write(0, $28, 0)
                   Case #PB_Shortcut_S
                     PressedNotes(2)\t = 0
                     CanvasUpdate()
                     OPN_Write(0, $28, 1)
                   Case #PB_Shortcut_X ; re
                     PressedNotes(3)\t = 0
                     CanvasUpdate()
                     OPN_Write(0, $28, 2)
                   Case #PB_Shortcut_D
                     PressedNotes(4)\t = 0
                     CanvasUpdate()
                     OPN_Write(0, $28, 4)
                   Case #PB_Shortcut_C ; mi
                     PressedNotes(5)\t = 0
                     CanvasUpdate()
                     OPN_Write(0, $28, 5)
                 EndSelect
             EndSelect

         EndSelect

       Case #PB_Event_CloseWindow
         qiut = 1
   
     EndSelect
   Until qiut = 1
   CloseOPNDriver()
   If OPNhdll : CloseLibrary(OPNhdll) : EndIf
   
EndIf

End
BarryG
Addict
Addict
Posts: 3292
Joined: Thu Apr 18, 2019 8:17 am

Re: Help converting from Visual Basic

Post by BarryG »

infratec wrote: Sat Aug 15, 2015 9:33 amMid() needs at minimum 1 as Startpos
It'll actually default to 1 if 0 is passed, though. But yeah, best practice is to ensure a correct value is passed.
Post Reply