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);
+	}
+}