Jump to content

Diode Matrix Input


jimhenry
 Share

Recommended Posts

This is a continuation of the discussion started by John S in the Pipe Organ Conversion to MIDI thread.  There he made the excellent suggestion that using a diode matrix approach like the one shown on the MIOS download page in the sm_example_v1 for keyboard input simplifies keyboard wiring.  He suggests that TK's example could be easily expanded to support 1024 inputs using 1 Core, 1 DIN, and 1 DOUT.

A question for those more familiar with the workings of MIOS, aside from the issue of parts count, is there any advantage to a 32x32 matrix as compared to a 16x64 matrix?  I ask because it may be that some applications will not be able to easily split the common bus under the keys.  If this project could support a 64 bit wide DIN, then splittling the bus could be avoided at the cost of a second DIN card.

Is it practical to make the DIN width and the DOUT depth configurable so that they can used however needed, probably with an upper limit of 1024 inputs to keep the input to MIDI translation table simple?

Jim Henry

Link to comment
Share on other sites

  • Replies 51
  • Created
  • Last Reply

Top Posters In This Topic

Hi Jim,

for somebody with programming experiences it should be very easy to adapt the code to any hardware constraints he want. But a user-friendly configuration would make the whole thing more complex, that means: slower (reduced performance due to variables) and error-prone (normaly every possible configuration should be tested in reality)

I would suggest that we define three or four useful setups, for which I could provide the source codes. The "scanmatrix drivers" have to be tested by somebody else. Everything else will lead to a configuration disaster ;-)

Best Regards, Thorsten.

Link to comment
Share on other sites

I think those are very sound observations Thorsten.  My theatre organ emulator, the Miditzer, isn't at all configurable for exactly the reasons you have stated.  People sometimes ask about it but much less than I expected.  Of course, I keep promising to improve that aspect so maybe that keeps them quiet. ;)

I counted up the input points I'll need for a 2 manual Wurlitzer console, which is a pretty big job because of the second touch contacts, and 512 is more than enough.  Making 16x32 and 8x64 configurations will probably satisfy almost everbody.

My own effort will be 16x32 so we won't even be able to test an 8x64 until someone else steps forward with that requirement.

Whoever codes this, and I assume that will be me if John Swenson doesn't want to do it, should probably keep in mind the possibility of other matrix dimensions.  But that possibility goes out the window if it hinders the task at hand.

Link to comment
Share on other sites

Hi Jim H, yes you COULD do a 16 x 64 (or 8 x 64) using 1 DOUT and 2 DINs, but then you loose one of the big advantages of the diode matrix approach: small amount of wiring to each keyboard. You would still have to bring all 64 wires out of each and combine them together into the DIN boards. Thats why I really like using the 8x8, it only takes 16 wires to each manual.

For your arrangement you could either put the diodes at the keys, then connect to the wires and connect each set in parallel at the DINs, or you could run the wires directly from the key contacts to a big diode board that goes to the DINs.

I agree with Thorsten that trying to make a unified configurable code would be a mess, his approach of having several configurations would be the way to go.

One advantage to the 16x64 approach is that the latency is still fairly low at around 16ms. With a 32x32 you are getting to 32ms which might wind up being noticable.

Thorsten mentioned he could do the drivers, but I could do them as well and let Thorsten focus on the really important stuff, making MIOS the most flexible PIC environment in the world.

John S.

Link to comment
Share on other sites

The number I recall hearing bandied about for acceptable latency on keyboard input is 10 mSec.  Bear in mind that whatever the MIDI output is driving will have latency too.  So the MIDI Box should strive for even less than 10 mSec latency.  We need to be very careful about creating too much latency in the key input.

I believe that the 10 mSec figure actually lumps together latency issues and jitter issues.  I think only the keenest of ears can sense 10 mSec delay from pressing a key to hearing a sound.  But 10 mSec of variability in the time between pressing a key and hearing a sound I believe can be perceived as a "sloppy" action.  Notes that are supposed to be sounding together start to have distinct attacks.  Not that I could hear any of this.  But there are performers who have said things to me that suggest they can hear these kinds of things.  Just to provide a point of reference, at 120 bpm a sixty-fourth note is just over 30 mSec long.

