Sauraen

MIDIbox FM V2.1 on STM32F4

63 posts in this topic

This is MIDIbox FM V2.1, the STM32F4 version of the Gen 2 MBFM. Please note that this is not an official successor to MIDIbox FM V1.4, nor is it a project that is intended to be easily replicated by members of the community, at least not in the forseeable future.

For the thread on MIDIbox FM V2.0, the same synth before I upgraded the processor from the LPC17, see here (some build information, more pictures, etc.):

 

I have successfully upgraded my MIDIbox FM from the LPC17 core to the STM32F4 core, both hardware and software, and re-christened it MIDIbox FM V2.1. A stable, decently full-featured (but not 100% complete) build is available. I upgraded mainly due to RAM limitations on the LPC17 core, and now the LPC17 core will no longer be supported, in favor of STM32F4.

 

Working features:

  • MIDIbox NG V1 integration; all synth controls are MBNG parameters, so you can lay out and wire your front panel how you want. Menus are fixed, though, and certain controls (e.g. 18 voice-selection buttons with two-color LEDs, 8 softkeys, 4 mode buttons) are basically mandatory. Other things (e.g. controls for operator parameters) may be done how you like (e.g. MBNG banking).
  • Supports 1 or 2 OPL3s (potentially 4, now that we have more RAM, though performance may become an issue). With 2 OPL3s (as I have), there are no noticeable performance problems, even when playing 30+-voice MIDI files into the synth.
  • Edit all 18 (per OPL3) 2-operator voices independently; set up six pairs (per OPL3) of 2-operator voices independently to be 4-operator voices; set up one set of 3 (per OPL3) 2-operator voices to become a 5-voice percussion system. All OPL3 parameters editable and modulatable (even bit flags and separate audio outputs for two halves of a 4-operator voice).
  • Set voices as polyphonic copies (DUPL) that follow parameters, or LINK them so they play together but have semi-independent parameters.
  • Customize transpose, tuning, portamento, EG retrigger, and delay per voice.
  • Arbitrarily assign two LFOs, one ADLDSR EG, velocity, mod wheel, and CC2 values to modulate voice, operator, or modulator parameters, per voice, up to 16 modulation connections per 2-op voice.
  • Set up a custom temperament system (e.g. just intonation) with independent root note selection and frequency controls. One-touch switch to equal temperament and back.
  • Intelligently assign voices to MIDI channels, the synth does the DUPL work (unless you disable it for custom configurations).
  • Save and load named patch files from SD card in intelligent folder hierarchy and human-readable (editable, hackable) format. About 75% of General MIDI Bank 0 patches are complete.
  • Customize synth's response to incoming MIDI messages: Bank MSB/LSB, Program, Pan, Volume, Expression. Enable/disable automatic patch loading on Program receive.
  • MIDI mixer window with real-time-updating separate Volume and Expression controls per channel.
  • Control MIDI input behavior per port.

Not done yet:

  • MIDI output port menu and behavior.
  • The rest of the GM patch bank.
  • There are some bugs with saving/loading 4-op voices, plus some untested (probably broken) corner cases for saving/loading complex LINK-DUPL voice arrays.
  • The "wavetable" modulator (step sequence of pre-programmed values).
  • The drum sequencer.
  • AOUT support (beyond what is offered in MBNG).

If anyone would like to build one of these, please let me know! I can send you information personally, or if applicable make a wiki page and/or put up the code somewhere.

Edited by Sauraen

Share this post


Link to post
Share on other sites

New demo video! MIDIbox FM V2.1 playing Zelda Majora's Mask: End Credits (Part 1) by Koji Kondo, a MIDI exported from the ROM using some software I'm developing.

 

Share this post


Link to post
Share on other sites
Hi Sauraen!
 
I hope you don't mind me contacting you. I asked a question in the forums and Thorsten suggested I ask you for your schematics and source code. That's a pretty impressive synth you've put together. I'm aiming for something a lot simpler to start with:
 
 
In particular I'm interested in how you connected the LPC board to the OPL. In your thread you said:

 

The parallel interface will have D7:D0 of the OPL3 module connected to J10 of the LPC17 module, /RS of the OPL3 module connected to J19:RC1 or RC2 (whichever is not otherwise in use), and the other OPL3 pins (A0, A1, /CS for OPL3 A, and /CS for OPL3 B) connected to J28. I expect one full register write operation to take around 15 us.

 

It looks like J10 has 3.3V GPIOs from the micro, but doesn't the OPL require 5V? Or does it work at 3.3V too? Also when you said /RS I guess you mean /RD? What was the reason you chose those pins?

 

Thanks a lot for your great work!

Share this post


Link to post
Share on other sites
I hope you don't mind me contacting you.

Of course not! I'd be happy to help.

 

It looks like J10 has 3.3V GPIOs from the micro' date=' but doesn't the OPL require 5V? Or does it work at 3.3V too? Also when you said /RS I guess you mean /RD? What was the reason you chose those pins?[/quote]

