Notice. New forum software under development. It's going to miss a few functions and look a bit ugly for a while, but I'm working on it full time now as the old forum was too unstable. Couple days, all good. If you notice any issues, please contact me.
|
Forum Index : Microcontroller and PC projects : Soundprogramm on the CMM2 Project. JOIN ?
Author | Message | ||||
TweakerRay Senior Member Joined: 01/08/2020 Location: GermanyPosts: 138 |
Hi ! I am a beginner in this so it might be to much but maybe here are cool guys to join in. I am searching for people who like to help me programm a chiptunish synth on the CMM2 Here's my Idea... I would love to programm some musicprogramms on the CMM2. I already started yesterday a little programm but its far away from what I have in mind. I want to use the keyboard as a pianokey and you can press keys and it plays the notes. The keys QWERTZUIOP are the white keys and 23 567 0ß ate the black keys. (Something like that) First step is archieved ! I set up a field with all the 88 notes frequencies and I can play them in the programm (I will link the programm below...) if you press + and - you can change oktaves. (Still have to limit that so it does not go below ot to high of the frequency range) And if you press a,s,d you change the sound from sine to sqare and noise The problem is I can't archieve that when I press a note and hold it that the sound continues to play that note... It always seems that it will be triggered again... I know there are "keydown" command and also inkey$ Maybe someone has a good idea how i can check if a note is pressed and still on hold. So If you want to join this project please contact me here and then we could look how we can pull this off... Next step also would be that you could play chords... at least with 4 notes (because as I understood you have 4 channels...) My progrogramm shall work a little like CYNTHCART on the C-64 Maybe we can have a small Chiptunish programm where you can play that ? It would be cool to have someone help me, because I know I am a beginner and can't pull this off without help. But I am a musician ;-) So I can maybe help with other stuff... So if you want to join: Comment below: Thanks a lot ! Here is the programm so far to download: Soundprg01.zip And here the CODE: cls fc=1: bc=9 : rem Color 1-15 volume=12 : rem Volume 1-25 Flag=0: s=1: rem sound 1=square 2=sine 3= noise okt=0 : rem oktave to zero dim freq(88), ta$(88) Print "Felder Dimensioniert" freq(01)=27.5000 : freq(11)=48.9995 : freq(21)=87.3071 : freq(31)=155.563 freq(02)=29.1353 : freq(12)=51.9130 : freq(22)=92.4986 : freq(32)=164.814 freq(03)=30.8677 : freq(13)=55.0000 : freq(23)=97.9989 : freq(33)=174.614 freq(04)=32.7032 : freq(14)=58.2705 : freq(24)=103.826 : freq(34)=184.997 freq(05)=34.6479 : freq(15)=61.7354 : freq(25)=110.000 : freq(35)=195.998 freq(06)=36.7081 : freq(16)=65.4064 : freq(26)=116.541 : freq(36)=207.652 freq(07)=38.8909 : freq(17)=69.2957 : freq(27)=123.471 : freq(37)=220.000 freq(08)=41.2035 : freq(18)=73.4162 : freq(28)=130.813 : freq(38)=233.082 freq(09)=43.6536 : freq(19)=77.7817 : freq(29)=138.591 : freq(39)=246.942 freq(10)=46.2493 : freq(20)=82.4069 : freq(30)=146.832 : freq(40)=261.626 freq(41)=277.183 : freq(51)=493.883 : freq(61)=880.000 : freq(71)=1567.98 freq(42)=293.665 : freq(52)=523.251 : freq(62)=932.328 : freq(72)=1661.22 freq(43)=311.127 : freq(53)=554.365 : freq(63)=987.767 : freq(73)=1760.00 freq(44)=329.628 : freq(54)=587.330 : freq(64)=1046.50 : freq(74)=1864.66 freq(45)=349.228 : freq(55)=622.254 : freq(65)=1108.73 : freq(75)=1975.53 freq(46)=369.994 : freq(56)=659.255 : freq(66)=1174.66 : freq(76)=2093.00 freq(47)=391.995 : freq(57)=698.456 : freq(67)=1244.51 : freq(77)=2217.46 freq(48)=415.305 : freq(58)=739.989 : freq(68)=1318.51 : freq(78)=2349.32 freq(49)=440.000 : freq(59)=783.991 : freq(69)=1396.91 : freq(79)=2489.02 freq(50)=466.164 : freq(60)=830.609 : freq(70)=1479.98 : freq(80)=2637.02 freq(81)=2793.83 freq(82)=2959.96 freq(83)=3135.96 freq(84)=3322.44 freq(85)=3520.00 freq(86)=3729.31 freq(87)=3951.07 freq(88)=4186.01 ta$(28)="q" ta$(29)="2" ta$(30)="w" ta$(31)="3" ta$(32)="e" ta$(33)="r" ta$(34)="5" ta$(35)="t" ta$(36)="6" ta$(37)="z" ta$(38)="7" ta$(39)="u" ta$(40)="i" ta$(41)="9" ta$(42)="o" ta$(43)="0" ta$(44)="p" ?"start" DO Keyboardtaste: tpress$=inkey$: Print @(10,40);"Taste:";tpress$ Print @(10,80);"Buffer:";buffer$ print @(140,40);"Flag:";Flag Print @(140,80);"Keydown:";kdn print @(10,120);"Frequency";freq(tnr) Print @(140,120);" ";tdn if tpress$="" and flag=0 then Play Stop: goto Keyboardtaste if tpress$="" and flag=1 then goto Soundausgabe if tpress$<>"" and flag=1 then goto Checktaste Checktaste: if tpress$="q" then tnr=28+okt if tpress$="2" then tnr=29+okt if tpress$="w" then tnr=30+okt if tpress$="3" then tnr=31+okt if tpress$="e" then tnr=32+okt if tpress$="r" then tnr=33+okt if tpress$="5" then tnr=34+okt if tpress$="t" then tnr=35+okt if tpress$="6" then tnr=36+okt if tpress$="z" then tnr=37+okt if tpress$="7" then tnr=38+okt if tpress$="u" then tnr=39+okt if tpress$="i" then tnr=40+okt if tpress$="9" then tnr=41+okt if tpress$="o" then tnr=42+okt if tpress$="0" then tnr=43+okt if tpress$="p" then tnr=44+okt if tpress$="+" then okt=okt+12: if tpress$="-" then okt=okt-12: if tpress$="a" then s=2 if tpress$="s" then s=1 if tpress$="d" then s=3 buffer$=tpress$ Soundausgabe: If s=1 then Play Sound 1,B,Q,freq(tnr),volume if s=2 then play Sound 1,B,S,freq(tnr),volume if s=3 then play sound 1,B,N,freq(tnr),volume pause 100 If Keydown(0)>0 then Flag=1:kdn=keydown(0) If Keydown(0)=0 and buffer$<>"" then Flag=0: kdn=keydown(0) LOOP http://tweakerray.bandcamp.com |
||||
matherp Guru Joined: 11/12/2012 Location: United KingdomPosts: 9386 |
Have a look at the attached. Hopefully this should give you the idea for one way of how to do what you want and achieve 4 note polyphony. Think of the pressed array as representing your 4 sound channels. The all you need to do in the main loop is to make a decision whether a channel is the same as last time. If it is do nothing, if it isn't start or stop the channel as appropriate option explicit option default integer dim pressed(3) settick 25,keyint dim i do for i=0 to 3 if pressed(i) then text i*mm.info(fontwidth),10, chr$(pressed(i)) else text i*mm.info(fontwidth),10, chr$(32) endif next i loop 'routine to monitor keypresses and maintain a list of up to 'four that are pressed at any one time sub keyint local i,j local clearkey local keys(7) ' take a local copy of the keydown function for i=0 to 4 keys(i)=keydown(i) next i if keys(0) > 4 then keys(0)=4 'limit of 4 keys can be pressed ' first clear any keys that were pressed that are no longer for i=0 to 3 clearkey=1 if pressed(i) then for j=1 to keys(0) if keys(j)=pressed(i) then clearkey=0 'still pressed so don't clear keys(j)=0 'remove the key so it isn't used as a new press endif next j endif if clearkey then pressed(i)=0 endif next i ' now establish if there are any new key pressed for i=0 to 3 if pressed(i) then continue for 'slot already used for j=1 to keys(0) if keys(j) then pressed(i)=keys(j) keys(j)=0 'make sure a key isn't processed twice endif next j next i end sub |
||||
TweakerRay Senior Member Joined: 01/08/2020 Location: GermanyPosts: 138 |
@ matherp: Thank you very much... This code looks very complex and complicated to me. does this work as its own programm ? So I can try and check what it does ? I have no clue how to implement this into my code... since this is too complex for my musical brain ;-) A lot of commands are still unknown to me and I have to read the manual what they do... I am sorry if you did so much work and I am simply just learning to understand. I will try to check this programm out and try to learn how it works... but its really very complex to me... sorry beginner... try to think of me as the 10 ?"Hallo"; 20 goto 10 guy ;-) Thats my level... I know a few things about fields and variables and input and stuff but not all the complex stuff you use... I hope I am soon able to understand. Thanks for your help Greets TweakerRay http://tweakerray.bandcamp.com |
||||
Womble Senior Member Joined: 09/07/2020 Location: United KingdomPosts: 267 |
Couple of hints regarding (matherp) Peter's program listing above ... 1. Is an interrupt driven program reading up to four simultaneous keypresses and displaying the character pressed on screen. 2. It does not produce any sound (yet). You would have to add your own "noise" code. 3. It prints out the contents of the pressed array (elements 0, 1 ,2 ,3) in a continuous loop. 4. If there is no character in an array element, then it prints a space. 5. The main loop continues processing the array forever, use CTRL+C to exit. 6. Meanwhile the interrupt subroutine triggers every 25ms and stuffs up to 4 pressed key characters into the array. 7. The interrupt subroutine also checks to see if a key is still pressed compared to the last time it was run, or there has been a change in the number of keys or which keys are pressed currently. Based on these tests it fills the array. Now you have some idea of what Peter's program is doing, in beginners terms, you should probably go through the code statement by statement and in conjunction with the manuals it should become clearer how the program does what it does. Also, I assume you have a copy of Programming with the Colour Maximite 2 A tutorial covering the Colour Maximite 2 and programming in the BASIC language. If not I suggest that this is a good place to get started Hope that helps. Womble |
||||
capsikin Guru Joined: 30/06/2020 Location: AustraliaPosts: 341 |
I didn't get very good results using inkey$, so I made a new function based on keydown. Have a look at this, there's just a few changes from your program and continuous sound plays properly. Main changes: new function "newinkey$" based on keydown function. variable "samesound" to keep track if it's playing the same sound. Removed some parts that were replaced by these. cls fc=1: bc=9 : rem Color 1-15 volume=12 : rem Volume 1-25 Flag=0: s=1: rem sound 1=square 2=sine 3= noise okt=0 : rem oktave to zero dim freq(88), ta$(88) Print "Felder Dimensioniert" freq(01)=27.5000 : freq(11)=48.9995 : freq(21)=87.3071 : freq(31)=155.563 freq(02)=29.1353 : freq(12)=51.9130 : freq(22)=92.4986 : freq(32)=164.814 freq(03)=30.8677 : freq(13)=55.0000 : freq(23)=97.9989 : freq(33)=174.614 freq(04)=32.7032 : freq(14)=58.2705 : freq(24)=103.826 : freq(34)=184.997 freq(05)=34.6479 : freq(15)=61.7354 : freq(25)=110.000 : freq(35)=195.998 freq(06)=36.7081 : freq(16)=65.4064 : freq(26)=116.541 : freq(36)=207.652 freq(07)=38.8909 : freq(17)=69.2957 : freq(27)=123.471 : freq(37)=220.000 freq(08)=41.2035 : freq(18)=73.4162 : freq(28)=130.813 : freq(38)=233.082 freq(09)=43.6536 : freq(19)=77.7817 : freq(29)=138.591 : freq(39)=246.942 freq(10)=46.2493 : freq(20)=82.4069 : freq(30)=146.832 : freq(40)=261.626 freq(41)=277.183 : freq(51)=493.883 : freq(61)=880.000 : freq(71)=1567.98 freq(42)=293.665 : freq(52)=523.251 : freq(62)=932.328 : freq(72)=1661.22 freq(43)=311.127 : freq(53)=554.365 : freq(63)=987.767 : freq(73)=1760.00 freq(44)=329.628 : freq(54)=587.330 : freq(64)=1046.50 : freq(74)=1864.66 freq(45)=349.228 : freq(55)=622.254 : freq(65)=1108.73 : freq(75)=1975.53 freq(46)=369.994 : freq(56)=659.255 : freq(66)=1174.66 : freq(76)=2093.00 freq(47)=391.995 : freq(57)=698.456 : freq(67)=1244.51 : freq(77)=2217.46 freq(48)=415.305 : freq(58)=739.989 : freq(68)=1318.51 : freq(78)=2349.32 freq(49)=440.000 : freq(59)=783.991 : freq(69)=1396.91 : freq(79)=2489.02 freq(50)=466.164 : freq(60)=830.609 : freq(70)=1479.98 : freq(80)=2637.02 freq(81)=2793.83 freq(82)=2959.96 freq(83)=3135.96 freq(84)=3322.44 freq(85)=3520.00 freq(86)=3729.31 freq(87)=3951.07 freq(88)=4186.01 ta$(28)="q" ta$(29)="2" ta$(30)="w" ta$(31)="3" ta$(32)="e" ta$(33)="r" ta$(34)="5" ta$(35)="t" ta$(36)="6" ta$(37)="z" ta$(38)="7" ta$(39)="u" ta$(40)="i" ta$(41)="9" ta$(42)="o" ta$(43)="0" ta$(44)="p" ?"start" 'function like inkey$, but returns the key as long as it's 'pressed, instead of just once. function newinkey$() 'check if key is pressed. if keydown(0)=0 then 'if no, return empty string newinkey$="" else 'if yes, convert from number to character string. newinkey$=chr$(keydown(1)) end if end function DO Keyboardtaste: tpress$=newinkey$(): Print @(10,40);"Taste:";tpress$;" " Print @(10,80);"Buffer:";buffer$;" " Print @(140,80);"Keydown:";kdn print @(10,120);"Frequency";freq(tnr);" " Print @(140,120);" ";tdn if tpress$="" then buffer$="" : Play Stop : goto Keyboardtaste if tpress$<>"" then goto Checktaste Checktaste: if tpress$="q" then tnr=28+okt if tpress$="2" then tnr=29+okt if tpress$="w" then tnr=30+okt if tpress$="3" then tnr=31+okt if tpress$="e" then tnr=32+okt if tpress$="r" then tnr=33+okt if tpress$="5" then tnr=34+okt if tpress$="t" then tnr=35+okt if tpress$="6" then tnr=36+okt if tpress$="z" then tnr=37+okt if tpress$="7" then tnr=38+okt if tpress$="u" then tnr=39+okt if tpress$="i" then tnr=40+okt if tpress$="9" then tnr=41+okt if tpress$="o" then tnr=42+okt if tpress$="0" then tnr=43+okt if tpress$="p" then tnr=44+okt if tpress$="+" then okt=okt+12: if tpress$="-" then okt=okt-12: if tpress$="a" then s=2 if tpress$="s" then s=1 if tpress$="d" then s=3 'Check if the same key is pressed, which means the sound is already playing if buffer$=tpress$ then samesound=1 else samesound=0 buffer$=tpress$ Soundausgabe: 'only use Play Sound command if it's not already playing the right one. if not samesound then If s=1 then Play Sound 1,B,Q,freq(tnr),volume if s=2 then play Sound 1,B,S,freq(tnr),volume if s=3 then play sound 1,B,N,freq(tnr),volume end if pause 100 kdn=keydown(0) LOOP Edited 2020-08-15 13:43 by capsikin |
||||
TweakerRay Senior Member Joined: 01/08/2020 Location: GermanyPosts: 138 |
@capsikin thats really aweseom ! I tried your new code and its much much better... I also limited the oktaving (so it does not go out of the frequency range if you press + and - Problem is if you press that key it only should lower or add the 12 halfnotes to the original note. In best case you can hold 1 note and if you press + it just skippes to the 12 halftones higher note... at the moment you hear the same note you played. I will try to work on that... mayb I have an idea. But for now Thanks so much for the cool help ! It's so much better now !!!! Thank you !!! Cheers TweakerRay http://tweakerray.bandcamp.com |
||||
capsikin Guru Joined: 30/06/2020 Location: AustraliaPosts: 341 |
That's great. I think I know why I hadn't been able to do what I was trying to do with using inkey$ as well as keydown: from the manual: "Using [keydown] function will clear the console input buffer." So inkey$ won't show any keyboard presses that happened before the previous keydown. Good idea, I only just noticed now with the version I posted, that if you hold + or - it will quickly jump two or more octaves - it doesn't check to only work on a new keypress, like it does with PLAY SOUND. You could try different numbers with the noise sound though, it doesn't use frequency in the same way. Numbers from 1 (higher frequency) to around 100 (lower frequency) seem good. Cheers, good luck. |
||||
capsikin Guru Joined: 30/06/2020 Location: AustraliaPosts: 341 |
Did you have any of the fixes available to post? Either the limiting octaves, or others you were considering? |
||||
TweakerRay Senior Member Joined: 01/08/2020 Location: GermanyPosts: 138 |
Hi @Capsikin... not yet... I was programming my chiptune drumsynth which now got really complex and cool ... you can store 16 patterns now to sd card and reload them each stepinformation has now (Step on/off / Volume / Pitch ) Information and you can do randomize patterns in volume and steps... So check that out... https://www.thebackshed.com/forum/uploads/TweakerRay/2020-08-31_072749_Drummachinev5.zip The Drumsynth is on Version 5 right now... I think a next step could be some kind of songmode... where you simply chain patterns together so that it plays the 16 memorypatterns in any order... but check the programm how it is right now. The Soundprogramm here with the musical keyboard is a little bit more complex because I still have to learn how to do that multiple keys would be pressed etc... I would love to have some kind of help... since I am a musician and this mmbasic is still all fresh to me how things are working... Here is the programm how it is right now: Soundprg01a.zip http://tweakerray.bandcamp.com |
||||
Daren Newbie Joined: 05/08/2020 Location: United KingdomPosts: 25 |
Midi would be great, although probably quite complicated, would probably need some kind of buffer to handle notes being pressed/released. I think you are making great progress TweakerRay, like you I’m a musician not a coder and I have not made anywhere near as much progress as you have, so kudos and keep going! I ordered my CMM2 a while back when I had a bit of free time, unfortunately it arrived a number of weeks later when I had no free time, so as such I have not done much with mine yet. |
||||
capsikin Guru Joined: 30/06/2020 Location: AustraliaPosts: 341 |
I may not be able to contribute very often, but I wrote some key routines that may help. It keeps track of which keys are held down, and which keys are newly pressed. The code I wrote for the keyboard. You call scankeys to update the records of which keys are currently pressed and which of them are new. Then you can call iskeypressed to check if a key is currently pressed down. Or use keys() and keys.count to get a list of which are currently pressed down. keys.count says how many. keys() has a list of which keys they are. keys.new() is a list of flags saying if the key is newly pressed. ischrpressed is similar to iskeypressed but works with a character instead of ascii code. chrdown$ is a function to read the keys() array and convert it into a character. I'm not sure, you might need more explanation. I've added it to the program, and fixed the octave problem by only changing the octave when + or - is newly pressed. The keyboard routines support multiple keys pressed, but the program will need more changes to make use of that. (edit: partly fixed. you still can't change octaves while pressing another key yet) mod of Soundprg01a copy.bas.zip here are the keyboard routines: ''''''''''''''''''''''''''' ''' code to handle keys ''' ''''''''''''''''''''''''''' dim keys.count dim keys(6) dim keys.new(6) sub scankeys local oldkeys(6) local i,j 'update key count, saving old value local oldkeys.count=keys.count keys.count=keydown(0) 'update list of keys down, saving old values. for i=1 to 6 oldkeys(i)=keys(i) keys(i)=keydown(i) next i for i=1 to keys.count 'the key is a new keypress unless we find it was already pressed. keys.new(i)=1 'check if key(i) was already pressed for j=1 to oldkeys.count if keys(i) = oldkeys(j) then keys.new(i)=0 end if next next end sub function iskeypressed(k) local n for n=1 to keys.count if keys(n) = k then iskeypressed=1 exit function end if next n 'if we got all the way through the loops without 'finding it and exiting, then it's not pressed iskeypressed=0 end function function ischrpressed(c$) ischrpressed=iskeypressed(asc(c$)) end function function chrdown$(i) chrdown$=chr$(keys(i)) end function and here are some short examples of using them (though I didn't test them all) sub demo1 do scankeys if ischrpressed(" ") then print "space" else print "no space" end if loop end sub sub demo2 do pause 100 scankeys Print "pressed: "; for n=1 to keys.count print chrdown$(n);" "; next n loop end sub sub demo3 do pause 100 scankeys for n=1 to keys.count if keys.new(n) then print chrdown$(n);" "; next n loop end sub Edited 2020-09-02 12:59 by capsikin |
||||
TweakerRay Senior Member Joined: 01/08/2020 Location: GermanyPosts: 138 |
Hi @ capsikin ! I have also worked on the programm ... so maybe you like to check this out... I called it now Mr. Monosynht ;-) Right now it plays all 4 channels and you can detune them and change octaves... you can also change the sound... this is all just me experimenting... IF you like Maybe we can go from this version of the programm and add also multikeysupport ? So that you can also press one key to make this one play 4 different keys at the same time ? so you can play chords ? I have added the option for people in the US where the Y and Z and changed. so you press "ESC" then it changes fomr DE Layout to US Layout (just the Y and Z echanges) I have made a small intro screen with all keys used... I am too stupid for multikeypress right now so IF someone will add this feature it would be very much appreciated... I can't use any short snippets of code because I don't know how it works... it has to be written into this programm... So if you like to work on this please feel free to add this feature. @Daren - Midi is out of the question for me... I am no pro programmer so that will also not work with this machine as the sound capebilitys are very limited... At least I have no clue how to make better sound on this as a simple square and sinewave... It's not a sid chip ;-) Mr-Monosynth.zip Maybe someone can help with the multikey feature so you can play chords. also if you detune or change oktaves you hear a sound - It would be cool if you could hold a key and change the octaves while pressing a key but like i said - I am too stupid for that feature... I also work on the small chipdrumsynth and that programm is even more complicated ;-) I have added a few new features on that programm like you can now edit the length of the note in the step... and also now frquency randomization for the drumlanes... But the more I programm into it the more I also get a delay from all the checking and what not ... so the timing is slightly off... I tried to compansate with short miliseconds delaytime but the timing on the CMM2 isn't the greatest ... I think it sometimes also runs faster or slower depending how the machine feels ... So it's far away from a rock solid timing... It works for me but its far away from a solid precize timing... But you will see that when I upload the new version of that drumsynth ;-) This here is all about Mr. MONOSYNTH ;-) Or maybe soon Mr. POLYSYNTH ... http://tweakerray.bandcamp.com |
||||
Print this page |