Sauraen

MIDIbox FM V2.1 on STM32F4

64 posts in this topic

HI Sauraen

 So I've been doing allot of searching and study regarding our discussion. The SSG EG may not be a 'left over' as I thought, as it is an independent structure on chips that also had the SSG PSG, according to decapped scans. Don't know the intent of Yamaha, but I think that it was added to the FM channels to compliment the PSG's EG. When they dropped the PSG from the OPN2, seems they abandoned it, at least in their Docs. 

  This mode is set thru 0x27, bits 7:6. It also requires Timer A to be running and the SSG EG bits for each Channel 3 OP to be setup. When enabled, at each Timer rollover an alternate Key on followed by a Key off are issued. With the attack set for 0 the OP moves directly to the D1R, first release, but the key off occurs and the output goes into the RR, release rate. So by selecting the value of Timer A and RR value you can design the sound. At least this is my understanding ATM :) There aren't any official docs so info is gleamed from experimental efforts and scattered in forums. The best source so far is this thread on SpritesMind http://gendev.spritesmind.net/forum/viewtopic.php?t=386 It's a monster at 47 pages, but there is allot of good info within. 

  I'll work on a Eagle schema for it but for my proto I just worked off the MB OPL header pinout +OPN2/TI PSG basic design + Mega Amp design for a basic board (currently waiting on a parts order for some finial bits). So about half way through porting the OPL3 module and I'll have to write some test code to test and get some sound :)

  I've got a few C questions I've been running down in regards to the Typedef Union{} structures and their usage, but I think I understand. I won't pull your ear here, at least till after I do some more homework.

Yogi

Share this post


Link to post
Share on other sites

Okay, so it's triggered from Timer A, I didn't realize that. Do you have any samples of someone using this EG to produce some sound? At the very least it seems it could be used for some sort of ring mod effect.

 

Just a reminder that I want both the distorted Mega Drive filter and the clean Mega Amp filter.

 

Please, go ahead and ask. I can't directly help with development right now, but I want to build two of these this summer, so I want to make sure everything is as good as it can be.

 

For starters, typedef some_type your_new_name simply makes a new type that's some_type that's called your_new_name. For instance, somewhere in MIOS32 is typedef unsigned int u32; typedef int s32; typedef unsigned short u16; etc.

 

A union is like a struct, but the elements all share the same memory--they're on top of each other, not one after another. For instance, compare:,

 

union{
    u32 a;
    u8 b[4];
}
//versus
struct{
    u32 a;
    u8 b[4];
}
The first is 4 bytes long, the second is 8 bytes long. And in the first, you can access that same data either all at once with a, or one byte at a time with b. Here's another example:  
union{
    u8 all;
    struct{
        u8 bitfield1:3;
        u8 bitfield2:1;
        u8 bitfield3:4;
    }
}

This is one byte long, and I can access that whole byte, or the bitfields within it. One step past this is what I have in opl3.h.

Share this post


Link to post
Share on other sites
Okay, so it's triggered from Timer A, I didn't realize that. Do you have any samples of someone using this EG to produce some sound? At the very least it seems it could be used for some sort of ring mod effect.

Just a quick search. These are from Aly James,

SSG effects on Sega HW-

SSG + CSM on YM VST-

Considering the first Vid, the SSG-EG seems to be independent of CSM (Channel3 Special Mode). This would explain the Mapping of 0x90+, low nibble listed as "SSG-EG". From the main doc it's just listed as 'proprietary' and should be set to 0 according to Yamaha. OTOH, Experiments done by Nemesis @ SpritsMind on this register show D3 as enable and D2:0 as ENV waveform. At the time I thought this was only for the CSM +SSG-EG mode, but SSG EG may be usable for all OPs as indicated by mapping this register for the 24 OPs. I'll need to search some more but I now think an SSG-EG can be enabled for all OPs, by setting 0x90+ D3=1 with a waveform selected by D2:0. I'll try to nail this down some more, and ask AJ as he has explored this mode a bit.

 

Just a reminder that I want both the distorted Mega Drive filter and the clean Mega Amp filter.

You bet! plan to have switchable selection for both Right and Left channels :smile: This is just a Cap value selection so users could vary the filter to their liking.

 

Please, go ahead and ask. I can't directly help with development right now, but I want to build two of these this summer, so I want to make sure everything is as good as it can be.

OK. After digesting your notes above, it confirms what I thought I understood. but one question from the opl3_channel_t typedef{}

