diff --git a/Tests/LibWeb/Text/expected/WebAudio/AudioBuffer-copyToChannel.txt b/Tests/LibWeb/Text/expected/WebAudio/AudioBuffer-copyToChannel.txt
new file mode 100644
index 00000000000..deaf4b6322b
--- /dev/null
+++ b/Tests/LibWeb/Text/expected/WebAudio/AudioBuffer-copyToChannel.txt
@@ -0,0 +1,9 @@
+Error calling copyToChannel: IndexSizeError: Channel index is out of range
+Error calling copyToChannel: TypeError: Not an object of type Float32Array
+5,5,5,5,5,5,5
+1,1,1,1,1,1,1
+1,1,1,1,1,1,1
+1,1,1,1,1,1,1
+2,2,3,3,3,3,3
+2,2,3,3,3,3,3
+Done.
diff --git a/Tests/LibWeb/Text/input/WebAudio/AudioBuffer-copyToChannel.html b/Tests/LibWeb/Text/input/WebAudio/AudioBuffer-copyToChannel.html
new file mode 100644
index 00000000000..2ba85faf1da
--- /dev/null
+++ b/Tests/LibWeb/Text/input/WebAudio/AudioBuffer-copyToChannel.html
@@ -0,0 +1,75 @@
+
+
diff --git a/Userland/Libraries/LibWeb/WebAudio/AudioBuffer.cpp b/Userland/Libraries/LibWeb/WebAudio/AudioBuffer.cpp
index c39b800fa9d..b9ae09f79fa 100644
--- a/Userland/Libraries/LibWeb/WebAudio/AudioBuffer.cpp
+++ b/Userland/Libraries/LibWeb/WebAudio/AudioBuffer.cpp
@@ -105,11 +105,31 @@ WebIDL::ExceptionOr AudioBuffer::copy_from_channel(JS::Handle AudioBuffer::copy_to_channel(JS::Handle&, WebIDL::UnsignedLong channel_number, WebIDL::UnsignedLong buffer_offset) const
+WebIDL::ExceptionOr AudioBuffer::copy_to_channel(JS::Handle const& source, WebIDL::UnsignedLong channel_number, WebIDL::UnsignedLong buffer_offset)
{
- (void)channel_number;
- (void)buffer_offset;
- return WebIDL::NotSupportedError::create(realm(), "FIXME: Implement AudioBuffer:copy_to_channel:"_fly_string);
+ // The copyToChannel() method copies the samples to the specified channel of the AudioBuffer from the source array.
+ //
+ // A UnknownError may be thrown if source cannot be copied to the buffer.
+ //
+ // Let buffer be the AudioBuffer with Nb frames, let Nf be the number of elements in the source array, and k be the value
+ // of bufferOffset. Then the number of frames copied from source to the buffer is max(0,min(Nb−k,Nf)). If this is less than Nf,
+ // then the remaining elements of buffer are not modified.
+ auto& vm = this->vm();
+
+ if (!is(*source->raw_object()))
+ return vm.throw_completion(JS::ErrorType::NotAnObjectOfType, "Float32Array");
+ auto const& float32_array = static_cast(*source->raw_object());
+
+ auto channel = TRY(get_channel_data(channel_number));
+
+ auto channel_length = channel->data().size();
+ if (buffer_offset >= channel_length)
+ return {};
+
+ u32 count = min(float32_array.data().size(), channel_length - buffer_offset);
+ float32_array.data().slice(0, count).copy_to(channel->data().slice(buffer_offset, count));
+
+ return {};
}
AudioBuffer::AudioBuffer(JS::Realm& realm, AudioBufferOptions const& options)
diff --git a/Userland/Libraries/LibWeb/WebAudio/AudioBuffer.h b/Userland/Libraries/LibWeb/WebAudio/AudioBuffer.h
index 205a807fff6..3bb8a735c8a 100644
--- a/Userland/Libraries/LibWeb/WebAudio/AudioBuffer.h
+++ b/Userland/Libraries/LibWeb/WebAudio/AudioBuffer.h
@@ -38,7 +38,7 @@ public:
WebIDL::UnsignedLong number_of_channels() const;
WebIDL::ExceptionOr> get_channel_data(WebIDL::UnsignedLong channel) const;
WebIDL::ExceptionOr copy_from_channel(JS::Handle const&, WebIDL::UnsignedLong channel_number, WebIDL::UnsignedLong buffer_offset = 0) const;
- WebIDL::ExceptionOr copy_to_channel(JS::Handle&, WebIDL::UnsignedLong channel_number, WebIDL::UnsignedLong buffer_offset = 0) const;
+ WebIDL::ExceptionOr copy_to_channel(JS::Handle const&, WebIDL::UnsignedLong channel_number, WebIDL::UnsignedLong buffer_offset = 0);
private:
explicit AudioBuffer(JS::Realm&, AudioBufferOptions const&);