问题
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.
回答1:
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.
来源:https://stackoverflow.com/questions/55286149/what-ffmpeg-command-to-use-to-convert-a-list-of-unsigned-integers-into-an-audio