forked from yobert/alsa
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathnegotiate.go
157 lines (128 loc) · 3.5 KB
/
negotiate.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
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
package alsa
import (
"fmt"
)
func range_check(params hwParams, p param, v int) error {
min, max := params.IntervalRange(p)
if v < 0 || uint32(v) < min || uint32(v) > max {
if min != max {
return fmt.Errorf("Requested value %d is out of hardware possible range (min %d max %d)", v, min, max)
}
return fmt.Errorf("Requested value %d is not supported by hardware: Must be %d", v, min)
}
return nil
}
func format_check(params hwParams, f FormatType) error {
if params.GetFormatSupport(f) {
return nil
}
list := ""
count := 0
for i := FormatTypeFirst; i < FormatTypeLast+1; i++ {
if !params.GetFormatSupport(i) {
continue
}
if count > 0 {
list += ", "
}
list += i.String()
count++
}
if count == 0 {
return fmt.Errorf("%s not supported: No possible formats", f)
}
if count == 1 {
return fmt.Errorf("%s not supported: Must be %s", f, list)
}
return fmt.Errorf("%s not supported: Must be one of %s", f, list)
}
func (device *Device) NegotiateChannels(channels ...int) (int, error) {
var err error
for _, v := range channels {
err = range_check(device.hwparams, paramChannels, v)
if err != nil {
continue
}
device.hwparams.Cmask = 0
device.hwparams.Rmask = 0xffffffff
device.hwparams.SetInterval(paramChannels, uint32(v), uint32(v), Integer)
err = device.refine()
if err == nil {
return v, nil
}
}
return 0, fmt.Errorf("Channel count negotiation failure: %v", err)
}
func (device *Device) NegotiateRate(rates ...int) (int, error) {
var err error
for _, v := range rates {
err = range_check(device.hwparams, paramRate, v)
if err != nil {
continue
}
device.hwparams.Cmask = 0
device.hwparams.Rmask = 0xffffffff
device.hwparams.SetInterval(paramRate, uint32(v), uint32(v), Integer)
err = device.refine()
if err == nil {
return v, nil
}
}
return 0, fmt.Errorf("Rate negotiation failure: %v", err)
}
func (device *Device) NegotiateFormat(formats ...FormatType) (FormatType, error) {
var err error
for _, v := range formats {
err = format_check(device.hwparams, v)
if err != nil {
continue
}
device.hwparams.Cmask = 0
device.hwparams.Rmask = 0xffffffff
device.hwparams.SetFormat(v)
err = device.refine()
if err == nil {
return v, nil
}
}
return 0, fmt.Errorf("Format negotiation failure: %v", err)
}
func (device *Device) NegotiateBufferSize(buffer_sizes ...int) (int, error) {
var err error
for _, v := range buffer_sizes {
if !device.hwparams.IntervalInRange(paramBufferSize, uint32(v)) {
err = fmt.Errorf("Buffer size %d out of range", v)
continue
}
device.hwparams.Cmask = 0
device.hwparams.Rmask = 0xffffffff
device.hwparams.SetInterval(paramBufferSize, uint32(v), uint32(v), Integer)
err = device.refine()
if err == nil {
return v, nil
}
}
return 0, err
}
func (device *Device) NegotiatePeriodSize(period_sizes ...int) (int, error) {
var err error
for _, v := range period_sizes {
if !device.hwparams.IntervalInRange(paramPeriodSize, uint32(v)) {
err = fmt.Errorf("Period size %d out of range", v)
continue
}
device.hwparams.Cmask = 0
device.hwparams.Rmask = 0xffffffff
device.hwparams.SetInterval(paramPeriodSize, uint32(v), uint32(v), Integer)
err = device.refine()
if err == nil {
return v, nil
}
}
return 0, err
}
func (device *Device) BytesPerFrame() int {
sample_size := int(device.hwparams.Intervals[paramSampleBits-paramFirstInterval].Max) / 8
channels := int(device.hwparams.Intervals[paramChannels-paramFirstInterval].Max)
return sample_size * channels
}