questions concerning the PLAY command

Started by ruthven, February 12, 2009, 08:29 AM

Previous topic - Next topic

0 Members and 1 Guest are viewing this topic.

ruthven

I'm wondering if it is possible to bend the pitch of notes with the PLAY command--for example, to play a frequency between C and C#?

Also, is it possible to sustain a frequency indefinitely using PLAY (I'm not talking about the sustain attribute of ADSR in the envelope, but rather the duration of the note which is normally fixed as a whole, half, quarter, eighth or sixteenth)?  I'm working on a synthesizer program and I want to make it so that a note frequency is held continuously as long as the user holds down a key, stopping only when the user releases the key.

From what I've read, I'm guessing that both of these things will only be possible by programming it with POKEs...(?)

BigDumbDinosaur

QuoteI'm wondering if it is possible to bend the pitch of notes with the PLAY command--for example, to play a frequency between C and C#?

The register values for the musical scale are computed from a look-up table in the BASIC interpreter, which means the pitches are hard coded into the PLAY statement.  You'd have to POKE the relevant values into the SID frequency registers to play quarter tones.

QuoteAlso, is it possible to sustain a frequency indefinitely using PLAY (I'm not talking about the sustain attribute of ADSR in the envelope, but rather the duration of the note which is normally fixed as a whole, half, quarter, eighth or sixteenth)?

Again, that is embedded into the BASIC interpreter.  The PLAY statement was designed to make music-making from BASIC easy for beginning programmers, which means, of course, that more advanced techniques become difficult.

QuoteI'm working on a synthesizer program and I want to make it so that a note frequency is held continuously as long as the user holds down a key, stopping only when the user releases the key.

From what I've read, I'm guessing that both of these things will only be possible by programming it with POKEs...(?)

You're better off doing that sort of thing in machine code.  Even in FAST mode, making music via POKEing is difficult to do well.  To achieve the results that were obtained in a program like SIDPlayer, you need to control numerous variables with reasonably precise timing.  That's tough to do in an interpreted, high level language.  It is essentially impossible to use the advanced SID features like ring modulation and filtering from BASIC, again due to execution speed (a lack of it).

You might be able to play the melody to "Yackety Sax" from BASIC but at a speed so slow it would sound more like "Pomp and Circumstance."
x86?  We ain't got no x86.  We don't need no stinking x86!

ruthven

Yeah, that's pretty much what I figured.  Just wanted to get this confirmed before I attempt getting into the very complicated/convoluted method of programming sound via POKEs.

QuoteYou're better off doing that sort of thing in machine code.

I'm sure the aspirations of most of my programming endeavors are beyond the scope of BASIC and are all better suited for machine/assembly code...  too bad I know nothing about low level programming!  Oh well, I'll do my best within BASIC and see how far I get...  it's my first C128 program ever so it doesn't have to be the coolest, most functional program of it's type.  :)

I've heard of SIDPlayer before and would like to check it out--does anyone know where I could download it?


SmallCleverDinosaur

For the C64, the SIDplayer as well as some other players can be found here.

For the C128, look here.

You can also find the sourcecode for the SIDplayer here.
Ignorance is a precious thing. Once lost, it can never be regained.

ruthven

Thanks!--one last question: a lot of these files have extensions I don't recognize; are .lzh, .lnx, .sda, and .sfx forms of compression?  If so, do I decompress them on my PC or do I have to send them over to the Commodore as is and decompress them there?

SmallCleverDinosaur

It doesn't have to be the last question. If you have more you are quite welcome to ask them :)

Yes, those are compressed files. You can't uncompress them on a PC since there is no PC-program that can uncompress these. So you'll have to use a Commodore computer.

Or VICE of course :)

.sfx is a selfextracting archive so no program is needed to uncompress these.
Ignorance is a precious thing. Once lost, it can never be regained.

ruthven

QuoteIt doesn't have to be the last question. If you have more you are quite welcome to ask them
Glad to know I'm not being too much of a pest... because I just thought of something else: what Commodore decompression software should I get and where on the Net can I acquire it?

Also, is VICE pretty much the best C128 emulator for PC?--how does it compare to CCS64 (the only emulator I've used) for C64 emulation?

SmallCleverDinosaur

Zimmers.net is always a good place to start. In this case http://www.zimmers.net/anonftp/pub/cbm/c64/packers/index.html. And of course, we have our own Andrew Wiskow's homepage :) Look at the bottom and you'll see "a collection of archive and library".'

I have always used VICE and since it's been around for a long time, I think the C64 emulation is just as good as that of the CCS64, if not better. When it comes to the C128 I don't know if there is another emulator than VICE.

Anyone else knows?
Ignorance is a precious thing. Once lost, it can never be regained.

Edwing

Hey :ö) This thread is a bit older but since I'm just meeting it now ...

So if it's still relevant to your programming projects, there actually is something you can do to use PLAY with indefinite note length ...

You see, there's a flag in the zeropage (sorry don't know the address now, someone else may help) that switches the BASIC interrupt on/off. If this is set to stop, sprites don't move by their own anymore (as by MOVSPR 1,90#5 etc.) which is useful for aligning sprites before starting them all at once ... but also, there's eg. no split screen (GRAPHIC 2, GRAPHIC 4) anymore and PLAY is paused, too...

