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
200 lines
8.7 KiB
3 years ago
|
/*
|
||
|
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
|