You seem to suggest that adding additional depth to the matrix (using more DOUT selected rows) adds substantial latency.  I find that surprising since my superficial understanding was that both DIN and DOUT are extensible shift registers.  My assumption is that row selection will be accomplished by loading a single row selection bit to DOUT and then shifting it one position to select the next row.  I assume there is also some overhead each time a new row is loaded to the DIN shift register.  32x32 involves 32 DOUT shifts & DIN loads while 16x64 involves only 16 shifts & loads.  Both require the same number of DIN shifts.  So the difference between 32x32 and 16x64 should be 16 shift & load operations.  Is the overhead of a DOUT shift & DIN load really about 1 mSec?

Are you including key debouncing in your latency estimates?

I agree that putting the diodes at the key contacts and reducing the keyboard cabling to 16 wires is a big advantage IF you have to cable the keyboards.  If you are dealing with a console that already has cabling to the keyboards, as I am, it becomes irrelevant.  In the later situation, avoiding multiple commons per keyboard becomes more important.  Splitting the Wurlitzer common bus doesn't look like it will be too hard.  Splitting it to 4 groups of 32 contacts seems acceptable (remember 122 contacts per manual on this one).  I'm less enthusiastic about making 8 groups of 16.  If I had only 61 contacts under a manual and a difficult to split common bus I would definitely think using a second DIN board to avoid splitting the bus would be a small price to pay.  To me the big advantage of a diode matrix is using 1 Core and to a lesser extent the use of fewer DIN/DOUT boards.

I fully agree that between you and I we should be able to allow Thorsten to work on other things.  I can't imagine he has any shortage of projects.  Looks like I should get busy and really start learning some of the nitty gritty of the MIDI Box.

Link to comment
Share on other sites

I think I see the source of your latency estimates John S.  "A  1 ms capturing cycle is used by the SRIO handler for the DIN and DOUT module."  So the easy way to implement the diode matrix is to write a row select on one cycle, read a row on the next cycle, and so on.

My first thought on achieving lower latency is to write something at the SRIO handler level specifically to use a DIN and DOUT together for matrix input.  At a minimum it should be possible to do the row select and the read in one cycle.  If settling time is needed after a row select, read and then select the next row.  I do see now why using 2 DINs for a wider row reduces latency with this approach.

But pushing the envelope, would it be possible to read an entire 32x32 matrix in a handler called every millisecond?  If not, any guesses as to the maximum number of rows that could be read?  It would seem that four rows (128 input points) should be possible as that will take only a bit longer than reading 4 DINs.  By limiting this project to diode matrix input and MIDI output, presumably eight rows can be done at a time because there is no conventional DOUT required.  

So it would seem that we can have at least an 8x32 (256 input) matrix with 1mS latency, a 16x32 with no more than 2mS, and 32x32 at 4mS.  This sounds pretty good.

Link to comment
Share on other sites

Currently the matrix driver uses the general timer interrupt driven SRIO handler which has been designed for the common approach for up to 128 digital INs and OUTs, the target was to capture as much registers as possible with lowest system load, so that a lot of other tasks can run additionally without affecting the realtime behaviour: in between 1 mS all tasks should be finished.

The handler is called every millisecond and consumes ca. 16 uS for each DIN/DOUT shift register pair, makes ca. 128 uS for 16 DIN/DOUT registers.

The DIN and DOUT registers are captured/loaded in parallel, the DOUT data gets valid after the DINs are captured, therefore it doesn't make a big difference how much DINs and DOUTs are chained, the longest chain defines the overall delay.

If the core has nothing else to do than to scan a matrix and to receive/transmitt MIDI events, it makes sense to bypass the common driver and to write a dedicated one which isn't called periodically, but every time when nothing else is to do (means: from USER_Tick - the mainprogram)

By doing so, an overall latency of ca. 8*20 uS can be achieved for a 8x8 matrix, maybe 16*80 uS for a 16x32 matrix

Some Jitter has to be expected, caused by the MIDI handlers (they are buffered and therefore don't stall the system) and for the debouncing counters which still require a timer interrupt, but this isn't a big problem when we are speaking about a latency of much below 200 uS

My suggestion: discuss about some useful hardware setups and draw the schematics. Once they are available, I will program the drivers for you. My own effort is low, since all routines do already exist, I only have to rearrange them... my effort would be higher if I would also have to documentate the stuff ;-)

