-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathswr.go
89 lines (73 loc) · 2.12 KB
/
swr.go
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
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
package gmf
/*
#cgo pkg-config: libswresample
#include "libswresample/swresample.h"
#include <libavcodec/avcodec.h>
#include <libavutil/frame.h>
int gmf_sw_resample(SwrContext* ctx, AVFrame* dstFrame, AVFrame* srcFrame){
return swr_convert(ctx, dstFrame->data, dstFrame->nb_samples,
(const uint8_t **)srcFrame->data, srcFrame->nb_samples);
}
int gmf_swr_flush(SwrContext* ctx, AVFrame* dstFrame) {
return swr_convert(ctx, dstFrame->data, dstFrame->nb_samples,
NULL, 0);
}
*/
import "C"
import (
"fmt"
)
type SwrCtx struct {
swrCtx *C.struct_SwrContext
outChannels int
outSampleFormat int32
outSampleRate int
inSampleRate int
}
func NewSwrCtx(
outChannelLayout int,
outSampleFormat int32,
outSampleRate int,
inChannelLayout int,
inSampleFormat int32,
inSampleRate int,
) (*SwrCtx, error) {
ctx := &SwrCtx{
swrCtx: C.swr_alloc_set_opts(
nil,
C.int64_t(outChannelLayout),
outSampleFormat,
C.int(outSampleRate),
C.int64_t(inChannelLayout),
inSampleFormat,
C.int(inSampleRate),
0,
nil,
),
outChannels: int(C.av_get_channel_layout_nb_channels(C.uint64_t(outChannelLayout))),
outSampleFormat: outSampleFormat,
outSampleRate: outSampleRate,
inSampleRate: inSampleRate,
}
if ret := int(C.swr_init(ctx.swrCtx)); ret < 0 {
return nil, fmt.Errorf("error initializing swr context - %s", AvError(ret))
}
return ctx, nil
}
func (ctx *SwrCtx) Free() {
C.swr_free(&ctx.swrCtx)
}
func (ctx *SwrCtx) Resample(input *Frame, outSamples int) (*Frame, error) {
inSamples := input.NbSamples()
// outSamples := int(C.av_rescale_rnd(C.swr_get_delay(ctx.swrCtx, C.longlong(ctx.inSampleRate))+C.longlong(inSamples), C.longlong(ctx.outSampleRate), C.longlong(ctx.inSampleRate), C.AV_ROUND_UP))
out, err := NewAudioFrame(ctx.outSampleFormat, ctx.outChannels, outSamples)
if err != nil {
return nil, fmt.Errorf("error creating new audio frame - %s\n", err)
}
ret := int(C.swr_convert(ctx.swrCtx, (**C.uchar)(&out.avFrame.data[0]), C.int(outSamples), (**C.uchar)(&input.avFrame.data[0]), C.int(inSamples)))
if ret < 0 {
out.Free()
return nil, AvError(ret)
}
return out, nil
}