MIPS MIDI播放器:播放和跳过问题

MIPS MIDI播放器:播放和跳过问题,mips,Mips,关于我的小组项目,我有几个问题。第一个问题是关于MIDI文件的播放。现在,我们的程序可以以大约75%的准确率播放0型文件(如果你能测量的话)。基本上,这首歌的“大部分”都是对的(或者非常接近)。很明显,它并没有播放所有的声音,而且它确实播放的一些声音失真了。那么,如果它能正确播放大部分音符,是什么原因导致它错过或扭曲其他音符呢 第二个问题与我们的中断处理程序有关。我试图调整指针,使程序向前/向后跳过X字节,但如果我在程序运行时尝试中断,它会暂停并锁定程序。如果我一步一步地运行中断,它不会停止。看

关于我的小组项目,我有几个问题。第一个问题是关于MIDI文件的播放。现在,我们的程序可以以大约75%的准确率播放0型文件(如果你能测量的话)。基本上,这首歌的“大部分”都是对的(或者非常接近)。很明显,它并没有播放所有的声音,而且它确实播放的一些声音失真了。那么,如果它能正确播放大部分音符,是什么原因导致它错过或扭曲其他音符呢

第二个问题与我们的中断处理程序有关。我试图调整指针,使程序向前/向后跳过X字节,但如果我在程序运行时尝试中断,它会暂停并锁定程序。如果我一步一步地运行中断,它不会停止。看起来我要么走了一半,要么完全偏离了目标(这是一个早期版本,但可能是b/c播放功能写得不正确)。如果我不得不猜测的话,我会说问题与with_STATUS和WITHOUT_STATUS函数有关。是这样吗

提前感谢您的帮助

PLAY_MIDI:          
        addi    $s5, $0, 0          # temporaries to control speed and volume
        addi    $t6, $0, 100   
        addi    $t9, $0, 0          
        addi    $sp, $sp, -4            # add a byte to the stack pointer and store the return address there
        sw  $ra, 0($sp)
        addi    $t4, $0, 3
LOOP:
        lh  $t0, DAT_Format
        bnez    $t0, NO_SUPPORTED
        addi    $s3, $s3, 1
        addi    $s1, $s1, -1    
        lbu     $t9, 0($s3)             # look for status byte
        blez    $s1, OFF_LOOP
        bltu    $t9, 0x80, LOOP
        bgeu    $t9, 0xa0, LOOP
WITH_STATUS:
        lbu     $t9, 0($s3)
        lb  $t6, -1($s3)            #sleep time 
        lb  $a1, 1($s3)         # load note
        lb  $a2, 2($s3)             # load volume
        addi    $s3, $s3, 4
        addi    $s1, $s1, -4
        move    $s2, $s1        # *** copy $s1 to $s2  for pause/play
        j   SLEEP
WITHOUT_STATUS:
        lb  $t6, -1($s3)            #sleep time
        lb  $a1, 0($s3)         # load note
        lb  $a2, 1($s3)             # load volume
        addi    $s3, $s3, 3         #increase stack
        addi    $s1, $s1, -3
        move    $s2, $s1        # ** copy $s1 to $s2    for pause/play
SLEEP:

        mul     $t6, $t6, $t4
        li  $v0, 32             # sleep until the next note should be played
        addu    $a0, $0, $t6            # sleep for $t6 ms
        syscall

        and     $a0, $t9,0x0F           # load channel
        and     $t9,$t9,0x000000F0      # load Command

                                               ######################################################
                                               ## copy $s1 to $s2 for use differentiating between  ##
        beq     $t9, 0x90, PLAY_NOTE_ON     ## stop and pause                   ##
        beq     $t9, 0x80, PLAY_NOTE_OFF        ## $s2 will hold last position of $s1               ##
        bgeu    $t9, 0xa0, LOOP             ######################################################

AFTER_PLAY:         
        blez    $s1, OFF_LOOP
        lbu     $t0, 0($s3)
        bgeu    $t0, 0x80, WITH_STATUS
        j   WITHOUT_STATUS

OFF_LOOP:       
        bne $s1, $s2, PAUSE_LOOP        # get the return address from the stack and decrease the pointer
        lw  $ra, 0($sp)
        addi    $sp, $sp, 4
        jr  $ra             # jump to the address we just loaded
PLAY_NOTE_ON:
        li  $v0, 60             # add a byte to the stack pointer and store the return address there
        syscall 
        j   AFTER_PLAY          

PLAY_NOTE_OFF:
        li  $v0, 61
        syscall
        j   AFTER_PLAY

NO_SUPPORTED:
j EXIT

#### Below is part of the interrupt handler ####
SKIP_FORWARD:       addi    $s3, $s3, 1         # by adding to $s3 program will move pointer ahead 
        la  $a0, skip_forward       # changed from $s3 to $s1 ***
        li  $v0, 4
        syscall
        jr  $ra

SKIP_BACKWARD:      addi    $s3, $s3, -1            # by subtracting from $s3 program will move pointer backwards
        la  $a0, skip_backward      # changed $s3 to $s1
        li  $v0, 4
        syscall 
        jr  $ra