Best Regards, Thorsten.

Link to comment
Share on other sites

Hi Jim, I think I'll go into detail on how all this works in MIOS so we can all be clear about whats going on so we can make good decissions. I've been pouring over the MIOS V1.7 source today so I think I REALLY understand how the SRIO is currently implemented and how Thorsten's current SM driver works.

In hardware you have chains of 8 bit shift registers. There are seperate DIN and DOUT chains which are clocked by a shift and latch clock (the same clocks used for both chains). For DIN the latch clock takes the parallel 8 bit data and latches it into the shift register to be clocked out later. For DOUT it takes the current value of the shift register and latches it onto the parallel data out pins. On the core module side you have 2 five pin connectors, each connector has +5V, gnd, shift clock, latch clock and data bit.

In software mios has a timer that causes an interrupt every 1 millisecond. The ISR for this latches the DIN chain, reads the DIN pin (which is pointing at bit 7 of register 0) stores it, writes the DOUT pin, sends out a shift clock pulse, and repeats until it has gone through all bits of all the shift registers. It then sends out a latch clock pulse to latch out the DOUT values.

This is all done in software durring an ISR, so latency is very important, which is why I presume Thorsten limits the number of shift registers (DIN or OUT) to 16.

So given the way this works, for a diode matrix you can enable a column (0 on that column, 1 on all others) with the DOUT boards and read the row from the previous column every ms. The read the previous is because the SR driver reads the DIN bit before it writes the DOUT bit. So for a 8x8 matrix it takes 8ms to cover the whole matrix. A 8x16 still takes 8ms. A 8x64 also takes 8ms. The latency is determined by the number of DOUT bits used, its independant of the number of DIN bits since all (up to 128) DIN bits are read every ms.

So for your situation you could have a 8x64 arrangement with 1 DOUT and 2 DIN boards and have 8ms latency on the matrix. You could even do 8 x 128 if you needed that many inputs but of course that takes more DIN boards.

Thorsten mentioned the possibility of writing a special SR driver that would do more than one pass on the SR chains every ms. This is how you would get the latency lower than the 8 ms. Since the core isn't going to be doing much of anything else this is probably all right. You still want to have SOME processor bandwidth left for writing out midi messages!

I hope that clears things up a bit.

BTW I have a pile of core and DIN/DOUT boards sitting around right now so I might try writing a 8x64 driver and trying it out. Its going to be a little while before my current project gets done, I got my front panels back and the switches don't fit so its not going together this weekend.

John S.

Link to comment
Share on other sites

My suggestion: discuss about some useful hardware setups and draw the schematics. Once they are available, I will program the drivers for you. My own effort is low, since all routines do already exist, I only have to rearrange them... my effort would be higher if I would also have to documentate the stuff

This sounds like a plan to me.  I'll commit to doing a diode matrix of 16x32.  Perhaps John S would want to define a matrix of half this size as a second configuration?  Should it be 16x16 or 8x32?  I'll do a schematic for my system.  John S I can do a schematic for a smaller system too if you like.

Can the analog input capability be left in?  It doesn't matter to me, my swell shoes also provide contact closures.  But I think there will be people who want to use various types of continuous controllers along with a large number of digital inputs for an organ type MIDI controller.  

Thorsten, I'll be more than happy to take the documentation off your shoulders.  Just point me at what you consider to be the best example of documentation for this type of project and I'll do something equivalent.

Link to comment
Share on other sites

John, thats a very good explanation about the SRIO driver - we should add this to the Wiki once it's available.

Jim: maybe the best documentation is just to write a report who you've realized your project (with a lot of pictures). I guess that not only the scanmatrix driver is for interest, but also the hardware around it.

Here is an example: http://mmd.foxtail.com/Tech/mvdReijden.html

Yes, you can use the analog input driver in parallel. It runs in background and doesn't add that much jitter.

Ok, here some news: today a friend brought me a keyboard from an older synth so that I was able to test the new, optimized scanmatrix driver:

keyboard_top.jpg

The contacts are realized with springs - thats a big advantage, because this allowed me to verify the debouncing routine.

keyboard_bottom.jpg

The DIN/DOUT register is soldered on a breadboard:

