doushen4719 2016-03-08 08:29
浏览 256

从Golang中的二进制文件读取int16

I'm currently working on a Golang program which reads a 16-bit integer from stdin. I am expecting a value of between 3 and ~128, however, when I print out the integer value it is completely random, going from 30,000+ to -30,000.

I am doing the same thing in PHP by doing the following:

<?php

$binary = fread($stream, 2);
$unpacked = unpack('s', $binary);
$int = reset($unpacked);

This works successfully. The Go code that I am working on is located on GitHub here: https://github.com/uniquoooo/dca/blob/decoding/main.go#L502-L536

I'm using bash pipes (e.g. cat testfile | command) to pipe the contents into the program.

Here is some testing Golang code:

package main

import (
    "bufio"
    "fmt"
    "encoding/binary"
    "io"
    "os"

    "github.com/layeh/gopus"
)

func main() {
    OpusDecoder, err := gopus.NewDecoder(48000, 2)
    if err != nil {
        panic(err)
    }
    _ = OpusDecoder

    dcabuf := bufio.NewReaderSize(os.Stdin, 16384)

    var opuslen uint16

    for {
        err = binary.Read(dcabuf, binary.LittleEndian, &opuslen)
        if err != nil {
            if err == io.EOF || err == io.ErrUnexpectedEOF {
                return
            }
            panic(err)
        }

        fmt.Println("Frame Size:", opuslen)

        opus := make([]byte, opuslen)
        err = binary.Read(dcabuf, binary.LittleEndian, &opus)
        if err != nil {
            if err == io.EOF || err == io.ErrUnexpectedEOF {
                return
            }
            panic(err)
        }

        // pcm, err := OpusDecoder.Decode(opus, 1920, false)
        // if err != nil {
        //     panic(err)
        // }

        // err = binary.Write(os.Stdout, binary.LittleEndian, &pcm)
        // if err != nil {
        //     if err == io.EOF || err == io.ErrUnexpectedEOF {
        //         return
        //     }
        //     panic(err)
        // }
    }
}

I would expect output to be similar to Frame Size: 128 but the value is a lot higher.

I have uploaded a test file on my Google Drive here: https://drive.google.com/file/d/0B_559nfSNrcfMUNhbWdJMGptZGs/view?usp=sharing

To run the program, build it with go build and then run like this:

cat test.dca | ./main

The executable name may be different.

  • 写回答

1条回答 默认 最新

  • duangua5308 2016-03-08 23:31
    关注

    It sounds like you are getting encoded bytes. In other words, 1 is becoming 49, etc (depends on the encoding). The way around this is to normalize the byte back to the represented value (e.g. byte-'0') for each byte within the int16.

    a possible way you could do this is

    a := uint16(((opuslen & 0xff00) >> 8) - '0')
    b := uint16((opuslen & 0x00ff) - '0')
    opuslen = (function to splice together)
    

    Though this is a chore, this is what you'd have to do to ensure bytes are not maintaining their encoding. That, or just don't store as a utf/ascii/whatever encoded value. would look funky to a human when cat-ing it, but yeah who cares :)

    You'll also notice I changed opuslen to uint just for ease of demonstration. if you expect negative length (to denote compression maybe?) then adjust as needed.

    Edit: If you truly are going to be working with encoded bytes, perhaps you should read into a string and use strconv.Atoi, which would make it easier for you since you wouldn't have to write the code yourself to convert.

    评论

报告相同问题?

悬赏问题

  • ¥50 永磁型步进电机PID算法
  • ¥15 sqlite 附加(attach database)加密数据库时,返回26是什么原因呢?
  • ¥88 找成都本地经验丰富懂小程序开发的技术大咖
  • ¥15 如何处理复杂数据表格的除法运算
  • ¥15 如何用stc8h1k08的片子做485数据透传的功能?(关键词-串口)
  • ¥15 有兄弟姐妹会用word插图功能制作类似citespace的图片吗?
  • ¥200 uniapp长期运行卡死问题解决
  • ¥15 latex怎么处理论文引理引用参考文献
  • ¥15 请教:如何用postman调用本地虚拟机区块链接上的合约?
  • ¥15 为什么使用javacv转封装rtsp为rtmp时出现如下问题:[h264 @ 000000004faf7500]no frame?