That is correct. According to the OPL3 datasheet (and this has worked for me), all the pins can be driven with 3.3V except the reset pin, which has to be at +5V when you don't want the chip to be in reset. The reset pin is called /IC ("initial clear") on the datasheet, but to me "IC" stands for "integrated circuit", so that's why I said "RS" for "reset"; the /RD pin is a read strobe, which should be connected directly to +5V (it is on the OPL3 board). I put the 8 data lines on J10 because there were already-existing subroutines to write the 8 bits at once; the other pins can be freely moved around (changing the configuration in the source code appropriately). The reason I put the /IC signal on J19:RC1 or RC2 is because those are buffered to +5V; you can move this signal to another pin, but then you have to make a simple level shifting circuit to interface it to the /IC pin of the OPL3.

 

I never actually drew schematics for this... ;)

 

I have a module driver for the OPL3 chip for LPC17 and STM32F4 that will do the low-level communication, and give you functions to set each of the parameters of each of the voices/channels. I could email it to you, but maybe there is a better way. TK, if you're reading this, where should I put up this code? On the wiki? Would you be able to give me commit privileges just for the folder mios32/trunk/modules/opl3/ ?

Edited by Sauraen

Share this post


Link to post
Share on other sites

Hi Sauraen, really great work. The dual OPLs sound so good.

  I would very much like a copy of your code; at some point I want to build this monster and ATM I'm planning a related project based on a YM2612 and a SN76489 for a Sega Gen synth. 

  Have been going through the PIC18F code but like you, see the STM32F4 as the future. Seeing a working example would help a great deal to get me started on the platform. I know I'll have to write a new HW driver and adapt some/lot of the synth engine, but the YM2612 seems like a sub set of the OPL in a lot of ways.

  Have you considered some file playback from SD card. Don't know the difficulties involved but it would be interesting to be able to play Adlib Tracker II songs :)

Yogi

Share this post


Link to post
Share on other sites
 I would very much like a copy of your code; at some point I want to build this monster and ATM I'm planning a related project based on a YM2612 and a SN76489 for a Sega Gen synth. 

  Have been going through the PIC18F code but like you, see the STM32F4 as the future. Seeing a working example would help a great deal to get me started on the platform. I know I'll have to write a new HW driver and adapt some/lot of the synth engine, but the YM2612 seems like a sub set of the OPL in a lot of ways.

I apologize for not having put up the code, I've been very busy this semester. TK did give me commit priveleges so it's just a matter of spending a few hours putting in the right preprocessor commands to make the driver specified for STM32F4 and all that, and trying to commit it without ruining the repository.

 

For your design, are you planning to use it primarily for real-time performance, or controlled by a DAW like a tracker? If the former, my synth engine might be appropriate; if the latter, you probably want to write a simpler application that puts each of the voices permanently on a different channel, and controls all the parameters from CCs.

 

Have you considered some file playback from SD card. Don't know the difficulties involved but it would be interesting to be able to play Adlib Tracker II songs

On my synth, I've considered MIDI file playback, but right now I can do that just fine by playing a MIDI from my computer into the synth. Probably the best way to support Adlib or something like that, would be to write a Juce program that reads the file format and outputs custom MIDI messages to the synth for notes and all the controllers. On the other hand, I do have to admit that I never wrote the part of MBFM V2.1 that lets you control all the parameters of the voices from CCs; only standard CCs like volume, pan, mod wheel, and sustain pedal are implemented, not things to change the actual parameters of the voice. This is partly because the synth supports making sounds that use several voices--you could, if you had the patience, set up all 36 voices as a single monophonic sound, maybe with detuned saw waves or something!--and I never figured out how to let you use CCs to tweak individual parameters within those voices, since there would be several hundred in that example.

Share this post


Link to post
Share on other sites
I apologize for not having put up the code, I've been very busy this semester. TK did give me commit priveleges so it's just a matter of spending a few hours putting in the right preprocessor commands to make the driver specified for STM32F4 and all that, and trying to commit it without ruining the repository.

 

Hi Sauraen, no worries. When you can is fine. The differences between the OPL and YM2612 will demand a fair amount of unique code, but I'm hoping, at some point, to adapt some of the great features of MBFM; LFOs, EGs, Wavetables and Mod Matrix.

 

For your design, are you planning to use it primarily for real-time performance, or controlled by a DAW like a tracker? If the former, my synth engine might be appropriate; if the latter, you probably want to write a simpler application that puts each of the voices permanently on a different channel, and controls all the parameters from CCs.

  I'm planning to implement the the same CC assignments that Littlescale chose for the GenMDM interface, mainly to maintain compatibility with user patches and VST software. With his design each of the 6  4op voices is assigned to a midi channel (1-6) and CC values are used for the voice's registers (~88 per voice). In addition there is special handling for Channels 3 & 6 and SSG 'Illegal' mode as well as support for the SN76489 PSG.  So polyphonic channels are at odds with this design so far. 

  Being so 'non-standard', patch handling will be  important for live play. The original design is limited due to the Teensy uC's resources, so on the STM32 I expect far better control.  

 