dindout.jpg

The new driver can now be found in the MIOS download section (sm_example2_v1.zip).

I've measured the capturing cycle for 64 nodes with a scope, it's 80 uS, so much less than expected! :)

Jim: which MIDI events should be sent by the various buttons?

Best Regards, Thorsten.

Link to comment
Share on other sites

Nice work with the keyboard and fantastic report on the latency Thorsten!  

Jim: which MIDI events should be sent by the various buttons?

Is it possible that this could be table driven as it is in IO128?  There will of course be many keys that are Note On/Off but there will also be stops where there is not so much standardization.  I am developing a concept where there can be some standardization of a Stop On/Off message that provides the information needed by the receiving device to properly implement the stop.  But even if these concept is proven, I'm sure there will be many who have other needs.

There will also be trem tabs which hopefully can be Modulation Messages but there are some issues to be worked out on that.  Swell shoe contacts will produce Expression controller messages.

In short, it's a big mess!  

Link to comment
Share on other sites

Thorsten: WOW you are incredible!!  I spent the weekend with my sister, her husband and my Dad, driving around to all the old places where he grew up, went to school etc.   I get back and you've already got it done!

Jim,

tomorrow I'll take a stab at modifying Thorsten's driver for different size matrices.

As to what to do with the buttons I had a few thoughts on that. The current table would get too big with a really large matrix so I was thinking about a two stage table. The first level table is indexed by the button number right shifted 3 bits. The 3 LSBs of the button number would be added to the value in the table. This would handle the "note on" type function where a bunch of buttons get the same midi function just differing by some value related to the button number.

IF the seond value has the MSB set (which should not happen in a regular midi message) it means the entry is really a pointer into the second table. Again the 3  LSBs are added to the value in the first table (probably the 3rd byte or the bottom 7 bits of the second byte) and used as an index into the second table. THIS table contains individual middi messages for each button put in this table.

So for a 16x64 (or other large table) we have 128 first table entries which cover MOST of the note on type messages, but for those that need to have independant middi message you have 128 entries in the second table  for stop changes, "pistons", crescendo sets, whatever.

Make any sense?

BTW my arms are quite sore after spending a couple hours with a file enlarging the holes on my front panel so the switches would fit, but itall done now.

John S.

Link to comment
Share on other sites

John,