So my idea for holding a note is to start it with PLAY, then switch off the IRQ, wait until the key is released, then switch the IRQ on again for having the note sound off. Here's some pseudo code example:

10 ESC$=CHR$(27)
20 ENVELOPE 0,Attack,Decay,Sustain,Release:PLAY"U9 X0 T0":REM for preset 0, choose for a sustain a little longer than the BASIC loop takes
30 ?"<cls>EDWING'S SMALL MONOPHONIC SYNTHESIZER"
40 ?"<down>PRESS ANY NOTE KEY TO PLAY - ESC TO EXIT"
50 DO
55 GETKEY A$:IF INSTR("CDEFGAB",A$) THEN BEGIN
65 DO:V%=V%+1:IF V%=4 THEN V%=1
70 PLAY"M V"MID$(STR$(V%+1),2)A$:POKE Irq,off:DO:GET B$:LOOP WHILE B$=A$
80 POKE Irq,on:A$=B$:LOOP WHILE B$>ESC$
90 BEND
100 LOOP UNTIL A$=ESC$


Notes:
65 - I cycle the voice used so that it's possible to "slide" from one key to another, rather than having to let the first go before being able to press the second. It's still monophonic though.
70 - Notice the "M" parameter in the PLAY command; in case you don't know, it means "wait for measure" and causes PLAY to wait until the present note is finished. The idea is to finish the sounding off of the former note before starting a new (indefinite) one which would also cause the first one to keep on going. I didn't test the program, but this should work b/c the "M" is played in the old voice and then we switch to the new one. It also should do no harm for the first note played b/c there's no notes waiting in the IRQ queue.

You could also try fiddling with the TEMPO command, which can be set to play really long notes.

But actually, it may be best to use SOUND instead of PLAY for these purposes ... you could have it play a tone and change the frequency ... with POKEs even in real time ... not as much work as it sounds, just two POKEs for a frequency ... I believe this approach still would be much easier than in BASIC 2.0 since even if you have to use some POKEs to accompany the BASIC 7.0 commands, on the 64 it would be ALL POKES ;ö)

Still, of course then you have to convert notes to frequencies via a table (there's one in the back of the C128 manual) in DATA lines (or from the PLAY command's table in the ROM?), but it gives you the flexibility to also encorporate quarter-tones (since you asked for them ;ö). Also, you only would have to define values for an octave, and then you could have the program calculate the rest.

Cheers,
Edwing :ö)

SmallCleverDinosaur

Quote from: Edwing on April 30, 2009, 01:11 PM
You see, there's a flag in the zeropage (sorry don't know the address now, someone else may help) that switches the BASIC interrupt on/off. If this is set to stop, sprites don't move by their own anymore (as by MOVSPR 1,90#5 etc.) which is useful for aligning sprites before starting them all at once ... but also, there's eg. no split screen (GRAPHIC 2, GRAPHIC 4) anymore and PLAY is paused, too...
There are more than one flag that stops the BASIC portion of the IRQ service routine in the C128. One of them is in zeropage, address 216 ($D8). If you store a value of 255 ($FF) in this location you can directly access the VIC registers that sets upp screen resolution etc. But that also disables BASIC's ability to change display modes using the GRAPHIC command.

The other flag is at location 4861 ($12FD). If you store a value that is non-zero in this location the IRQ service routine will disable the effects of the BASIC commands MOVSPR, COLLISION, SOUND and PLAY. So in this case, this is the location you should use.
Ignorance is a precious thing. Once lost, it can never be regained.

Edwing