2016-10-31 14:15
浏览 86


I wrote a small application which records data from a sound card and stores the data in an array for later processing.

Whenever new data is available, portaudio executes the callback record. Within the callback I append the data to the array

The golang builtin function append adds as expected another element to the slice, but for whatever reason also overwrites all existing elements within the array with exactly the same data.

I have been trying to isolate the problem for more than two days, without success.

Here is a stripped down version of the code, which works and shows the problem:

package main

import (
//    "reflect"


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


    stream, err := portaudio.OpenDefaultStream(inputChs, outputChs, samplingRate, framesPerBuffer, rec.record)
    if err != nil {

    defer stream.Close()
    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) = append(, in)
    fmt.Println("Content of after adding received sound sample:")
    fmt.Println(, "
    time.Sleep(time.Millisecond * 500) //limit temporarily the amount of data read
    // iterate over all recorded data and compare them
    for i, d := range{
        if reflect.DeepEqual(d, in){
                fmt.Printf("Data at index %d is the same as the recorded one, but should not be!
", i )

2. Update

This is the application output:

Received sound sample:
[[0.71575254 1.0734825 0.7444282]]
Content of after adding received sound sample:
[[[0.71575254 1.0734825 0.7444282]]]

Received sound sample:
[[0.7555193 0.768355 0.6575008]]
Content of 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 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 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 ....

As we one can see, over time, the size of the slice is growing, but instead of just appending the data, the data in the array gets also overwritten.

This should not happen. portaudio provides in the callback a [][]float32 with the audio sample recorded from the sound card. As you can see they are always different.

As mentioned, the code above is a stripped down version of my application. Usually I would record lets say 5 seconds, and then perform a Fast Fourier Transformation (FFT) over the samples to calculate the spectrum. I left this part away since it has no impact on this particular problem.

I would very much appreciate any help. Maybe somebody can point me out what I'm doing wrong.


  • 点赞
  • 写回答
  • 关注问题
  • 收藏
  • 邀请回答

1条回答 默认 最新

  • dtwupu6414 2016-10-31 17:52

    The buffer passed into the callback is reused by the portaudio package, so you are appending the same slice structure to your data slice. Each time the buffer allocated by portaudio overwrites the data, you see the results in every element of your data slice.

    You will need to allocate new slices and make a copy of the data:

    func (re *RecData) record(in [][]float32) {
        buf := make([][]float32, len(in))
        for i, v := range in {
            buf[i] = append([]float32(nil), v...)
        } = append(, buf)


    点赞 打赏 评论

相关推荐 更多相似问题