kopia lustrzana https://github.com/OpenRTX/OpenRTX
				
				
				
			Implement three levels of verbosity
Implemented the three levels of verbosity, besides none and beep: 1. Low: menus will speak but frequency and channel changes will just beep. 2. Medium: everything will speak but extra descriptions are eliminated except where ambiguity might occur. 3. High: Like medium except extra descriptions are spoken unles rapidly keying through menus in which case only the value will be spoken.md1702
							rodzic
							
								
									16abf941d4
								
							
						
					
					
						commit
						206e827aeb
					
				|  | @ -64,5 +64,6 @@ void announceContact(contact_t* contact, VoicePromptQueueFlags_T flags); | ||||||
| void announceContactWithIndex(uint16_t index, VoicePromptQueueFlags_T flags); | void announceContactWithIndex(uint16_t index, VoicePromptQueueFlags_T flags); | ||||||
| void announceTimeslot(uint8_t timeslot, VoicePromptQueueFlags_T flags); | void announceTimeslot(uint8_t timeslot, VoicePromptQueueFlags_T flags); | ||||||
| void  announceColorCode(uint8_t rxColorCode, uint8_t txColorCode, VoicePromptQueueFlags_T flags); | void  announceColorCode(uint8_t rxColorCode, uint8_t txColorCode, VoicePromptQueueFlags_T flags); | ||||||
|  | VoicePromptQueueFlags_T GetQueueFlagsForVoiceLevel(); | ||||||
| 
 | 
 | ||||||
| #endif //VOICE_PROMPT_UTILS_H_INCLUDED
 | #endif //VOICE_PROMPT_UTILS_H_INCLUDED
 | ||||||
|  | @ -195,13 +195,18 @@ consecutively, it is only desireable to initially stop speech in | ||||||
| progress and only play after the last prompt is queued. | progress and only play after the last prompt is queued. | ||||||
| If however calling an announceXX function in isolation, normally any prompt in  | If however calling an announceXX function in isolation, normally any prompt in  | ||||||
| progress should be interrupted and play should be called immediately. | progress should be interrupted and play should be called immediately. | ||||||
|  | At Voice level 1, changing channels in memory mode or frequencies in VFO mode  | ||||||
|  | is indicated by a beep however if F1 is pressed, we will still say the current  | ||||||
|  | channel name or frequency. This is accomplished by queueing but not playing a  | ||||||
|  | prompt. | ||||||
| */ | */ | ||||||
| typedef enum | typedef enum | ||||||
| { | { | ||||||
| 	vpqDefault = 0, | 	vpqDefault = 0, | ||||||
| 	vpqInit=0x01, // stop any voice prompts already in progress.
 | 	vpqInit=0x01, // stop any voice prompts already in progress.
 | ||||||
| 	vpqPlayImmediately=0x02, // call play after queue.
 | 	vpqPlayImmediately=0x02, // call play after queue at all levels.
 | ||||||
| 	vpqIncludeDescriptions=0x04 | 	vpqPlayImmediatelyAtMediumOrHigher =0x04, | ||||||
|  | 	vpqIncludeDescriptions=0x08 | ||||||
| } VoicePromptQueueFlags_T; | } VoicePromptQueueFlags_T; | ||||||
| 
 | 
 | ||||||
| typedef enum | typedef enum | ||||||
|  |  | ||||||
|  | @ -21,7 +21,7 @@ | ||||||
| #include <stdlib.h> | #include <stdlib.h> | ||||||
| #include <string.h> | #include <string.h> | ||||||
| #include <state.h> | #include <state.h> | ||||||
| 
 | #include "interfaces/cps_io.h" | ||||||
| #include "core/voicePromptUtils.h" | #include "core/voicePromptUtils.h" | ||||||
| 
 | 
 | ||||||
| static void vpInitIfNeeded(VoicePromptQueueFlags_T flags) | static void vpInitIfNeeded(VoicePromptQueueFlags_T flags) | ||||||
|  | @ -32,7 +32,10 @@ static void vpInitIfNeeded(VoicePromptQueueFlags_T flags) | ||||||
| 
 | 
 | ||||||