typedef union {

u8 ALL[3];

struct {

// Byet 0

...;

// Byte 1

...;

union{

struct {

// Byte 2

...;

};

struct {

u8 dummy2:4;

u8 dest:4;

};

};

};

So the Typdef union{ u8 ALL[3] Creates a new type called ALL made of 3 bytes and the following struct { } defines names for the bit fields within? The second union{ } with 2 structs{ } ? It is within of the typedef union{ }, so does it create a 1 byte element (the 3rd byte of the first union ) that can either hold the //Byte 2 bits OR the dest nibble?

As to usage I think I understand:

extern opl3_chip_t opl3_chip[OPL3_COUNT];

Here is created a Variable array called opl3_chip_t. So A= opl3_chip_t.opl3mode[1] would return with A holding the 1 bit OPL mode value at D 0 for the 2nd chip EDIT: Chip #1. And A= opl3_chip_t.csw[2] would return A with the csw bit for chip 3 EDIT: Chip#2 in D7 or would it be at D0? In other words, is the bit position preserved?

EDIT: So I mixed up opl2_chip_t with opl3_chip[], the first being the data type and the last being the variable right?

Thanks for your help,

yogi

Edited by yogi

Share this post


Link to post
Share on other sites

Thanks for the videos, the formant synthesis is cool. I didn't look too closely, but it looks to me like the SSG EG affecting an operator's EG can be done on any operator, since the register for it is duplicated for each operator. I'm not sure what that does for Key On and Key Off; maybe it just affects the envelope for that operator?

 

I guess I wasn't that clear about the typedef thing. When you write

 

typedef union {
//blah blah blah
} my_new_type_t;

 

you're defining "union { /*blah blah blah*/ }" to be a new type my_new_type_t. It's a little confusing since the name comes at the end, but that's how it is. The "_t" is a convention; you've probably seen things like "size_t" or "time_t" in the C standard. But anyway, then you will see in opl3.c the code "opl3_chip_t opl3_chip[OPL3_COUNT];", this actually makes an array of opl3_chip_t's that's OPL3_COUNT long, that's called opl3_chip. The version of this in opl3.h that starts with "extern" actually is like a function prototype, it's there so when the header is included by other files, they will see that this variable is defined, but "extern" does not actually allocate memory for the array.

 

As far as the nested unions/structs, you can think of every union as holding all the different names for the same data, and the struct as setting out elements one after another. So:

 

typedef union {
  u8 ALL[3]; //This allows us to access the data byte by byte in an array if we want.
  struct { //This struct is also a total of three bytes long, and it refers to the same 
           //three bytes as ALL[3], but with individual names. The struct itself is not named;
           //you can leave out the name if it's in a larger struct or union.
    //Byte 0
    u8 fnum_low; //The bits will be in the right order for the OPL3
    
    //Byte 1
    u8 fnum_high:2; //These will be bits 1:0 of the second byte
    u8 block:3;     //These will be bits 4:2
    u8 keyon:1;     //etc.
    u8 dummy:2;
    
    //Byte 2, and I'm going to provide two different sets of names for that byte.
    union{
      struct {
        //First set of names gives us synthtype, feedback, and the outputs one at a time.
        u8 synthtype:1;
        u8 feedback:3;
        u8 left:1;
        u8 right:1;
        u8 out3:1;
        u8 out4:1;
      };
      struct {
        //Second set of names gives us the outputs as one 4-bit integer. Since we already
        //have the first 4 bits covered, but we have to get past them to get to the second
        //four, we call the first four dummy2.
        u8 dummy2:4;
        u8 dest:4;
      };
    };
  };
} opl3_channel_t;

 

You're asking about the bit direction D7:D0. I made sure to get it right here, of course it works, so just do it the same way. The first bit that appears is the lowest bit, D0, and yes the other bitfields are in the right order.

 

Use examples (these are all from opl3.c):

 

opl3_chip[chip].vibratodepth = tmpval;
opl3_channels[chan].left = tmpval; //tmpval is a 1-bit value
opl3_channels[chan].dest = tmpval; //tmpval is a 4-bit value; note that this is writing to some of the same memory as the last command
opl3_operators[op].attack = tmpval;
u8 data = opl3_operators[op].ALL[reg]; //an example where ALL is read, this is when getting a byte from memory to send to the OPL3


Also important are the maps (listed under "Lookup Tables"). These took me a while to figure out, so don't be upset if you don't right away! The point of them is that the registers in the sound chip are not in a nice pattern--well, they're in a pattern, but it's not nice. As described in that long comment in opl3.h, my driver does the conversion between a sensible scheme listed there, and the OPL3's internal numbering; these lookup tables are what do that. You will need a similar system for the OPN2, though the actual mappings will of course be different.

 

Also, get used to 0-indexing! u8 blah[4] has elements 0,1,2, and 3, which are the first, second, third, and fourth. :) "blah[4] = something;" will crash. So the second OPL3 is chip==1.

Edited by Sauraen

Share this post


Link to post
Share on other sites
Thanks for the videos, the formant synthesis is cool. I didn't look too closely, but it looks to me like the SSG EG affecting an operator's EG can be done on any operator, since the register for it is duplicated for each operator. I'm not sure what that does for Key On and Key Off; maybe it just affects the envelope for that operator?

Cool stuff indeed! Yes I do believe SSG EG is a OP by OP basis, The SSG EG parameters are mapped to each OP for a total of 24. seems very redundant if it only applies to just Channel 3. I think the Timer/auto Key on/off effect I wrote about earlier only pertains to SSG-EG + CSM on Channel 3.

  How the SSG-EG on the other channels work (?) I think it is tied to the normal Key On/OFF, only active when a manual on/off is. I recall seeing a chart of the different waveforms that can be used, they appeared to be the same as on the AY 3-8910 ( believe the chart came from the YM2608 doc). So when a channel is active the SSG EG begins for all OPs that have it enabled. As to to the frequency for the repeating waveforms, not sure. May be based on the LFO setting?

  There is another fine point with the interaction of these modes,; when CSM + SSG EG is active, a manual Key on will override the auto key on/off till a manual key off occurs. Further, register 0x28 controls key on/off, bits 2:0 select the channel and bits 7:4 are the on/off for each OP of that channel. By convention the high nibble is set/reset as a group. Either b0000 or b1111, but it may be possible to key individual OPs for a channel, at least for channel 3 in Special Mode. 

 

 

I guess I wasn't that clear about the typedef thing. When you write

 

typedef union { //blah blah blah } my_new_type_t;

 

you're defining "union { /*blah blah blah*/ }" to be a new type my_new_type_t. It's a little confusing since the name comes at the end, but that's how it is. The "_t" is a convention; you've probably seen things like "size_t" or "time_t" in the C standard. But anyway, then you will see in opl3.c the code "opl3_chip_t opl3_chip[OPL3_COUNT];", this actually makes an array of opl3_chip_t's that's OPL3_COUNT long, that's called opl3_chip. 

Very clear, thank you. I was messy with my question/explanation but that is how I understood it.

  So with OPL_COUNT = 3,  the variable array opl3_chip would  be made of 3 opl3_chip_t data types, using a total of 9 bytes in memory. I could access the first opl3_chip_t  with u32 A=opl3_chip[0].ALL or as a bits field with u8 B=opl3_chip[0].vibratodepth. In the latter, u8 B would only have the bit value of  the vibratodepth bit, I.E. B=0x00 or 0x01

 

 

As far as the nested unions/structs, you can think of every union as holding all the different names for the same data, and the struct as setting out elements one after another

This is the part that was the major confusion to me. Thank you for the commented code, it cleared it up. 

 

So in this

opl3_chip[chip].vibratodepth = tmpval;
opl3_channels[chan].left = tmpval; //tmpval is a 1-bit value 
opl3_channels[chan].dest = tmpval; //tmpval is a 4-bit value; note that this is writing to some of the same memory as the last command

You can access the individual bit values left, right, out3 and out4 or all 4 bits at once with dest. 

 

 

Also important are the maps (listed under "Lookup Tables"). These took me a while to figure out, so don't be upset if you don't right away! 

I have a feeling I understand how you set them up. But I don't know the register structure of the OPL3 well enough.

  The nice thing with OPN2 is it is streamlined with regards to the register mapping. For instance there is no 2OP mode to deal with. For each OP parameter there are 12 address within a 16 byte block; organized as 4 groups (for the 4 OPs) of 4 addresses ( for 3 Channels, the 4th address is null).. So Parameter Byte Address= Base Address +(OP#*4)+Channel#.

  The Channel registers are even simpler, with each parameter mapped to a block of 4 addresses. So Channel Byte Address=Base Address+Channel#

  The Base Address can be computed or in a lookup table like such:

//OP Reg ADR = OPN2OperRegBegin[x] + (OP_Num_offset*4) + CH_offset
static const u8 OPN2OperRegBegin[7] = {
  0x30, 0x40, 0x50, 0x60, 0x70, 0x80, 0x90
};
 
For example, to compute the address of the 4th Parameter Register of OP4 of Channel 1:
Address = 0x60 + (0x03 * 4) + 0x00  =  0x6C
So at this point I don't see much need to re-map the registers, not too the extent you had to with the OPL3. I've looked over the table you have in the comments and I must say that the OPL3's address layout is way more complex then the OPN2.
Thanks again,
Yogi

Share this post


Link to post
Share on other sites

Looks like you got it now.

 

The one thing I still think you should remap with those lookup tables is the operators. For instance, the first set of registers for the operators for the first channel are at 0x030, 0x034, 0x038, and 0x03C; then the next channel, the operators are at 0x031, 0x035, 0x039, and 0x03D. But you will probably want to keep the numbering more consistent in the driver, so that channel 0 has operators 0,1,2,3; channel 1 has operators 4,5,6,7; etc. This means you will need a lookup table to say something like

static const u8 OPN2OperRegOffset[12] = {
    0x0, 0x4, 0x8, 0xC,
    0x1, 0x5, 0x9, 0xD,
    0x2, 0x6, 0xA, 0xE
};

 

Also, speaking of the SSG-EG and undocumented features, there's two "Illegal" modes for Channels 3/6. Anyone know what they do?

Share this post


Link to post
Share on other sites

Hi Sauraen

The one thing I still think you should remap with those lookup tables is the operators.

Yes. I already ported these. Glad to know we are thinking alike:)

 

//OP Reg ADR = OPN2OperRegBegin[x] + (OP_Num_offset*4) + CH_offset
static const u8 OPN2OperRegBegin[7] = {
  0x30, 0x40, 0x50, 0x60, 0x70, 0x80, 0x90
};
 
//CH Reg ADR = OPN2ChanRegBegin[x] + CH_offset
//For Ch3 Special mode, Supplemtal Freq regs of OPs 4:2 at 
// (OPN2ChanRegBegin[2] || OPN2ChanRegBegin[3]) + OP_Spc_offset
static const u8 OPN2ChanRegBegin[6] = {
  0xA0, 0xA4, 0xA8, 0xAC, 0xB0, 0xB4
};
 
// Only access with CH_GP = A1 = 0
static const u8 OPN2ChipReg[8] = {
  0x22, 0x24, 0x25, 0x26, 0x27, 0x28, 0x2A, 0x2B
};
  //-------------------------------------------------------------
  // Ported 3/6/2015
  // 
  // edit for YM2612, normalized OP address offsets
  // 1 dim const array
  // OPN2RegOffset[] = ((CH#[0:2})*4)+(OP#[0:3])
  //------------------------------------------------------------- 
static const u8 OPN2RegOffset[12] = {
  //Row=Channel, Col=OP#
  0x00, 0x04, 0x08, 0x0C,   //CH0 OP#[0:3] address offsets
  0x01, 0x05, 0x09, 0x0D,   //CH1 OP#[4:7] address offsets
  0x03, 0x06, 0x0A, 0x0E,   //CH2 OP#[8:11] address offsets
};
 
 
// could re-map channels here
static const u8 OPN2ChannelMap[6] = {
  0,  1,  2,  3,  4,  5
};
 

The OPN2ChannelMap[ ] seemed redundant, the index value and the returned value are the same. But I included it in the case that I would need to re map things later, based on porting other sections of code.

 

 

Also, speaking of the SSG-EG and undocumented features, there's two "Illegal" modes for Channels 3/6. Anyone know what they do?

Are you referring to the Ch3 Mode bits in 0x27? The Yamaha doc lists combos 10 and 11 as illegal, but in fact Mode =10 is the CSM+SSG EG mode we've discussed. Mode=11 is Channel 3 Special, same as Mode=01 according to the tests.

  There are a couple other undocumented registers/effects that have some impact, one affects the output Vol of the Channel 6 DAC and another allows some control of panning. I need more research on them but if they are of use I'll add support.

Yogi

Share this post


Link to post
Share on other sites

Oh, I think you may want to look at this in s32 OPL3_AddChipQueue( )

 

  opl3_chip_queue[chip_queue_idx] = val;
  chip_queue_idx++;
  if(chip_queue_idx >= 4*OPL3_COUNT){
    DEBUG_MSG("PANIC!! [opl3.c] Chip queue overflow on write chip_queue_idx==%d!", chip_queue_idx);
    chip_queue_idx = 4*OPL3_COUNT; 
  }

Seems like the last statement should be:

    chip_queue_idx = (4*OPL3_COUNT)-1;

Yogi

EDIT: I also noticed that there is no return at the end of OPL3_SendDemoPatch(). Is this ment to fall through to OPL3_OnFrame()?

Edited by yogi

Share this post


Link to post
Share on other sites
Seems like the last statement should be: chip_queue_idx = (4*OPL3_COUNT)-1;

Good catch, you are correct. However, as you can see from the "PANIC" statement, the execution should never be there; if it is, something else has already messed up. I was having trouble with some other code and the synth was crashing in the sound-chip-sending routines, so I was trying to isolate the problem.

 

I also noticed that there is no return at the end of OPL3_SendDemoPatch(). Is this ment to fall through to OPL3_OnFrame()?

The function is declared void, so there's no value to return at the end.

Share this post


Link to post
Share on other sites

Hi

 

Good catch, you are correct. However, as you can see from the "PANIC" statement, the execution should never be there; if it is, something else has already messed up. I was having trouble with some other code and the synth was crashing in the sound-chip-sending routines, so I was trying to isolate the problem.

OK. bit by bit I'm understanding your code but going through some functions I take it 'on faith' that the logic works even if I don't understand it clearly in the first read.

 With the 'Return', old ASM habits got the best of me, JSR with an RTS :) But Your answer jogged my memory; thanks.

  Only have a few more functions to port from opl3.c and edit the makefile to start testing the low level code.

Yogi 

Share this post


Link to post
Share on other sites
I take it 'on faith' that the logic works even if I don't understand it clearly in the first read.

I'm pretty confident there's no bugs in opl3.c, due to months of testing, so this is probably relatively accurate. But when you get to the synth engine, mbfm_whatever.c, this is absolutely not true. I have a list of known issues that I never got around to fixing; you'll probably find some of them as you're working with it. So don't be afraid to ask when something looks wrong!

 

With the 'Return', old ASM habits got the best of me, JSR with an RTS :smile: But Your answer jogged my memory; thanks.

I've only learned assembler in the last couple of years, and then the only two I know are AVR and MIPS 1 (from N64 hacking, haha). So I don't recognize those two particular instructions. x86? ARM? I'm probably never going to try to learn a CISC ASM, leave that to the compilers. :)

 

You can see some near-ASM C code in opl3.c for the SendAddrData routine. I tried to write lines of C that would compile to one or two lines of assembler each, since that code is time-critical. I know I tend to make it write-only sometimes, I guess that's not great for collaboration...

Share this post


Link to post
Share on other sites

Hope I didn't sound like a critic, was trying to say I trust that the code works even if I don't understand. My goal at the moment is to try to fully understand it and the impact of changes I make :) I think I'm getting there, it took awhile to follow the over all interaction between the queues, On Frame functions and SendAddrData. 

 

