Jump to content

Search the Community

Showing results for tags 'MIDI'.

More search options

  • Search By Tags

    Type tags separated by commas.
  • Search By Author

Content Type


  • Atari Systems
    • Atari General
    • Atari 2600
    • Atari 5200
    • Atari 7800
    • Atari Lynx
    • Atari Jaguar
    • Atari VCS
    • Dedicated Systems
    • Atari 8-Bit Computers
    • Atari ST/TT/Falcon Computers
  • Classic Consoles
  • Classic Computing
  • Modern Consoles
  • Gaming General
  • Marketplace
  • Community
  • Community
  • Game Programming
  • Site
  • PC Gaming
  • The Club of Clubs's Discussion
  • I Hate Sauron's Topics
  • 1088 XEL/XLD Owners and Builders's Topics
  • Atari BBS Gurus's Community Chat
  • Atari BBS Gurus's BBS Callers
  • Atari BBS Gurus's BBS SysOps
  • Atari BBS Gurus's Resources
  • Atari Lynx Programmer Club's CC65
  • Atari Lynx Programmer Club's ASM
  • Atari Lynx Programmer Club's Lynx Programming
  • Atari Lynx Programmer Club's Music/Sound
  • Atari Lynx Programmer Club's Graphics
  • The Official AtariAge Shitpost Club's Shitty meme repository
  • The Official AtariAge Shitpost Club's Read this before you enter too deep
  • Arcade Gaming's Discussion
  • Tesla's Vehicles
  • Tesla's Solar
  • Tesla's PowerWall
  • Tesla's General
  • Harmony/Melody's CDFJ
  • Harmony/Melody's DPC+
  • Harmony/Melody's BUS
  • Harmony/Melody's CDFJ+
  • Harmony/Melody's General
  • ZeroPage Homebrew's Discussion
  • Furry Club's Chat/RP
  • PSPMinis.com's General PSP Minis Discussion and Questions
  • PSPMinis.com's Reviews
  • Atari Lynx 30th Birthday's 30th Birthday Programming Competition Games
  • 3D Printing Club's Chat
  • Drivers' Club's Members' Vehicles
  • Drivers' Club's Drives & Events
  • Drivers' Club's Wrenching
  • Drivers' Club's Found in the Wild
  • Drivers' Club's General Discussion
  • Dirtarians's General Discussion
  • Dirtarians's Members' Rigs
  • Dirtarians's Trail Runs & Reports
  • Dirtarians's Wrenching
  • The Green Herb's Discussions
  • Robin Gravel's new blog's My blog
  • Robin Gravel's new blog's Games released
  • Robin Gravel's new blog's The Flintstones Comic Strip
  • Atari Video Club's Harmony Games
  • Atari Video Club's The Atari Gamer
  • Atari Video Club's Video Game Summit
  • Atari Video Club's Discsuuions
  • Star Wars - The Original Trilogy's Star Wars Talk
  • PlusCart User's Bug reports
  • PlusCart User's Discussion
  • DMGD Club's Incoming!
  • DASM's General
  • AtariVox's Topics
  • Gran Turismo's Gran Turismo
  • Gran Turismo's Misc.
  • Gran Turismo's Announcements
  • The Food Club's Food
  • The Food Club's Drinks
  • The Food Club's Read me first!
  • The (Not So) Official Arcade Archives Club's Rules (READ FIRST)
  • The (Not So) Official Arcade Archives Club's Feedback
  • The (Not So) Official Arcade Archives Club's Rumor Mill
  • The (Not So) Official Arcade Archives Club's Coming Soon
  • The (Not So) Official Arcade Archives Club's General Talk
  • The (Not So) Official Arcade Archives Club's High Score Arena
  • Adelaide South Australia Atari Chat's General Chat & Welcome
  • Adelaide South Australia Atari Chat's Meets
  • Adelaide South Australia Atari Chat's Trades & Swaps
  • KC-ACE Reboot's KC-ACE Reboot Forum
  • The Official Lost Gaming Club's Lost Gaming
  • The Official Lost Gaming Club's Undumped Games
  • The Official Lost Gaming Club's Tip Of My Tounge
  • The Official Lost Gaming Club's Lost Gaming Vault
  • The Official Lost Gaming Club's Club Info
  • GIMP Users's Discussion
  • The Homebrew Discussion's Topics
  • Hair Club for Men's Bald? BEGONE!


There are no results to display.

There are no results to display.


  • AtariAge Calendar
  • The Club of Clubs's Events
  • Atari BBS Gurus's Calendar

Find results in...

Find results that contain...

Date Created

  • Start


Last Updated

  • Start


Filter by number of...


  • Start










Custom Status



Currently Playing

Playing Next

