Sona 0.50 Source

Sona 0.50/tools/mml2sona/stream.h

#ifndef STREAM_H_
#define STREAM_H_

#include "main.h"

// Avaiable channels
typedef enum {
   CHAN_NONE,
   CHAN_CTRL,
   CHAN_FM1, CHAN_FM2, CHAN_FM3, CHAN_FM4, CHAN_FM5, CHAN_FM6, CHAN_FMX,
   CHAN_PSG1, CHAN_PSG2, CHAN_PSG3, CHAN_PSG4, CHAN_PSGX,
   CHAN_PCM1, CHAN_PCM2, CHAN_PCMX,
   NUM_CHANNELS
} Channel;

// Possible stream event types
typedef enum {
   EVENT_NONE,                   // (ignore)
   
   EVENT_LOAD,                   // Load instrument
   EVENT_KEYON,                  // Key-on
   EVENT_KEYOFF,                 // Key-off
   EVENT_PITCH,                  // Set pitch
   EVENT_VOLUME,                 // Set volume
   EVENT_PAN,                    // Set panning
   EVENT_TEMPO,                  // Set tempo
   EVENT_FMREG,                  // FM register write
   EVENT_LOOP,                   // Set loop point
   EVENT_LOCK,                   // Lock channel
   
   EVENT_VMMOVE,                 // var = value
   EVENT_VMADD,                  // var = var + value
   EVENT_VMSUB,                  // var = var - value
   EVENT_VMAND,                  // var = var AND value
   EVENT_VMOR,                   // var = var OR value
   EVENT_VMXOR,                  // var = var XOR value
   
   EVENT_RAW,                    // Raw byte
} EventType;

// Data for a single stream event
typedef struct {
   EventType type;               // Event type
   Channel channel;              // Affected channel
   int arg[4];                   // Event arguments
   
   uint64_t timestamp;           // Event timestamp in ticks
   size_t sort_priority;         // Sorting order priority between events
                                 // that have the same timestamp (events with
                                 // lower values are placed earlier)
} Event;

// Data for a whole stream
typedef struct {
   Event *events;                // Pointer to array of events
   size_t num_events;            // Number of events in the stream
   size_t allocated_events;      // Number of allocated slots in the array
   uint64_t timestamp;           // Current timestamp
   uint64_t end_timestamp;       // Timestamp at end of stream
   
   unsigned looped: 1;           // Set if it loops
} Stream;

Stream *create_stream(void);
Event *create_event(Stream *stream);
void sort_stream(Stream *stream);
void delete_stream(Stream *stream);

//***************************************************************************
// Quick functions to determine if a channel is of a given type.
//---------------------------------------------------------------------------
// Yes, the inline is needed (not for optimization, but because it tells the
// compiler to not complain if a function isn't used despite being static —
// it's either that or turn them into macros)
//***************************************************************************

static inline int is_fm(Channel chan) {
   return chan >= CHAN_FM1 && chan <= CHAN_FMX;
}
static inline int is_psg(Channel chan) {
   return chan >= CHAN_PSG1 && chan <= CHAN_PSGX;
}
static inline int is_square(Channel chan) {
   return is_psg(chan) && chan != CHAN_PSG4;
}
static inline int is_pcm(Channel chan) {
   return chan >= CHAN_PCM1 && chan <= CHAN_PCMX;
}
static inline int is_real_chan(Channel chan) {
   return is_fm(chan) || is_psg(chan) || is_pcm(chan);
}

#endif