Groups keyboard shortcuts have been updated
Dismiss
See shortcuts

Trouble getting different notes to play

10 views
Skip to first unread message

Alec Jahn

unread,
Mar 23, 2008, 8:57:14 PM3/23/08
to wsu-assem...@googlegroups.com

I've got a simple little mock-up program to work out some background details for my project or hello-sound (I have the feeling the latter will evolve into something for my final).  Unfortunately, I can't get any different notes to play.  I'm assuming there's a flaw in my quick plan (basically it's just the sample sound program combined with hello-sprite's key-press loop) or maybe I'm not telling it the frequency in the right manner.

I've zipped the whole thing with one proprietary include file and it should also require ibmpc1.inc, gbhw.inc as well as gbhw-snd.inc.

Currently, all directional buttons seem to play the same F (at least for me), for the record.
 
Halp!
 
 
Alec-Hello-Noise.zip

John Harrison

unread,
Mar 24, 2008, 12:34:14 AM3/24/08
to wsu-assem...@googlegroups.com
the problem is that you have no RET opcode at the end of any of your
routines. So, for example, every keypad routine is called, one after the
other, when you press the right key. Regardless of the key you press,
the down routine is last so it is executed last. The pitch you are
hearing is the one triggered by the down routine.

--
John Harrison
http://alumni.media.mit.edu/~harrison

Alec Jahn

unread,
Mar 24, 2008, 11:48:35 AM3/24/08
to wsu-assem...@googlegroups.com
Oh, duh... 
*embarrassed*
Thanks!

 

Alec Jahn

unread,
Mar 27, 2008, 4:20:46 PM3/27/08
to wsu-assem...@googlegroups.com
Round 2 of my problems that I described yesterday after class.  The weird poltergeist things went away after I did something but I can't remember what.
 
Now I've got it to the point that it will play all eight notes, but when you try to 'unlock' the second set of four, it will still play the original set as well.  What I need to to (this is in my comments, too) is make it so that if B is still being pressed at the end of SecondLoop, it stays in SecondLoop instead of simply returning and running through MainLoop.  I tried a simple copy/paste of the other button press codes but it kills my SP since they don't get popped off (I think).  Either 1.  There's a simple way to check for B again, or 2.  I need to re-think my logic entirely (:P).
hello-noise-synthv2.zip

John Harrison

unread,
Mar 27, 2008, 10:32:40 PM3/27/08
to wsu-assem...@googlegroups.com
You were real close with the code you commented out. Two small things were wrong:
  • line 186 you have a call to SecondLoop. You want a jp (or jr) there instead. Make sure you are really clear on the difference between jr and call. I learned BASIC first so for me the analogy was to think of call as gosub and jp or jr as goto. Or if you think in C, calling a routine is like calling a function. Your function is SecondLoop. But within a function all of the loop structures you are used to (for, while, repeat) need to be constructed with jr or jp. The purpose of call is that you store the address you are calling from in the stack. With jr or jp you don't store the address. Storing the address takes a few bytes of stack space. For every call you need a ret or you have a memory leak and your stack will overflow. Perhaps somebody else on the list might take a stab as well at describing the difference?
  • just like every call needs to have a matching ret, every push needs to have a matching pop. In line 184 you have a push but you don't have the corresponding pop if the test for button B is true because your conditional call/jp is line 186 and the matching pop is line 187. You could switch lines 186 and 187 and the code would work, but really you don't need either the push or the pop. The purpose of push is to store the value of a register for later use. But you have no purpose for using this info later, since it is storing the results of the getkeys call and you are about to do that call again for fresh results.
-John

Alec Jahn

unread,
Mar 27, 2008, 11:33:27 PM3/27/08
to wsu-assem...@googlegroups.com
Yeah, that push/pop was bugging me, but I was thinking maybe I actually needed to push for some reason, leaving no room for pop after it loops.
All that explaination makes sense, which is good.  Everything works now, which is even better, EXCEPT when I try to do a diagonal (harmony), which just makes a horrible noise.

 
hello-noise-synthv3.zip

John Harrison

unread,
Mar 28, 2008, 12:50:35 AM3/28/08
to wsu-assem...@googlegroups.com
in the main loop you use voices 1 and 2 and in the second (B) loop you are trying to use voice 1 for both tones.

Alec Jahn

unread,
Mar 28, 2008, 12:52:16 AM3/28/08
to wsu-assem...@googlegroups.com
Oh, whoops.  I had just done a bunch of copy+paste'ing to test stuff initially.  Forgot to change that.  Thanks.

Alec Jahn

unread,
Mar 28, 2008, 11:44:41 AM3/28/08
to wsu-assem...@googlegroups.com
I also added a "menu" so you can choose between a higher octive and lower octive.  As for changing sound parameters, is that something I can do with LoByteVar?
hello-noise-synthv4.zip