On my synth, I've considered MIDI file playback, but right now I can do that just fine by playing a MIDI from my computer into the synth. Probably the best way to support Adlib or something like that, would be to write a Juce program that reads the file format and outputs custom MIDI messages to the synth for notes and all the controllers. On the other hand, I do have to admit that I never wrote the part of MBFM V2.1 that lets you control all the parameters of the voices from CCs; only standard CCs like volume, pan, mod wheel, and sustain pedal are implemented, not things to change the actual parameters of the voice. This is partly because the synth supports making sounds that use several voices--you could, if you had the patience, set up all 36 voices as a single monophonic sound, maybe with detuned saw waves or something!--and I never figured out how to let you use CCs to tweak individual parameters within those voices, since there would be several hundred in that example.

  I mentioned Midi file playback because I had in mind some sort of VGM file player. Midi bandwidth wouldn't support VGM streaming too well, especially if the VGM has heavy use of PCM samples, but I was thinking that it might be workable via SD card. It's not a priority ATM but would be an interesting feature or separate project.

  Coming back to your project, I will definitely be building a dual OPL synth at some point soon. I've been working on-n-off on a PIC based FM but will re work it I think :smile:

Yogi 

Share this post


Link to post
Share on other sites

Hi Yogi, 

your Synth is a great project for my spring holiday :)

I would be very grateful if you give me your schematics and documents.

 

Best regards

Marxon

Share this post


Link to post
Share on other sites

I should be able to put up the code this weekend.

 

Just to mention, SD card bandwidth is not great either, though the files you're talking about may be small enough to load entirely into the huge 192kB RAM of the STM32F4 (of which less than half is used for MBFM, including MBNG and MIOS32).

 

It should be easy enough to hard map the sound chip voices to MIDI channels, and keep the framework I have in place for modulation, patch loading/saving, etc. Changing what the modulated parameters are should be straightforward, though of course it will take some work. Much of the complexity of MBFM2 is keeping track of multiple voices as one channel, with polyphony and two kinds of linked parameters.

 

I have also always wanted a Genesis synth. I don't have time this semester to build or code anything else, but if you have a PCB made with a group order, this summer I might like to build one. I can help you debug the code, but I probably won't have time to do any development myself.

Share this post


Link to post
Share on other sites
Hi Yogi, 

your Synth is a great project for my spring holiday :smile:

I would be very grateful if you give me your schematics and documents.

 

Best regards

Marxon

Hi Maxon. the original project that I got interested in is over @ Spritemind.net 

http://gendev.spritesmind.net/forum/viewtopic.php?t=1470&sid=86c0fd483001fc05b12fa14c4ec97f08

I'll have to draw up a schema of the FM/PSG board that I prototyped, will get that together in the next few days. The basic changes from Foobat's project are: a single YM2612 and a SN76489 with stereo output via a 'Mega Amp', as per the post at Sega16.com

 http://www.sega-16.com/forum/showthread.php?26568-Introducing-the-Mega-Amp-The-universal-Genesis-audio-circuit

As to the firmware well just starting with that :)

Yogi

Share this post


Link to post
Share on other sites

I was going to suggest a switch to toggle between Genesis 1 and 2 filters, the former with the original distortion. Can't quite tell if that Mega Amp lets you switch between filters.

Share this post


Link to post
Share on other sites
I should be able to put up the code this weekend.

 

Just to mention, SD card bandwidth is not great either, though the files you're talking about may be small enough to load entirely into the huge 192kB RAM of the STM32F4 (of which less than half is used for MBFM, including MBNG and MIOS32).

 

It should be easy enough to hard map the sound chip voices to MIDI channels, and keep the framework I have in place for modulation, patch loading/saving, etc. Changing what the modulated parameters are should be straightforward, though of course it will take some work. Much of the complexity of MBFM2 is keeping track of multiple voices as one channel, with polyphony and two kinds of linked parameters.

 

I have also always wanted a Genesis synth. I don't have time this semester to build or code anything else, but if you have a PCB made with a group order, this summer I might like to build one. I can help you debug the code, but I probably won't have time to do any development myself.

Hi Sauraen. OK very good

 VGM files are a recording of Register writes with timing. With the inclusion of  8b PCM samples a VGM would be larger then a Midi file. Unlike the SNES rompler type synth, Mega Drive music mainly uses the PCM channel for drums so while bigger then a Midi file, it's still compact.

  Most of the projects I've reviewed rely on an Arduino and the USB VCom to stream the file, and choke with files that include PCM voices due to bandwidth, RAM limits and timing . There was one project that uses an 8b AVR that did handle the streamed data well, using HID bulk mode, I think, and coded in straight C. I'm hoping the block transfers (512 bytes ?) from the SD card will be fast enough for playback from a large RAM buffer.  

