gordonklaus / portaudio

Go bindings for the PortAudio audio I/O library
MIT License
704 stars 95 forks source link

Hou would I record a 16bit 16khz pcm with this lib? #22

Closed knelasevero closed 6 years ago

gordonklaus commented 6 years ago

You can do this with only small modifications to examples/record.go.

adneg commented 6 years ago

hello. I have similar problem

I want send audio over udp her: https://github.com/adneg/streemmic/ This work. I send over udp gzip pcm audio. But I want use codec (encode and deocde) for this repo: https://github.com/zaf/g711/ Reduce audio size. I can't do that becaues i don't now how get 16bit 8kHz LPCM with this lib.. It is posible to get example?

Next problem is how shout record to file raw pcm? I try delete from record.go the code that adds the file header. But when i tray play in linux: play -t raw -r 44100 -s4 test.raw it's quiet.

I apologize for my English and thank you for the library.

gordonklaus commented 6 years ago

@adneg You should be able to change int32 on this line to int16 and 44100 to 8000 on the next line to get the format you want. And then:

enc, err := g711.NewUlawEncoder(w, g711.Lpcm)
binary.Write(enc, binary.BigEndian, in)

although I'm not sure about the endianness.

I don't know why your play command is quiet. Are you sure your microphone is working? Have you tried the command with a known good file?

adneg commented 6 years ago

I have to do something wrong but I do not know what.

package main

import (
    "encoding/binary"
    //"fmt"
    "os"
    "os/signal"
    //"strings"

    "github.com/gordonklaus/portaudio"
)

func main() {
    sig := make(chan os.Signal, 1)
    signal.Notify(sig, os.Interrupt, os.Kill)

    fileName := "test.raw"

    f, err := os.Create(fileName)
    chk(err)

    portaudio.Initialize()
    defer portaudio.Terminate()
    in := make([]int16, 64)
    stream, err := portaudio.OpenDefaultStream(1, 0, 44100, len(in), in)
    chk(err)
    defer stream.Close()

    chk(stream.Start())
    for {
        chk(stream.Read())
        chk(binary.Write(f, binary.BigEndian, in))
        //nSamples += len(in)
        select {
        case <-sig:
            return
        default:
        }
    }
    chk(stream.Stop())
}

func chk(err error) {
    if err != nil {
        panic(err)
    }
}

my test.raw is 1 channel 16-bit 44100Hz. i play: play -t raw -r 44100 -e signed -b 16 -c 1 test.raw

test.raw:

 File Size: 971k      Bit Rate: 706k
  Encoding: Signed PCM    
  Channels: 1 @ 16-bit   
Samplerate: 44100Hz      
Replaygain: off         
  Duration: 00:00:11.00  

and is only nois . hmmm but when change in record.go lines: chk(binary.Write(f, binary.BigEndian, int16(16))) //bits per sample and

in := make([]int16, 64)
stream, err := portaudio.OpenDefaultStream(1, 0, 44100, len(in), in)

gor run recrod test.aiff next a play:

play test.aiff 

test.aiff:

 File Size: 185k      Bit Rate: 353k
  Encoding: Signed PCM    
  Channels: 1 @ 16-bit   
Samplerate: 44100Hz      
Replaygain: off         
  Duration: 00:00:04.20  

In:50.0% 00:00:02.10 [00:00:02.10] Out:92.6k [      |      ] Hd:0.0 Clip:0    
Done.

I hear what I was saying.

hmmm why is there different Bit Rate.

gordonklaus commented 6 years ago

@adneg Try binary.LittleEndian?

adneg commented 6 years ago

@gordonklaus Yes it helped. it solved all my problems. Thank you very much.

gordonklaus commented 6 years ago

@adneg You're welcome 😄