John Harrison

unread,
Mar 29, 2008, 9:56:07 AM3/29/08
to wsu-assem...@googlegroups.com
I opened notes.asm really quick and saw that you are hardcoding your notes i.e. writing a separate routine for every note you want to play. It will be better and much more scalable and easier to modify in the future to have a table of note values, then use one routine to read the correct value of notes you based on placement in the table. For example, maybe your table looks like
Notes:
    db    330
    db    350
    db    390
    etc.

then you have some sort of routine which you call with hl containing the note number you want to play (0,1,2)
in that routine you have something like
    push   hl
    pop   de   ; de = hl
    ld   hl,Notes
    add   hl,de ; point to the right place in the table
    ld   a,[hl] 

now a contains the note freq you want.

I'm not sure what you are asking about LoByteVar. The purpose of LoByteVar is to give you a memory address to store an 8 bit value. The value is stored while the GB is on so if you declare a variable:
    LoByteVar   myVar

then you have somewhere in your code
    ld   a,27
    ld   [myVar],27

then somewhere else (anywhere else in your code) you have
    ld   a,[myVar]
then a = 27. You can reassign myVar to any other value between 0 and 255 as many times as you want as this is just RAM.

Hope this helps.

Alec Jahn

unread,
Mar 31, 2008, 1:26:08 AM3/31/08
to wsu-assem...@googlegroups.com
Sorry to bother at prime-time, but I was trying out code like the stuff you reccommended I use, and it won't let me do things like
Notes:
    db    330
    db    350
    db    390
    etc.
as the assembler says I can only use 8-bit values (makes sense, can't put $106 into hl).
Is there a simple way around this?
 
I figured I'd have the new code uploaded tonight, but I guess I'll just let my old hardcoded stuff stay for now.

John Harrison

unread,
Mar 31, 2008, 1:38:00 AM3/31/08
to wsu-assem...@googlegroups.com
you'll have to use 2 bytes, a low byte and a high byte. You could write a macro to calculate the values of the 2 bytes based on your number that you are wanting to store. Then you code is going to have to read both bytes.

I'm just doing this on an email and not testing, but the jist of it would be:

NOTES:   MACRO
        db    \1-(\1/256)*256)     ; LOW BYTE
        db    \1/256            ; HIGH BYTE
    ENDM

Then your note list would be
    NOTES   330
    NOTES   350

then to read you'd do something like
; get HL to point to the low byte you want to read
    ld   a,[hl+]
    ld   e,a
    ld   a,[hl+]
    ld   d,a      ; now DE = the note freq you want. and HL points to the next note

Alec Jahn

unread,
Mar 31, 2008, 1:43:47 AM3/31/08
to wsu-assem...@googlegroups.com
This is getting complicated (at least from my point of view). 
 
How about just subtract 256 from all the values and sorta "add it in" later (not literally, of course) in the calculation?  That's probably another of my logic attempts that isn't quite plausible.

 

Alec Jahn

unread,
Mar 31, 2008, 1:45:25 AM3/31/08
to wsu-assem...@googlegroups.com
Well, I should say I totally understand what you're suggesting, though I'm a little scared my grasp of coding isn't quite up to par.

John Harrison

unread,
Mar 31, 2008, 1:51:26 AM3/31/08
to wsu-assem...@googlegroups.com

Alec Jahn wrote:
>
>
> How about just subtract 256 from all the values and sorta "add it in"
> later (not literally, of course) in the calculation? That's probably
> another of my logic attempts that isn't quite plausible.
>
>

Yeah I was thinking about this as a possibility too, but then you have
the limitation of freqs only between 256 and 511. I wanted to go over
lookup tables in class tomorrow anyway, so it might make more sense
after that.

John

Alec Jahn

unread,
Mar 31, 2008, 1:53:42 AM3/31/08
to wsu-assem...@googlegroups.com
Alright, cool.  For now, I'll just stare at code until I'm sleepy.  :P

On 3/31/08, John Harrison <john.h...@wichita.edu> wrote:

Alec Jahn

unread,
Apr 1, 2008, 1:51:38 PM4/1/08
to wsu-assem...@googlegroups.com
Well, my programmer works great, but I'm having trouble with my code. 
 
When I hold a note, it doesn't play the note for the entire hey press.  Only when you let go of the button will it play it, and it's just a little blip of sound.
I remember a couple of classes ago you mentioned some problem you had to fix when you tried the hello-noise example on a real gameboy, but I don't remember if my code was written after the change or even what the change was.  Could this possibly be the solution?
 
On 3/31/08, Alec Jahn <ocedto...@gmail.com> wrote:

John Harrison

unread,
Apr 1, 2008, 2:12:29 PM4/1/08
to wsu-assem...@googlegroups.com
it sounds like you are having bouncing problems with the keypad. Try disabling the need for the keypad in your code (call the code which is supposed to play the note, regardless of input, then go to the wait infinite loop) and see if you get what you expected. That will help you figure out what is wrong.

Alec Jahn

unread,
Apr 8, 2008, 11:54:19 AM4/8/08
to wsu-assem...@googlegroups.com

I just wanted to say that I fixed my (currently hard-coded) synth program to workproperly on a Gameboy.  Originally, it wouldn't play the note if I held it down.  When I let go of that key press, it would play that note for whatever length it was defaulted on (it played one "blip!!!").

I thought, "Hey, lets throw a halt (and subsequent nop) in there after the note call and see what happens.  Well, that happened to have worked out great.  So instead of

 push af
 and PADF_DOWN
 call nz,adownB
 pop af

as my hard-coded note press (in this case, for the down direction) I now have

 push af
 and PADF_DOWN
 call nz,adownB
 halt
 nop
 pop af

Cool.

Only problem is now unlike on the emulator (before the halts) it does not play the note continuously (like singing one long note) it instead plays the note really fast (like hitting a note on a piano really fast over and over again) which is OK, I suppose.  Much better than what I had.  I can understand why it is doing this, but not sure how to fix it.  Any suggestions?



On 4/1/08, John Harrison <john.h...@wichita.edu> wrote:
it sounds like you are having bouncing problems with the keypad. Try disabling the need for the keypad in your code (call the code which is supposed to play the note, regardless of input, then go to the wait infinite loop) and see if you get what you expected. That will help you figure out what is wrong.


Alec Jahn wrote:
Well, my programmer works great, but I'm having trouble with my code. 
 
When I hold a note, it doesn't play the note for the entire hey press.  Only when you let go of the button will it play it, and it's just a little blip of sound.
I remember a couple of classes ago you mentioned some problem you had to fix when you tried the hello-noise example on a real gameboy, but I don't remember if my code was written after the change or even what the change was.  Could this possibly be the solution?
 
On 3/31/08, Alec Jahn <ocedto...@gmail.com> wrote:
Alright, cool.  For now, I'll just stare at code until I'm sleepy.  :P

On 3/31/08, John Harrison <john.harrison@wichita.edu> wrote:



Alec Jahn wrote:
>
>
> How about just subtract 256 from all the values and sorta "add it in"
> later (not literally, of course) in the calculation?  That's probably
> another of my logic attempts that isn't quite plausible.
>
>
Yeah I was thinking about this as a possibility too, but then you have
the limitation of freqs only between 256 and 511. I wanted to go over
lookup tables in class tomorrow anyway, so it might make more sense
after that.

John



John Harrison

unread,
Apr 8, 2008, 2:03:38 PM4/8/08
to wsu-assem...@googlegroups.com
send your code and any "proprietary" include files to the list.

Alec Jahn

unread,
Apr 8, 2008, 2:09:51 PM4/8/08
to wsu-assem...@googlegroups.com
uploaded to the files section

John Harrison

unread,
Apr 8, 2008, 2:32:01 PM4/8/08
to wsu-assem...@googlegroups.com
what files section? You could put it in "project scratchpad" in the blog if you wanted...

Alec Jahn

unread,
Apr 8, 2008, 2:33:58 PM4/8/08
to wsu-assem...@googlegroups.com
In the discussion board's files.  I'll just upload it through gmail.
hello-synth-alecj-v2.zip

John Harrison

unread,
Apr 8, 2008, 2:47:05 PM4/8/08
to wsu-assem...@googlegroups.com
just so I understand: it works fine on the emulator. On a real GB it won't play a note when you press a key. When you release the key, it plays the note? What about the length of the note? Is that correct?

Alec Jahn

unread,
Apr 8, 2008, 2:51:41 PM4/8/08
to wsu-assem...@googlegroups.com
Well, that was before I added a halt/nop after the note is called.  Now, it will call the note over and over and over again when I hold it, but it isn't one continuous sound on the gameboy, but instead the note getting hit really fast (almost sounds right).
 
The length of one note press is correct.

 

John Harrison

unread,
Apr 8, 2008, 3:09:36 PM4/8/08
to wsu-assem...@googlegroups.com
OK. I don't have a real GB setup to test here, but I have a good guess at what is wrong.

From looking at your code it appears that as long as a key is down, you key retriggering the GB to play the note. Without the halt/nop stuff you are doing that so incredibly fast that you are probably "freaking out" the audio hardware, creating unpredictable results (which apparently translates to no sound).