A VGM player isn't the #1 priority but VGMs are the file of choice for most cross platform trackers so supporting them would benefit a few users. Will probably have to filter the VGM either on a PC or real time on the arm, to strip and redirect the console's addressing but I haven't investigated too much; on the ToDo list :) 

  But for right now will be happy to get a simple synth framework working. I would like to support poly midi modes but I think that it would require selecting the synth mode, kind of a 'Midi' or 'GenMDM' mode switch; somewhat like the MBSid engine. So I think it will have to be added in the future. 

​  Will definitely hook you up when I do a board run, maybe late spring? Depends on how much time I can devote.

Yogi 

 

 

Share this post


Link to post
Share on other sites
I was going to suggest a switch to toggle between Genesis 1 and 2 filters, the former with the original distortion. Can't quite tell if that Mega Amp lets you switch between filters.

Good point. The Mega Amp does allows for different filters; there are taylored schemas for the different YM version used in the range of models produced. In fact, a mod board that is being produced does have switches for the filter caps. So yea, it's do-able. Switches would also be needed depending on the YM chip used by builders, YM2612s or YM3834s. The 3834 has better drive levels and the mixing is fixed to eliminate the 'zipper' effect, but some like and want the Version 1 sound dynamics.

 So two DPDT, one per output channel, to switch the filter caps between two settings: Light filtering and Classic.

Yogi

Share this post


Link to post
Share on other sites

The code is up! It was much more painless than I had expected, and nearly the same procedure as git. Oh well. I am happy to now be a published programmer!

 

I would recommend you start with making the sound chip driver, starting by copying and pasting the OPL3 driver. Of course the data structures and functions will need to be changed, but some of the code will not. Then I would suggest making a simple mios32 app that plays notes on one of the channels, and from there test the driver.

Share this post


Link to post
Share on other sites
The code is up! It was much more painless than I had expected, and nearly the same procedure as git. Oh well. I am happy to now be a published programmer!

 

I would recommend you start with making the sound chip driver, starting by copying and pasting the OPL3 driver. Of course the data structures and functions will need to be changed, but some of the code will not. Then I would suggest making a simple mios32 app that plays notes on one of the channels, and from there test the driver.

Awesom! (SVN is so cool and easy!)

 Good advice. Yes the bit level chip access is different then the OPL3 so will be the first task to conquer.

Thanks again

Yogi 

Share this post


Link to post
Share on other sites
Yes the bit level chip access is different then the OPL3 so will be the first task to conquer.

Actually from looking at the datasheet it looks decently similar. The parallel interface should be nearly identical. Just change the register definitions in the header file, and then change the OPL3_SetWhatever() functions to match.

 

If you wouldn't mind, when you write all the code, please make the number of sound chips a preprocessor variable (like I have OPL3_COUNT). It might be more complicated because you want to have multiple different chips running on the same parallel interface. I am still a little confused about all the OPN series chips, which include the SSG and which don't, and which type of SSG to use externally. The most flexibility is of course the best, especially at the driver level. But I understand completely if you want to just make the driver support a YM2612+SN76489 or YM3834. But it would be nice to support large numbers of each. I see on eBay 10x SN76489 for $6 total--that would be a cool sound! 10x YM2612 is a little more expensive at roughly $30, but imagine the polyphony! Oh well. I would settle for a single Genesis, but two would be nice. I understand that at the application level, there are separate MIDI channels for each sound chip channel, and you might not have enough to implement two or four separate groups; but you could map them to separate UART MIDI input ports, or separate virtual USB ports.

 

I just got a few cheap 1U rackmount cases; and from my previous projects, the front panel is the most time-consuming part of the project; so if I did build one of these this summer, it would probably be a rackmount with four Genesises (4x YM2612 and 4x SN76489), with a minimal control surface, but four MIDI IN ports and one USB MIDI port that had four virtual inputs, each mapped to one Genesis with that scheme you mentioned above. I think the STM32F4 is powerful enough (in this case, I mean quick enough, it certainly has enough RAM) to run four Genesises in parallel; after all, six voices on YM2612 and three on SN76489 is nine voices, times four sound chips is 36; and right now I have the STM32F4 running two OPL3s, which is also a total of 36 voices. The LPC17 would lag a bit when I was using 30-33 of them at once; the STM32F4 does not, at least not noticeably.

 

Edit: Also you might want to start a new topic for this. :)

Edited by Sauraen

Share this post


Link to post
Share on other sites

Hi Sauraen

Actually from looking at the datasheet it looks decently similar. The parallel interface should be nearly identical. Just change the register definitions in the header file, and then change the OPL3_SetWhatever() functions to match.

The pin driver will be very similar I think, with just the addition of handling of A0 and A1. Haven't looked too close but the OPN2 probably has fewer register per voice due to the fixed 4op voices and fixed waveform, as well as fewer voices. I'll work on a comparison between the chips' register and work them into a matrix which should ease porting some functions.

  

 