I'm pretty confident there's no bugs in opl3.c, due to months of testing, so this is probably relatively accurate. But when you get to the synth engine, mbfm_whatever.c, this is absolutely not true. I have a list of known issues that I never got around to fixing; you'll probably find some of them as you're working with it. So don't be afraid to ask when something looks wrong!

  Yea, when I get into the synth engine, the differences between the OPL3 and the OPN2, and the addition of the SN76489, will cause major rewriting and function changes. For the most part, the opl3.c has been straight forward, adjusting array sizes for the OPN2's reg structure and changes to the minor differences in the access algorithms. 

 

 

I've only learned assembler in the last couple of years, and then the only two I know are AVR and MIPS 1 (from N64 hacking, haha). So I don't recognize those two particular instructions. x86? ARM? I'm probably never going to try to learn a CISC ASM, leave that to the compilers.  :smile:

  I'm just the opposite, I've mess with C on and off over the years but never felt comfortable. I started out 'back in the day' on Atari 800, learning Basic and 6502 Assembly (JSR, RTS: jump to sub, return from sub). Then started in on uControllers, the MCS 8052 then the PICs. And lately got into some NES and Atari projects (back to the 6502). 

  Tried some of the PIC Cs but Asm seemed more efficient and easier for me. But with the STM32s I'm with you, 'leave it to the compiler'! :) One of my objectives with this project, is to sharpen my C.

 

