/*-----------------------------------------------------------------------------------------
* This software is in the public domain, furnished "as is", without technical
* support, and with no warranty, express or implied, as to its usefulness for
* any purpose.
*
* Wave.ino
*
* Function to coordinate 5 differnt wave sounds matching the LED-modes.
*
* Wateralert [Amode]: playing sos morse code if wateralert is given
* MoLess [Mmode] : playing music in standstill
* RotOnly [Mmode] : fast turbine sound mixed with slower warp sound at rotation
* (frequenz depending on mo_degree)
* LinOnly [Mmode] : turbine sound at linear movement
* (frequenz depending on mo_absolut or VS_manual)
* ServoMode [Tmode] : playing ping sound (frequenz depending on Prop_now of switchprop)
*
* Function calls of wave.ino are consolidated with LED-Modes.
*
* Author: Volker Frauenstein
* Date: 01/02/2023 Version: 1.2 implementation of mixing of two waves within RotOnly mode
*
* Date: 31/01/2023 Version: 1.1 implementation of wateralert function and introduction of
* to be used 8bit PCM wave data files
* Date: 30/01/2023 Version: 1.0 integration of XT_DAC_Audio classes and implementation of
* first functions
*
*/
// Definitions to include wave files -> all 8bit pcm wave file (samplerate in file name)
#include "waves/intro11025.h" // data for song (wave) defined as const to save dram
#include "waves/cylon11025.h" // data for ping noise (wave) defined as const to save dram
#include "waves/warp11025.h" // data for warp noise (wave) defined as const to save dram
#include "waves/wimmerbach11025.h" // data for driving noise (wave) defined as const to save dram
#include "waves/sos11025.h" // data for alert (wave) defined as const to save dram
/* alternativ definitons (other sounds) to include wave files
#include "waves/wamapum11025.h" // data for warp noise (wave) defined as const to save dram
#include "waves/turbine11025.h" // data for driving noise (wave) defined as const to save dram
#include "waves/tracktora11025.h" // data for driving noise (wave) defined as const to save dram
#include "waves/tracktorb11025.h" // data for driving noise (wave) defined as const to save dram
#include "waves/boldor11025.h" // data for driving noise (wave) defined as const to save dram
#include "waves/wassert11025.h" // data for driving noise (wave) defined as const to save dram
#include "waves/kochw11025.h" // data for driving noise (wave) defined as const to save dram
*/
// Definitions to handle sound with XTronical DAC Audio Library
#include "XT_DAC_Audio.h" // DAC Audio classes include
// pinout definition for DAC sound output
XT_DAC_Audio_Class DacAudio(26,0); // Create the main player class object with GIO 26 and timer 0
// generig definitions for debug
//#define DEBUG_W 1 // set activ if debuging of sound function is needed
//#define DEBUG_WW 1 // set activ if detailed debuging of sound function is needed
// definitions for adjustable values
// volatile int LED_Mmode = 0; // movement LED Mode definitions
// volatile int LED_Tmode = 0; // turntable LED Mode definitions
// volatile bool LED_Amode[2] = {false, false}; // alarm LED Mode definitions
// volatile float mo_absolut = 0; // RC linear motion absolut
// volatile float VS_manual = 0; // RC VS input absolut in manual mode
// volatile float yawrate = 0; // speed of rotation in degrees per second
// volatile float Prop_now = 0; // calculated proportional value
// generig definitions
XT_Wav_Class Song(song); // definition of wave data as pcm coded char at MoLess
XT_Wav_Class Ping(ping); // definition of wave data as pcm coded char for ServoMode
XT_Wav_Class Warp(warp); // definition of wave data as pcm coded char for RotOnly
XT_Wav_Class Drive(antrieb); // definition of wave data as pcm coded char for Lin and RotOnly
XT_Wav_Class Alert(walarm); // definition of wave data as pcm coded char for water alert
const int WaveNum = 4; // number of waves used -> excluded mixed wave
// Arrey to flag playing wave {song, ping, turbine, sos}
bool ItemPlaying[WaveNum] = {false, false, false, false};
bool mixing = false; // flag to mark if wave mixing Turbine/warp is activ
void setup_Wave() { // set up function for DAC sound
Song.RepeatForever=true; // all waves should playing forever
Ping.RepeatForever=true;
Warp.RepeatForever=true;
Drive.RepeatForever=true;
Alert.RepeatForever=true;
}
// main functions for wave playback
void RunWave() { // call every 20ms and check for changes
/* #ifdef DEBUG_W
Serial.print("ItemPlaying[");Serial.print(ItemPlaying[0]);
int j;
for (j = 1;j < WaveNum; j++) {
Serial.print(", ");Serial.print(ItemPlaying[j]);
}
Serial.println("], ");
#endif */
DacAudio.FillBuffer(); // fill the sound buffer with data
if (LED_Amode[1]) {
if (StopOtherPlay(3)) { // check if other wave is playing and stop for switching
DacAudio.Play(&Alert, true); // start the play and repeate
ItemPlaying[3]=true; // and update playing flag
#ifdef DEBUG_WW
Serial.print("Alert");
#endif
}
return; // water alert is high priorety now further evaluation
}
switch (LED_Mmode) { // switch of activ FlashLED
case 0: // MoLess
if (LED_Tmode == 2) { // in Servo Mode
PlayServo(Prop_now); // play wave for ServoMode
}
else {
PlayMoLess(); // play wave for MoLess
}
break;
case 1: // RotOnly
PlayTurbo(); // play turbine wave fast
break;
case 2: // LinOnly or LinRot
if (LED_Tmode == 1){ // manuel mode play turbine wave
PlayDrive(mo_manually); // use RC input as speed value
}
else { // syncronised mode play turbine wave as well
PlayDrive(mo_absolut); // but use mo_absolut as speed value
}
break;
}
} // function RunWave closed
void PlayMoLess() { // function to play or replay song at standstill
if (StopOtherPlay(0)) { // check if other wave is playing and stop for switching
DacAudio.Play(&Song, true); // start the play and repeate
ItemPlaying[0]=true; // and update playing flag
}
#ifdef DEBUG_WW
Serial.print("Music");
#endif
} // function PlayMoLess closed
void PlayServo(float PosServo){ // function to play wave in ServoMode and coordinate playspeed to angle
float Sspeed = abs(PosServo)+0.8; // calc the wave speed, range is from 0,8 to 1,8 times faster
if (StopOtherPlay(1)) { // check if other wave is playing and stop for switching
Ping.Speed = Sspeed; // set playing speed
DacAudio.Play(&Ping, true); // start the play and repeate
ItemPlaying[1]=true; // and update playing flag
}
else {
Ping.Speed = Sspeed; // set playing speed
}
#ifdef DEBUG_WW
Serial.print("Sspeed: ");Serial.print(Sspeed);Serial.print(", ");
#endif
} // function PlayServo closed
void PlayTurbo(){ // function to play fast turbine wave and coordinate playspeed to rotation
float Tspeed = abs(yawrate)/900+0.5; // calc the speed, yawrate up to 900 at 2,5 Rotations/sec -> speed 0.5 to 1.5
Drive.Speed = Tspeed; // set playing speed for drive wave
Warp.Speed = Tspeed*2; // set playing speed for warp wave -> speed 1 to 3 times faster
Warp.Volume = (Tspeed-0.5)*127; // volume of warp sound from zero to full power (127)
if (StopOtherPlay(2)) { // check if other wave is playing and stop for switching
DacAudio.Play(&Drive, true); // start the play and repeate turbine
DacAudio.Play(&Warp, true); // mixing warp sount to it
ItemPlaying[2]=true; // and update playing flag
mixing=true; // and set mixing flag activ
} // no else needed
#ifdef DEBUG_WW
Serial.print("TSpeed: ");Serial.print(Tspeed);Serial.print(", ");
#endif
} // function PlayTurbo closed
int PlayDrive(float LinSpeed) { // function to play turbine wave and coordinate playspeed vehiclespeed
float Dspeed = abs(LinSpeed)+0.5; // calc the speed, range is from 0.5 to 1.5 times faster
Drive.Speed = Dspeed; // set playing speed
if (StopOtherPlay(2)) { // check if other wave is playing and stop for switching
DacAudio.Play(&Drive, true); // start the play and repeate
ItemPlaying[2]=true; // and update playing flag
} // no else needed
#ifdef DEBUG_WW
Serial.print("Dspeed: ");Serial.print(Dspeed);Serial.print(", ");
#endif
} // function PlayDrive closed
bool StopOtherPlay (int wave) { // function to check if an other wave is playing and stop it
// function supports only one wave playing at time
uint8_t i; // counter for loop
for (i = 0; i < WaveNum; i++) { // run over the flags in ItemPlaying
if (ItemPlaying[i]) { // yes a wave is playing
if (i == wave) { // no switching of wave right now -> wave is already playing
#ifdef DEBUG_WW
Serial.print("NoStop, ");
#endif
return false; // noting to do return
}
else {
DacAudio.StopAllSounds(); // switch of activ wave playing, stop all playing
#ifdef DEBUG_W
Serial.println();
Serial.print("StopPlaying: ");Serial.print(i);
Serial.print("-> Flags: ");Serial.print(ItemPlaying[0]);
int j;
for (j = 1;j < WaveNum; j++) {
Serial.print(", ");Serial.print(ItemPlaying[j]);
}
Serial.print("], Mode(M,T): (");Serial.print(LED_Mmode);
Serial.print(", ");Serial.print(LED_Tmode);Serial.print("), StartPlaying: ");
Serial.print(wave);Serial.print(", ");
#endif
ItemPlaying[i]=false; // and update playing flag
if (i = 2) { // check if mixing was active
if (mixing) { // yes it was activ
mixing=false; // reset mixing
}
}
return true; // and return
}
}
}
#ifdef DEBUG_WW
Serial.print("NoPlay, ");
#endif
return true; // no wave is playing, same return as stoped
} // function StopOtherPlay closed