If you wouldn't mind, when you write all the code, please make the number of sound chips a preprocessor variable (like I have OPL3_COUNT). It might be more complicated because you want to have multiple different chips running on the same parallel interface. I am still a little confused about all the OPN series chips, which include the SSG and which don't, and which type of SSG to use externally. The most flexibility is of course the best, especially at the driver level. But I understand completely if you want to just make the driver support a YM2612+SN76489 or YM3834. But it would be nice to support large numbers of each. I see on eBay 10x SN76489 for $6 total--that would be a cool sound! 10x YM2612 is a little more expensive at roughly $30, but imagine the polyphony! Oh well. I would settle for a single Genesis, but two would be nice. I understand that at the application level, there are separate MIDI channels for each sound chip channel, and you might not have enough to implement two or four separate groups; but you could map them to separate UART MIDI input ports, or separate virtual USB ports.

  I do intend to try and keep things as modular as possible and expandable. Being able to have two or three YMs and PSGs would rock. That is a really good idea with the separate midi ports, hadn't thought about it that way (still thinking in 8bit terms,). Foobat's original  project was for two YMs and the only reason I chose to start with a single YM and a SN was to have a baseline close to the Sega design. But yes there are several people interested in expanded designs.

  Following Littlescale's Midi assignments does impose limits and makes it hard to use standard midi tracks, which is easier with the MBFM implementation. In fact there is a native Sega tracker project by Count Synphonic that will include a standard midi patch set to help with mapping midi songs to YM. His work may be useful for a alt midi interface.

 Here is a thread that touches on the OPN line a little.

http://gendev.spritesmind.net/forum/viewtopic.php?t=386&sid=b6f09aeaa39b1346034bfb281f085806

 I'm not real sure on the SSG usage with the 2612; the YM2608 doc in that thread may help. Aly James has demoed some format effects that sound very interesting. His FMDrive VST does replicates the SSG but the Yamaha docs only refer to it as 'illegal' so it wasn't used with most (or any) MD music. Seems overlooked for the most part which is a shame.

 

I just got a few cheap 1U rackmount cases; and from my previous projects, the front panel is the most time-consuming part of the project; so if I did build one of these this summer, it would probably be a rackmount with four Genesises (4x YM2612 and 4x SN76489), with a minimal control surface, but four MIDI IN ports and one USB MIDI port that had four virtual inputs, each mapped to one Genesis with that scheme you mentioned above. I think the STM32F4 is powerful enough (in this case, I mean quick enough, it certainly has enough RAM) to run four Genesises in parallel; after all, six voices on YM2612 and three on SN76489 is nine voices, times four sound chips is 36; and right now I have the STM32F4 running two OPL3s, which is also a total of 36 voices. The LPC17 would lag a bit when I was using 30-33 of them at once; the STM32F4 does not, at least not noticeably.

 

  Glad to have your appraisal of the F4, my gut says that it should have enough cycles but you've put it through it's paces with the OPL3s. 

  Haven't thought too much about the UI, just kind of like the simplicity of the sammichFM but don't know how people find it for use-ability. There seems like two camps, one for 'a knob for every function' and the other likes 'a menu system with softs buttons'. I kind of wander between the two; but thats the beauty of MIOS, build as much or as little as you like. I like your FM 2.1 CS very much but space is always at a premium around here so leaning towards a more minimal CS. Being built on the MB NG foundation would hopefully allow builders to expand easily.

 

Edit: Also you might want to start a new topic for this.  :smile:

   Yes I'll open a User Project thread/wiki page when I get a little something more then vapor-ware. Didn't mean to highjack your thread :)

Much Thanks for your input, 

Yogi

Share this post


Link to post
Share on other sites
The pin driver will be very similar I think' date=' with just the addition of handling of A0 and A1[/quote']

Nope, the OPL3 has those too. Check to make sure they're the same, but they should be. The SNs will have a different setup though. But you should be able to hook everything to the same parallel bus, with separate #CS lines for each chip.

 

I'm really liking the idea of 4x each of the two sound chips. Please try to make the driver support this! I don't think there's much chance people will want to build boxes with chips other than those two. And besides we might not be able to test them.

 

This is what I did with MIDIbox FM V2.1, I went with the overall architecture of a polyphonic, multitimbral synth that I could play game MIDI files into and it would load the right instruments on each channel and play. This was a pain, but the architecture is done, if you want to modify this for another sound chip. Making a synth engine that just responds to MIDI commands to set all the parameters would be a lot easier. I have no knowledge of VGM files or exactly what commands they contain.

 

It might be worth doing it like this. Have several modes, switchable by menus. One is like MBFM2 with patch loading and saving, and polyphony. One maps channels to channels and CCs to parameters, but in a way that's easy for use in a DAW, not copying register contents. And another plays VGMs off a SD card, or streamed somehow from the computer.

 

That's the other part about where MIDIbox FM V2.1 falls short a bit. Buttons, encoders, LEDs, etc. are all mapped through MBNG, so builders can make the hardware configured as they want; but the application has fixed functions it expects each button and LED to perform. For instance, the only way to change the attack rate of an operator is to send a MBNG message corresponding to that encoder change. You can configure this with MBNG to be any encoder, or to be the same as another encoder with bank switching; but you can't configure this to be a menu option, that you select and turn the datawheel. The front panel functionality of MIDIbox FM V2.1 was too complex to implement it in MBNG configuration and scripts, so it's hard-coded. Even if I had somehow done it all with MBNG scripts, it would have been so complex that editing the configuration would be just the same as editing the C code.

 

Since I personally would want to build one with little to no control surface, but I am unwilling to hunt through menus to change parameters, I would be happy just using it in the mode where you control all the parameters from CCs in a DAW. Basically it would be the backend for a tracker. But you're doing the design, not me; and I've never used a traditional (i.e. TK) MIDIbox synth, only my own designs. So if you can make a Sammich-like interface, and it works well, great; maybe I can learn something.

 

Regardless of the interface, in any mode where there's a synth engine running and not just CCs controlling sound chip parameters, the synth engine from MBFM2 should work as a starting place. It's also possible to have the unused CCs on each channel control things like the software LFOs and EGs.

Share this post


Link to post
Share on other sites

How about something like this? 1U but a 2x40 LCD and enough buttons that all the parameters could be available in menus. I'm thinking for the buttons on the top row, hold it down and select one of the 8 softkeys (corresponding to 8 choices on the screen, but there's no room to fit the buttons under the screen).

 