You can see some near-ASM C code in opl3.c for the SendAddrData routine. I tried to write lines of C that would compile to one or two lines of assembler each, since that code is time-critical. I know I tend to make it write-only sometimes, I guess that's not great for collaboration...

Yea there is some tight code there :)  The hard part for me was remembering that the native data width is 32bit. The bit wise sections weren't too hard, think I got it right. When I got to the later functions, things made more sense. 

 Anyway, getting late. Talk to you later,

Yogi

Share this post


Link to post
Share on other sites
it took awhile to follow the over all interaction between the queues' date=' On Frame functions and SendAddrData[/quote']

The idea is simple: when you write to a register with the external functions, the value is put in the local copy of the registers, and that register's number is put on the queue to be updated. Then when it gets to OnFrame(), it doesn't have to check lots of registers for changes, it just runs through the queues. Assuming relatively few changes per frame, this is faster; it does have to check the queue when it puts something new on the queue, but if there's only a few things there, that's still faster than having OnFrame check all the registers for changes.

Share this post


Link to post
Share on other sites

So how's the progress on the module drivers going?

Share this post


Link to post
Share on other sites

Hi,

first of all: great work and great project BUT so confusing, so much unsorted information. For me it is not clear what is going on with the project. I'm trying to find a way through the fog, but there is none. I do not see the benefit for the forum. This also applies to various other projects.

How should a project look like: For example, like Wilba has made the Seq V4 Project or SIDV2: Clear Information, and most importantly, it was brought to an end and everyone can use it and therefore it is a great success and this is the best thing that can happen.

I see absolutely no benefit from confusing projects that are not completed. I must say this because it is the truth for me.

It's frustrating to spend so much time reading to realize that you can forget the project because it is not finished.

My public project would have 3 pillars: clear Information, finish the project and make it completely working and last make it available for the community.

Perhaps I am now the Boo-Man but that's ok because I want to help as I describe my vision as a non-developer.

Finally, again: Your Midibox FM 2.1 is top class but that does not help me.
I would like to order parts and get started ...

 

 
 

 

Share this post


Link to post
Share on other sites
4 hours ago, modulator said:

Hi,

first of all: great work and great project BUT so confusing, so much unsorted information. For me it is not clear what is going on with the project. I'm trying to find a way through the fog, but there is none. I do not see the benefit for the forum. This also applies to various other projects.

How should a project look like: For example, like Wilba has made the Seq V4 Project or SIDV2: Clear Information, and most importantly, it was brought to an end and everyone can use it and therefore it is a great success and this is the best thing that can happen.

I see absolutely no benefit from confusing projects that are not completed. I must say this because it is the truth for me.

It's frustrating to spend so much time reading to realize that you can forget the project because it is not finished.

My public project would have 3 pillars: clear Information, finish the project and make it completely working and last make it available for the community.

Perhaps I am now the Boo-Man but that's ok because I want to help as I describe my vision as a non-developer.

Finally, again: Your Midibox FM 2.1 is top class but that does not help me.
I would like to order parts and get started ...

Hi modulator,

I'm sorry that you expected a complete well-documented project. I suppose that early in development I was hoping that the project would be one that others online could follow along with, but it quickly became complicated and hack-y enough that I stopped thinking that was really feasible. As I'm sure you understand, it takes a significant amount of work to document something, and even more to produce it in a manner that can be easily replicated.

Many users on the MIDIbox Forums build projects, for which they take photos, have forum threads about their work, etc., and never offer a complete project that someone online can buy parts for and just build it with no issues. Wilba's excellent projects were well-documented primarily because boards and parts for the projects were being sold on the MIDIbox Shop. Similarly, for my MIDIbox Quad Genesis project that is currently in development, I will be selling MBHP_Genesis boards, and therefore I have documented them well here.

You say "I see absolutely no benefit from confusing projects that are not completed" but you seem not to realize that a) MIDIbox FM V2.1 is completed, at least as much as it probably will be; and b) I gain benefit from using the synth whenever I play it, which is almost every day. I'm sorry that you had to read a few dozen forum posts before realizing that MIDIbox FM V2.1 isn't a project that users can just go and build, but simply a synth I built.

