@@ -71,17 +71,24 @@ func NopCloser[T any](w Writer[T]) WriteCloser[T] {
7171}
7272
7373func NewSwitchWriter (sampleRate int ) * SwitchWriter {
74- if sampleRate <= 0 {
75- panic ("invalid sample rate" )
74+ // This protects from a case when sample rate is not initialized,
75+ // but still allows passing -1 to delay initialization.
76+ // If sample rate is still uninitialized when another writer is attached,
77+ // the SampleRate method will panic instead of this check.
78+ if sampleRate == 0 {
79+ panic ("no sample rate specified" )
7680 }
77- return & SwitchWriter {
78- sampleRate : sampleRate ,
81+ if sampleRate < 0 {
82+ sampleRate = - 1 // checked by SetSampleRate
7983 }
84+ w := & SwitchWriter {}
85+ w .sampleRate .Store (int32 (sampleRate ))
86+ return w
8087}
8188
8289type SwitchWriter struct {
83- sampleRate int
8490 ptr atomic.Pointer [PCM16Writer ]
91+ sampleRate atomic.Int32
8592 disabled atomic.Bool
8693}
8794
@@ -108,8 +115,8 @@ func (s *SwitchWriter) Swap(w PCM16Writer) PCM16Writer {
108115 if w == nil {
109116 old = s .ptr .Swap (nil )
110117 } else {
111- if w .SampleRate () != s . sampleRate {
112- w = ResampleWriter (w , s . sampleRate )
118+ if rate := s .SampleRate (); rate != w . SampleRate () {
119+ w = ResampleWriter (w , rate )
113120 }
114121 old = s .ptr .Swap (& w )
115122 }
@@ -121,14 +128,29 @@ func (s *SwitchWriter) Swap(w PCM16Writer) PCM16Writer {
121128
122129func (s * SwitchWriter ) String () string {
123130 w := s .Get ()
124- return fmt .Sprintf ("Switch(%d) -> %v" , s .sampleRate , w )
131+ return fmt .Sprintf ("Switch(%d) -> %v" , s .sampleRate .Load (), w )
132+ }
133+
134+ // SetSampleRate sets a new sample rate for the switch. For this to work, NewSwitchWriter(-1) must be called.
135+ // The code will panic if sample rate is unset when a writer is attached, or if this method is called twice.
136+ func (s * SwitchWriter ) SetSampleRate (rate int ) {
137+ if rate <= 0 {
138+ panic ("invalid sample rate" )
139+ }
140+ if ! s .sampleRate .CompareAndSwap (- 1 , int32 (rate )) {
141+ panic ("sample rate can only be changed once" )
142+ }
125143}
126144
145+ // SampleRate returns an expected sample rate for this writer. It panics if the sample rate is not specified.
127146func (s * SwitchWriter ) SampleRate () int {
128- if s .sampleRate == 0 {
147+ rate := int (s .sampleRate .Load ())
148+ if rate == 0 {
129149 panic ("switch writer not initialized" )
150+ } else if rate < 0 {
151+ panic ("sample rate is unset on a switch writer" )
130152 }
131- return s . sampleRate
153+ return rate
132154}
133155
134156func (s * SwitchWriter ) Close () error {
0 commit comments