gallery_10357_300_145750.png

Share this post


Link to post
Share on other sites

Hi Sauraen, been going through and learning FM2.1 code, mainly the OPL3 module. Looks like much of it will work very well :) and retain the multi chip support. So I'll plan for support of at least 4 synth boards, 24 FM Chns, 12 Sq Wave Chans and 4 Noise Chans :p Multi-Midi cables, both USB and serial, will accommodate the 4 count nicely, allowing CC controls for all the parameters. 

  I didn't change too much with the OPL header on the synth proto board, just brought out the YM's /RD and /CS to separate pins and a /CS (functions as a /WR strobe) for the PSG. The /RD may not be needed if I allow for the worst case timing on the setup waits (~80 cycles); about the only thing you can read from the chip IS it's status for the next write.  Not sure with the OPL but the OPN2 is very variable, some registers only require < 18 cycles and others about 80. And of course, which is which isn't documented very well. So I'll try it with both ways, a timed wait or a read status check between writes.

 

It might be worth doing it like this. Have several modes, switchable by menus. One is like MBFM2 with patch loading and saving, and polyphony. One maps channels to channels and CCs to parameters, but in a way that's easy for use in a DAW, not copying register contents. And another plays VGMs off a SD card, or streamed somehow from the computer.

 Yes, much like the SID synth engines are implemented. The CC based control engine would offer DAW based sound design and a more traditional multi timbral engine offers simpler live play, I think both require strong patch handling; which was one of the limitations of LS's design. The Teensey's limited RAM/Flash couldn't support (very many) patches, so to change instruments on a voice required re-writing the parameters (28 for each 4 op voice) via CCs between Note messages.Kind of cumbersome, especially  with the limited Knob/Buttons on a keyboard. 

 Your 1U FP looks good and kind of what I have in mind.  As far as the soft buttons being to the side of the LCD, don't think that will be too big an issue. Would seem natural after abit of use, i'm sure; no worst then using a joypad while watching game video. 

Yogi

Share this post


Link to post
Share on other sites
So I'll plan for support of at least 4 synth boards' date=' 24 FM Chns, 12 Sq Wave Chans and 4 Noise Chans :p Multi-Midi cables, both USB and serial, will accommodate the 4 count nicely, allowing CC controls for all the parameters.[/quote']

My experience with the OPL3s is it's best to have everything made for N sound chips, rather than 6N or 18N etc. channels, operators, etc. Let me explain. All of these sound chips--very much so the OPL3, but also a little the OPN2 and PSG--have voices that are not homogenous, and parameters that apply to the whole sound chip.

On the OPL3:

  • Twelve of the voices can be combined pairwise (controlled individually) into six 4-operator voices.
  • Three of the voices can be combined as a whole into a 5-voice drum system.
  • Three of the voices can't be combined into anything.
  • (TK's design for MIDIbox FM V1.X made the 4-op voices permanent and the drum system, and ignored those other three 2-op voices. This may have been necessary for the PIC core, but I didn't want to see voices wasted!)
  • There's also global bits for changing the amplitude of the two LFOs.

I only looked over the OPN2 datasheet quickly, but as far as I can tell:

  • Four standard 4-op voices.
  • Two 4-op voices in which the operator frequencies can be set independently.
  • (I'm not sure what you're going to do with this, but each operator can be turned on or off independently, both on standard and independent-frequency voices. In the former case this might be used for effects? In the latter case, four individual voices!)
  • Global LFO with a variety of parameters.

The SSG only seems to have one interesting thing:

  • The noise channel can be modulated by Channel 3. Thus Channel 3 has to be handled differently than Channels 1 and 2.