If you're still upset about this, consider this. The firmware I designed requires a lot of buttons, LEDs, and encoders on a front panel. Their particular configuration can be edited via MBNG commands, but the range of controls must be available for the synth to be usable. So if you wanted to make one, even if I had documented everything 100%, you would have to make an aluminum front panel and a custom front panel PCB, both of which will be expensive and time-consuming.

From the other side, if you have time to put into this project and you want to move forward knowing that there will be a lot of challenges, I am happy to help and give whatever documentation I can. But at this point I cannot just make this into an easy project for everyone to build.

Sauraen

Share this post


Link to post
Share on other sites

Not necessarily completely but clean documented. In my opinion a proper documentation is as important as the rest even if it is initially only for yourself. Tk's documentation is a perfect example of this. And the documentation is certainly not the largest proportion of the total work. Because you write down just stuff what you have previously considered.

With a good documentation, everyone can quickly read into the topic and help if necessary.

I think that your Midibox FM 2.1 could be very successful but without documentation no one can read in properly. And a Midibox FM 2.1 for everyone would be great because I think that it is little bit unattended and therefore you did a gread job.

 

I think Wilbas Boards are therefore landed in the shop because they were perfectly developed and documented (hardware, software, documentation).
They have reached a development status which can be called “ready for mass production”.

