Untitled

mail@pastecode.io avatar
unknown
c_cpp
2 years ago
3.8 kB
35
Indexable
Never
#include "SpiritMP3Enc.h"
#include <stdio.h>
#define MP3_FRAME_SIZE 576
#define PCM_SIZE (MP3_FRAME_SIZE*2)   // MP3_FRAME_SIZE*2, single channel(mono) working as double-buffering

volatile uint8_t pcm_ready;
int main()
{
  TMP3E_persist Enc;        // Declare encoder instance
  TMP3E_scratch Scratch;    // Declare encoder scratch pad
  short pcmBuffer[PCM_SIZE];  
  FILE *fileMP3;            // file I/O variables
  
  // coding parameters
  unsigned long ulSampleRateHz = 44100;
  int iBitrateKbps = 64;
  int iChannels = 1;
  int status;
  
  // Init STM32 stuff
  Configure Timer(sample_Rate, enable TRGO on update, no interrupts or dma required);
  Configure ADC(Enable continuous_DMA REQUEST, enable trigger from Timer TRGO, enable DMA Circular mode, 16bit size);
  HAL_Start_ADC_DMA(pcmBuffer, PCM_SIZE);    // Doesn't start the conversion until we enable the timer.
  
  uint8_t mp3_running=0;
  short * source;
  // Main loop
  while(1){
  
    // Main loop
    if(button_start && !mp3_running){
      
      printf("Starting the MP3 encoder\n");
      
      // Initialize encoder.
      status = MP3E__Init(&Enc, &Scratch, ulSampleRateHz, iBitrateKbps, iChannels);
      if (!status) { // initialization failed
        printf("ERROR: Invalid coding parameters!\n");
        continue;
      }
  
      // open input output MP3 files
      fileMP3 = fopen("voice.mp3", "wb");
      
      if (!fileMP3){  // failed to open file
        printf("ERROR: problems opening output MP3 file!\n");
        continue;
      }
      
      // Start timer, ADC will begin storing samples to asPCM
      Start_Timer();
      
      mp3_running = 1;
    }
    
    if(button_stop && mp3_running){
      
      printf("Stopping the MP3 encoder\n");
      Stop_Timer();    
      fclose(fileMP3);
      mp3_running = 0;
    }
    
    // Check if we must process PCM data and encode it to MP3
    if(pcm_ready){
      if(pcm_ready==1){             // Process first half of the buffer
        source=pcmBuffer[0];
      }
      else if(pcm_ready==2){        // Process second half of the buffer
        source=pcmBuffer[PCM_SIZE/2];
      }
      else if(pcm_ready==3){        // Buffer overflow!
        Stop_Timer();    
        fclose(fileMP3);
        printf("PCM buffer overflow detected!!\n");
        pcm_ready=0;
        continue;                   //  Skip rest of the loop
      }

      pcm_ready=0;

      // If signed conversion is needed, subtract adc_range/2:
      // (so 0...4095 becomes -2047...2048)
      for(uint16_t i=0; i<(PCM_SIZE/2); i++){
        *(source+i) -= 2047;
      }
      // MP3E__Encode576 outputs data to these variables
      unsigned int uiBitBufSize;        // Size of mp3 data generated by the encoder
      unsigned char *pCodedData;        // Pointer to mp3 encoded data
      
      // Encode PCM data.
      pCodedData = MP3E__Encode576(
            &Enc, // encoder
            source, // mono channel
            NULL,   // right channel unused
            iChannels, // PCM interleave
            &uiBitBufSize // [OUT] coded data size
            );
            
      if (uiBitBufSize) { // write MP3 data to file
        fwrite(pCodedData, sizeof(char), uiBitBufSize, fileMP3);
      }
    }
  }
}


HAL_ADC_Half_transferComplete_callback(){
  // First half ready, set flag
  if(pcm_ready){
    // Buffer Overflow error!
    // cpu is not able to process the buffer fast enough
    pcm_ready=3;
  }
  pcm_ready=1;
}

HAL_ADC_Full_transferComplete_callback(){
  // Second half ready, set flag
  if(pcm_ready){
    // Buffer Overflow error!
    // cpu is not able to process the buffer fast enough
    pcm_ready=3;
  }
  pcm_ready=2;
}