Because of all this, I think it's better to have which chip is active (for editing) as a sort of top-level parameter; that the synth engine is set up to deal with all the parameters of the voices on one chip, and loop over the number of chips, rather than sorting them into kinds of voices. You'll see this all over in MBFM2.1.

 

Good luck--remember the /RD on the OPN2 is an input, and the READY line on the SSG is an output. Reading the single line from the SSGs shouldn't be a problem--combine them all into one with a wired-AND or wired-OR scheme, preferably using an external transistor next to each sound chip; and connect this to an unused input pin on the SSG. But reading back the status from the OPN2s is a little more of a pain, since you'd have to reconfigure the data lines as an input, with the correct settings. Then again, faster is always better.

 

Ha ha, I've built two MIDIboxes, but in each case I did the synth engine myself, so I've never played with a TK MIDIbox engine.

 

This should not be a problem on STM32F4. Here's what the Piano1 patch on MBFM2.1 looks like, the following is saved on the SD card by the synth in /mbfm/BMSB0/BLSB0/Pat0.fm:

#MIDIbox FM V2.0 Patch File

name=Piano1

drum=0

use2op=1

use4op=0

# Begin voice data

voice2op=0

tp=0

tune=0

retrig=1

porta=0

dlyscale=0

dlytime=0

feedback=4

dest=3

alg=0

op=0

bits=8

wave=0

fmult=5

atk=4

dec=12

sus=8

rel=10

vol=21

op=1

bits=48

wave=1

fmult=1

atk=0

dec=12

sus=7

rel=9

vol=63

eg=0

atk=0

dec1=64

lvl=64

dec2=128

sus=0

rel=0

lfo=0

freq=128

delay=0

wave=0

lfo=1

freq=128

delay=0

wave=0

modconn=0

src=9

dest=6

depth=13

You should be able to easily modify this. I will warn you that there are bugs in the current implementation in MBFM2.1, mainly to do with loading and saving patches that involve complex linked groups of voices. You might think your patches will be simpler than that, but you will have to account for cases like saving a patch that encompasses Channel 3 and the noise channel in the PSG.

 

One other thing I haven't even considered: how will you deal with PCM/PWM drum samples for the SSG to play? If it's playing VGM or streaming control changes from the PC, we just have to hope the bandwidth is high enough. But let's say for live performance. How will that be set up? Where will the sound data come from?

Share this post


Link to post
Share on other sites

Hey there, Thanks for the input. Been working on porting opl3.c and opl3.h so far. The typedef structs are changed for the OPN2 specifics and of course changed all the related structures that use the new data types. I've edited most the pin and chip level functions but I'll have to come up with some test apps to verify the changes I've made.

  Following the naming from here

http://www.smspower.org/maxim/Documents/YM2612#reg2a

   

   I'm getting a feel for the flow of your code and am trying to maintain compatibility with the higher level FM synth functions. Some OPL function don't have any meaning on the OPN, such as waveform or 2 op channels. And as you pointed out the alt modes of channel 3 and 6 have no OPL meaning. So there is a bit of sorting involved but for the most part translates well.

 

remember the /RD on the OPN2 is an input, and the READY line on the SSG is an output. Reading the single line from the SSGs shouldn't be a problem

  Yes indeed, If I do implement a /RD, will also have to control the /WR strobe separate from the /CS pins for the YM chips.This isn't a huge deal but requires two more ARM pins (depending on the fanout for the pins could also require a buffer for mutii-chip setup) as well as complications for reversing the data bus (which may be a HUGE deal).  I plan on testing the timed write access first before I make thing more complicated. After all, the only advantage here is saving some cycles waiting for the YM to be ready. It's really not too different then accessing an LCD.

  For the PSG (I assume you meant that rather then SSG), it's write only; so just needs it's own /CS (or /WR) strobe. Not too sure about the READY but think it can be ignored for the most part. When I dive into the PSG code will review LittleScale's SN76489 code, he has several blog posts for multi-chip PSG projects.

 

  The alt channel modes, CH3 Special, SSG and DAC, will need to be handled separately from the main functions but I haven't gotten in to them just yet. Want to get the basic sound handling covered first off. 

 

One other thing I haven't even considered: how will you deal with PCM/PWM drum samples for the SSG to play? If it's playing VGM or streaming control changes from the PC, we just have to hope the bandwidth is high enough. But let's say for live performance. How will that be set up? Where will the sound data come from?

  Good question :) Haven't planned that out yet, but there would need to be a sample data set to draw from. It could be a const array in Flash but would like to load the samples from SD into ram. For drum samples wouldn't have to worry about loop points and samples on the YM or PSG chip are 8b (I think less on the PSG) so the sample set  wouldn't be huge. 

 

  Can you answer a question about one of the data types, u8 dest:4? I haven't tracked it's usage in code yet, is this nibble used for voice allocation?

 Another DA question, that's more of a general C coding question, can I reuse label names in the typedefs, I.E. for padding u8 structures, using u8 dummy2:2; for 2 bits or u8 dummy1:1; for 1 bit at more then one location in the def?

  And here is a snippet that may be a typo

 

