Append function overwrites existing data in slice
我写了一个小应用程序,它记录声卡中的数据,并将数据存储在一个数组中,以便以后处理。
每当有新数据可用时,portaudio执行回调
golang内置函数
我已经试图孤立这个问题两天多了,但没有成功。
下面是代码的简化版本,它可以工作并显示问题:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 | package main import ( "fmt" "time" // "reflect" "github.com/gordonklaus/portaudio" ) type RecData struct{ data [][][]float32 } func main() { var inputChs int = 1 var outputChs int = 0 var samplingRate float64 = 48000 var framesPerBuffer int = 3 //for test purpose that low. Would normally be 1024 or 2048 rec := RecData{make([][][]float32, 0, 1000)} portaudio.Initialize() stream, err := portaudio.OpenDefaultStream(inputChs, outputChs, samplingRate, framesPerBuffer, rec.record) if err != nil { fmt.Println(err) } defer stream.Close() stream.Start() for { time.Sleep(time.Millisecond * 10) } } // callback which gets called when new data is in the buffer func (re *RecData)record(in [][]float32) { fmt.Println("Received sound sample:") fmt.Println(in) re.data = append(re.data, in) fmt.Println("Content of RecData.data after adding received sound sample:") fmt.Println(re.data," ") time.Sleep(time.Millisecond * 500) //limit temporarily the amount of data read // iterate over all recorded data and compare them /* for i, d := range re.data{ if reflect.DeepEqual(d, in){ fmt.Printf("Data at index %d is the same as the recorded one, but should not be! ", i ) } }*/ } |
2。更新
这是应用程序输出:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | Received sound sample: [[0.71575254 1.0734825 0.7444282]] Content of RecData.data after adding received sound sample: [[[0.71575254 1.0734825 0.7444282]]] Received sound sample: [[0.7555193 0.768355 0.6575008]] Content of RecData.data after adding received sound sample: [[[0.7555193 0.768355 0.6575008]] [[0.7555193 0.768355 0.6575008]]] Received sound sample: [[0.7247052 0.68471473 0.6843796]] Content of RecData.data after adding received sound sample: [[[0.7247052 0.68471473 0.6843796]] [[0.7247052 0.68471473 0.6843796]] [[0.7247052 0.68471473 0.6843796]]] Received sound sample: [[0.6996536 0.66283375 0.67252487]] Content of RecData.data after adding received sound sample: [[[0.6996536 0.66283375 0.67252487]] [[0.6996536 0.66283375 0.67252487]] [[0.6996536 0.66283375 0.67252487]] [[0.6996536 0.66283375 0.67252487]]] .... etc .... |
号
正如我们所看到的,随着时间的推移,切片的大小在增加,但数组中的数据也会被覆盖,而不仅仅是追加数据。
这不应该发生。
如前所述,上面的代码是我的应用程序的精简版。通常我会记录5秒,然后对样本执行快速傅立叶变换(FFT)来计算光谱。我把这部分忘了,因为它对这个问题没有影响。
我非常感谢你的帮助。也许有人能指出我做错了什么。
谢谢!
传递到回调的缓冲区被portaudio包重用,因此您要将相同的切片结构附加到
您需要分配新的切片并复制数据:
1 2 3 4 5 6 | func (re *RecData) record(in [][]float32) { buf := make([][]float32, len(in)) for i, v := range in { buf[i] = append([]float32(nil), v...) } re.data = append(re.data, buf) |
例子:https://play.golang.org/p/cf57lqizfu