It's a clever scheme but it won't work for me.  :(  I'm probably pretty unique in that regard.  My problem is that I won't be able to make the notes consecutive.  The first and second touch contacts use the same common wire and that is immutably set by the mechanical construction.  I could arrange things so the low order bit indicated first or second touch and bits 1 to 3 would be note offset.  Not too hard to handle with code but terribly special cased.

How about this variation on your idea:

There is an input table that has 2 bytes for every input point.  I think 512 input points is a reasonable maximum.  (That means that's all I think I will ever need.  ;) )  So this would be a 1024 byte table.  

The contents of each entry in the input table would be 4 bit event pointer, 4 bit channel, and 7 bit value.  

The 4 bit event pointer is a pointer into one of two 16 by 2 byte tables.  One table is for the contact changing to closed and the other table is for change to open.  

Each 2 byte entry in the event tables is a MIDI event message prototype.  

The first 4 bits are the MIDI event.  

The next 4 bits could be a channel offset (or maybe a mask?) but would normally (always?) be 0.  The channel is provided from the input table and possibly modified by the event prototype.

The second byte is the value for the second byte of the MIDI message, where high bit set means not used.  

The last byte of the MIDI message is the value from the event table.

Is 1,088 bytes a manageable amount for the tables to define the MIDI messages?

Have I missed any MIDI events that could plausibly be needed but can't be generated by this scheme?

Link to comment
Share on other sites

Have I missed any MIDI events that could plausibly be needed but can't be generated by this scheme?

Yes I have.  My scheme doesn't provide for different on/off values in the MIDI messages.  Most messages could probably get by with 0 as the value of the off message.  However the expression message probably requires arbitrary values of 0-127 for both on and off.  Back to the drawing board.

What is a reasonable number of bytes to use for the tables?

Link to comment
Share on other sites

Jim,

I don’t think your requirements are unique. I find the flexibility of assigning various MIDI messages to keys, stops, toe studs, push buttons invaluable. My plans are to use the Miditzer and Hauptwerk with various organs (theatre and classical) with one, two, or three manuals, pedal, one or more swell shoes, and a lot of stop keys, combination buttons, toe studs and buttons for effects like door bells, train whistles and what have you. The ability to load a different MIDI configuration with just a few keystrokes is worth a lot to me. The keyboards and the pedals use more or less standard MIDI assignments but when you come to the other keys it’s a different story. Some of the Virtual Organs can be configured some can’t. The use of a diode matrix saves a lot of hardware and cabling effort, but there might be a price to pay by having configuration limitations.

I started using the MIDO128 with 128 inputs some years ago and have recently built some more DIN modules, I now have 384 inputs which should keep me busy (with cabling!) for the next few years.

Per S

Link to comment
Share on other sites

So long it's ok for you to modify the table directly in the source code, and don't rely on any SysEx editor or mk_xxx_syx.pl script, it isn't so much effort.

At least 16k internal flash are still unusued in the sm_example2 application, this means that you could define up to 2730 complete "On" and "Off" events (2 * 3 bytes) in the same way like in the MIDIO 128 project (see midio_presets.inc, search for "MIDIO_Presets_OffsetOut").

A table of 1024 On/Off entries allocates 6*1024 = 6k bytes

I will create the other drivers next weekend.

Best Regards, Thorsten.

Link to comment
Share on other sites

Per points out the value of being able to readily reprogram the MIDI messages produced by the digital inputs.  Thorsten indicates that there is enough memory to support even 1024 input points with a straightforward table.  I think it is a good use of memory to make the configuration of the input to MIDI message translation easy.  It ought to be consistent with IO128.  John S, are you persuaded that we don't need to be tricky to conserve memory?

Link to comment
Share on other sites

This is slightly off topic but it is close and I think those of you participating in this discussion will be among the few who will quickly grasp what I am suggesting.

I am planning to create a MIDI "organ relay" that can receive MIDI Note Messages and Stop Messages and produce MIDI Note Messages that reflect the logic that would be performed by an organ relay.  Perhaps this could eventually be integrated into this project or another MIDI Box project.  For now, it will be implemented on a PC.

The Stop Messages would be controller messages, possibly a pair of General Controllers like 5 & 6.  4 bits of the value in the third byte would be an output channel.  The fundamental operation of the MIDI Relay is to remember the Stop Message and setup a mapping of the Input Channel of the Stop Message to the Output Channel in the value of the Stop Message.  A pair of controllers are used so that one of the pair sets the stop mapping and the other clears the mapping.

The remaining 3 bits of the value define a transposition for the mapping.  It would be nice to have 7 bits to define transpositions of -63 to +64 notes.  However I can't think of any way to fit that into the framework of a 3 byte MIDI message generated by a stop.  (This is where this become somewhat related to the topic of this thread.)  So I am thinking of using the 3 bits to define transpositions of -3 to +4 octaves, 64' to 1/2' stops in organ terms.

I am thinking another pair of controllers would be dedicated to mutation stops with the 8 transposition values mapped onto the mutation pitches commonly found in organs.

A third pair of controllers would be dedicated to trap stops, primarily for theatre organs.  This is a mapping of the OR of all Note Messages on the Controller Channel to Channel 10 with the Note given by the Controller Value.

A fourth pair of controllers might be dedicated to couplers.  These work exactly like the first pair of controllers but the controllers control a relay stage in front of the relay stage controlled by the 6 controllers described above.  The coupler relay stage has to default to a unison mapping of course.

Any thoughts on this approach to handling the stops?

Link to comment
Share on other sites

I took another step up the bottom end of the MIDI Box learning curve last night and setup my DIN with the MidiIO128 project.  Thorsten, you have done a fantastic job with the MIDI Box!  Everything worked just as it should on the first try.  It's a real thrill to connect a jumper wire and hear a piano note come out of the computer!  ;D

I'll stuff my DOUT board and setup the sm2 example in the next few days in a vain attempt to keep up with Thorsten on this project.

I think it would be great if the Switch Matrix project could use the same approach to the event tables as IO128.  It looks like IO128 supports all the MIDI Out events I need.  If no one else want to take on modifying the IO128 SysEx support for Switch Matrix, I'll do it.  I don't know Perl so it may take a little while for me to get everything done.  But I'm pretty good at modifying programs in languages I don't know so I think I'll be OK.

Link to comment
Share on other sites

Nice to hear that your core was running immediately! :)

The problem with SysEx support is, that the .syx generator has to be aligned with the application every time you make changes in the configuration tables. Every new or changed function leads to special effort, and once people are using the script and saving their tables in this fixed format, it will be much harder to implement changes.

So, it could make sense to create a comfortable SysEx configuration mechanism once this application has reached a state where you are sure that it won't get dramatic changes anymore (after one year or so...), but before it would be wasted time.

Especially when you take into account that the configuration within an assembler file (-> see midio_presets.inc) is also simple and that the upload of new code just takes some seconds - it's just another way to define the setup. By using additional constant definitions and macros, the assembler file could look very similar to the midio128.ini file, only drawback is that the user has to download the assembler tools (see http://www.ucapps.de/howto_tools_mpasm.html)

Best Regards, Thorsten.

Link to comment
Share on other sites

Jim:  the simple table is fine as long as there is enough memory to support it and the software can read it. I was just woried that with the current scheme the table was going to get rather large.

On the stop configuration stuff let me rephrase it in my own words so I make sure I understand what you are talking about.

It sounds like you are trying to make a configurable note "router". The end result is that a note on event comes in on say channel 5 and goes out on say channel 9 transposed up an octave. It might also go out channel 7 as well but not transposed this time. You could also have an event coming in on channel 4 also go to channel 9 but in this case it also goes to channel 6.

All this gets configured by midi controller events that specify that routings get added or deleted from a certain input channel. Controller messages are used to specify channel and transposition.

Ok this makes sense, but what specifies the stops that are present on each channel (unless you are only going to have 16 stops total)? Do you use a program change in addition to the controller specified above? Or does the program change from the stop switch cause a midi mapping then program change for the new channel?

John S.

Link to comment
Share on other sites

Hi John,

Yes, you understand the stop configuration idea correctly.  It is a static channel assignment scheme.  For theatre organs, 15 "ranks," which might include tuned percussions, plus traps works quite well.  For classical organs that could be limiting.

The idea is that you obtain organ like control of MIDI synthesizers without having to configure things.  Just as a MIDI Note message is self contained, saying play this pitch and that channel, the stop messages are self-contained saying map this input channel to that output channel with this transposition.  In both cases, Bank and Program changes can be sent to define what the significance of the channels is.  The major contribution is that single MIDI Input Channel can control multiple MIDI Output Channels in a musically powerful way.

There is a tension between defining things in a way that you can just plug them together and play and defining them in a way that the pieces have to be configured to play together.  MIDI supports both approaches and each has its place.

If you want to define a virtual pipe organ with a lot of ranks (MIDI Instruments) that are unlikely to be played at the same time, you want to do a dynamic assignment of instruments to channels.  My scheme isn't useful for that because it has no notion of what ranks are.  My scheme is only useful where there is a way to control the assignment of ranks to channels outside of the relay, a fixed one to one mapping being by far the easiest way to handle that.

I could envision a MIDI Controller with stops that have labels like "8' Ch3."  The performer could send a MIDI file that sets the instruments on the channels which then determines what "8' Ch3" sounds like.  It might be bagpipes at one time and an electric guitar at another.  The stop might have controls that determine what the stop means.  The real goal is to abstract the idea of organ stops to a general MIDI controller.

Link to comment
Share on other sites

Configuration within an assembler file (-> see midio_presets.inc) is also simple and that the upload of new code just takes some seconds - it's just another way to define the setup.

OK, I agree that makes sense.  Am I understanding what you have coded so far in http://www.ucapps.de/mios/sm_example2_v1.zip correctly if I conclude that for the moment you are just computing a Note Message based on the pin number?  And support of a table like midio_presets.inc is to be added?  

Were you planning on going that far or do you want to hand that off to John or myself?  Would it be of help if I were to create midio_presets.inc type tables for the configurations that will be supported initially?

What configurations will be offered initially?  8x8 and 32x16 presumably.  Anything else?  (Terminology wise should we refer to DINxDOUT or DOUTxDIN for the matrix configuration?)

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...
 Share


×
×
  • Create New...