3

I have a file that contains a list of about forty thousand integers that are space delimited, with each integer between the value of 0 and 255. It is this file here:

https://github.com/johnlai2004/sound-project/blob/master/integers.txt

If you connect a speaker to an ESP32 breakout board, then run this list of integers through the digital to analog converter at a frequency of 24kHz, you will hear the sentence, "That's not the post that you missed."

What I want to know is how do you use FFMPEG to convert this list of integers into a sound file that other computer can play to hear the same phrase? I tried this command:

ffmpeg -f u8 -ac 1 -ar 24000 -i integers.txt -y audio.wav

But my audio.wav just sounds like white noise. I tried a few other values for -f and for -ar, but all I hear are different frequencies of white noise and maybe some extra buzzing.

Is it possible to use ffmpeg to translate my list of integers into an audio file for other computers to play? If so, what's the correct ffmpeg command to do this?

OTHER NOTES

If it helps, this is the sketch file that I upload to an ESP32 if I want to hear the audio:

https://github.com/johnlai2004/sound-project/blob/master/play-audio.ino

In short, the file looks like this:

#define speakerPin 25                          //The pins to output audio on. (9,10 on UNO,Nano)
#define bufferTotal 1347
#define buffSize 32

byte buffer[bufferTotal][buffSize];
int buffItemN = 0;
int bufferN = 0;

hw_timer_t * timer = NULL;
portMUX_TYPE timerMux = portMUX_INITIALIZER_UNLOCKED;

void IRAM_ATTR onTimer() {
  portENTER_CRITICAL_ISR(&timerMux);


  byte v = buffer[bufferN][buffItemN];
  dacWrite(speakerPin,v);

  buffItemN++;

  if(buffItemN >= buffSize){                                      //If the buffer is empty, do the following
    buffItemN = 0;                                              //Reset the sample count
    bufferN++;
    if(bufferN >= bufferTotal)
      bufferN = 0;
  }

  portEXIT_CRITICAL_ISR(&timerMux);

}

void setup() {      

/* buffer records */
buffer[0][0]=88;  // I split the long list of integers and load it into a 2D array
buffer[0][1]=88;
buffer[0][2]=86;
buffer[0][3]=85;
//etc....
buffer[1346][28]=94;
buffer[1346][29]=92;
buffer[1346][30]=92;
buffer[1346][31]=95;


/* end buffer records */

  timer = timerBegin(0, 80, true);
  timerAttachInterrupt(timer, &onTimer, true);
  timerAlarmWrite(timer, 41, true);
  timerAlarmEnable(timer);

}

void loop() {

}

The buffer... is the list of integers found in the integers.txt file.

John
  • 32,403
  • 80
  • 251
  • 422
  • ffmpeg cannot read a list of integers. You will need to convert it to a binary file, probably using sscanf in a while loop. – Gyan Mar 21 '19 at 18:47
  • @Gyan Thanks, I wrote a script to convert to binary, hopefully it's correct. I tried this command `ffmpeg -ar 24000 -ac 1 -i binary.txt -y audio.wav` but I get the message `Format image2 detected only with low score of 5, misdetection possible! Option sample_rate not found.` Can you suggest a `-f` that would be appropriate? And any other flags? – John Mar 21 '19 at 19:19
  • 1
    If it's unsigned 8 bit, then `-f u8 -sample_rate 24000 -channels 1 -i binary.txt` – Gyan Mar 21 '19 at 19:24

1 Answers1

2

As @Gyan suggested in comments, I had to convert my list of integers to a binary file first before running the ffmpeg command. So I created a golang script called main.go with this:

package main

import (
  "io/ioutil"
  "strings"
  "strconv"
  "os"
)
func main() {

  input:="./integers.txt"
  output:="./binary.raw"

  // Load the list of integers into memory
  contentbyte, _ := ioutil.ReadFile(input)
  content := strings.Split(string(contentbyte)," ");

  // Prepare to output a new binary file
  f, err := os.OpenFile(output, os.O_APPEND|os.O_WRONLY|os.O_CREATE, 0600)
  if err != nil {
      panic(err)
  }
  defer f.Close()

  for _,val := range content {
    // Convert each integer to a binary value and write to output file
    i,_ := strconv.Atoi(val)
    if _, err = f.Write([]byte{byte(i)}); err != nil {
        panic(err)
    }
  }

}

I run the go run main.go to give me the binary.raw file. I then ran the ffmpeg command as posted in my question like this ffmpeg -f u8 -ar 24000 -ac 1 -i binary.raw -y audio.wav.

The audio.wav file sounds just like the output of my ESP32 + speaker, which is what I wanted.

John
  • 32,403
  • 80
  • 251
  • 422