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

Overview
Comment:Add convenience methods to write buffers of other types
Downloads: Tarball | ZIP archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA3-256: 4461ed395d57c6b2562d509e500c90747be7afd6153c2c49aca97ab32fb24ff9
User & Date: alexa 2024-10-28 08:12:44.629
Context
2024-10-28
08:13
Add Timestamp.fromBytePos, Timestamp#toBytePos, Timestamp#nanoseconds, and Timestamp#- methods. check-in: 83424a863a user: alexa tags: trunk
08:12
Add convenience methods to write buffers of other types check-in: 4461ed395d user: alexa tags: trunk
08:11
Add some often-used constants check-in: 6f9f824e80 user: alexa tags: trunk
Changes
Unified Diff Ignore Whitespace Patch
Changes to src/remiaudio/drivers.cr.
66
67
68
69
70
71
72


73
74
75
76
77
78
79
    # This value changes depending on what you set for `#bufferSize`.
    getter expectedBufferSize : UInt32 = 4096u32

    # Returns `true` if the device has been started, or `false` otherwise.
    getter? started : Bool = false

    @outputSize : UInt32 = 4096u32 * sizeof(Float32)



    # Sets the buffer size.  This dictates what size of array you must pass into
    # `#writeBuffer`.  This is per-channel, so if this is 2048 and there are two
    # channels, then you need an array of 4096 elements for a buffer.
    #
    # This MUST NOT change after the driver has been started, and you MUST
    # ALWAYS pass the correct buffer size to `#writeBuffer`.  Any attempt to







>
>







66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
    # This value changes depending on what you set for `#bufferSize`.
    getter expectedBufferSize : UInt32 = 4096u32

    # Returns `true` if the device has been started, or `false` otherwise.
    getter? started : Bool = false

    @outputSize : UInt32 = 4096u32 * sizeof(Float32)

    @f32ConvBuf : Array(Float32)? = nil

    # Sets the buffer size.  This dictates what size of array you must pass into
    # `#writeBuffer`.  This is per-channel, so if this is 2048 and there are two
    # channels, then you need an array of 4096 elements for a buffer.
    #
    # This MUST NOT change after the driver has been started, and you MUST
    # ALWAYS pass the correct buffer size to `#writeBuffer`.  Any attempt to
106
107
108
109
110
111
112




























113
114
115
116
117
118
119
    abstract def writeBuffer(buf : Array(Float32)|Slice(Float32)) : Nil

    # :ditto::
    @[AlwaysInline]
    def <<(buf : Array(Float32)|Slice(Float32)) : 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`.







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







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
    abstract def writeBuffer(buf : Array(Float32)|Slice(Float32)) : Nil

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

    {% begin %}
      {% for size in [8, 16, 32] %}
        {% typ = "Int#{size}".id %}
        # 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({{typ}})|Slice({{typ}})) : 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) * INT{{size}}_INV_F32)
          end
          self.writeBuffer(f32Buf)
        end

        # :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`.