1
Fork 0
jacker/player.hpp

125 lines
2.9 KiB
C++
Raw Permalink Normal View History

2010-02-05 11:28:16 +02:00
#pragma once
#include <vector>
#include "midi.hpp"
#include "ring_buffer.hpp"
namespace Jacker {
//=============================================================================
2010-02-10 00:44:06 +02:00
struct Message : MIDI::Message {
enum Type {
// empty, for updating position
TypeEmpty = 0,
// midi package
TypeMIDI = 1,
2010-03-21 17:31:24 +02:00
// command
TypeCommandChannelVolume = 'V',
2010-03-21 17:37:03 +02:00
TypeCommandTempo = 'T',
2010-02-10 00:44:06 +02:00
};
Type type;
long long timestamp;
int frame;
int bus;
int bus_channel;
int port;
2010-02-10 00:44:06 +02:00
Message();
};
class MessageQueue : public RingBuffer<Message> {
public:
MessageQueue();
volatile long long write_samples; // 0-32: subsample, 32-64: sample
volatile int position; // in frames
volatile long long read_samples;
2010-03-21 17:31:24 +02:00
void on_note(int bus, int channel, int value, int velocity);
2010-02-10 00:44:06 +02:00
void on_cc(int bus, int ccindex, int ccvalue);
2010-03-21 18:14:53 +02:00
void on_command(int bus, int channel, Message::Type command, int value, int value2, int value3);
void all_notes_off(int bus);
2010-02-10 00:44:06 +02:00
void status_msg();
void init_message(int bus, Message &msg);
2010-02-10 00:44:06 +02:00
2010-02-12 09:02:08 +02:00
void set_model(class Model &model);
protected:
class Model *model;
2010-02-10 00:44:06 +02:00
};
2010-02-05 11:28:16 +02:00
class Player {
public:
2010-02-10 00:44:06 +02:00
enum {
// how many message queues are used
// for flipping?
QueueCount = 4,
};
2010-02-06 01:06:39 +02:00
struct Channel {
2010-03-21 17:31:24 +02:00
float volume;
2010-02-12 00:20:20 +02:00
int note;
2010-02-06 01:06:39 +02:00
Channel();
};
typedef std::vector<Channel> ChannelArray;
2010-02-12 00:20:20 +02:00
typedef std::vector<char> NoteArray;
2010-02-06 01:06:39 +02:00
2010-02-05 11:28:16 +02:00
struct Bus {
2010-02-06 01:06:39 +02:00
ChannelArray channels;
2010-02-12 00:20:20 +02:00
// stores which key is pressed on
// which channel. (notes[key] = channel)
NoteArray notes;
2010-02-05 11:28:16 +02:00
Bus();
};
Player();
2010-02-06 15:28:58 +02:00
void reset();
void mix();
2010-02-08 10:02:26 +02:00
void process_messages(int size);
virtual void on_message(const Message &msg) {}
2010-02-05 21:49:45 +02:00
2010-02-06 15:28:58 +02:00
void set_model(class Model &model);
2010-02-05 21:49:45 +02:00
void set_sample_rate(int sample_rate);
2010-02-06 15:28:58 +02:00
void stop();
void play();
2010-02-10 00:44:06 +02:00
void seek(int position);
2010-02-10 14:34:56 +02:00
void flush();
2010-02-06 15:28:58 +02:00
int get_position() const;
2010-02-10 00:44:06 +02:00
bool is_playing() const;
2010-02-06 15:28:58 +02:00
void play_event(int track, const class PatternEvent &event);
2010-09-06 20:52:56 +03:00
void stop_events(int track);
2010-02-05 21:49:45 +02:00
protected:
2010-02-10 00:44:06 +02:00
void premix();
void mix_events(MessageQueue &queue, int samples);
void mix_frame(MessageQueue &queue);
2010-02-08 10:02:26 +02:00
void handle_message(Message msg);
long long get_frame_size();
2010-02-10 00:44:06 +02:00
MessageQueue &get_back();
MessageQueue &get_front();
void flip();
2010-02-05 21:49:45 +02:00
int sample_rate;
2010-02-10 00:44:06 +02:00
volatile int front_index; // index of messages front buffer
2010-02-06 15:28:58 +02:00
std::vector<Bus> buses;
2010-02-10 00:44:06 +02:00
MessageQueue messages[QueueCount];
MessageQueue rt_messages;
2010-02-06 15:28:58 +02:00
class Model *model;
2010-02-10 00:44:06 +02:00
volatile int read_position; // last read position, in frames
volatile bool playing;
2010-02-05 11:28:16 +02:00
};
//=============================================================================
} // namespace Jacker