FreeCalypso > hg > fc-tourmaline
view src/cs/services/buzm/buzm_process.c @ 297:8dfdf88d632f
BUZM SWE initial implementation
author | Mychaela Falconia <falcon@freecalypso.org> |
---|---|
date | Tue, 29 Mar 2022 03:45:41 +0000 |
parents | |
children |
line wrap: on
line source
/* * In this module we are going to implement the main process functions * for BUZM. */ #include "buzm/buzm_env.h" #include "buzm/buzm_func_i.h" #include "rv/rv_general.h" #include "rvf/rvf_api.h" #include "rvm/rvm_use_id_list.h" #include "ffs/ffs_api.h" #include "main/sys_types.h" #include "buzzer/pwt.h" static void stop_current_melody(void) { PWT_stop_tone(); rvf_stop_timer(BUZM_TIMER); PWT_block_off(); ffs_close(buzm_env->ffs_fd); buzm_env->melody_running = FALSE; } void buzm_process_start_req(struct buzm_start_msg *msg) { T_FFS_SIZE rdsize; /* stop any previous melody first */ if (buzm_env->melody_running) { stop_current_melody(); rvf_send_trace("Melody play interrupted by new melody start",43, NULL_PARAM, RV_TRACE_LEVEL_DEBUG_MEDIUM, BUZM_USE_ID); } rdsize = ffs_read(msg->fd, (void *) buzm_env->chunk_buf, sizeof(struct melody_entry) * MELODY_CHUNK_SIZE); if (rdsize < sizeof(struct melody_entry)) { ffs_close(msg->fd); rvf_send_trace("Error: invalid melody file", 26, NULL_PARAM, RV_TRACE_LEVEL_ERROR, BUZM_USE_ID); return; } /* start this melody */ rvf_send_trace("Starting PWT melody play", 24, NULL_PARAM, RV_TRACE_LEVEL_DEBUG_LOW, BUZM_USE_ID); PWT_block_on(); buzm_env->melody_running = TRUE; buzm_env->ffs_fd = msg->fd; buzm_env->play_volume = msg->volume; buzm_env->loop_mode = msg->loop; buzm_env->chunk_play_ptr = 0; buzm_env->chunk_end_ptr = rdsize / sizeof(struct melody_entry); buzm_env->melody_end_flag = FALSE; rvf_start_timer(BUZM_TIMER, 1, FALSE); } void buzm_process_stop_req(struct buzm_stop_msg *msg) { if (buzm_env->melody_running) { stop_current_melody(); rvf_send_trace("Melody play stopped by command", 30, NULL_PARAM, RV_TRACE_LEVEL_DEBUG_LOW, BUZM_USE_ID); } else { rvf_send_trace("Redundant melody play stop command", 34, NULL_PARAM, RV_TRACE_LEVEL_DEBUG_MEDIUM, BUZM_USE_ID); } } static void melody_loop_restart(void) { T_FFS_SIZE rdsize; ffs_seek(buzm_env->ffs_fd, 0, FFS_SEEK_SET); rdsize = ffs_read(buzm_env->ffs_fd, (void *) buzm_env->chunk_buf, sizeof(struct melody_entry) * MELODY_CHUNK_SIZE); if (rdsize < sizeof(struct melody_entry)) { rvf_send_trace("Bad melody file on loop restart!", 32, NULL_PARAM, RV_TRACE_LEVEL_ERROR, BUZM_USE_ID); PWT_block_off(); ffs_close(buzm_env->ffs_fd); buzm_env->melody_running = FALSE; return; } buzm_env->chunk_play_ptr = 0; buzm_env->chunk_end_ptr = rdsize / sizeof(struct melody_entry); buzm_env->melody_end_flag = FALSE; rvf_start_timer(BUZM_TIMER, 1, FALSE); } static void melody_normal_finish(void) { PWT_block_off(); ffs_close(buzm_env->ffs_fd); buzm_env->melody_running = FALSE; rvf_send_trace("Melody play finished", 20, NULL_PARAM, RV_TRACE_LEVEL_DEBUG_LOW, BUZM_USE_ID); } static void melody_end_process(void) { if (buzm_env->loop_mode) melody_loop_restart(); else melody_normal_finish(); } void buzm_handle_timer(void) { struct melody_entry *curnote; UINT8 pwt_vol; T_FFS_SIZE rdsize; /* weed out any spurious timer hits */ if (!buzm_env->melody_running) return; /* real end of previous note or rest */ PWT_stop_tone(); if (buzm_env->melody_end_flag) { melody_end_process(); return; } curnote = buzm_env->chunk_buf + buzm_env->chunk_play_ptr; if (curnote->note_volume) { pwt_vol = ((buzm_env->play_volume * curnote->note_volume + 63) >> 6) - 1; PWT_play_tone(curnote->pwt_note, pwt_vol); } rvf_start_timer(BUZM_TIMER, curnote->duration, FALSE); buzm_env->chunk_play_ptr++; if (buzm_env->chunk_play_ptr < buzm_env->chunk_end_ptr) return; /* do we have more? */ rdsize = ffs_read(buzm_env->ffs_fd, (void *) buzm_env->chunk_buf, sizeof(struct melody_entry) * MELODY_CHUNK_SIZE); if (rdsize < sizeof(struct melody_entry)) buzm_env->melody_end_flag = TRUE; else { buzm_env->chunk_play_ptr = 0; buzm_env->chunk_end_ptr = rdsize / sizeof(struct melody_entry); } }