From this point you can also ask for money because you get something (boards, software) that works.

 

Your mbhp_genesis could be a very great device but no Midibox FM because it does not use the OPL3-Chip?

 

Designing a frontpanel is not so great work. The point for me is: I see this great machine working so i think it has to be possible to reconstruct it.

If you don't want to make a wiki page, I would probably try to familiarize myself with the stuff I can get from you.

 

Cheers!

Edited by modulator

Share this post


Link to post
Share on other sites

Dear Modulator,

I could understand your criticism if the project was marked finished. However as Sauren clearly indicates it's not. At the moment it's just a show case. 

As for me it's not clear what your angle is. But if you want to try and make a Midibox project based on Sauren code, then i think there are more constructive ways to go about criticizing the developer. If you want a ready made project without any need to put any effort in, please wait until this project is done.

Share this post


Link to post
Share on other sites

Sauraen's project isn't a typical MIDIbox project, and this might be confusing for users like Modulator who expect a certain documentation standard, which starts with the high-level view + completion state, and and then goes down to the hardware components and firmware description.

What might also be confusing: "MIDIbox FM V2" is neither the official successor of "MIDIbox FM V1", nor a uCApps project, therefore no documentation can be found at my website.

It makes sense to clarify this in the first posting so that readers are aware about this before continuing reading, and don't start unnecessary discussions.