| static void vpPlayIfNeeded(VoicePromptQueueFlags_T flags) | static void vpPlayIfNeeded(VoicePromptQueueFlags_T flags) | ||||||
| { | { | ||||||
| 	if (flags & vpqPlayImmediately) | 	uint8_t vpLevel = state.settings.vpLevel; | ||||||
|  | 	 | ||||||
|  | 	if ((flags & vpqPlayImmediately) | ||||||
|  | 			|| ((flags & vpqPlayImmediatelyAtMediumOrHigher) && (vpLevel >= vpMedium))) | ||||||
| 		vpPlay(); | 		vpPlay(); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | @ -175,6 +178,7 @@ VoicePromptQueueFlags_T flags) | ||||||
| 	 | 	 | ||||||
| 	// mask off init and play because this function will handle init and play.
 | 	// mask off init and play because this function will handle init and play.
 | ||||||
| 	VoicePromptQueueFlags_T localFlags=flags & ~(vpqInit | vpqPlayImmediately);  | 	VoicePromptQueueFlags_T localFlags=flags & ~(vpqInit | vpqPlayImmediately);  | ||||||
|  | 	// Force on the descriptions for level 3.
 | ||||||
| 	if (state.settings.vpLevel == vpHigh) | 	if (state.settings.vpLevel == vpHigh) | ||||||
| 		localFlags |= vpqIncludeDescriptions; | 		localFlags |= vpqIncludeDescriptions; | ||||||
| 	// if VFO mode, announce VFO.
 | 	// if VFO mode, announce VFO.
 | ||||||
|  | @ -405,3 +409,48 @@ void  announceColorCode(uint8_t rxColorCode, uint8_t txColorCode, VoicePromptQue | ||||||
| 	 | 	 | ||||||
| 	vpPlayIfNeeded(flags); | 	vpPlayIfNeeded(flags); | ||||||
| } | } | ||||||
|  | /*
 | ||||||
|  | there are 5 levels of verbosity: | ||||||
|  | 
 | ||||||
|  | vpNone: no voice or beeps. | ||||||
|  | vpBeep: beeps only. | ||||||
|  | vpLow: menus talk, but channel and frequency changes are indicated with a beep  | ||||||
|  | and only voiced on demand with f1. | ||||||
|  | vpMedium: menus, channel and frequency changes talk but with extra  | ||||||
|  | descriptions eliminated unless ambiguity would result. E.g. We'd say "FM"  | ||||||
|  | rather than "Mode: FM" in the channel summary. | ||||||
|  | vpHigh: like vpMedium except with extra descriptions: e.g. "Mode fm". | ||||||
|  | Also, if a voice prompt is in progress, e.g. changing a menu item, the descriptions are eliminated. | ||||||
|  | e.g. changing ctcss tones would not repeat "ctcss" when arrowing through the  | ||||||
|  | options rapidly. | ||||||
|  | */ | ||||||
|  | VoicePromptQueueFlags_T GetQueueFlagsForVoiceLevel() | ||||||
|  | { | ||||||
|  | 	VoicePromptQueueFlags_T flags = vpqInit; | ||||||
|  | 	 | ||||||
|  | 	uint8_t vpLevel = state.settings.vpLevel; | ||||||
|  | 	switch (vpLevel) | ||||||
|  | 	{ | ||||||
|  | 	case vpNone: | ||||||
|  | 	case vpBeep: | ||||||
|  | 		return vpqDefault; | ||||||
|  | 	// play some immediately, other things on demand.
 | ||||||
|  | 	case vpLow: | ||||||
|  | 		flags |= vpqPlayImmediatelyAtMediumOrHigher; | ||||||
|  | 		break; | ||||||
|  | 	// play all immediatley but without extra descriptions
 | ||||||
|  | 	case vpMedium: | ||||||
|  | 	{ | ||||||
|  | 		flags |= vpqPlayImmediately; | ||||||
|  | 		break; | ||||||
|  | 	} | ||||||
|  | 	// play immediatley with descriptions unless speech is in progress.
 | ||||||
|  | 	case vpHigh: | ||||||
|  | 		flags |= vpqPlayImmediately; | ||||||
|  | 		if (!vpIsPlaying()) | ||||||
|  | 			flags |= vpqIncludeDescriptions; | ||||||
|  | 		break; | ||||||
|  | 	} | ||||||
|  | 	 | ||||||
|  | 	return flags; | ||||||
|  | } | ||||||
|  | @ -796,9 +796,7 @@ void _ui_fsm_menuMacro(kbd_msg_t msg, bool *sync_rtx) | ||||||
|     bool tone_tx_enable = state.channel.fm.txToneEn; |     bool tone_tx_enable = state.channel.fm.txToneEn; | ||||||
|     bool tone_rx_enable = state.channel.fm.rxToneEn; |     bool tone_rx_enable = state.channel.fm.rxToneEn; | ||||||
|     uint8_t tone_flags = tone_tx_enable << 1 | tone_rx_enable; |     uint8_t tone_flags = tone_tx_enable << 1 | tone_rx_enable; | ||||||
| 	VoicePromptQueueFlags_T queueFlags=vpqInit | vpqPlayImmediately; | 	VoicePromptQueueFlags_T queueFlags=GetQueueFlagsForVoiceLevel(); | ||||||
| 	if (!vpIsPlaying()) |  | ||||||
| 		queueFlags |= vpqIncludeDescriptions; |  | ||||||
| 	 | 	 | ||||||
|     switch(ui_state.input_number) |     switch(ui_state.input_number) | ||||||
|     { |     { | ||||||
|  | @ -1060,6 +1058,7 @@ void ui_updateFSM(bool *sync_rtx) | ||||||
|         kbd_msg_t msg; |         kbd_msg_t msg; | ||||||
|         msg.value = event.payload; |         msg.value = event.payload; | ||||||
| 		bool f1Handled = false; | 		bool f1Handled = false; | ||||||
|  | 		VoicePromptQueueFlags_T queueFlags = GetQueueFlagsForVoiceLevel(); | ||||||
|         // If we get out of standby, we ignore the kdb event
 |         // If we get out of standby, we ignore the kdb event
 | ||||||
|         // unless is the MONI key for the MACRO functions
 |         // unless is the MONI key for the MACRO functions
 | ||||||
|         if (_ui_exitStandby(now) && !(msg.keys & KEY_MONI)) |         if (_ui_exitStandby(now) && !(msg.keys & KEY_MONI)) | ||||||
|  | @ -1119,8 +1118,7 @@ void ui_updateFSM(bool *sync_rtx) | ||||||
|                         ui_state.last_main_state = state.ui_screen; |                         ui_state.last_main_state = state.ui_screen; | ||||||
|                         // Open Menu
 |                         // Open Menu
 | ||||||
|                         state.ui_screen = MENU_TOP; |                         state.ui_screen = MENU_TOP; | ||||||
| 					    // TODO: announce the menu name.
 | 					    // TODO: announce the menu name and selected item.
 | ||||||
| 					    // The selected item will be announced when the item is first selected.
 |  | ||||||
|                     } |                     } | ||||||
|                     else if(msg.keys & KEY_ESC) |                     else if(msg.keys & KEY_ESC) | ||||||
|                     { |                     { | ||||||
|  | @ -1132,8 +1130,8 @@ void ui_updateFSM(bool *sync_rtx) | ||||||
|                         { |                         { | ||||||
|                             // Switch to MEM screen
 |                             // Switch to MEM screen
 | ||||||
|                             state.ui_screen = MAIN_MEM; |                             state.ui_screen = MAIN_MEM; | ||||||
| 						    // Anounce the active channel name.
 | 						    // anounce the active channel name.
 | ||||||
| 						    announceChannelName(&state.channel, state.channel_index, (vpqInit | vpqPlayImmediately)); | 						    announceChannelName(&state.channel, state.channel_index, queueFlags); | ||||||
|                         } |                         } | ||||||
|                     } |                     } | ||||||
|                     else if(msg.keys & KEY_HASH) |                     else if(msg.keys & KEY_HASH) | ||||||
|  | @ -1152,7 +1150,7 @@ void ui_updateFSM(bool *sync_rtx) | ||||||
|                             state.channel.rx_frequency += 12500; |                             state.channel.rx_frequency += 12500; | ||||||
|                             state.channel.tx_frequency += 12500; |                             state.channel.tx_frequency += 12500; | ||||||
|                             *sync_rtx = true; |                             *sync_rtx = true; | ||||||
| 						    announceFrequencies(state.channel.rx_frequency, state.channel.tx_frequency, (vpqInit | vpqPlayImmediately)); | 						    announceFrequencies(state.channel.rx_frequency, state.channel.tx_frequency, queueFlags); | ||||||
|                         } |                         } | ||||||
|                     } |                     } | ||||||
|                     else if(msg.keys & KEY_DOWN || msg.keys & KNOB_LEFT) |                     else if(msg.keys & KEY_DOWN || msg.keys & KNOB_LEFT) | ||||||
|  | @ -1164,7 +1162,18 @@ void ui_updateFSM(bool *sync_rtx) | ||||||
|                             state.channel.rx_frequency -= 12500; |                             state.channel.rx_frequency -= 12500; | ||||||
|                             state.channel.tx_frequency -= 12500; |                             state.channel.tx_frequency -= 12500; | ||||||
|                             *sync_rtx = true; |                             *sync_rtx = true; | ||||||
| 						    announceFrequencies(state.channel.rx_frequency, state.channel.tx_frequency, (vpqInit | vpqPlayImmediately)); | 						    announceFrequencies(state.channel.rx_frequency, state.channel.tx_frequency, queueFlags); | ||||||
|  |                         } | ||||||
|  |                     } | ||||||
|  |                     else if(msg.keys & KEY_F1) | ||||||
|  |                     { | ||||||
|  | 				    	if (state.settings.vpLevel > vpBeep) | ||||||
|  | 				    	{// quick press repeat vp, long press summary.
 | ||||||
|  | 				    		if (msg.long_press) | ||||||
|  | 				    			announceChannelSummary(&state.channel, 0, (vpqInit | vpqPlayImmediately)); | ||||||
|  | 				    		else | ||||||
|  | 				    			ReplayLastPrompt(); | ||||||
|  | 				    		f1Handled = true; | ||||||
| 				    	} | 				    	} | ||||||
|                     } |                     } | ||||||
|                     else if(input_isNumberPressed(msg)) |                     else if(input_isNumberPressed(msg)) | ||||||
|  | @ -1202,12 +1211,12 @@ void ui_updateFSM(bool *sync_rtx) | ||||||
|                     if(ui_state.input_set == SET_RX) |                     if(ui_state.input_set == SET_RX) | ||||||
| 					{ | 					{ | ||||||
|                         ui_state.input_set = SET_TX; |                         ui_state.input_set = SET_TX; | ||||||
| 						announceInputReceiveOrTransmit(true, (vpqInit | vpqPlayImmediately)); | 						announceInputReceiveOrTransmit(true, queueFlags); | ||||||
| 					} | 					} | ||||||
|                     else if(ui_state.input_set == SET_TX) |                     else if(ui_state.input_set == SET_TX) | ||||||
| 					{ | 					{ | ||||||
|                         ui_state.input_set = SET_RX; |                         ui_state.input_set = SET_RX; | ||||||
| 						announceInputReceiveOrTransmit(false, (vpqInit | vpqPlayImmediately)); | 						announceInputReceiveOrTransmit(false, queueFlags); | ||||||
| 					} | 					} | ||||||
|                     // Reset input position
 |                     // Reset input position
 | ||||||
