mirror of
https://github.com/RGBCube/serenity
synced 2025-07-28 02:47:34 +00:00
Kernel/Audio: Introduce a new design architecture for the subsystem
We have 3 new components: 1. The AudioManagement singleton. This class like in other subsystems, is responsible to find hardware audio controllers and keep a reference to them. 2. AudioController class - this class is the parent class for hardware controllers like the Sound Blaster 16 or Intel 82801AA (AC97). For now, this class has simple interface for getting and controlling sample rate of audio channels, as well a write interface for specific audio channel but not reading from it. One AudioController object might have multiple AudioChannel "child" objects to hold with reference counting. 3. AudioChannel class - this is based on the CharacterDevice class, and represents hardware PCM audio channel. It facilitates an ioctl interface which should be consistent across all supported hardware currently. It has a weak reference to a parent AudioController, and when trying to write to a channel, it redirects the data to the parent AudioController. Each audio channel device should be added into a new directory under the /dev filesystem called "audio".
This commit is contained in:
parent
6218ec8afa
commit
6efa27537a
13 changed files with 382 additions and 127 deletions
|
@ -9,6 +9,7 @@
|
|||
#include <Kernel/Arch/x86/IO.h>
|
||||
#include <Kernel/Bus/PCI/API.h>
|
||||
#include <Kernel/Bus/PCI/Device.h>
|
||||
#include <Kernel/Devices/Audio/Controller.h>
|
||||
#include <Kernel/Devices/CharacterDevice.h>
|
||||
#include <Kernel/Interrupts/IRQHandler.h>
|
||||
|
||||
|
@ -17,25 +18,18 @@ namespace Kernel {
|
|||
// See: https://www-inst.eecs.berkeley.edu/~cs150/Documents/ac97_r23.pdf
|
||||
// And: https://www.intel.com/content/dam/doc/manual/io-controller-hub-7-hd-audio-ac97-manual.pdf
|
||||
|
||||
class AC97 final : public PCI::Device
|
||||
, public IRQHandler
|
||||
, public CharacterDevice {
|
||||
friend class DeviceManagement;
|
||||
class AC97 final
|
||||
: public AudioController
|
||||
, public PCI::Device
|
||||
, public IRQHandler {
|
||||
|
||||
public:
|
||||
static void detect();
|
||||
static ErrorOr<NonnullRefPtr<AC97>> try_create(PCI::DeviceIdentifier const&);
|
||||
|
||||
virtual ~AC97() override;
|
||||
|
||||
// ^IRQHandler
|
||||
virtual StringView purpose() const override { return class_name(); }
|
||||
|
||||
// ^CharacterDevice
|
||||
virtual bool can_read(const OpenFileDescription&, u64) const override { return false; }
|
||||
virtual bool can_write(const OpenFileDescription&, u64) const override { return true; }
|
||||
virtual ErrorOr<void> ioctl(OpenFileDescription&, unsigned, Userspace<void*>) override;
|
||||
virtual ErrorOr<size_t> read(OpenFileDescription&, u64, UserOrKernelBuffer&, size_t) override;
|
||||
virtual ErrorOr<size_t> write(OpenFileDescription&, u64, const UserOrKernelBuffer&, size_t) override;
|
||||
virtual StringView purpose() const override { return "AC97"sv; }
|
||||
|
||||
private:
|
||||
enum NativeAudioMixerRegister : u8 {
|
||||
|
@ -150,9 +144,6 @@ private:
|
|||
// ^IRQHandler
|
||||
virtual bool handle_irq(const RegisterState&) override;
|
||||
|
||||
// ^CharacterDevice
|
||||
virtual StringView class_name() const override { return "AC97"sv; }
|
||||
|
||||
AC97Channel channel(StringView name, NativeAudioBusChannel channel) { return AC97Channel(*this, name, m_io_bus_base.offset(channel)); }
|
||||
void initialize();
|
||||
void reset_pcm_out();
|
||||
|
@ -161,6 +152,13 @@ private:
|
|||
void set_pcm_output_volume(u8, u8, Muted);
|
||||
ErrorOr<void> write_single_buffer(UserOrKernelBuffer const&, size_t, size_t);
|
||||
|
||||
// ^AudioController
|
||||
virtual RefPtr<AudioChannel> audio_channel(u32 index) const override;
|
||||
virtual ErrorOr<size_t> write(size_t channel_index, UserOrKernelBuffer const& data, size_t length) override;
|
||||
virtual void detect_hardware_audio_channels(Badge<AudioManagement>) override;
|
||||
virtual ErrorOr<void> set_pcm_output_sample_rate(size_t channel_index, u32 samples_per_second_rate) override;
|
||||
virtual ErrorOr<u32> get_pcm_output_sample_rate(size_t channel_index) override;
|
||||
|
||||
OwnPtr<Memory::Region> m_buffer_descriptor_list;
|
||||
u8 m_buffer_descriptor_list_index = 0;
|
||||
bool m_double_rate_pcm_enabled = false;
|
||||
|
@ -173,6 +171,7 @@ private:
|
|||
AC97Channel m_pcm_out_channel;
|
||||
u32 m_sample_rate = 0;
|
||||
bool m_variable_rate_pcm_supported = false;
|
||||
RefPtr<AudioChannel> m_audio_channel;
|
||||
};
|
||||
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue