Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview
Comment:When using libao, send Int16 buffers straight to it. Also expand the convenience methods to UInt8 and Int24 samples.
Downloads: Tarball | ZIP archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA3-256: 9b3d4919637ac1772221314a9a6a004782818dc662a1b35ea3377fd90c92e9ab
User & Date: alexa 2024-10-29 05:09:17.201
Context
2024-10-29
05:35
Let cueplayer also play WAVE files in CUEs check-in: 480c924f47 user: alexa tags: trunk
05:09
When using libao, send Int16 buffers straight to it. Also expand the convenience methods to UInt8 and Int24 samples. check-in: 9b3d491963 user: alexa tags: trunk
2024-10-28
08:21
Fix spec for Ogg demuxer check-in: ad02ac220b user: alexa tags: trunk
Changes
Unified Diff Ignore Whitespace Patch
Changes to src/remiaudio/drivers.cr.
136
137
138
139
140
141
142









































143
144
145
146
147
148
149
        # :ditto::
        @[AlwaysInline]
        def <<(buf : Array({{typ}})|Slice({{typ}})) : Nil
          writeBuffer(buf)
        end
      {% end %}
    {% end %}









































  end

  # Creates a new `AudioDevice` instance, then yields it to the block.  This
  # ensures that `AudioDevice#stop` is called once the block exits.
  #
  # **T** must be a subclass of `RemiAudio::Drivers::AudioDevice` except
  # **`RemiAudio::Drivers::TcpDevice`.







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
        # :ditto::
        @[AlwaysInline]
        def <<(buf : Array({{typ}})|Slice({{typ}})) : Nil
          writeBuffer(buf)
        end
      {% end %}
    {% end %}

    # Plays back the audio in *buf* by sending it to the underlying backend.
    # This variation will first convert 24-bit signed integer audio to Float32
    # internally.
    #
    # You MUST ALWAYS pass the correct buffer size to `#writeBuffer`, as defined
    # by the value of `#bufferSize` multiplied by the number of `#channels`.
    def writeBufferI24(buf : Array(Int32)|Slice(Int32)) : Nil
      f32Buf = @f32ConvBuf
      if f32Buf.nil? || f32Buf.size != buf.size
        @f32ConvBuf = f32Buf = Array(Float32).new(buf.size, 0.0f32)
      end

      f32Buf.size.times do |i|
        f32Buf.unsafe_put(i, buf.unsafe_fetch(i) * INT24_INV_F32)
      end
      self.writeBuffer(f32Buf)
    end

    # Plays back the audio in *buf* by sending it to the underlying backend.
    # This variation will first convert audio to Float32 internally.
    #
    # You MUST ALWAYS pass the correct buffer size to `#writeBuffer`, as defined
    # by the value of `#bufferSize` multiplied by the number of `#channels`.
    def writeBuffer(buf : Array(UInt8)|Slice(UInt8)) : Nil
      f32Buf = @f32ConvBuf
      if f32Buf.nil? || f32Buf.size != buf.size
        @f32ConvBuf = f32Buf = Array(Float32).new(buf.size, 0.0f32)
      end

      f32Buf.size.times do |i|
        f32Buf.unsafe_put(i, (buf.unsafe_fetch(i).to_i16! - 128) * INT8_INV_F32)
      end
      self.writeBuffer(f32Buf)
    end

    # :ditto::
    @[AlwaysInline]
    def <<(buf : Array(UInt8)|Slice(UInt8)) : Nil
      writeBuffer(buf)
    end
  end

  # Creates a new `AudioDevice` instance, then yields it to the block.  This
  # ensures that `AudioDevice#stop` is called once the block exits.
  #
  # **T** must be a subclass of `RemiAudio::Drivers::AudioDevice` except
  # **`RemiAudio::Drivers::TcpDevice`.
Changes to src/remiaudio/drivers/ao.cr.
216
217
218
219
220
221
222


223
224
225
226
227
228
229
        Libao.close(@devicePtr)
        @devicePtr = Libao::PDevice.null
      end
      Libao.shutdown if @started
      @started = false
    end



    @[AlwaysInline]
    private def fillBuf(buf : Array(Float32)|Slice(Float32)) : UInt32
      len : Int32 = buf.size
      foreignLen : Int32 = len
      neededLen : Int32 = len
      i : Int32 = 0








>
>







216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
        Libao.close(@devicePtr)
        @devicePtr = Libao::PDevice.null
      end
      Libao.shutdown if @started
      @started = false
    end

    # Fills the internal buffer with audio from *buf* by converting it to the
    # proper format.
    @[AlwaysInline]
    private def fillBuf(buf : Array(Float32)|Slice(Float32)) : UInt32
      len : Int32 = buf.size
      foreignLen : Int32 = len
      neededLen : Int32 = len
      i : Int32 = 0

289
290
291
292
293
294
295








296






297



        unless buf.size == @expectedBufferSize
          raise AudioDeviceError.new("Buffer was the incorrect size: #{buf.size} != #{@expectedBufferSize}")
        end
      {% end %}
      len : UInt32 = fillBuf(buf)
      Libao.play(@devicePtr, @foreignBuf.to_unsafe.unsafe_as(Pointer(UInt8)), len)
    end








  end






end










>
>
>
>
>
>
>
>
|
>
>
>
>
>
>
|
>
>
>
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
        unless buf.size == @expectedBufferSize
          raise AudioDeviceError.new("Buffer was the incorrect size: #{buf.size} != #{@expectedBufferSize}")
        end
      {% end %}
      len : UInt32 = fillBuf(buf)
      Libao.play(@devicePtr, @foreignBuf.to_unsafe.unsafe_as(Pointer(UInt8)), len)
    end

    # :ditto:
    def writeBuffer(buf : Array(Int16)|Slice(Int16)) : Nil
      if @bitDepth == 16
        {% unless flag?(:remiaudio_wd40) %}
          raise AudioDeviceError.new("Device not started") unless @started
          unless buf.size == @expectedBufferSize
            raise AudioDeviceError.new("Buffer was the incorrect size: #{buf.size} != #{@expectedBufferSize}")
          end
        {% end %}

        # We can just send the buffer straight to libao.
        Libao.play(@devicePtr, buf.to_unsafe.unsafe_as(Pointer(UInt8)), buf.size * sizeof(Int16))
      else
        super(buf)
      end
    end
  end
end