TF2 Sentry - Page Work in Progress


Audio System

The audio system will play the audio of the sentry everytime it completes a 90 degree movement, the sound of it spotting a target, and the sound of the sentry firing. I did NOT include a motor sound for two reasons. One, the real motor has it's own sound, and two, the motor's own sound will drown out the sound effect.

Design of the System
The way the sentry will provide audio is using DAC (Digital to Analog Conversion), an audio amplifier and obviously a speaker. I will output a datastream from the audio from the STM to the amplifier, which will be connected to a speaker. The amplifier is the PAM8302A.
sentry front I will use the HAL libraries along with DMA. Following the AN3126 guide from STM, I designed a system to play audio. First to test, I generated a sine wave with the following code I made
uint8_t samples = 100;
void getSineVal(){
    for(int i = 0; i < samples; i++){
        sineVal[i] = (sin(2*i*PI/samples)+1)*((0xFFF+1)/2);
    }
}
getSineVal();
HAL_TIM_Base_Start(&htim6);
HAL_DAC_Start(&hdac, DAC_CHANNEL_1);
HAL_DAC_Start_DMA(&hdac, DAC_CHANNEL_1, sineVal, 100, DAC_ALIGN_12B_R);
// sineVal being the data, 100 being the # of data points
I am using TIM6 since it is specifically used to drive the DAC. The clock for TIM6 is at 80Mhz. The prescalar is 80-1, the period is 100-1, and the #samples is 100. So 80Mhz/(80 * 100 * 100) = 100Hz. Below is an image of the generated sine wave on my oscilloscope. sentry front
Sending the Audio Data
Now I see I can properly send data, so how can I send the audio data? Well first I need the actual audio files, so I ripped them from the TF2 files. I used a program called WavToCode to edit some of the properties of the audio and generate a file of the audio data. I changed it to an 8 bit sound (which will be explained in the next section). The audio frequency is at 44.1kHz, which we must keep in mind. The reason being is according to the datasheet and documentation, the timer (TIM6 in this case) must be running at the same frequency. To get 44.1kHz from 80Mhz, I need to divide. 80Mhz/44.1khz is approximately 1814. So in the counter period, I put 1814-1, which will give 44.1kHz.
Now I have separate files for each separate sound. I create a pointer to the start of the audio data. I don't need the first 44 bytes that describe the file as I already set everything else myself.
Processing the Data
This is the tricky part. I'm using the half callbacks and full callbacks. I have a wave buffer of size 512. Before I put the data into the buffer, I shift the 8 bit data left 4 times to create 12 bit data. Just for a small quality boost. Dac OUT = Vref(DOR/0xFFF). Vref is 3.3, DOR is the data and 0xFFF is the DAC Max Digital Value, 2^12 or 4095. So this allows a voltage of 0 to 3.3V. Now, I start with sending the first 512. Upon a half callback, 256 pieces of data should of been sent. Imagine two sections, the first half of the 512 and the second half. Once I have the half callback, that means the first 256 has been processed. So for effiency, I now fill that first half with new data so after the second half completes, it's immediately ready to go with the next 512. Then when the full call back is complete, it now fills the second half with new data, and the process repeats depending on the length of the audio file, which I have predefined. Using this method allows me to use only one buffer and not needing to constantly stop and start the dac/dma everytime I need to fill in the new data. This has to be done this way because you can't just send 100k data at once.
Storing the Data
I wanted to avoid needing extra memory to store the audio. For example, needing an SD card to store the audio. The good news is, I can store the data onto the flash ROM on the STM. There's enough room. After some research, I found out by going into the FLASH_ROM.ld file, I can define the areas in the ROM where I want to store the audio file data. I define the starting address and the size required. Using the software from STM called the STM Monitor, I can see where on the STM there is available space on the ROM. I do this because I don't want to override something that the STM needs. Then in the code, I have a pointer to this data to use it.
Results
Below is photos from my oscilloscope and a video of one of the sounds playing on the speaker (the sound specifically being the scanning beep).
  • DAC Signal

    The DAC signal at different horizontal levels.
  • Amplified Signal

    This is the signal after it goes through the amplifier.
Back to Motor System