|                     ui_state.input_position = 0; |                     ui_state.input_position = 0; | ||||||
|  | @ -1287,6 +1296,18 @@ void ui_updateFSM(bool *sync_rtx) | ||||||
|                         // Reset text input variables
 |                         // Reset text input variables
 | ||||||
|                         _ui_textInputReset(ui_state.new_callsign); |                         _ui_textInputReset(ui_state.new_callsign); | ||||||
|                     } |                     } | ||||||
|  |                     else if(msg.keys & KEY_F1) | ||||||
|  |                     { | ||||||
|  | 				    	if (state.settings.vpLevel > vpBeep) | ||||||
|  | 				    	{// quick press repeat vp, long press summary.
 | ||||||
|  | 				    		if (msg.long_press) | ||||||
|  | 				    			announceChannelSummary(&state.channel, state.channel_index,  | ||||||
|  | 				    		(vpqInit | vpqPlayImmediately)); | ||||||
|  | 				    		else | ||||||
|  | 				    			ReplayLastPrompt(); | ||||||
|  | 				    		f1Handled=true; | ||||||
|  | 				    	} | ||||||
|  |                     } | ||||||
|                     else if(msg.keys & KEY_UP || msg.keys & KNOB_RIGHT) |                     else if(msg.keys & KEY_UP || msg.keys & KNOB_RIGHT) | ||||||
|                     { |                     { | ||||||
|                         _ui_fsm_loadChannel(state.channel_index + 1, sync_rtx); |                         _ui_fsm_loadChannel(state.channel_index + 1, sync_rtx); | ||||||
|  |  | ||||||
|  | @ -87,6 +87,9 @@ bool DidSelectedMenuItemChange(char* menuName, char* menuValue) | ||||||
| 
 | 
 | ||||||
| static void announceMenuItemIfNeeded(char* name, char* value) | static void announceMenuItemIfNeeded(char* name, char* value) | ||||||
| { | { | ||||||
|  | 	if (state.settings.vpLevel <= vpLow) | ||||||
|  | 		return; | ||||||
|  | 
 | ||||||
| 	if (!name || !*name) | 	if (!name || !*name) | ||||||
| 		return; | 		return; | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
		Ładowanie…
	
		Reference in New Issue
	
	 vk7js
						vk7js