Sampled Instrument Player with static and monolithic design. All instruments are built-in.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

200 lines
8.7 KiB

/*
Calf Box, an open source musical instrument.
Copyright (C) 2010-2011 Krzysztof Foltman
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef CBOX_SEQ_H
#define CBOX_SEQ_H
#include <stdint.h>
#include "dom.h"
#include "midi.h"
#include "mididest.h"
struct cbox_engine;
struct cbox_midi_pattern;
struct cbox_track;
struct cbox_song;
/////////////////////////////////////////////////////////////////////////////////////////////////////
struct cbox_midi_playback_active_notes
{
uint16_t channels_active;
uint32_t notes[16][4]; // 0..127
};
extern void cbox_midi_playback_active_notes_init(struct cbox_midi_playback_active_notes *notes);
extern void cbox_midi_playback_active_notes_copy(struct cbox_midi_playback_active_notes *dest, const struct cbox_midi_playback_active_notes *src);
extern void cbox_midi_playback_active_notes_clear(struct cbox_midi_playback_active_notes *notes);
extern int cbox_midi_playback_active_notes_release(struct cbox_midi_playback_active_notes *notes, struct cbox_midi_buffer *buf, struct cbox_midi_playback_active_notes *leftover_notes);
/////////////////////////////////////////////////////////////////////////////////////////////////////
struct cbox_midi_pattern_playback
{
struct cbox_midi_event *events;
uint32_t event_count;
int ref_count;
GSequence *note_lookup;
struct cbox_midi_playback_active_notes note_bitmask;
};
extern struct cbox_midi_pattern_playback *cbox_midi_pattern_playback_new(struct cbox_midi_pattern *pattern);
extern void cbox_midi_pattern_playback_ref(struct cbox_midi_pattern_playback *mppb);
extern void cbox_midi_pattern_playback_unref(struct cbox_midi_pattern_playback *mppb);
extern void cbox_midi_pattern_playback_destroy(struct cbox_midi_pattern_playback *mppb);
extern gboolean cbox_midi_pattern_playback_is_note_active_at(struct cbox_midi_pattern_playback *mppb, uint32_t time_ppqn, uint32_t channel, uint32_t note);
/////////////////////////////////////////////////////////////////////////////////////////////////////
struct cbox_midi_clip_playback
{
struct cbox_midi_pattern_playback *pattern;
struct cbox_master *master;
uint32_t pos;
int rel_time_samples;
// [start, end) of the pattern slice
uint32_t start_time_samples, end_time_samples;
uint32_t item_start_ppqn, min_time_ppqn;
int offset_ppqn;
struct cbox_midi_playback_active_notes *active_notes;
};
extern void cbox_midi_clip_playback_init(struct cbox_midi_clip_playback *pb, struct cbox_midi_playback_active_notes *active_notes, struct cbox_master *master);
extern void cbox_midi_clip_playback_render(struct cbox_midi_clip_playback *pb, struct cbox_midi_buffer *buf, uint32_t offset, uint32_t nsamples, gboolean mute);
extern void cbox_midi_clip_playback_seek_ppqn(struct cbox_midi_clip_playback *pb, uint32_t time_ppqn, uint32_t min_time_ppqn);
extern void cbox_midi_clip_playback_seek_samples(struct cbox_midi_clip_playback *pb, uint32_t time_samples, uint32_t min_time_ppqn);
extern void cbox_midi_clip_playback_set_pattern(struct cbox_midi_clip_playback *pb, struct cbox_midi_pattern_playback *pattern, int start_time_samples, int end_time_samples, int item_start_ppqn, int offset_ppqn);
/////////////////////////////////////////////////////////////////////////////////////////////////////
// all times in this structure are in PPQN
struct cbox_track_playback_item
{
uint32_t time;
struct cbox_midi_pattern_playback *pattern;
uint32_t offset;
uint32_t length;
// in future, it should also contain a pre-calculated list of notes to release
};
struct cbox_track_playback
{
struct cbox_uuid track_uuid; // used as identification only
struct cbox_track_playback_item *items;
struct cbox_master *master;
uint32_t items_count;
uint32_t pos;
uint32_t generation; // of the original track
int ref_count;
struct cbox_midi_buffer output_buffer;
struct cbox_midi_clip_playback playback;
struct cbox_midi_playback_active_notes active_notes;
struct cbox_midi_merger *external_merger;
struct cbox_song_playback *spb;
struct cbox_track_playback *old_state;
gboolean state_copied;
gboolean mute;
};
extern struct cbox_track_playback *cbox_track_playback_new_from_track(struct cbox_track *track, struct cbox_master *master, struct cbox_song_playback *spb, struct cbox_track_playback *old_state);
extern void cbox_track_playback_render(struct cbox_track_playback *pb, uint32_t offset, uint32_t nsamples);
extern void cbox_track_playback_seek_ppqn(struct cbox_track_playback *pb, uint32_t time_ppqn, uint32_t min_time_ppqn);
extern void cbox_track_playback_seek_samples(struct cbox_track_playback *pb, uint32_t time_samples);
extern void cbox_track_playback_start_item(struct cbox_track_playback *pb, int time, int is_ppqn, int skip_this_pos);
extern void cbox_track_confirm_stuck_notes(struct cbox_track_playback *pb, struct cbox_midi_playback_active_notes *stuck_notes, uint32_t new_pos);
extern void cbox_track_playback_destroy(struct cbox_track_playback *pb);
/////////////////////////////////////////////////////////////////////////////////////////////////////
struct cbox_tempo_map_item
{
uint32_t time_ppqn;
uint32_t time_samples;
double tempo;
int timesig_num, timesig_denom;
struct cbox_bbt bbt;
};
/////////////////////////////////////////////////////////////////////////////////////////////////////
struct cbox_adhoc_pattern
{
struct cbox_adhoc_pattern *next;
struct cbox_master *master;
struct cbox_midi_pattern *pattern;
struct cbox_midi_pattern_playback *pattern_playback;
struct cbox_midi_playback_active_notes active_notes;
struct cbox_midi_clip_playback playback;
struct cbox_midi_buffer output_buffer;
int id;
gboolean completed;
};
extern struct cbox_adhoc_pattern *cbox_adhoc_pattern_new(struct cbox_engine *engine, int id, struct cbox_midi_pattern *pattern);
extern void cbox_adhoc_pattern_render(struct cbox_adhoc_pattern *adp, uint32_t offset, uint32_t nsamples);
extern void cbox_adhoc_pattern_destroy(struct cbox_adhoc_pattern *ap);
/////////////////////////////////////////////////////////////////////////////////////////////////////
struct cbox_song_playback
{
struct cbox_master *master;
struct cbox_song *song; // for identification only
struct cbox_track_playback **tracks;
uint32_t track_count;
struct cbox_tempo_map_item *tempo_map_items;
int tempo_map_item_count;
int tempo_map_pos;
uint32_t song_pos_samples, song_pos_ppqn, min_time_ppqn;
uint32_t loop_start_ppqn, loop_end_ppqn;
GHashTable *pattern_map;
struct cbox_midi_merger track_merger;
struct cbox_engine *engine;
};
extern struct cbox_song_playback *cbox_song_playback_new(struct cbox_song *song, struct cbox_master *master, struct cbox_engine *engine, struct cbox_song_playback *old_state);
extern void cbox_song_playback_prepare_render(struct cbox_song_playback *spb);
extern void cbox_song_playback_render(struct cbox_song_playback *spb, struct cbox_midi_buffer *output, uint32_t nsamples);
extern int cbox_song_playback_active_notes_release(struct cbox_song_playback *old_spb, struct cbox_song_playback *new_spb, uint32_t new_pos, struct cbox_midi_buffer *buf);
extern void cbox_song_playback_seek_ppqn(struct cbox_song_playback *spb, int time_ppqn, int skip_this_pos);
extern void cbox_song_playback_seek_samples(struct cbox_song_playback *spb, uint32_t time_samples);
extern int cbox_song_playback_tmi_from_ppqn(struct cbox_song_playback *spb, uint32_t time_ppqn);
extern int cbox_song_playback_tmi_from_samples(struct cbox_song_playback *spb, uint32_t time_samples);
struct cbox_midi_pattern_playback *cbox_song_playback_get_pattern(struct cbox_song_playback *spb, struct cbox_midi_pattern *pattern);
extern void cbox_song_playback_apply_old_state(struct cbox_song_playback *spb);
uint32_t cbox_song_playback_correct_for_looping(struct cbox_song_playback *spb, uint32_t abs_samples);
extern void cbox_song_playback_destroy(struct cbox_song_playback *spb);
/////////////////////////////////////////////////////////////////////////////////////////////////////
struct cbox_song_time_mapper
{
struct cbox_time_mapper tmap;
struct cbox_engine *engine;
};
extern void cbox_song_time_mapper_init(struct cbox_song_time_mapper *tmap, struct cbox_engine *engine);
#endif