Best Regards, Thorsten.

Share this post


Link to post
Share on other sites

I updated the first post in the thread to explicitly state that this is not a project intended for users to be able to easily replicate. I have to admit that originally I was hoping it would become a successor to MIDIbox FM V1.4, but this hasn't happened for several reasons: the complexity of the design not being too community-friendly, my own lack of time to work on documentation, and not a very high level of interest in the community.

Modulator, I will offer again: if you want to get started with this project, it IS possible, and your questions may spur me to better document what I've done. At the core, the synth consists of a MBHP_CORE_STM32F4 module with whatever MIDI I/O you want; two MBHP_OPL3 modules; and a MBNG-compatible front panel. The core and MIDI I/O board(s) are standard; the front panel requires certain buttons, but the actual hardware is completely compatible with MIDIbox NG, so you can lay out the buttons and encoders however you want; the MBHP_OPL3 modules are standard except each board has a separate /CS wire to the core--the parallel interface is described in the source code and is somewhat configurable, but I can document this a little more if you want.

Share this post


Link to post
Share on other sites

Hi,

I must admit that my criticism is completely unjustified when one considers that the project was never meant to rebuild. But that was my hope.

With my criticism, I try to bring the project back into focus because it looks a bit discontinued and some people liked the project from the beginning.

Thank You Sauraen for your understanding and your answer fits perfectly! What is inside the case? With that information i can do the first step and order some parts and that can take weeks.

It has reasons that I don't write a silent pm. I want that everyone can read this and get some new information what is going on ....

 

Cheers!

 

 

 

Share this post


Link to post
Share on other sites

 

13 hours ago, Sauraen said:

I updated the first post in the thread to explicitly state that this is not a project intended for users to be able to easily replicate. I have to admit that originally I was hoping it would become a successor to MIDIbox FM V1.4, but this hasn't happened for several reasons: the complexity of the design not being too community-friendly, my own lack of time to work on documentation, and not a very high level of interest in the community.

Modulator, I will offer again: if you want to get started with this project, it IS possible, and your questions may spur me to better document what I've done. At the core, the synth consists of a MBHP_CORE_STM32F4 module with whatever MIDI I/O you want; two MBHP_OPL3 modules; and a MBNG-compatible front panel. The core and MIDI I/O board(s) are standard; the front panel requires certain buttons, but the actual hardware is completely compatible with MIDIbox NG, so you can lay out the buttons and encoders however you want; the MBHP_OPL3 modules are standard except each board has a separate /CS wire to the core--the parallel interface is described in the source code and is somewhat configurable, but I can document this a little more if you want.

 

Speaking for myself, the three arguments you mention are very much intertwined. Although i think you probably have technically designed a great synth due to the complexity of your CS i have not even considered it myself. Don't get me wrong it looks great: gallery_10357_214_1471269.jpghowever it also looks intimidating. Due to the lack of documentating people don't really feel invited to participate. 

Share this post


Link to post
Share on other sites

Hi,

Damn,this control surface oO great stuff!

I was planning to build a FM synth 1.4 , with a old 8-bits PIC core and the old HUI, based upon the old OLP3. So I have few simple questions:

- Does the MBHP genesis board (available from smashTV) offer a FM synthesis (sound) much like the OLP3 ? what are the differences in the great lines? (there is not much audio examples)

- Are the synthesis chips easily availables?

- Does the fact of being connected to a STM32F4 core will offer more new features?

- Can you please describe in few words and based upon your picture what parts of your control surface are dedicated to? it's kinda messy without explanations.

 

I would like to ehance the Midibox FM 1.4 , especially regarding the control surface.but i thought something half way between the original FM synth and your control surface.

I saw something looking near to the MB-6582 in terms of size..

Thank you in advance for your answers, and please beg me if i misread something.

sincerely,

JK

Share this post


Link to post
Share on other sites

Hi Psykhaze,

To answer your questions:

1) MIDIbox Quad Genesis (and its smaller cousins, MIDIbox Genesis Tracker and MIDIbox VGM Player, all of which use the MBHP_Genesis board), create the sound of a Sega Genesis / Mega Drive. Just listen to some music from this system on Youtube compared to some OPL3 music, and you'll get the overall idea. It's similar, but each has some strengths the other lacks. The OPL3 has more powerful operators and four-op voices, and it has a FM percussion system; the OPN2 (on the Genesis board) has sampling capabilities, a more powerful LFO, and the board also includes the SN76489 PSG chip for square waves and noise.

2) Yes, OPL3, OPN2, and PSG are all available for $2-$5 each.