When you add the halt/nop you are still triggering continually, but now much slower...like 60Hz if the only interrupt is VBLANK, maybe. You are hearing the retriggering.

So you need to rewrite you code. There are several ways you could rewrite.
One way is:
MainLoop:
  for each key:
    if (key is pressed)
       trigger the note for this key
       wait-for-key-to-be-released
       stop that note
  jr MainLoop

Also, I noticed that you have an envelope on your notes so even though you say to continually play them, they will fade to mute quickly as the envelope goes to 0. So take out the envelope.

If you want to support double-stops, your logic will have to be just a bit more complicated:

create a variable, where each bit in the variable is a flag set to 1 if the key is pressed and to 0 if the key is released:
MainLoop
  for each key:
    if (key is pressed)
       if flag(key) == 0
         trigger the note for this key
    else \\ key is not pressed
      if flag(key) == 1
          stop the note for this key
          flag(key) = 0

for keypad press and release, take a look at keypad.asm on the wiki. That has keypad press and release detection routines which you could include in your code. They are pretty simple --- you could also write your own.

Alec Jahn

unread,
Apr 8, 2008, 3:19:20 PM4/8/08
to wsu-assem...@googlegroups.com
All seems quite logical.  I'll take a look at the keypad stuff, definitely.  Thanks for the help!

sms...@wichita.edu

unread,
May 7, 2008, 8:32:27 PM5/7/08
to wsu-assem...@googlegroups.com

John Harrison

unread,
May 7, 2008, 9:09:42 PM5/7/08
to wsu-assem...@googlegroups.com
I found one problem and to my untrained eye it may have fixed it:

When you use bigsprite, there's actually 3 numbers involved with every
description: the bigsprite ID, the sprite ID or sprite IDs associated
with that bigsprite, and the tile ids associated with each sprite.
Obviously you can use the same tile(s) for multiple sprites and thus for
multiple bigsprites, but the list of sprite #s for each bigsprite must
be unique.

In your case, you used sprite 5 in both bigsprite 9 and bigsprite 10.
But 1 sprite can't be in 2 places at once so you have a conflict.

Sometimes it appears there are only 2 sets of numbers but believe you me
and the one-eyed-cat there's 3. The confusion comes from the fact that
bigsprite tries to make life easier for us by associating each sprite #
with the corresponding tile number i.e. sprite 5 is assigned to tile 5,
sprite 6 to tile 6, etc. This happens automatically in the background
when we do INIT_BS. So that's where the 3rd set of numbers come in. It
is possible, though, to have for example both sprites 5 and 6 assigned
to tile 5. But we have to do that manually after the bigsprite
initialization. What is not possible is to have bigsprites 5 and 6
assigned to sprite 5. Or it's possible I suppose. But it gives, shall we
say, "alternative" results.

What I assume you want is to have bigsprite 9 and bigsprite 10 both use
tile 5, which is why you assigned them both to sprite 5. Here's how I
did accomplished that:

I left bigsprite 9 alone. It seemed happy enough. I noticed you weren't
using sprite 12 anywhere in your code so for bigsprite 10 I changed it's
assignment from sprite 5 to sprite 12 i.e. my line 64 of DaMan.asm reads:
db 12 ; was 5

Ok that's fine except that now bigsprite will assign bigsprite 10 to
tile 12 after the INIT_BS call and I assume you wanted it assigned to
tile 5. No problem. Reassign it yourself after bigsprite initializes. In
MrMonkeyMan.asm in line 127 right after INIT_BS:
SetSpriteTileNum 12,5
which assigns sprite 12 to tile 5.

Incidentally, your code actually built on my machine, which made me very
happy...except that I had to comment out your line:
LoWordVar RandSeed
because that's already declared in the "stock" version of gbrandom.

Let me know if this solves it. I know you've been sweating this for awhile.

Cool game, BTW.

-John


sms...@wichita.edu wrote:
>
> Updated files but still same issue :(
>
>
>
> http://cratel.wichita.edu/blogs/assembly08/2008/05/06/hello-monkey/
>
>
> >

--
John Harrison
http://alumni.media.mit.edu/~harrison

sms...@wichita.edu

unread,
May 9, 2008, 9:22:14 AM5/9/08
to wsu-assem...@googlegroups.com

Umm, do you have no idea what is wrong or was i just overlooked?

 

----- Original Message -----

From: sms...@wichita.edu

Date: Wednesday, May 7, 2008 7:32 pm

Subject: [wsu-assembly-engrs:408] Re: Trouble getting different notes to play

John Harrison

unread,
May 9, 2008, 9:30:29 AM5/9/08
to wsu-assem...@googlegroups.com
I fixed this and emailed about it. Check the link.
Reply all
Reply to author
Forward
0 new messages