package icsmediaconv import ( "sync" "gitlab.com/cinnamon/voiceagent/icserror" "gitlab.com/cinnamon/voiceagent/icslog" "gitlab.com/cinnamon/voiceagent/icspacketparser" "gitlab.com/ics_cinnamon/joy4/av" "gitlab.com/ics_cinnamon/joy4/cgo/ffmpeg" "gitlab.com/ics_cinnamon/joy4/codec" ) const ( ICS_PT_MULAW = 0 ICS_PT_ALAW = 8 ICS_PT_G729 = 18 ICS_PT_END = ICS_PT_G729 ) const PCM_8K_16BIT_10MS_SIZE = 160 type Converter struct { payloadtype icspacketparser.PayloadType codec av.AudioCodecData decoder *ffmpeg.AudioDecoder samplingRate int onePacketSize int isStart bool m *sync.Mutex ID int } func NewConverter(id int, pt icspacketparser.PayloadType) (*Converter, *icserror.IcsError) { conv := &Converter{payloadtype: pt} conv.ID = id conv.isStart = false conv.m = &sync.Mutex{} switch pt { case ICS_PT_MULAW: conv.codec = codec.NewPCMMulawCodecData() conv.samplingRate = 8000 conv.onePacketSize = 160 case ICS_PT_ALAW: conv.codec = codec.NewPCMAlawCodecData() conv.samplingRate = 8000 conv.onePacketSize = 160 case ICS_PT_G729: conv.codec = codec.NewG729CodecData() conv.samplingRate = 8000 conv.onePacketSize = 10 default: return nil, icserror.ICSERRCONVNotSupportedCodec } var err error conv.decoder, err = ffmpeg.NewAudioDecoder(conv.codec) if err != nil { icserror.ICSERRCONVNotSupportedCodec.SetError(err) return nil, icserror.ICSERRCONVNotSupportedCodec } ffmpeg.SetLogLevel(ffmpeg.QUIET) conv.Start() l := icslog.GetIcsLog() l.Printf(icslog.LOG_LEVEL_DEBUG2, id, "### NewDecode()") return conv, nil } func (c *Converter) Start() { c.m.Lock() c.isStart = true c.m.Unlock() } func (c *Converter) Stop() { c.m.Lock() c.isStart = false c.m.Unlock() } func (c *Converter) IsStart() bool { return c.isStart } func (c *Converter) Close() { c.Stop() c.decoder.Close() l := icslog.GetIcsLog() l.Print(icslog.LOG_LEVEL_INFO, c.ID, "Closed Decoder") } func (c *Converter) Decode(packet []byte) ([]byte, *icserror.IcsError) { //l := icslog.GetIcsLog() //l.Printf(icslog.LOG_LEVEL_DEBUG2, -1, "converter### Decode() packet length: %d", len(packet)) retBuf := make([]byte, PCM_8K_16BIT_10MS_SIZE*2) packetLen := len(packet) iter := 0 for packetLen >= c.onePacketSize { packetLen -= c.onePacketSize //fmt.Printf("### Decode() iter(%d) packetlen(%d)\n", iter, packetLen) buf := packet[c.onePacketSize*iter : c.onePacketSize*(iter+1)] //fmt.Printf("### Decode() iter(%d), buf length %d %v\n", iter, len(buf), buf) //l.Printf(icslog.LOG_LEVEL_DEBUG2, c.ID, "### Decode() iter(%d), buf length %d %v", iter, len(buf), buf) c.m.Lock() if c.IsStart() { ok, frame, errDec := c.decoder.Decode(buf) if !ok { icserror.ICSERRCONVDecodeFail.SetError(errDec) //icserror.ICSERRCONVDecodeFail.Print() c.m.Unlock() return nil, icserror.ICSERRCONVDecodeFail } //fmt.Println("###frame len", iter, PCM_8K_16BIT_10MS_SIZE*iter, PCM_8K_16BIT_10MS_SIZE*(iter+1)) //fmt.Println("###frame len", len(frame.Data[0]), len(frame.Data), frame) copy(retBuf[PCM_8K_16BIT_10MS_SIZE*iter:PCM_8K_16BIT_10MS_SIZE*(iter+1)], frame.Data[0][:PCM_8K_16BIT_10MS_SIZE]) } c.m.Unlock() /* f1, err := os.OpenFile("./tx.voice.raw", os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644) if err != nil { log.Fatal(err) } f1.Write(frame.Data[0][:PCM_8K_16BIT_10MS_SIZE]) f1.Sync() f1.Close() */ iter++ } //fmt.Println("###retBuf len", len(retBuf), retBuf) return retBuf, nil }