1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-06-01 10:38:13 +00:00
serenity/Userland/Applications/Piano/Track.h
David Isaksson b6d075bb01 LibAudio: Rename Audio::Frame -> Audio::Sample
"Frame" is an MPEG term, which is not only unintuitive but also
overloaded with different meaning by other codecs (e.g. FLAC).
Therefore, use the standard term Sample for the central audio structure.

The class is also extracted to its own file, because it's becoming quite
large. Bundling these two changes means not distributing similar
modifications (changing names and paths) across commits.

Co-authored-by: kleines Filmröllchen <malu.bertsch@gmail.com>
2021-11-08 16:29:25 -08:00

88 lines
2.7 KiB
C++

/*
* Copyright (c) 2018-2020, Andreas Kling <kling@serenityos.org>
* Copyright (c) 2019-2020, William McPherson <willmcpherson2@gmail.com>
* Copyright (c) 2021, kleines Filmröllchen <malu.bertsch@gmail.com>
*
* SPDX-License-Identifier: BSD-2-Clause
*/
#pragma once
#include "Music.h"
#include <AK/Noncopyable.h>
#include <AK/SinglyLinkedList.h>
#include <LibAudio/Buffer.h>
#include <LibDSP/Effects.h>
using RollIter = AK::SinglyLinkedListIterator<SinglyLinkedList<RollNote>, RollNote>;
class Track {
AK_MAKE_NONCOPYABLE(Track);
AK_MAKE_NONMOVABLE(Track);
public:
explicit Track(const u32& time);
~Track();
const Vector<Audio::Sample>& recorded_sample() const { return m_recorded_sample; }
const SinglyLinkedList<RollNote>& roll_notes(int note) const { return m_roll_notes[note]; }
int wave() const { return m_wave; }
int volume() const { return m_volume; }
int attack() const { return m_attack; }
int decay() const { return m_decay; }
int sustain() const { return m_sustain; }
int release() const { return m_release; }
NonnullRefPtr<LibDSP::Effects::Delay> delay() { return m_delay; }
void fill_sample(Sample& sample);
void reset();
String set_recorded_sample(const StringView& path);
void set_note(int note, Switch);
void set_roll_note(int note, u32 on_sample, u32 off_sample);
void set_wave(int wave);
void set_wave(Direction);
void set_volume(int volume);
void set_attack(int attack);
void set_decay(int decay);
void set_sustain(int sustain);
void set_release(int release);
private:
Audio::Sample sine(size_t note);
Audio::Sample saw(size_t note);
Audio::Sample square(size_t note);
Audio::Sample triangle(size_t note);
Audio::Sample noise(size_t note);
Audio::Sample recorded_sample(size_t note);
void sync_roll(int note);
void set_sustain_impl(int sustain);
Vector<Audio::Sample> m_recorded_sample;
u8 m_note_on[note_count] { 0 };
double m_power[note_count] { 0 };
double m_pos[note_count]; // Initialized lazily.
// Synths may use this to keep track of the last wave position
double m_last_w[note_count] { 0 };
Envelope m_envelope[note_count] { Done };
int m_wave { first_wave };
int m_volume;
int m_attack;
double m_attack_step;
int m_decay;
double m_decay_step;
int m_sustain;
double m_sustain_level;
int m_release;
double m_release_step[note_count];
const u32& m_time;
NonnullRefPtr<LibDSP::Transport> m_temporary_transport;
NonnullRefPtr<LibDSP::Effects::Delay> m_delay;
SinglyLinkedList<RollNote> m_roll_notes[note_count];
RollIter m_roll_iterators[note_count];
};