How to write a binary file using Bash?

后端 未结 6 1845
迷失自我
迷失自我 2021-02-05 05:46

My problem is that I need to create a file with this exact bytes: 48, 00, 49, 00.

I cannot use C, perl, other scripting language (the target is an embedded

6条回答
  •  陌清茗
    陌清茗 (楼主)
    2021-02-05 06:42

    A couple of more general functions to output integers:

    le16 () { # little endian 16 bit binary output 1st param: integer to 2nd param: file 
      v=`awk -v n=$1 'BEGIN{printf "%04X", n;}'`
      echo -n -e "\\x${v:2:2}\\x${v:0:2}" >> $2
    }
    
    le32 () { # 32 bit version
      v=`awk -v n=$1 'BEGIN{printf "%08X", n;}'`
      echo -n -e "\\x${v:6:2}\\x${v:4:2}\\x${v:2:2}\\x${v:0:2}" >> $2
    }
    

    Use to make an audio WAV file header for iio data stream:

    channels=2
    bits_per_sample=16
    let "block_align = channels * bits_per_sample / 8"    
    
    wave_header () { # pass file name and data size as parameters; rest are constants set elsewhere
      data_size=$2
      let "RIFFsize = data_size + 44 - 8"
      let "bytes_per_sec = sampleHz * block_align"
    
      echo -e -n "RIFF" > $1
        le32 $RIFFsize $1
      echo -e -n "WAVEfmt " >> $1
        le32 16 $1  # format size
        le16 1 $1   #format tag: 1 = PCM
        le16 $channels $1
        le32 $sampleHz $1
        le32 $bytes_per_sec $1
        le16 $block_align $1
        le16 $bits_per_sample $1   # bits per sample
      echo -e -n "data" >> $1
        le32 $data_size $1
    }
    

    Linux iio ADC data capture to WAV file:

    sampleHz=8000
    milliseconds=15  # capture length 
    
    cd /sys/bus/iio/devices/iio:device0
    
    cat /sys/bus/iio/devices/trigger0/name > trigger/current_trigger
    
    echo 0 > buffer/enable
    
    echo 0 > scan_elements/in_voltage0_en  #
    echo 1 > scan_elements/in_voltage1_en  #  
    echo 1 > scan_elements/in_voltage2_en  # 
    echo 0 > scan_elements/in_voltage3_en  #
    
    echo $sampleHz > sampling_frequency
    sampleHz=`cat sampling_frequency`  # read back actual sample rate
    
    let "buffer_length = block_align * sampleHz * milliseconds / 1000"
    echo $buffer_length > buffer/length
    
    cd $HOME
    
    echo 1 > /sys/bus/iio/devices/iio:device0/buffer/enable
    wave_header data.wav $buffer_length
    head -c $buffer_length /dev/iio:device0 >> data.wav  # LE16 data
    echo 0 > /sys/bus/iio/devices/iio:device0/buffer/enable
    

提交回复
热议问题