3) Yes, both MIDIbox Quad Genesis and MIDIbox FM V2.1 are much more full-featured than MIDIbox FM V1.4. MIDIbox FM V2.1 supports two OPL3s, is fully multitimbral (each MIDI channel plays a different patch at the same time), has a powerful modulation system and a simple drum sequencer, etc. Here is a typical example of its use, playing a large MIDI file. MIDIbox Quad Genesis has a different architecture, it's based on playing VGM files from Genesis games, and even normal patches are actually implemented as very short snippets of VGM files. All of this is way beyond the PIC core--it can barely interface with an SD card, let alone stream four VGM files in parallel from it.

Here's the bad news, which also addresses (4). MIDIbox FM V2.1 is as finished as it will ever be, and the code is available on SVN, but there's little-to-no documentation. When I originally started the project, I wanted to make this the official successor to MIDIbox FM V1.4 (hence the name). But basically my ambition ran away with me, and I ended up making a synth that was way too complicated and kind of hacky internally, which led me to think nobody would want to build it, which led me to not want to document it, which led to nobody wanting to build it. Now it's not impossible: the software is there for you, and the hardware isn't too crazy--it's the standard STM32F4 core and OPL3 board and a MBNG-compatible front panel. All you need to know is the connection between the OPL3 module and the core, which is very simple, and you need to design a front panel that has controls corresponding to mine, which is at least conceptually simple since you're just following the MIDIbox NG project. I can document these two elements without too much trouble, if you want to go this route.

MIDIbox Quad Genesis IS a project that is designed to be well-documented and reasonable for other people to build. In fact MIDIbox VGM Player is already "released", meaning all the documentation and code is available, and MIDIbox Genesis Tracker should be out soon as well. But MIDIbox Quad Genesis itself, the one with the giant front panel, won't be in a releasable state until later in the summer--there's a LOT of code to write. At that time front panel boards will be available, as well as the design files so you can order the matching aluminum front panel and the 3D printed parts.

None of these synths work well with an in-between control surface. There is sammichFM, but that has custom interface code--unless you want to do some real programming it's not easy to change what controls are available.

tl;dr: If you want a synth project that you can start now that's been well-vetted by the community and is very well designed within its limitations, go with MIDIbox FM V1.4. If you want a cool crazy Genesis synth with a giant front panel chock full of LEDs, wait around for a few months and then build a MIDIbox Quad Genesis. If you want a project that's more of an organizational challenge--and you want to design and build a front panel from scratch--MIDIbox FM V2.1 is for you.

Sauraen

Share this post


Link to post
Share on other sites

Hi sauraen,

first of all, a big thank for your answer =) wasn't expecting something that precise so quickly.You just answered to everything and even more.

After a -very quick- youtube tour, i get some of the audio difference between the chips : they sound very likely, but not exactly the same. To be honest i like them both very much.

I first got into the midibox thing through the SID v2 synth 7 years ago because my first computer was a C64 . Found crazy that i could make a synth with. I stayed tuned to ucapps until the MB-6582 : to me one of the best projects here : powerful electronic & external design, nice PCB design , simple assembly etc... thanks to wilba and smashTV again .
The key to me was that optimized control surface that wilba made.I got my first MB-6582 almost finished, filled with 6582 chips. But on my second MB-6582 pending, thanks to the PCB design, i will make a hybrid setup : half 6581 and half 6582.

Sorry for telling my life but this was to introduce the following question :

Do you think it could be possible (and not too hard?) to make a kind of "hybrid" FM synth with a 2 stereo outputs OLP3 and 2 stereo outputs OPN2?
In short words instead of a core driving 4 OPN2 (>quad genesis) , a core driving 2 OPL3 and 2 OPN2 at the same time,sharing a same Control surface ?
(I REALLY like them both ^^)

I love designing Control surfaces, designing the PCB and frontpanels ,choose simple and costless components solutions. And good news, my work is programming code =) 
i'll have a review to your code uploaded, i should understand some, or ask some question then

Some parts of the FM synthesis concepts should be very common between the two chips? this is what i need to be explained clearly, some dark zones stay there for me
I'll check out more in details TK virtual interfaces to the FM synth 1.4.if you have any useful link that may help me understand FM synthesis more deeper i take it =)

So to summarize,i'm that kind of crazy geek who (now) have some few skills and who wants to help you in going further into that project.
I think by making a bridge between your project and the current MBFM 1.4 trough designing a "easy-to-use-but-complex-enough Control surface" for an hybrid design we would maybe get the community interested into your work.

The big point to me is the control surface. I like leds and button,and most especially illuminated button (who said sparkfun?) . new components now make some HUI possibles . But we have to discuss on howto make a compromise between your design (a little too complex) and the current MBFM 1.4 design (too simple)
I have some time to spend in, and the MBFM project need a new breath. You started it ,i'll try to follow ^^

Feel free to email me we could get in IM contact.
Best regards,
JK

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