Какую команду ffmpeg использовать для преобразования списка целых чисел без знака в аудиофайл? - PullRequest
1 голос
/ 21 марта 2019

У меня есть файл, который содержит список из примерно сорока тысяч целых чисел, разделенных пробелом, причем каждое целое число находится в диапазоне от 0 до 255. Вот этот файл:

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

Если вы подключите динамик к плате ESP32, а затем проведете этот список целых чисел через цифроаналоговый преобразователь с частотой 24 кГц, вы услышите предложение: «Это не тот пост, который вы пропустили».

Что я хочу знать, так это как вы используете FFMPEG для преобразования этого списка целых чисел в звуковой файл, который другой компьютер может воспроизвести, чтобы услышать ту же фразу? Я попробовал эту команду:

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

Но мой audio.wav просто звучит как белый шум. Я попробовал несколько других значений для -f и -ar, но все, что я слышу, это разные частоты белого шума и, возможно, какое-то дополнительное жужжание.

Можно ли использовать ffmpeg для перевода моего списка целых чисел в аудиофайл для воспроизведения на других компьютерах? Если да, то какая команда ffmpeg подходит для этого?

ДРУГИЕ ПРИМЕЧАНИЯ

Если это поможет, это файл эскиза, который я загружаю на ESP32, если я хочу услышать звук:

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

Короче говоря, файл выглядит так:

#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() {

}

buffer... - это список целых чисел, найденных в файле integers.txt.

1 Ответ

1 голос
/ 21 марта 2019

Как предложил @Gyan в комментариях, мне пришлось сначала преобразовать мой список целых чисел в двоичный файл, прежде чем запускать команду ffmpeg. Итак, я создал скрипт golang с именем main.go с этим:

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)
    }
  }

}

Я запускаю go run main.go, чтобы дать мне файл binary.raw. Затем я запустил команду ffmpeg, как указано в моем вопросе, как это ffmpeg -f u8 -ar 24000 -ac 1 -i binary.raw -y audio.wav.

Файл audio.wav звучит так же, как выходной сигнал моего динамика ESP32 +, что я и хотел.

...