static const u32 OPL3CSPins [OPL3_COUNT] = OPL3_CS_PINS;

In opl3.c. Is the space between 'OPL3CSPins' and '[OPL3_COUNT]' valid?

Thanks again

Yogi

Share this post


Link to post
Share on other sites
It could be a const array in Flash but would like to load the samples from SD into ram.

 

We should have plenty of room for both, especially considering the low quality. But of course people will want to edit samples on an SD card, even if that's a pain. :smile:

 

 

u8 dest:4

 

The OPL3 has four-channel output: L, R, and outputs 3 and 4 which are usually unnamed. These are the bits for whether that voice is sent to each destination; I'm pretty sure bit 0 is L, etc. On OPN2 this would be two bits, and the field would be absent on PSG.

 

 

Another DA question, that's more of a general C coding question, can I reuse label names in the typedefs, I.E. for padding u8 structures, using u8 dummy2:2; for 2 bits or u8 dummy1:1; for 1 bit at more then one location in the def?

 

Sorry that was confusing. When I write u8 dummyA:B, B is the bit width of the unused bits, which has to be correct; and A can be anything, as long as two fields don't have the same name. I just incremented A every time I needed another dummy. So you can have

 

u8 something_useful:3;
u8 oasfbklasdfkabdf:3; //this is dummy
u8 another_useful:1;
u8 aoskdbflsdfbbs:1; //this is dummy

 

but not

 

u8 something_useful:3;
u8 dummy:3;
u8 another_useful:1;
u8 dummy:1; //error, multiple declaration of "dummy"

 

 

static const u32 OPL3CSPins [OPL3_COUNT] = OPL3_CS_PINS;

 

Yes, you can put whitespace wherever you want in C, as long as it's not in the middle of a word. (Or in a preprocessor command like #define, those care about whitespace.) So you could have

 

static        const         u32      OPL3CSPins     [       OPL3_COUNT         ]             =             OPL3_CS_PINS            ;

 

Try it! (Well, not like that! Most of the time extra spaces are inserted to make things line up nicely.)

 

 

PSG (I assume you meant that rather then SSG)

 

Pardon the n00b question, but what does SSG mean? I didn't know there was a difference. I meant to be referring to the TI chip.

Edited by Sauraen

Share this post


Link to post
Share on other sites
 

 

 

Quote

It could be a const array in Flash but would like to load the samples from SD into ram.

 

We should have plenty of room for both, especially considering the low quality. But of course people will want to edit samples on an SD card, even if that's a pain.  :smile:

Maybe a default set in flash, with it loaded to ram at runtime, as well as SD support. 

 

 

 On OPN2 this would be two bits, and the field would be absent on PSG.

Ok thought is was something similar. I've mapped the channel reg for the audio output bits in the typedef and I assume there is a function using the dest structure for each channel also, so I'll add it back in and adjust the bit value.

 

Sorry that was confusing. When I write u8 dummyA:B, B is the bit width of the unused bits, which has to be correct; and A can be anything, as long as two fields don't have the same name. I just incremented A every time I needed another dummy. So you can have

Not confusing at all :) yes my only question was the naming rules. whether or not I could reuse labels. Which it only makes sense that you couldn't have different  data types with the same name. DUH!

 

Yes, you can put whitespace wherever you want in C, as long as it's not in the middle of a word. (Or in a preprocessor command like #define, those care about whitespace.)

 Very good, I knew C is very liberal with white space, but i'd never seen a pointer array that way.

 

Pardon the n00b question, but what does SSG mean? I didn't know there was a difference. I meant to be referring to the TI chip.

No problem. Not sure of what the initials stand for, Sound ? Generator. From Wikipedia:

 

The Yamaha YM2149F 'SSG' chip has the same pinout as the AY-3-8910, with the minor difference that pin 26 could halve the master clock if pulled low. 

So 'SSG' is not entirely correct, on the YM2612. It's the leftover envelope generator from the parent chip YM2608, I think. When Yamaha redesigned the chip they removed the internal AY 3 8910 (YM2149) but left the Env generator silicone on the die. The slim manual for the YM2612 only notes it as an 'illegal' mode (which some claim was due to a J to E translation error)  but it does in fact work. Though it wasn't used in Sega music (perhaps because it was listed as Illegal) it is capable of producing format sounds and crude speech to a point.

Thanks for your help,

Yogi

Share this post


Link to post
Share on other sites
It's the leftover envelope generator from the parent chip YM2608

Ahh, that explains why I was getting them confused. I didn't look at it too closely, but where's the actual control registers for the SSG EG? The registers mentioned there are the registers setting how much each voice is affected by the EG, not setting the period and mode of the EG itself.

 

Anyway, how's the project coming? Not only do I plan to build one for myself this summer, but I know an indie game composer (who shall remain nameless for now) who wants me to build him one as well. So I will need eight sound chip boards! Bulk order time! You've already done the layout for one, right?

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!


Register a new account

Sign in

Already have an account? Sign in here.


Sign In Now