Found 22 results

  1. There is a sound recording of the first attempt to simulate wind chimes within the following .ZIP file. It was recorded using Window 10's Voice Recorder. The A8 used Atari BASIC's RND(0) function to pick note, volume, and delay values for the chime strikes. Then sent the MIDI data to the Yamaha TG33 Tone Generator, Preset 2 #87 PC*Bells. You don't need the A8 setup to hear the recording. Its in .m4a format. A8 Wind Chimes - Gentle Breeze in C minor.zip If you are interested in the A8 side of this, read on. The idea was/is to simulate wind chimes by programming an A8 to output MIDI data to the tone generator. The 850-Arduino-Midi connection has been described in previous blog entries. The first thing that needed to be accomplished was to decide which Midi notes to assign to the six chimes. Information on how to build your own chimes was found on Michigan Technological University's site. It had suggestions on how to choose the notes. One was to pick the notes and then play them as randomly as possible on the keyboard. http://www.phy.mtu.edu/~suits/windchime.html The other was to setup a pentatonic scale used to make most of the tuned chimes. The major and minor keys are explained at: http://www.phy.mtu.edu/~suits/pentatonic.html These links provided enough information to start programing the chimes. Once the MIDI Note values have been chosen, the program chooses a random note, and random volume and some random delay between notes. It took some experimenting to get the program to start to sound like wind chimes. BASIC made this really easy. Change the parameters, enter RUN, then press reset to stop the program. I could have done this all day; and perhaps I did. 1 REM WIND CHIMES USING ARDUINO MIDI OUTPUT. 2 REM PACK007 - 9/29/2016 3 REM First experiment to determine MIDI Note vales, random timing values, and volume values for chime simulation 10 GOSUB 30000:REM SET UP RS232 PORT 20 DIM TONE(6):CMD=144 30 TONE(1)=60:REM NOTE C4 40 TONE(2)=TONE(1)+3 50 TONE(3)=TONE(2)+2 60 TONE(4)=TONE(3)+2 70 TONE(5)=TONE(4)+3 80 TONE(6)=TONE(5)+2 100 MIDINOTE=TONE(INT(RND(0)*6)+1) 110 VOL=INT(RND(0)*60)+20 120 DELAY=INT(RND(0)*500) 200 PUT #1,CMD:PUT #1,MIDINOTE:PUT #1,VOL 210 ? MIDINOTE,VOL,DELAY 220 FOR X=1 TO DELAY:NEXT X 230 GOTO 100 29999 REM SETUP RS232 PORT FOR CONCURRENT OUTPUT TO ARDUINO-MIDI 30000 CLOSE #1:OPEN #1,9,0,"R2:":XIO 36,#1,14,0,"R2:":XIO 38,#1,32,0,"R2:":XIO 40,#1,0,0,"R2:":RETURN Making changes to the program can be fun but now a program needs to be developed to adjust the variables to simulate any atmospheric condition, during program execution.
  2. Drum Synth/Bass Synth by Glen Gutierrez are 2 programs featured in the Antic Feb. 1985 issue. Antic Editor: "These are the most realistic instrument simulations we've ever heard at Antic." The Drum Synth program has been MIDIfied to except data from an Arduino+MIDI shield through the joystick port. Now the drums can be beat from a MIDI keyboard(MKB) or sequencer. Software: The chart follows the data from the MIDI NOTE ON source to the Atari Computer running the Drum program. The general MIDI LEVEL 1 Percussion key map was used to maintain some continuity between different midi instruments. <https://www.midi.org/specifications/item/gm-level-1-sound-set> The drum hit starts at the MKB. Press the key for the drum sound you want. This sends a MIDI NOTE ON message byte to the Arduino. The Arduino has been checking the data stream from the MKB to find a NOTE ON command for a specific MIDI Channel(channel 1 in this case). When it detects that byte it reads the next two bytes, the note number and then the velocity. If the velocity is above 0, the note number is used to set the patterns for the joystick port input. Any note number not mapped to a drum sound in the computer is ignored and the Arduino looks for the next NOTE ON+channel message. When the Joystick pins has been set, the trigger is set to tell the computer to read the joystick port. A short delay is used to give the computer a chance to read the port before it is reset. The computer has been sitting there waiting for the trigger to change state. If it changes while a percussion sound is being made, it POPs out of the FOR-NEXT Loop turns off the sounds and returns to the input loop. The input loop is where the computer reads the joystick pins and looks for a number between 1 and 12. This number is used as an index into an array(JTOK()) containing the original computer key codes mapped to the sound routines. The key codes are then used as an index into an array that contains the subroutine line numbers for the different percussion sounds; a hold over from the original program. Hardware: A MIDI shield for Arduino can be purchased for less then the cost to build one. It might be a good idea to get one that has a MIDI THRU port. It gives you the option of adding additional synthesizers to your MIDI setup. The Arduino-to-Joystick circuit is the same for the Drum-MIDI interface and the Wii-Nunchuk interface. Don't hook up the Nunchuk and plug in a midi shield. Digital pin assignments are a little different and are listed below. The MIDI shield connects to D0 and D1 for serial communication with the MIDI source. I still like using optocouplers to isolate the Arduino and computer whenever I can. NUNCHUK + ARDUINO = ATARI JOYSTICK From <http://atariage.com/forums/blog/572/entry-11529-nunchuk-arduino-atari-joystick/> The pin assignments for this project are as follows: Arduino Optocoupler # Joystick pin D4 1 1 D5 2 2 D6 3 3 D7 4 4 D3 5 6(trig) 8 GND for Atari side of optocoupler Pin assignments can be changed as long as the Arduino sketch is modified to match. The ZIP File Contains midi_drum_02 - Arduino sketch folder. SYNDRUM3.ATR - single density format DOS.SYS,DUP.SYS - DOS 2.5 SYNDRUM.BAS - original program from Antic SYNDRUM3.BAS - MIDIfied Program to use with Arduino interface SYNDRUM3.BTX - LISTED BASIC code SYNDRUM3.zip I was going to record the drums. Running the original program will get you the same sound by pressing the keyboard keys. I'll make the recording when I get some drum patterns programed into MMS. Send the midi data through the MIDIMax to a second computer with an Arduino-MIDI shield interface(channel 10). Then daisy-chain a third computer with interface(channel 11) through the THRU port. Run the audio outputs to a mixer and record, maybe adding some FX. That's after I find way to remove the unwanted low level hiss coming out of the Atari. P.S. This is not a MIDIjoy unit. Although I did take some inspiration from its makers. I am going to make one, someday.
  3. k-Pack


    I've added a third computer to the MIDI chain. Computer #1 plays drums, and Computer #2 runs S.A.M. and Computer #3 plays the lead, . Each computer had a specific BASIC program written to read data from the joystick ports. For this example, Queen's -" We Will Rock You" was arranged for the three computers. You can listen to the MP3 file and then decide if you want to read about the how. SAM Rocks - mp3.zip COMPUTER #0 - Control The music was entered using the MIDI MUSIC SYSTEM software. Voice 1 - Lead was assigned to MIDI channel 1, Voice 2 - SAM assigned to MIDI channel 3, and Voice 3 - Drums is Channel 10. All the editing was done using the CASIO-481 keyboard. Once the playback was acceptable, the rest of the computers were programed in BASIC and the Arduino interfaces were built. COMPUTER #1 - MIDI Channel 10 - Drums The same drum setup from the last two blog entries was used. Only one computer was required for this simple drum pattern. Computer #2 - MIDI Channel 3 - S.A.M. Getting SAM to sing the words was accomplished by activating the trigger button at the right time. The Arduino would read the MIDI data stream. Whenever a 146(NOTEON+2) command was received by the Arduino the joystick state was changed to zero for 10 milliseconds. When the Atari program detected the joystick status change, the next word is sung. Before the Atari was programmed the phoneme spelling of the words were created using the SAM Word Editor(another previous blog entry). Then a small test program was used to change the speed and pitch of the voices to meet the requirements of the music. The BASIC program simply reads the joystick port and when it reads 0 the next word is sung. This created a problem. If SAM was speaking it couldn't detect that the next word needed to be sung and resulting in skipped words. This problem was finally solved by changing the TEMPO in MMS from 175 to 160. Computer #3 - MIDI Channel 1 - Lead If I had started the work on the this computer, the project may never have been finished. Since the work on SAM was done I had to continue on. Bad solder joints, program logic and a misunderstanding of the MIDI data from the Casio or MMS added to the confusion. This was the first time a full 8bits were required to be received by the Atari8(A8). Four additional optoisolators were added to the Arduino Uno. This way the Atari could look for the MIDI command number for NOTEON or NOTEOFF. When NOTEON was detected at PORTA(joystick address) the computer would wait till the note number was set and the joystick trigger logic state changed. The note number was then used to calculate the index for an array holding frequency settings. The Arduino did most of the work decoding the midi data. You would almost think that a NOTEON would be followed by the NOTEOFF command before the next NOTEON command. NOTSO, when the Casio Keyboard was being used to test the hardware and software. Eventually the Casio was hooked up to the IBM running a MIDI Monitor. Press a note key and a NOTEON command was sent. Release the key and a NOTEON command was sent. The only difference was the velocity setting. Setting a NOTEON at 0 velocity does stop the note from being heard. You would almost think that a NOTEON would be followed by the NOTEOFF command before the next NOTEON command. NOTSO, when MMS was used to create the MIDI data stream. Some times the NOTEON command was issued before the last note turned on was turned off. So, the NOTEOFF command received by the Arduino was sent to the Atari only if the note matched the last note turned on. A function to set the output pins on the Arduino was used instead of the "case" used in the drum software. Each bit of the note byte is checked starting at bit 0. When the 7th bit is turned on the A8 computer knows it is a command byte that starts the process of turning on or off a note. The A8 then waits for the joystick trigger button to change state to indicate the note number is ready to be read. delay()s are used to give the A8 enough time to check the PORTA and the trigger. Project Software The ATRs and Arduino source code are in the zip file. The computers in the midi chain have no monitor so the programs for the drums and lead will autorun the BASIC programs. SAM would not allow the autorun code to execute the BASIC program when appended onto end of the AUTORUN.SYS file, so an easy name of "A" was used to reduce typing required to RUN "D:A". The Arduino source code for each of the instruments are in the folder. Also, an ATR containing the MMS music and info files is included. SAM Rocks - support files.zip That should be enough information if I ever want to rebuild this setup. Its been nice to be able to write custom programs and build Arduino interfaces for each voice but I have to start thinking about…. 1. A polyphonic A8 program for general use. 2. Two way communication between the Arduino and A8 3. Using commands beyond NOTEON and NOTEOFF 4. Programming using MAC/65 5. An editor for SAM to include pitch and speed manipulation 6. Getting a new furnace before winter sets in.
  4. After recording PRELUDE1.MP3 it seemed that the Atari BASIC sound program needed to be reprogrammed in assembly. I got out the MAC65 cart and two days later things were so messed up I wasn't sure if it was the Arduino and/or Atari software or the Arduino interface hardware giving me the headaches. I decided to go back and setup the equipment/software as it was for "house of the Rising sun". That seemed to work fine and it still did. I couldn't just turn it off and start programming. I had hookup the MIDIMax and played some MMS songs and then I wondered what it would sound like if I used the TRU connection and the miniEngine USB as a second sound source. As it turns out, the notes received on the Atari and miniEngine could be mixed to create some unique sounds. Later the software was stripped down to simplify the logic for conversion to assembly language. The simplified BASIC program was tested, compiled with MMG compiler and loaded on a MAX FLASH cart. Good news 'cause I don't need a monitor and disk drive to set up an Atari for sound generation. Before the assembly programing commences(again), this recording of Bach's Invention 1 was made. A 130XE, MIDIMax and MIDI Music System software send data out on channel one to the Arduino and same data was used bythe Atari800 and miniEngine Organ(#19) sound. The synths were on separate inputs to the mixer and then panned left and right. Two tracks were recorded one for MMS voice 1 and another for voice 2. The pan settings were changed to each track. Timing notes were recorded so the music tracks could be synced. These time notes were not deleted before exporting to an MP3. This is that file: Sound file invent01.mp3 Program files INVENT01.zip What else has been going on: 1- The initial design of an Arduino shield to be mounted between the Arduino and MIDI shield has been competed using Fritzing. The shield will hold the optocouplers and resistors that connect the Atari joystick ports and SIO motor control pins to the Arduino digital pins. I haven't really decided if or from where I am going to order. I only need one If multitrack recording techniques are going to be use. 2- I found a 3D printer model of the SIO design made by Norm8332 on Thingiverse. An AtariAge forum subject was started (sometime ago) with the link to the model. http://atariage.com/forums/topic/258097-3d-printed-atari-sio-plug-400800600xl-etc/ I'm still learning how to 3D print and forgot to take into account the shrinkage of the print material(PLA). The first attempts(5) were a little loose in the socket and the contacts were hard to get inserted. Since only 2 pins are needed for feedback from the Atari to the Arduino, it only takes a little effort to clean out the holes. Not sure I would want to do it for all 13. I measured a 2.6% difference between the printed and original. So of course, I did a test print on the plug at 1.03X and found it to be a little tight. Next I'll try 1.026X. 3- Having the software run from the AtariMax cart. is going to make life a lot easier. Just slip the cart into the slot and bootup. Hit return and away we go. No need for monitor or disks drive…accept… The joystick port is set by reverse logic. Turning on an Arduino pin turns on the optocoupler grounding the joystick pin to 0. At boot up the Arduino turns on all pins that ground the joystick port pins. The AtariMax menu expects only one pin to be grounded and gets confused when they all are. The setup() function needs to be programed to toggle the joystick trigger pin to start program one on the menu whenever the Arduino is turned on or reset. I just have to remember to turn on the Atari first. Who am I trying to kid. Is it really going to be that easy?
  5. Had some fun recording this one. MP3 audio file batsam_mp3.zip
  6. I currently have a MT-32 and CM-32 MIDI units. Originally, I was going to keep & use both for the small percentage of games that prefer one over the other. But have lately decided that it really isn't worth it (to me at least.) This leads to my current conundrum Which to keep? They both have games that sound best on that specific type. But the MT-32 is more likely for the games in question to need severe speed control (games that are moved to emulation, and thus it could be emulated as well. On the other hand, the MT-32 also has the nice display & buttons. If one was the CM-64 instead, I'd keep that one. So, suggestions anyone? Thoughts? Thank you.
  7. Sending MIDI commands (by serial, comlynx adapter) to two lynxes: http://lynxdev.atari.org/midi_synth_with_2x4_chan.webm using a pmidi and a modified ttymidi to play normal midi files.
  8. Dear all, I'd like to open this thread on my recent development "MidiJoy" because the topic of the thread which led to its inception is now only merely loosely connected to what has come out of it. I'll begin with posting some general information on MidiJoy, afterwards I'm looking forward to questions, comments and bug reports here . The most up-to-date information will probably always be on my website: http://www.phobotron.de/midijoy_en.html and a video introducing the basic idea of MidiJoy is available on YouTube. However, the software will only be available after the ABBUC hardware contest in which MidiJoy is participating (this is part of the competition's rules). Of course I'd be glad if you vote for it in the contest, and if it should make it to the Top 3, I'd make MidiJoy available for free afterwards . Enjoy, F.
  9. Finally got the DH-100 digital horn telling the Atari8 what tones to make and when. There was a couple of times I didn't think it was going to happen. Luckily the compiled basic program runs fast enough to keep up with the filtered data from the Arduino. Some sound tests have been recorded and placed in the following ZIP file. sound checks.zip Nothing has been done to enhance the sound from the Pokey chip other then combining 2 channels to allow the use of 16 bits to define the tones. The breath controller was turned on during the recording to maximize any delay that may exist. While messing with the mixer and sound effects I recorded a bonus file for your listening pleasure. Cranked up the sound effects to full on, so I hope it don't make your ears bleed. I may record some music when I get the band together. (Or should I say, I have to get the ST operational and remember how the Band-In-A-Box software works) The technical stuff: This project has been ongoing over the last 6 months and will continue to be modified/ tweaked probably as often as it is used. Older blog entries begin with "DH100". It should make them easier to find. The Arduino interface hardware hasn't changed since it was last described. It is close to being a good general purpose design for manipulating the joystick port. I'm debating if I should design a PC board for an Arduino shield. I have to build 5 or 6 more interfaces for the Atari MIDI rack of my dreams. The software used for the Arduino and Atari8 are in the following zip file. You should be able to follow most of the logic. I tried to comment. DHMIDI.zip DH100-2-ATARI8 folder. Holds the Arduino program. The biggest difference from the last blog entry is that a counter for the Breath control data was added. The counter keeps track of the number of 208 MIDI commands (pressure control set points) have been received. Then every 15th data point is sent to the Atari and the counter reset. This greatly reduce the number of data points being sent to the Atari and still give some degree of volume control. DHMIDI.ATR contains- DHMIDI.EXE is the compiled DHMIDI.BAS using the MMG BASIC Compiler. The double precession integer math used instead of the floating point package greatly increased the speed of the program. Most of the received MIDI commands are printed to the screen since the display doesn't need to be turned off to save processor time. DHMIDI.BAS is the program that receives the data from the Arduino and turns it into sounds. This may help if you wish to examine the code. 1-9 Title and program information 10 GOSUB 14000 to set up variables, then GOTO 500 to start 100-150 subroutine to get a byte of data from the joystick port- returns x 500-530 gets input - if command then split upper and lower bits 600-630 Pressure sensor command - set new volume 700-720 Set Portomento flag 800-830 Set Atari Distortion level - should be used to select different voice envelopes 900-990 Plays note when portomento is turned off or redirects to portomento routine 2000-2060 portomento slide to next note. Same number steps between any 2 notes 14000-14200 sets up variables, tables, register names, motor control bit, unitize sound registers 15000-15170 data for audio control bytes Low byte, High byte and double byte. Used to save time calculating these number when called. Saved so MIDI note number = index 15500 data for distortion number. 10 -pure tone. upper 4 bits of AUDIO Control 2 location. It hurts my brain when I try to think of all the ways this program can be improved/modified. The system works as a monophonic sound source when any MIDI instrument is hooked up and transmitting data on channel 1.
  10. Hi there, Maybe a few of you wondered why there is (in the original BLL kit) a com program to interface the lynx with 31250baud to an Atari ST? Short answere: The Lynx has some very weird baud rate setttings. The onyl useable for a normal PC is 9600baud, but 31250 matches exactly the MIDI specifications. And the Atari ST comes with a MIDI port. Makes debuggin and uploading much much faster. BUT (now comes the bad things): MIDI is using a current loop (5V) while comlynx is level sensitive to 5V. Thus you risk either to damage something or you need some adapter. Nothign special, a simple optocoupler and a few resistors & diodes. Actually, the MIDI specs require that you decouple the MIDI In. PS: Did I mention that, if you "just" connect it by some passive resistors, the polarity of the signal is inverted? And, you need to set the serial setting to 31250E1, because the lynx expects ALWAYS a parity bit. Very bad, because the MIDI specs are 31250N1. This can be done easily if you have a ST or PC where you can set the port parameters. You just have to remember to do it. Q: Now, if I build me some adapter, could we use MIDI In to connect a Keyboard to comlynx? A: No. (Reason 2). The Keyboard will send out data withou parity bit. The Lynx will reject the data bytes (even if you disable parity checking!). A: Yes. If you but some "intelligence" inbetween. A simple microcontroller will do. Or a Laptop. So, You connect the keyboard with a midi adapter to your laptop and use an configurable(!) second adapter to send it out including parity. Or, to make it a bit simpler, you send out the data by a normal serial port with 9600E1 setting, which interfaces directly with a standard serial-comlynx interface. 9600 is a bit slow for MIDI, thus the timing is a bit ... inaccurate. But: Its working!
  11. Do you remember me mentioning that the first attempt to write a machine language program to read MIDI data delivered to the Atari joystick port was a complete failure? The Arduino hardware has remained the same. The joystick trigger and cassette motor control(CMC) pin on the SIO port are still being used to control data flow. But this time I redefined the project specs to simplify the ML program and tested the ML data transfer routine as a USR call. The USR routine was written to replace the BASIC code that checked the joystick trigger to see if data is ready to be read, gets the data, and tells the Arduino to get the next byte by setting the CMC. (the subroutine starting at line 100 in many of the earlier programs) The data byte is stored in a page Zero location to be PEEKed after control is returned to BASIC. Once working as a USR call the PLA was removed and the M65 file was edited and saved for later inclusion in the Project file as a subroutine. #INCLUDEd READMIDI.M65 routine is as follows: READMIDI.M65 01 ;USR FUNCTION TO GET MIDI DATA FROM02 ;ARDUINO BOARD WITH DATA FLOW CNTRL03 ;DATA RETURNED IN LOCATION $CB04 ;05 ;Kevin Packard 4/201906 ;0100 ;STRIG0 = $0284 -ARDUINO DSR0110 ;PORTA = $D300 -JOYSTICK INPUT0120 ;PACTL = $D302 -SIGNIAL ARDUINO0130 ;0140 READMIDI0150 MU1 LDA $0284 ;STRIG00160 CMP #00170 BEQ MU1 ;WAIT FOR DATA0180 LDA $D300 ;PORTA-READ DATA0190 STA $CB ;STORE BYTE PEEK(203)0200 LDA #52 ;DATA READ0210 STA $D302 ;PACTL-CMC ON0220 MU2 LDA $0284 ;STRIG00230 CMP #10240 BEQ MU2 ;LOOP TILL RESET0250 LDA #60 ;TURNS OFF BYTE0260 STA $D302 ;PACTL - CMC OFF0270 RTS ;RETURN Playing a MIDI note on the monophonic-Atari in its simplest form consists of receiving the MIDI note number for the tone to play or to turn the tone off . If you assume the volume value to be the same for every note then the volume data doesn't have to be sent. Since a MIDI note can have a value of 0 - 127, passing a value of 128 can be used to signal note off. The Arduino had to be reprogramed to minimize the data being sent to the Atari. The Arduino will first look for MIDI data for channel one. If its a NOTEON or NOTEOFF command it reads the following MIDI note number and then the volume byte. It then makes the decision to send a note number to start or change the pitch OR turn off the note being played. The logic makes sense considering a NOTEOFF command can be transmitted for a note that isn't being played or a NOTEON can set the volume to ZERO. /*Mono synth - channel 1 * Sends: * MIDI Note number to play * or * Bit 7 ON(128) to turn off note * * Kevin Packard May 2019 */// Atari PORTA(54016) mapped to pins on arduinoint porta0 = 4;int porta1 = 5;int porta2 = 6;int porta3 = 7;int porta4 = 8;int porta5 = 9;int porta6 = 10;int porta7 = 11;int DSR = 3; //data set ready triggerint DTR = 13;//Atari ready cmc byte zero = 0;byte midiData = 0;byte midiCommand = 0;byte midiNoteNum = 0;byte lastMidiNoteNum = 0;byte volume = 0;byte volOff = 128; //Function to Send a byte to the Atarivoid sendByte(byte byteToSend){ setPorta(byteToSend); digitalWrite(DSR,LOW); //data ready-Trigger 0 while(digitalRead(DTR) == LOW){} //Wait for Atari to get byte cmc goes low digitalWrite(DSR,HIGH); //data not ready-trigger 1 while(digitalRead(DTR) == HIGH){} //wait for Atari to signal ok to get next byte} void setPorta(byte byteToMap){ // Sets digital pins to transfer data to Atari joystick ports(PORTA) // When digital port high, joystick pin shorted to ground or logic 0 if (byteToMap & B00000001){digitalWrite(porta0,LOW);} else {digitalWrite(porta0,HIGH);} if (byteToMap & B00000010){digitalWrite(porta1,LOW);} else {digitalWrite(porta1,HIGH);} if (byteToMap & B00000100){digitalWrite(porta2,LOW);} else {digitalWrite(porta2,HIGH);} if (byteToMap & B00001000){digitalWrite(porta3,LOW);} else {digitalWrite(porta3,HIGH);} if (byteToMap & B00010000){digitalWrite(porta4,LOW);} else {digitalWrite(porta4,HIGH);} if (byteToMap & B00100000){digitalWrite(porta5,LOW);} else {digitalWrite(porta5,HIGH);} if (byteToMap & B01000000){digitalWrite(porta6,LOW);} else {digitalWrite(porta6,HIGH);} if (byteToMap & B10000000){digitalWrite(porta7,LOW);} else {digitalWrite(porta7,HIGH);}} void setup() { pinMode(porta0,OUTPUT); pinMode(porta1,OUTPUT); pinMode(porta2,OUTPUT); pinMode(porta3,OUTPUT); pinMode(porta4,OUTPUT); pinMode(porta5,OUTPUT); pinMode(porta6,OUTPUT); pinMode(porta7,OUTPUT); pinMode(DSR,OUTPUT); pinMode(DTR,INPUT); Serial.begin(31250); setPorta(zero);// digitalWrite(DSR,HIGH);} void loop() { //read data until its a Midi command //command bytes will have bit 7 true while (midiCommand != 128 && midiCommand != 144){ //midi command + Channel while(Serial.available()<1){}//wait for data midiCommand = Serial.read(); //read MIDI stream } // get data required by command. while(Serial.available()<1){} midiNoteNum = Serial.read(); while(Serial.available()<1){} volume = Serial.read(); if(midiNoteNum == lastMidiNoteNum && ((midiCommand == 128) || (midiCommand == 144 && volume == 0))){ sendByte(volOff); lastMidiNoteNum = 0; } if(midiCommand == 144 && volume > 0 && midiNoteNum != lastMidiNoteNum){ sendByte(midiNoteNum); lastMidiNoteNum = midiNoteNum; } midiCommand = 0;} // End of Listing The Atari now simply has to wait for the Arduino to set the trigger as new data is ready to be received. It then will turn off the sound, turn on the note, or change the pitch. The response time seems to be much faster then the compiled BASIC program. The Arduino"s data buffer didn't get overwritten when I ran my fingers up and down the keyboard or mashed down a bunch of keys over and over. I did note a bit of a delay as the buffer emptied. SINGBYTE.M65 0100 ;MIDI SYNTH MONO VOICE0110 ;ARDUINO 8BIT INPUT/CMC CONTROL0120 ; Monosyn_1-Byte_Data.ino0130 ;K-PACK 20190140 ;0150 STRIG0 = $02840160 AUDCTL = $D208 ;SET TO 120 - 16BIT FREQUENCEY DEFINITIONS0170 AUDF1 = $D200 ;LOWBIT- VOICE 10180 AUDF2 = $D202 ;HIBIT - VOICE 10190 AUDC2 = $D203 ;VEL-DIS-VOICE 10200 AUDF3 = $D204 ;LOWBIT- VOICE 20210 AUDF4 = $D206 ;HIBIT - VOICE 20220 AUDC4 = $D207 ;VEL-DIS-VOICE20230 SKCTL = $D20F0240 PORTA = $D300 ;JOYSTICKS VALUE0250 PACTL = $D302 ;CMC 60-OFF 52-ON0260 CMCON = 520270 CMCOFF = 600280 MIDIBYTE = $CB0290 ;0300 *= $40000310 .INCLUDE #D:FREQTABL.M650320 .INCLUDE #D:READMIDI.M650330 ;0340 ;0350 ;0360 START0370 LDA #0 ;RESET AUDIO0380 STA AUDCTL0390 LDA #30400 STA SKCTL0410 LDA #1200420 STA AUDCTL ;SET 16 BIT SOUND0430 LDA #CMCOFF0440 STA PACTL ;SET CASS MOTOR0442 LDA #00444 STA $022F ;kill SCREEN0450 ;MAIN LOOP0460 JP1 JSR READMIDI0470 LDA MIDIBYTE0490 CMP #128 ;NOTE OFF?0500 BNE JP20502 LDX #00505 STX AUDC20520 JMP JP1 ;GET NEXT DATA0530 JP2 LDX MIDIBYTE ;OFFSET FREQ TABLE0540 LDA FREQLO,X ;SET FREQ0550 STA AUDF10560 LDA FREQHI,X0570 STA AUDF20590 LDX #173 ;DIS=10 VOL=130600 STX AUDC2 ;TURN SET VOL0610 JMP JP1 ;NEXT COMMAND BYTE0620 ;0630 *= $02E20640 .WORD START0650 .END I'm hoping this program will be a good start for some interesting routines to modulate the sounds. A sound recording didn't seem to be necessary and the Arduino interface has been explained in previous blog entries. The atr file contains the MAC/65 files and BASIC files used to create and test the USR input routine. mls01.atr
  12. I ordered the MIDIPLUS miniEngine USB sound synthesizer to reward myself for doing something special. This is the first chance I've had to play with it and can't remember exactly what that something was. Maybe it wasn't that special. The thing that interested me most about this general midi sound module is its size( 3" X 4" X 1"). I just don't have the room to keep the TG-33 and sound mixer on my desk. If I want to have a short retro session, it can quickly be set up in a few minuets. I'm not going into great detail, its already on the web. I did (and still do) have some questions that the answers didn't appear in page one of the search engine results. I will be using it with an Atari8 with a Wizztronics MidiMax interface and MIDI Music System(MMS) software. If your retro computer can dump data out to a midi port this may be something to look into. I wasn't expecting $1000 worth of sound out of a $65 box. I am happy with it's sound. It has all the general MIDI instruments assigned to the standard patch numbers for use on all the channels except Channel 10; which is reserved for the Drum Kit. A reverb effect is built in and can be adjusted using the DATA wheel. This will have a great effect on the perceived sound quality. My biggest complaint is that it did not come with a MIDI Implementation Chart. I know it will accept NOTEON and NOTEOFF data on all channels, patches can be assigned to each channel and up to 64 notes can be played at the same time. I had the Casio DH-100 horn hooked up and noted a lack of after touch response and no portomento. (darn) I also noted that there were different drum kits on Channel 10. Assign different patch numbers to channel 10 to make the change. It would change on the 8s. Patch number 0 - 7 for the first drum kit, 8-15 for the second, and 16 - 23 for the third and so on. I lost my concentration in the higher numbers and can't really say what the effects were. There are other questions a Midi Implementation Chart might have answered. Like, can I turn on and off midi channels, incase I want to use more then one sound module? Can the channels be panned? Can the Channels be set for MONO or POLY? (I'm thinking no, no, and no.) Anyway…….., most of the youTube videos have examples of the patches. I have uploaded a zip file containing a complete composition in MP3 format and the original MMS file. I named it STARFIN back in the 80's when it was first produced using the Advanced Music System(AMS) for the Atari8. I called it Starfin for the fact that if I tried to write music for a living I would be starfin. The file got converted from AMS to MMS at some point. It contains 4 voices and each was assigned to a different channel. Voice 1(Channel 1) was assigned patch 118 Synth Drum. Voices 2-4(Channel 2-4) were assigned patch 81 Lead2(Saw Tooth). The Reverb was adjusted to 68 and then recorded using Audacity on the PC. The only adjustments to the recorded sound was to Normalize for a slight DC offset and a short Fade in was added. It was exported to a MP3 file and zipped. starfin_mp3 - midi engine.zip Sure, you can hook this up to your modern PC or tablet but where's the retro fun in that.
  13. How much can you change a program before it becomes a different program? I believe I have reached that point with Computer Blues. Version 4 got rid of the base repeats and Version 5 gave each voice its own channel and different patches for the JAM() and base notes. Fixing the timing can be done but would require a major rewrite. Here are the resulting sound and program files for Version 5. MIDI Computer Blues 5 - 3 channels.zip These are the changes made to version 4 to produce Version 5. Added "16 POKE 559,0" - turned off display to speed up processing. May have improved timing. The port setup routine was modified to include sending out program changes for each channel. JAM() was assigned to channel 1 and uses patch 97 - Vibes LOW() was assigned to channel 2 and uses patch 27 - ElecBass BASE() was assigned to channel 3 and uses patch 27. 3000 CLOSE #1:OPEN #1,9,0,"R2:":XIO 36,#1,14,0,"R2:":XIO 38,#1,32,0,"R2:":XIO 40,#1,0,0,"R2:" 3100 PUT #1,192:PUT #1,97:REM C1-I97 3110 PUT #1,193:PUT #1,27:REM C2-I27 3120 PUT #1,194:PUT #1,27:REM C3-I27 3130 RETURN The (channel# - 1) was added to CMD for note on and note off to direct the note information to the correct channel. The JAM() did not require changing, going to channel #1. 535 CMD=145:MIDINOTE=LOW(CHORD):VELOCITY=90:GOSUB 3 540 CMD=146:MIDINOTE=BASE(CHORD,THNOT):VELOCITY=90:GOSUB 3 700 CMD=129:MIDINOTE=LOW(CHORD):VELOCITY=0:GOSUB 3 710 CMD=130:MIDINOTE=BASE(CHORD,THNOT):VELOCITY=0:GOSUB 3 That's it for me and the Blues. I had thought about setting up the ST and record the MIDI data using Tiger Cub and then quantize the music, add tracks, and ……; or feed it into the MIDIMAX on another A8 computer. Brain Fart: What if I had a MIDIJOY setup. Then I could output the RAMO equipped A8 MIDI data to the MIDIJOY equipped A8. It would sound just like playing it on an A8 machine. Updated Hardware: Although I may not be playing Computer Blues, I'm sure I will be using the hardware for other music programs. The hardware was rebuilt to free up the shields for future projects and have a permanent setup for the A8 (or any other RS232 equipped computer). Remember at the end of the first blog on this subject there was a photo of the parts for an optional setup. Those parts were mounted on a wood plaque and wired. Slightly more permanent. http://atariage.com/forums/blog/572/entry-13269-midi-computer-blues-setting-up-the-hardware/ I looked up some prices and found the major parts would cost about $16. Arduino UNO compatible = $5.00 RS232 to TTL converter = $7.00 MIDI Socket - Panel mount = $2.77 220 ohm - $.90/100 I had a lot of incidentals laying around and was able to use them at no additional cost. There is a MIDI switch box connected to the R2: port of the 850 on my system. The cable between them is wired so that the pin outs of the box outputs follow the standard(?) for an IBM RS232 port or USB-to-RS232 converter with DB9 male connector(Data Terminal). The Shield had a DB9 Female connector wired to be a Data Set, thus allowing the use of a standard cable (db9-female to db9-male). The RS-232 to TTL converter I purchased has a DB9 male and was wired as a Data Terminal. A null-modem cable is needed to connect the two Data Terminals. How you solve your cable problems is up to you.
  14. When I started the Computer Blues Project I really thought there was no way to program the MIDI MATE from BASIC and that using the RS232 port was an option. If you don't have a MIDI Mate or MIDI Max, it is an option. If you do, there are ways of programing BASIC MIDI applications for them. I am just now starting to discover those methods. That’s at the end of this blog story. Where to start? Once upon a time….. I wasn't going to replace the MIDI Mate I sold after getting the ST but when the opportunity arose, I could only resist for about 3 months. The Wizztronics MIDI Max arrived and I was soon looking for my old MIDI Music System(MMS) song files. I unarced the song files and played some. It was like hitting the 25 year rewind. There was also a file named PD.ARC. I read over the MMS documentation again but this time the Command Summary seemed to be a little hard to read. Lots of commands on a 4.25X5.5 inch page. Retyping the chart helped me reconnect to the long term memory paths and the larger format makes for a little less eye strain. MIDI MUSIC SYSTEM comand summary.pdf I started entering some drum patterns from the book 200 Drum Machine Patterns by Rene-Pierre Bardet. That was fun but it made me realize how much effort it would take to make me an adequate drum programmer. It ain't going to happen. I'm playing with the drum kit on the Casio CTK-481. Not sure if anyone can use them. I will post the MMS files at a later date. Curiosity got the better of me and the PD.ARC file was unarched. The XMO file extensions makes me think that these are Public Domain files downloaded from Compuserve just before putting away the A8. I don't even remember reading/running them. The original XMO extensions have been changed to reflect the content of the files. PD PROGAMS atr.zip MIDIDR.DOC (MIDIDR.XMO) MIDIMate Software Interface Documentation 5/21/1985 By Hybrid Arts, Inc. This file contains technical information on the MIDIMate hardware and a listing of the fig-FOURTH source code for the driver software. (also compatible with the MIDIMax). (There are hardware schematics of midi interfaces that use the cassette motor control line to turn on and off the midi circuits. It would seem reasonable that these home brewed interfaces could be compatible with the Hybrid Arts MIDI software. (One more thing to find out.) MIDIDEMO.BAS MIDITRACK III simulated DEMO By Charles Faris This is a tutorial program for the MIDITRACK III software. It explains the screen data and most of the commands of the MIDITRACK software. HANDLR.ARC (contains HANDMIDI.DOC and HANDLER.MID) HANDMIDI.DOC The M: device. Documentation By James Dillow 1987 Released through Bitwise Computer Services This (kind of) explains the MIDI driver software that can send/receive MIDI data using standard I/O commands. It creates a M: device. It can be programed using BASIC command OPEN, CLOSE, PRINT, INPUT, etc. Or any language. (There are problems in the listed BASIC example that will make the information useless. More information and better example below). HANDLER.MID Compiled driver software. This is the binary load file that creates a M: device. Load from DOS or Rename to AUTORUN.SYS to auto boot. PATCHER.BAS CZ-101 Voice Patcher by Greg Kopchak Load and Save voice patch data to the CZ-101 MIDI keyboard. PORGAN.XMO Numeric data file - may be patch data for CZ-101 from PATCHER program????? DRTCVR.BAS (DRTCVR.XMO) Dr. T Patch Format To Patcher by Greg Kopchak Converts Dr. T tone data file to 16 PATCHER data files and a text file of patch names. HACVRT.BAS CZ-Patch Format to Patcher by Greg Kopchak Converts Hybrid Arts CZ-PATCH tone data to 16 Patcher data files and a text file of patch names. CZMIX.BAS CZ-101 Voices By Greg Kopchak I think this is a voice mixer? for the CZ-101. I had a CZ-101s but never used this program to edit voices. SSBMID.BAS (SSBMID.XMO) Star Spangled Banner by Francis Scott Key Program by Greg Kopchak 11/86 BASIC program to play Star Spangle Banner. Says "Requires Midimate and CZ-101". There are Program Change messages that call specific voice patches on the CZ-101 which may or may not sound good on your synth. There is a 270 byte machine language routine and a lot of poking into the IO routines. Have yet to figure out how the program works. Disk IO did not work after program is stopped using the break key. ------------------------------------------------------------------------- The M: device - HANDLR.ARC This file called to me and I had to give it a try. The resulting program is in an zipped .ATR image. MTEST.BAS will play middle C three times, if the driver is loaded and your MIDI system is attached. midi device test atr.zip The MIDI Device Test.ATR is in 720 sector format with DOS 2.0s and MEM.SAV. The HANDLER.MID is the binary load file that installs the M: device onto the computer. The M: device can then be accessed like other devices within a given language. The HANDMIDI.DOC is the documentation on the M: device and example program. The BASIC example program has several errors and will not be of much help. AUTORUN.SYS is a copy of the HANDLER.MID file and sets up the M: device driver at boot up. MTEST.BAS/.BTX is the Atari BASIC test program. 10 REM OPEN CHANNEL-START CONCURENT 20 OPEN #1,13,0,"M:" 30 XIO 40,#1,0,0,"M:" 40 REM PLAY NOTES - NOTE ON 45 FOR Y=1 TO 3:REM PLAY NOTE 3X 50 REM NOTE ON:MIDDLE C:VEL=100 60 PUT #1,144:PUT #1,60:PUT #1,100 70 FOR X=1 TO 50:NEXT X:REM DELAY 80 REM NOTE OFF:MIDDLE C:VEL=0 90 PUT #1,128:PUT #1,60:PUT #1,0 100 FOR X=1 TO 50:NEXT X:REM DELAY 110 NEXT Y 120 CLOSE #1 130 END There are three problems with the example given in the .DOC file that needed to be addressed to get middle C to play. a. The AUX1 in the OPEN Command should be 13. "13" is the same number used to set up concurrent in and out mode on the 850 interface. b. The AUX2 is missing from the XIO command. AUX2 = 0. This is a syntax error if you enter this line in Atari BASIC. c. The Note on and Note off MIDI commands require 3 bytes. The command number+channel, note number, and velocity. The example only shows 2 bytes being sent. Once these changes were made, the note came on and turned off 3 times. The CLOSE #channel and END commands are to made sure the program ended properly. Try it on your MIDI setup. Or better yet, write the nxt-gen MIDI game.
  15. In order not to pollute the thread of Sound List Ripper with this, I've created a small utility in VB5 which converts MID files into TI-99 sound lists. It's somewhat crude, but I'm posting it anyway since there has been interest in it. I think it facilitates the development of sound lists for the TI-99 which are a nice, compact format with a player built into ROM. You can find details on its usage in the README file supplied with it. The ZIP file contains an EXE file, the source code project and the README file. Oh, sorry to say, but since it was developed in VB5, it only runs on Windows. I'm not exactly sure which versions it will run on, but I'm pretty sure it will run on Windows XP, 7 and 10. Maybe earlier versions (from 95 upward) are also OK, but I haven't tested it. Enjoy! Kurt MIDI_TO_Sound_List_0_0_1.zip
  16. Getting ready for the arrival of Dropcheck's XE Super Cart 128 with MidiMaze. For this project I decided to take a stock 16K 600XL that was badly in need of a RAM upgrade, and trick it out with MIDI in mind. To do this, I started with my SIO2MIDI board, after first shaving it down a tiny bit on the sides. This allowed me to drop it into the area where the RF modulator once resided, and would allow the new MIDI jacks to be even with the power and video jacks. I also took the opportunity to add the 64Kx4 RAM chips, and modify the addressing (some bent up IC pins and 3 jumper wires). For the new video jack I used a UAV to give it the best possible picture. And as long as I had this guy cracked open, I also changed out the Basic RevB ROM for a RevC ROM. The following pictorial documents the hardware changes required. Surgery - gotta make room for the SIO2PC, as well as strip out all of the unneeded video components. Unfortunately some traces get severed on the bottom side that will need to be jumpered. Bottom view of 'inserted' SIO2MIDI board, some required wire jumpers to replace missing traces, and all held in place by clear epoxy. Upper view showing black epoxy used between MIDI and Video jacks to add strength, UAV & RAM installed. SIO connections. Overview, all board mods completed. Adding new holes in the case for the MIDI and Video jacks. Modified board placed back in the case (front view). Modified board placed back in the case (rear view). Adding MIDI com LED (required a hole in the bottom metal frame of the keyboard) Finished look of MIDI com LED installation. MIDI com LED activated. Finished look of new MIDI and Video jacks + labeling (had to enhance the image to see the new DIN jacks). At this point the system is fully operational except for two minor omissions caused by some traces that got cut as part of the modding. That would be Audio-In on both the SIO and the PBI. Since I don't really need those for my intended application, I decided to not run jumper wires to restore them. However if that changes, I can always add them in at a later time. Now I just need my MIDI-MAZE cart, and I can link this up to my MIDI ring and start blasting happy faces .
  17. I finished work on the last blog entry, unplugged the keyboard and plugged the digital horn. I was a little surprised to see how much data the breath pressure sensor(after touch) was being streamed to the Atari 8. Far more then it could keep up with. The Arduino needed to be reprogramed to reduce the number of bytes being send to the Atari8. The interface software was tested with the previous Atari 8 test program and it performed much better. The data seemed to make sense and it was difficult to overwrite the serial input buffer on the Arduino. These are the ways that the data stream was reduced. The DH-100 has 4 types of data it will generate. The Arduino reads in the data, modifies it and sends it out in the void loop() function. Casio DH-100 MIDI output 1 Note On Event 1001nnnn, 0kkkkkkk, 0vvvvvvv (144+,n,v) 2 Control Change 1011nnnn, 0ccccccc, 0vvvvvvv (176+,65,v) value 0=off, 127=on (portomento) 3 Program Change 1100nnnn,0ppppppp (192+,p) p = 0 to 5 (patch change) 4 Channel Pressure 1101nnnn,0vvvvvvv (208+,v) v = 0-127 scaled to 0-15 for Atari volume(breath controller) The DH-100 will only transmit data on MIDI channel 1. The Arduino will check for any incoming command byte. If it is a command byte, it will have the 7th bit set and bits 0-3 will contain the channel number(zero for channel 1). If the data for the command can be stated in under 4 bits it can be combined with the command in one byte and sent. Channel Pressure: This command generates a continuous stream of data. This 2 byte command is reduced to one byte by scaling the 0-127 from the DH100 to 0 - 15 for the Atari. The Atari value replaces the channel number. It is far less sensitive to changes and by sending the byte only when it has changed will reduce the data flow. Program Change: has a value of 0 to 5. It also can be added to the command byte and sent as one byte. It doesn't happen very often but its still 1/2 the original data byte count. Control Change: The DH-100 only has one controller and it is 65 for the Portomento switch. The Atari can assume that if a Control Change command is received and, the 65 doesn't have to be sent. A value of 0 for off or 127 for on. Change the 127 to 1 and added it to the command byte. Another byte saved. Note On: The third byte of the command is the volume and can be handled the same way as the Channel Pressure. The second byte (note number) may as well be sent as an unmodified second byte. Reducing this to 2 bytes is still a savings in time. All of this data is checked for redundancy and not sent unless there is a change. When a command is not to be sent to the Atari the command is reset to zero and some how makes it back to reading the data until a command byte is detected otherwise it is sent using the second switch-case set of routines. The Atari can split the data off the command byte without to much trouble. The integer math of the MMG Basic complier should make it even faster. Where X = combined input data: Command = int(X/16)*16 DataValue= X - Command /* Midi data transfer test 1/2018 * * This program reads midi data then outputs * the data to the Atari Joystick ports. * * The use of the control lines to the Atari Trigger * and from the cassette motor control line on the SIO * port are used for data flow control. * * An effort to minimize data transfer by combining data bytes * since DH100 uses Midi channel 1 the first four bits of the * data byte can be used for Atari Volume(0-15) and controller * data. Atari can then strip the lower four bits and make the settings. */ // Atari PORTA(54016) mapped to pins on Arduino int porta0 = 4; int porta1 = 5; int porta2 = 6; int porta3 = 7; int porta4 = 8; int porta5 = 9; int porta6 = 10; int porta7 = 11; int DSR = 3; //Arduino ready int DTR = 12;//Atari ready byte zero = 0; byte midiData = 0; byte midiCommand = 0; byte midiNoteNum = 0; byte lastMidiNoteNum = 0; byte volume = 0; byte lastVolume = 0; byte portemento = 0; //0=OFF 127=ON byte patch = 0; //0 - 5 byte controlChange = 0; byte dataByte = 0; //Function to Send a byte to the Atari void sendByte(byte byteToSend){ setPorta(byteToSend); digitalWrite(DSR,LOW); //data ready-Trigger 0 while(digitalRead(DTR) == LOW){} //Wait for Atari to get byte cmc goes low digitalWrite(DSR,HIGH); //data not ready-trigger 1 while(digitalRead(DTR) == HIGH){} //wait for Atari to signal ok to get next byte } void setPorta(byte byteToMap){ // Sets digital pins to transfer data to Atari joystick ports(PORTA) // When digital port high, joystick pin shorted to ground or logic 0 if (byteToMap & B00000001){digitalWrite(porta0,LOW);} else {digitalWrite(porta0,HIGH);} if (byteToMap & B00000010){digitalWrite(porta1,LOW);} else {digitalWrite(porta1,HIGH);} if (byteToMap & B00000100){digitalWrite(porta2,LOW);} else {digitalWrite(porta2,HIGH);} if (byteToMap & B00001000){digitalWrite(porta3,LOW);} else {digitalWrite(porta3,HIGH);} if (byteToMap & B00010000){digitalWrite(porta4,LOW);} else {digitalWrite(porta4,HIGH);} if (byteToMap & B00100000){digitalWrite(porta5,LOW);} else {digitalWrite(porta5,HIGH);} if (byteToMap & B01000000){digitalWrite(porta6,LOW);} else {digitalWrite(porta6,HIGH);} if (byteToMap & B10000000){digitalWrite(porta7,LOW);} else {digitalWrite(porta7,HIGH);} } void setup() { pinMode(porta0,OUTPUT); pinMode(porta1,OUTPUT); pinMode(porta2,OUTPUT); pinMode(porta3,OUTPUT); pinMode(porta4,OUTPUT); pinMode(porta5,OUTPUT); pinMode(porta6,OUTPUT); pinMode(porta7,OUTPUT); pinMode(DSR,OUTPUT); pinMode(DTR,INPUT); Serial.begin(31250); setPorta(zero);// digitalWrite(DSR,HIGH); } void loop() { //read data until its a Midi command //command bytes will have bit 7 true while (midiCommand < 128){ while(Serial.available()<1){}//wait for data midiCommand = Serial.read(); //read MIDI stream } // get data required by command. // volume - make sure it is an incremental change // midiCommand = 0 if not valid or redundant - do not send // patch - should be >6 switch(midiCommand){ case 208:// Breath controller while(Serial.available()<1){} volume = Serial.read(); if(volume != 0){volume = map(volume,1,127,1,15);} if(volume == lastVolume){midiCommand = 0;} break; case 144:// NoteOn command while(Serial.available()<1){} midiNoteNum = Serial.read(); while(Serial.available()<1){} volume = Serial.read(); if(volume != 0){volume = map(volume,1,127,1,15);} if((volume == 0) && (midiNoteNum != lastMidiNoteNum)){midiCommand = 0;} break; case 192: //Patch change while(Serial.available()<1){} patch = Serial.read(); if (patch >5){midiCommand = 0;} break; case 176: //control change (65=portemento) 0 off,127 on while(Serial.available()<1){} controlChange = Serial.read(); if (controlChange == 65){ while(Serial.available()<1){} portemento = Serial.read(); if (portemento >0){portemento = 1;} //1 = on break; } else {midiCommand = 0; break; } default: //if not a DH-100 command ignore midiCommand = 0; break; } // //combine data and send if command <> 0 if (midiCommand != 0){ switch(midiCommand){ case 208: //breath controller dataByte = midiCommand + volume; sendByte(dataByte); lastVolume = volume; break; case 192: dataByte = midiCommand + patch; sendByte(dataByte); break; case 176: dataByte = midiCommand + portemento; sendByte(dataByte); break; case 144: dataByte = midiCommand + volume; sendByte(dataByte); lastVolume = volume; sendByte(midiNoteNum); lastMidiNoteNum = midiNoteNum; break; } } midiCommand = 0; } A8 - Frequency tables De Re Atari has a chapter on sound that is quite interesting. Seems that SOUND 1 and SOUND 2 can be combined to improve pitch control. Then I found the article "Perfect Pitch" by Fred Coffey in COMPUTE!'S SECOND BOOK OF ATARI. It provided the information and formulas to convert frequency data to the equivalent 16 bit numbers needed to produce those numbers and it seemed to make the whole process easy. A utility program has been written to produce the DATA statements for a 108 X 3 array. The MIDI note number from the Arduino can be used to index into the array and then the 16 bit number (to be used for portomento calculations), high byte, and low bit can be accessed for use. This program should make it easy to modify the data statements if changes are to be made. Who knows, maybe the need will arise when they are required in MAC/65 format. The frequency data came from a keyboard chart. <http://newt.phys.unsw.edu.au/jw/notes.html> Line 20 needs to be changed when the DATA statements are to be listed to disk. Then they can be ENTERed into a program. Typing the Frequency DATA once was enough for me. 10 LINE=5000:REM LINE NUMBER 20 OPEN #1,8,0,"S:":REM "D:FTABLE.BTX" 30 ? #1;"4999 REM FREQUENCY FOR MIDINOTE 21-108(NOTE A0 TO C8)" 40 TRAP 300 50 ? #1;LINE;" ";"DATA "; 60 FOR X=1 TO 5 90 READ PITCH 100 P2=INT((1789790/(2*PITCH)-7)/256) 110 P1=INT(1789790/(2*PITCH)-7-256*P2+0.5) 115 P0=P2*256+P1 117 REM 2 BYTE, HI BYTE, LO BYTE 120 ? #1;P0;",";P2;",";P1; 125 IF X<5 THEN ? #1;","; 130 NEXT X 140 ? #1 150 LINE=LINE+10 160 GOTO 50 300 ? #1;-1:CLOSE #1:END 490 REM FREQUENCY FOR MIDINOTE 21-108(NOTE A0 TO C8) 500 DATA 27.5,29.135,30.868,32.703,34.648,36.708,38.891,41.203,43.654,46.249,48.999,51.913 510 DATA 55,58.270,61.735,65.406,69.296,73.416,77.782,82.407,87.307,92.499,97.999,103.83 520 DATA 110,116.54,123.47,130.81,138.59,146.83,155.56,164.81,174.61,185,196,207.65 530 DATA 220,233.08,246.94,261.63,277.18,293.67,311.13,329.63,349.23,369.99,392,415.30 540 DATA 440,466.16,493.88,523.25,554.37,587.33,622.25,659.26,698.46,739.99,783.99,830.61 550 DATA 880,932.33,987.77,1046.5,1108.7,1174.7,1244.5,1318.5,1396.9,1480,1568,1661.2 560 DATA 1760,1864.7,1975.5,2093.0,2217.5,2349.3,2489,2637,2793,2960,3136,3322.4 570 DATA 3520,3729.3,3951.1,4186
  18. I was going to start writing my list of resolutions for 2018. Then I thought about writing about what I didn't accomplish in 2017. Then I decided to just work on programing the interface and get the Atari to read and print the MIDI data stream through the joystick port. I had high hopes of creating a midi monitor that would accept the data and print out the commands as they were received but all that extra code was getting in the way of finding errors. I was happy when I got the Atari8 and Arduino to just reliably print the correct bytes. A SIO cable was to be modified because the SIO2PC dead-ends the SIO chain. I just attached jumper wires with female ends to the 4th and 8th pins on a standard cable. Saved me a lot of plugging and unplugging. I wasn't looking forward to programming the Arduino and Atari 8 because trouble shooting was going to be a painful endeavor. Was it the interface hardware, the Arduino program or the Atari8 program that is the problem. Yes, I had problems with all three and even created more. The Arduino Program. The Arduino performs the following steps. 1. Reads the midi data stream and puts it into a buffer. Continuously. 2. Gets a bit from the buffer. FIFO 3. Sets control pins for the 8 joystick pins 4. Sets trigger to signal that data is ready to be read 5. Waits for Atari to signal it got the data 6. Sets the trigger to signal data not ready 7. Waits for Atari to signal reset the process to step 2. Its simple, when you remember that the logic from the Arduino is inverted. When a pin on the Arduino is set high the transistor in the optocoupler turns on, shorting the pin to ground. Thus making the logic level, read by the Atari, LOW. /* Midi data transfer test 12/2017 * * This program reads midi data then ouputs * the data to the Atari Joystick ports. * * The use of the control lines to the Atari Trigger * and from the cassette motor control line on the SIO * port are used for data flow control. * */ // Atari PORTA(54016) mapped to pins on arduino int porta0 = 4; int porta1 = 5; int porta2 = 6; int porta3 = 7; int porta4 = 8; int porta5 = 9; int porta6 = 10; int porta7 = 11; int DSR = 3; //data set ready int DTR = 12;//Atari ready byte zero = 0; byte tempX = 0; int midiData = 0; //Function to Send a byte to the atari and void sendByte(byte byteToSend){ setPorta(byteToSend); digitalWrite(DSR,LOW); //data ready-Trigger 0 while(digitalRead(DTR) == LOW){} //Wait for Atari to get byte cmc goes low digitalWrite(DSR,HIGH); //data not ready-trigger 1 while(digitalRead(DTR) == HIGH){} //wait for Atari to signal ok to get next byte } void setPorta(byte byteToMap){ // Sets digital pins to transfer data to Atari joystick ports(PORTA) // When digital port high, joystick pin shorted to ground or logic 0 if (byteToMap & B00000001){digitalWrite(porta0,LOW);} else {digitalWrite(porta0,HIGH);} if (byteToMap & B00000010){digitalWrite(porta1,LOW);} else {digitalWrite(porta1,HIGH);} if (byteToMap & B00000100){digitalWrite(porta2,LOW);} else {digitalWrite(porta2,HIGH);} if (byteToMap & B00001000){digitalWrite(porta3,LOW);} else {digitalWrite(porta3,HIGH);} if (byteToMap & B00010000){digitalWrite(porta4,LOW);} else {digitalWrite(porta4,HIGH);} if (byteToMap & B00100000){digitalWrite(porta5,LOW);} else {digitalWrite(porta5,HIGH);} if (byteToMap & B01000000){digitalWrite(porta6,LOW);} else {digitalWrite(porta6,HIGH);} if (byteToMap & B10000000){digitalWrite(porta7,LOW);} else {digitalWrite(porta7,HIGH);} } void setup() { pinMode(porta0,OUTPUT); pinMode(porta1,OUTPUT); pinMode(porta2,OUTPUT); pinMode(porta3,OUTPUT); pinMode(porta4,OUTPUT); pinMode(porta5,OUTPUT); pinMode(porta6,OUTPUT); pinMode(porta7,OUTPUT); pinMode(DSR,OUTPUT); pinMode(DTR,INPUT); Serial.begin(31250); setPorta(zero);// digitalWrite(DSR,HIGH); } void loop() { if (Serial.available()>0){ midiData = Serial.read(); //read MIDI stream tempX = byte(midiData); sendByte(tempX); //Send to Atari } } The Atari Program When the Atari wants data it checks the trigger button to see if there is any to read. If not, this program simply waits for one to show up. 10 GOSUB 29000:REM SET UP VARIABLES 15 POKE PACTL,CMCOFF:REM CAS.OFF 20 IF STRIG(0)=0 THEN GOTO 20:REM WAIT ARDUINO TO SIGNAL DATA READY 30 MIDIDATA=PEEK(PORTA):REM READ 35 ? MIDIDATA;" ";:SOUND 0,200,15,15:SOUND 0,0,0,0:REM SHOW DATA ON SCREEN 40 POKE PACTL,CMCON:REM GOT DATA 60 IF STRIG(0)=1 THEN GOTO 60:REM ARDUINO BUSY GETTING DATA 70 POKE PACTL,CMCOFF:REM TELL ARDUINO TO HOLD DATA UNTILL READY 80 GOTO 20:REM GO WAIT FOR NEXT BYTE TO BE READY 29000 PORTA=54016:REM STICK 0 AND 1 29020 PACTL=54018:REM PORTA CONTROL 29030 CMCON=52:REM CASSETTE MOTOR ON 29040 CMCOFF=60:REM CAS. MOTOR OFF 29050 REM POKE 559,0:REM TRUN OFF SCREEN 29100 RETURN A Casio Keyboard was attached to the interface and data was sent to the Atari and dumped on the screen. The following screen shot shows three 255s that were produced when the Arduino was turned on and the reset button was pushed twice. Then anytime a key was pressed or released a NOTE ON command on channel 0 (144) was sent. You see the 144 then the MIDI key number and then the volume setting. If a volume setting was 0 the key was released. The keyboard is not pressure sensitive so its volume defaults to 100. I didn't see any data being missed by the Atari but it was so slow. I mean, it make 300 baud seem fast. I mean, it was so slow that I tried to turn off the display. I mean, it was soooooo slooooooow that I thought I would have to get out the M65 cartridge. Instead, the program was compiled using the MMG Compiler. The speed improvement was remarkable. I couldn't get the buffer to over flow even when a bunch of keys were pressed and released. Since the digital horn is monophonic, its data output should be manageable even when it is transmitting the breath pressure(after touch) data. I also took the time to load the compiled program onto a Max Flash cartridge. Easily running these programs on computers with out a monitor and disk drive will simplify the hardware setup significantly. There was a problem when the Arduino was powered up, all the joystick pins were reading LOW. This confused the Max Flash menu and the program didn't load when the return was pressed. Pressing the Reset button on the Arduino resets the pins until they are turned off again by void Setup() function and hitting the return key on the Atari before that happens will run the program. Now on to writing the program that actually makes some noise and maybe a little music.
  19. Between the time that the Casio DH-100 Digital Horn was introduced and todays prices on eBay, the price dropped to the point where it seemed to be a bargain. I was fortunate enough to have pulled the batteries (15 years ago), so there was a good chance that it would still work. Now I want to build an Atari8 sound module to accept MIDI information from the DH-100's MIDI port(or any MIDI controller). The MIDI Implementation chart for the DH-100 is not extensive but the streaming of the channel pressure data could easily overwhelm the system. I'm going to attempt to do this in Atari BASIC to facilitate experimentation. The plan is to increase the data transfer rate from the MIDI-Arduino interface to the computer by using the cassette motor pin on the SIO port to set up feed back to the Arduino. The Trigger can indicate DataSetReady and cassette motor control for DataTerminalReady thus eliminate the use of delay loops for transfer timing. My previous Atari BASIC MIDI programs have been kept very simple; mostly NOTE ON and NOTE OFF. The MIDI Implementation Chart shows 4 midi commands that can be sent from the DH-100 to control the sound. A closer look at the horn and chart should help define the program requirements for the A8. CASIO DH-100 Call it a digital horn, wind controller, or breath controller, the DH-100 works like a wind instrument. Press some keys to change the pitch and blow into the mouth piece. The harder you blow the louder the sound. On its own as a performance instrument, the internal speaker and sound synthesizer made it sound like an expensive toy. The sounds could get annoying after about 10 min. of play. (A personal observation.) The MIDI OUT port was its redeeming feature. Use it as a MIDI controller on a $500 MIDI synth and it sounded like a $500 instrument. But that's not what I want to do. I want the output for the DH-100 to control a Atari8 programed to be the sound synthesizer. Then it will sound a little POKEY. (The DH-100 has a tendency to develop a squeal(audio feedback loop). This is generally caused by 2 capacitors that can be replaced. It happened to my horn. Even though the internal sounds were useless, the MIDI output still worked. I turned down the volume and played the synth. Eventually I found the information on which capacitors to change and how. The original sound is restored. Sorry, that was a couple of years ago and the link to the information has been lost.) The horn was hooked up to the MIDI monitor to view the data stream. This information will be of value when the Arduino and Atari are programmed. These are my observations while testing the switches and buttons. Casio DH-100 MIDI Implimentation Chart.pdf Breath - off: This allows the playing of the horn without having to blow into it. Press the note keys and the sound will be produced. Press sends a NOTE ON at velocity 64, Release sends a NOTE ON at zero velocity. Breath - on: Press the note keys and then blow into the mouthpiece. A NOTE ON will be sent with a velocity proportional to the force of your exhale. Stop blowing and a NOTE ON at 0 velocity will be sent. While the note is on, the pressure sensor in the horn monitors the air pressure and sends out velocity(or after touch) whenever there is a change. Command 192+channel#, pressure from 1-127. Its difficult to maintain a constant air pressure. Transpose Button - Press the button and the note number being sent by the horn is increased by one note number. This continues up until an octave is reached, then drops 2 octaves. Keep pressing and you end up where you started. The note number is changes by the DH-100, no MIDI data is sent. Tone Selector - cycles the tone from 0 to 5. When this is pressed a PROGRAM CHANGE command is sent. Command 192+channel#,nnnn(0-5). Portamento - When pressed, notes will slide from one to the next. It uses a CONTROL CHANGE command and is controller number 65. Release the key to turn it off. The command is 176+channel#, controller #, value. Value is 0 for off and 127 for on. The command is sent only when the status has changed. That completes the tour of the MIDI Implementation Chart. I noted that there may be a typo at the Note Number - Transmitted numbers cell. The range has to be greater then 36-39. The note numbers may have to be manipulated to stay within the range that the Atari can produce. I'll deal with that at a later date.
  20. Old version MT-32, working & complete (with extra power adapter - lower profile & reduced heat generation.) Quite a few vintage games take advantage of bugs in the old version OS and don't sound correct on later models. Games designed specifically for the MT-32 are available for the Atari ST, Amiga, PC, MSX, NEC PC 98x1, & Sharp X68000 computers. Unit is complete with original power adapter, smaller profile power adapter, & MIDI cable. Asking $175 + shipping & PP fees. SOLD Based on sold listings at the bay (a little below over all average.)
  21. I am a complete newb on the sound capabilities of the ST and was curious about how they worked exactly. So is it something like this: -Keyboard/Synthesizer plugged into MIDI in port -Music sequencer software such as Cubase/Notator runs on ST, allows user to compose tracks -Midi-out runs to recording equipment? Was this how this was used or? What made having the MIDI so special back in the day?
  22. I finally got around to hooking my ST up to this old CASIO digital piano. The mount was made of scrap parts (brackets were from a rack mount network switch at the back, steel rod from a laser printer at the front), and slots in place of the music stand. It passed the cat stability tests too. MIDI cables are the high grade audiophile ones with ferrite beads (also known as ones that I soldered up from scrap DVI cables and cut down 8 pin DIN plugs).
  • Create New...