FreeCalypso > hg > fc-tourmaline
diff 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 diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/cs/services/buzm/buzm_process.c Tue Mar 29 03:45:41 2022 +0000 @@ -0,0 +1,143 @@ +/* + * 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); + } +}