Re: [LAD] Writing a music notation editor and need some help with MIDI, Jack, and FluidSynth

Previous message: [thread] [date] [author]
Next message: [thread] [date] [author]
To: <linux-audio-dev@...>
Date: Monday, December 24, 2012 - 12:52 am

Here's my first attempt. I figured I'd start with an alsa client that outlines
the basics of what I want it to do. Once I get this, I'll try making the jack
connections from within my program. For now, I'm using QJackCtl and QSynth to
get the others going and make the connection.

The abbreviated C++ code follows. I edited out command line and i/o stuff.
After reading a data file, the vector notes holds all the relevant stuff. If
anyone's interested, I can post the entire code and the sample data file.

The first thing I don't understand is in scheduleEvents() why passing absolute
times to the queue doesn't work. And once I have absolute times, how do I do
the play/pause in the transport loop in main().

// Trivial sequencer that reads note data from a file and plays the contents.

#include
#include
#include
#include
#include
#include
#include

using namespace std;

enum TransportState {Stopped = 0, Paused, Playing};

// Struct holding note start time, pitch, duration, volume.
// time and duration are in ticks.
struct NoteStruct {int t; int p; int d; int v;};

vector notes;

// Usage message and exit.
void usage(string msg);

// Exit with error message.
void die(string msg);

// Create a new client.
snd_seq_t *openClient()
{
snd_seq_t *seq;
int ret = snd_seq_open(&seq, "default", SND_SEQ_OPEN_DUPLEX, 0);
if (ret < 0) die("Failed to open sequencer client.");
snd_seq_set_client_name(seq, "AJDemo Client");
return seq;
}

// Create a new output (read) port and return the port id.
int createOutputPort(snd_seq_t *seq)
{
int id = snd_seq_create_simple_port(seq, "AJDemo Port",
SND_SEQ_PORT_CAP_READ|SND_SEQ_PORT_CAP_SUBS_READ,
SND_SEQ_PORT_TYPE_MIDI_GENERIC);
if (id < 0) die("Failed to create output port.");
return id;
}

void setTempo(snd_seq_t *seq, int q, int bpm, int ppq)
{
cout << "Setting tempo, bpm = " << bpm << ", ppq = " << ppq << endl;
int microsec = 60 * 1000000 / bpm;
snd_seq_queue_tempo_t *tempo;
snd_seq_queue_tempo_alloca(&tempo);
snd_seq_queue_tempo_set_tempo(tempo, microsec);
snd_seq_queue_tempo_set_ppq(tempo, ppq);
snd_seq_set_queue_tempo(seq, q, tempo);
}

// Put contents of notes on the queue as MIDI events.
void scheduleEvents(snd_seq_t *seq, int port, int q)
{
cout << "Scheduling events.\n";
int delta = 0;
int t = 0; // abs time
int prevT = 0;
snd_seq_event_t ev;
for (int i=0; i> c;
if (c == 'q') break;
else if (c == 'p')
{
if (state == Playing)
{
cout << "Pausing.\n";
state = Paused;
snd_seq_stop_queue(seq, qId, NULL);
}
else if (state == Paused)
{
cout << "Resuming playing.\n";
state = Playing;
setQueuePos(seq, portId, qId, 0);
snd_seq_continue_queue(seq, qId, NULL);
}
else
{
cout << "Playing.\n";
state = Playing;
snd_seq_start_queue(seq, qId, NULL);
scheduleEvents(seq, portId, qId);
}
}
else if (c == 's')
{
cout << "Stopping.\n";
state = Stopped;
snd_seq_drop_input(seq);
snd_seq_drop_output(seq);
snd_seq_stop_queue(seq, qId, NULL);
}

snd_seq_drain_output(seq);
}
snd_seq_free_queue(seq, qId);
return 0;
}

--
7:8
_______________________________________________
Linux-audio-dev mailing list
Linux-audio-dev@lists.linuxaudio.org
http://lists.linuxaudio.org/listinfo/linux-audio-dev

Previous message: [thread] [date] [author]
Next message: [thread] [date] [author]

Messages in current thread:
Re: [LAD] Writing a music notation editor and need some help..., M Donalies, (Mon Dec 24, 12:52 am)