summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authordeva <deva>2008-07-21 11:01:04 +0000
committerdeva <deva>2008-07-21 11:01:04 +0000
commit242285d4863a66b4033ca7b5371bae5160ccf62c (patch)
tree82764064fe098afeaff7b74a9191bafe8777ce44
parentad01025218b7883fcec1e9ef9f6df5b5f6f698e8 (diff)
First very simple sample implementation. Basic MIDI test framework.
-rw-r--r--src/Makefile.am12
-rw-r--r--src/drumgizmo.cc54
-rw-r--r--src/event.cc43
-rw-r--r--src/event.h47
-rw-r--r--src/jackclient.cc102
-rw-r--r--src/jackclient.h14
-rw-r--r--src/sample.cc55
-rw-r--r--src/sample.h41
8 files changed, 333 insertions, 35 deletions
diff --git a/src/Makefile.am b/src/Makefile.am
index aec9534..7e7ebbe 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -1,12 +1,16 @@
bin_PROGRAMS = drumgizmo
-drumgizmo_LDADD = $(JACK_LIBS)
+drumgizmo_LDADD = $(JACK_LIBS) $(SNDFILE_LIBS)
-drumgizmo_CXXFLAGS = $(JACK_CXXFLAGS)
+drumgizmo_CXXFLAGS = $(JACK_CXXFLAGS) $(SNDFILE_CXXFLAGS)
drumgizmo_SOURCES = \
drumgizmo.cc \
- jackclient.cc
+ event.cc \
+ jackclient.cc \
+ sample.cc
EXTRA_DIST = \
- jackclient.h
+ jackclient.h \
+ event.h \
+ sample.h
diff --git a/src/drumgizmo.cc b/src/drumgizmo.cc
index 019abbb..737a197 100644
--- a/src/drumgizmo.cc
+++ b/src/drumgizmo.cc
@@ -24,14 +24,66 @@
* along with DrumGizmo; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-
#include "jackclient.h"
+#include <jack/jack.h>
+#include <jack/midiport.h>
+
+static jack_port_t *test_midi_port = NULL;
+static size_t timer = 0;
+
+int process(jack_nframes_t nframes, void *arg)
+{
+ // if(jack_port_connected_to(test_midi_port, "DrumGizmo:midi_in")) {
+ void* port_buf = jack_port_get_buffer(test_midi_port, nframes);
+
+ if(timer > 44100) { // activate every second (44100 samples)
+ printf("ding\n");
+
+ jack_nframes_t time = 1;
+ size_t size = 3;
+ jack_midi_data_t all_notes_off[] = { 0xB0, 123, 0 };
+ jack_midi_event_write(port_buf, time, all_notes_off, size);
+ timer = 0;
+ }
+
+ timer += nframes;
+
+ return 0;
+}
+
+void sendMidi()
+{
+ jack_status_t status;
+
+ jack_client_t *jack_client = jack_client_open("MidiTest", JackNullOption, &status);
+
+ test_midi_port = jack_port_register(jack_client,
+ "midi_out",
+ JACK_DEFAULT_MIDI_TYPE,
+ JackPortIsOutput,// | JackPortIsTerminal,
+ 0);
+
+ jack_set_process_callback(jack_client, process, NULL);
+
+ jack_activate(jack_client);
+
+ jack_connect(jack_client, "MidiTest:midi_out", "DrumGizmo:midi_in");
+
+ jack_connect(jack_client, "DrumGizmo:output_1", "system:playback_1");
+ jack_connect(jack_client, "DrumGizmo:output_2", "system:playback_2");
+}
+
int main(int argc, char *argv[])
{
JackClient client;
client.activate();
+
+ sendMidi();
+
+ while(1) sleep(1);
+
return 0;
}
diff --git a/src/event.cc b/src/event.cc
new file mode 100644
index 0000000..804d42f
--- /dev/null
+++ b/src/event.cc
@@ -0,0 +1,43 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/***************************************************************************
+ * event.cc
+ *
+ * Mon Jul 21 10:56:02 CEST 2008
+ * Copyright 2008 Bent Bisballe Nyeng
+ * deva@aasimon.org
+ ****************************************************************************/
+
+/*
+ * This file is part of DrumGizmo.
+ *
+ * DrumGizmo 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 2 of the License, or
+ * (at your option) any later version.
+ *
+ * DrumGizmo 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 DrumGizmo; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+ */
+#include "event.h"
+
+Event::Event(Sample *sample, size_t onset)
+{
+ this->sample = sample;
+ this->onset = onset;
+ duration = 0;
+}
+
+Event::~Event()
+{
+}
+
+bool Event::operator<(const Event& event) const
+{
+ return onset + duration < event.onset + event.duration;
+}
diff --git a/src/event.h b/src/event.h
new file mode 100644
index 0000000..4f277a7
--- /dev/null
+++ b/src/event.h
@@ -0,0 +1,47 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/***************************************************************************
+ * event.h
+ *
+ * Mon Jul 21 10:56:01 CEST 2008
+ * Copyright 2008 Bent Bisballe Nyeng
+ * deva@aasimon.org
+ ****************************************************************************/
+
+/*
+ * This file is part of DrumGizmo.
+ *
+ * DrumGizmo 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 2 of the License, or
+ * (at your option) any later version.
+ *
+ * DrumGizmo 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 DrumGizmo; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+ */
+#ifndef __DRUMGIZMO_EVENT_H__
+#define __DRUMGIZMO_EVENT_H__
+
+#include <set>
+#include "sample.h"
+
+class Event {
+public:
+ Event(Sample *sample, size_t onset);
+ ~Event();
+
+ bool operator<(const Event& event) const;
+
+ Sample *sample;
+ size_t duration;
+ size_t onset;
+};
+
+typedef std::set< Event > Events;
+
+#endif/*__DRUMGIZMO_EVENT_H__*/
diff --git a/src/jackclient.cc b/src/jackclient.cc
index af25da0..42a85c2 100644
--- a/src/jackclient.cc
+++ b/src/jackclient.cc
@@ -56,7 +56,7 @@ JackClient::JackClient(size_t num_inputs, size_t num_outputs)
// Setup input port
midi_port = jack_port_register(jack_client,
- "Midi in",
+ "midi_in",
JACK_DEFAULT_MIDI_TYPE,
JackPortIsInput,// | JackPortIsTerminal,
0);
@@ -64,7 +64,7 @@ JackClient::JackClient(size_t num_inputs, size_t num_outputs)
// Setup input ports
for(size_t i = 0; i < num_inputs; i++) {
char port_name[32];
- sprintf(port_name, "Port %i", i);
+ sprintf(port_name, "input_%i", i + 1);
jack_port_t *port = jack_port_register(jack_client,
port_name,
JACK_DEFAULT_AUDIO_TYPE,
@@ -76,7 +76,7 @@ JackClient::JackClient(size_t num_inputs, size_t num_outputs)
// Setup output ports
for(size_t i = 0; i < num_outputs; i++) {
char port_name[32];
- sprintf(port_name, "Port %i", i);
+ sprintf(port_name, "output_%i", i + 1);
jack_port_t *port = jack_port_register(jack_client,
port_name,
JACK_DEFAULT_AUDIO_TYPE,
@@ -85,15 +85,18 @@ JackClient::JackClient(size_t num_inputs, size_t num_outputs)
output_ports.push_back(port);
}
- jack_on_shutdown(jack_client, _wrap_jack_shutdown, this);
+ //jack_on_shutdown(jack_client, _wrap_jack_shutdown, this);
jack_set_process_callback(jack_client, _wrap_jack_process, this);
- jack_set_thread_init_callback(jack_client, _wrap_jack_thread_init, this);
- jack_set_freewheel_callback(jack_client, _wrap_jack_freewheel_mode, this);
- jack_set_buffer_size_callback(jack_client, _wrap_jack_buffer_size, this);
- jack_set_sample_rate_callback(jack_client, _wrap_jack_sample_rate, this);
- jack_set_port_registration_callback(jack_client, _wrap_jack_port_registration, this);
- jack_set_graph_order_callback(jack_client, _wrap_jack_graph_order, this);
- jack_set_xrun_callback(jack_client, _wrap_jack_xrun, this);
+ //jack_set_thread_init_callback(jack_client, _wrap_jack_thread_init, this);
+ //jack_set_freewheel_callback(jack_client, _wrap_jack_freewheel_mode, this);
+ //jack_set_buffer_size_callback(jack_client, _wrap_jack_buffer_size, this);
+ //jack_set_sample_rate_callback(jack_client, _wrap_jack_sample_rate, this);
+ //jack_set_port_registration_callback(jack_client, _wrap_jack_port_registration, this);
+ //jack_set_graph_order_callback(jack_client, _wrap_jack_graph_order, this);
+ //jack_set_xrun_callback(jack_client, _wrap_jack_xrun, this);
+
+
+ sample = new Sample("/home/deva/snare.wav");
}
JackClient::~JackClient()
@@ -112,32 +115,74 @@ void JackClient::shutdown()
int JackClient::process(jack_nframes_t nframes)
{
- /*
- int pos = -1;
- Params *params = (Params*)arg;
-
- void *midibuffer = jack_port_get_buffer(params->midi_port, nframes);
+ void *midibuffer = jack_port_get_buffer(midi_port, nframes);
jack_nframes_t midievents = jack_midi_get_event_count(midibuffer);
for(jack_nframes_t i = 0; i < midievents; i++) {
- jack_midi_event_t event;
- jack_midi_event_get(&event, midibuffer, i);
- printf("[ Time: %d Size: %d ", event.time, event.size);
- for(int j = 0; j < event.size; j++) {
- jack_midi_data_t m = event.buffer[j];
+ jack_midi_event_t midi_event;
+ jack_midi_event_get(&midi_event, midibuffer, i);
+ /*
+ // Parse midi event
+ printf("[ Time: %d Size: %d ", midi_event.time, midi_event.size);
+ for(size_t j = 0; j < midi_event.size; j++) {
+ jack_midi_data_t m = midi_event.buffer[j];
printf(" Data: %d ", m);
}
printf("]\n");
- for(int i = 0; i < NUM_PORTS; i++) {
- pos = event.time;
- }
+ */
+
+ // Create trigger event
+ Event event(sample, midi_event.time);
+ events.insert(event);
+
}
- for(int i = 0; i < NUM_PORTS; i++) {
+ jack_midi_clear_buffer(midibuffer);
+
+ // Reset ports
+ Ports::iterator pi = output_ports.begin();
+ while(pi != output_ports.end()) {
+
+ jack_default_audio_sample_t *buffer;
+ buffer = (jack_default_audio_sample_t *)jack_port_get_buffer(*pi, nframes);
+
+ for(size_t j = 0; j < nframes; j++) {
+ buffer[j] = 0;
+ }
+
+ pi++;
+ }
+
+ // Handle events
+ Events::iterator ei = events.begin();
+ while(ei != events.end()) {
+
+ printf("Event\n");
+
+ Ports::iterator pi = output_ports.begin();
+ while(pi != output_ports.end()) {
+
+ jack_default_audio_sample_t *buffer;
+ buffer = (jack_default_audio_sample_t *)jack_port_get_buffer(*pi, nframes);
+
+ for(size_t j = 0; j < nframes; j++) {
+ buffer[j] = sample->data[j];//(float)rand() / (float)RAND_MAX; // Set output
+ }
+
+ pi++;
+ }
+
+ ei++;
+ }
+
+ // Remove all events
+ events.clear();
+ /*
+ for(size_t i = 0; i < output_ports.size(); i++) {
jack_default_audio_sample_t *buffer;
- buffer = (jack_default_audio_sample_t *)jack_port_get_buffer(params->drums[i].port, nframes);
+ buffer = (jack_default_audio_sample_t *)jack_port_get_buffer(output_ports[i], nframes);
for(int j = 0; j < nframes; j++) {
- if(j == pos) params->drums[i].samples[0].p = -j;
- offset_t p = params->drums[i].samples[0].p;
+ if(j == pos) drums[i].samples[0].p = -j;
+ offset_t p = drums[i].samples[0].p;
size_t data_size = params->drums[i].samples[0].data_size;
jack_default_audio_sample_t *samples = params->drums[i].samples[0].data;
if(p+j > data_size) buffer[j] = 0;
@@ -147,6 +192,7 @@ int JackClient::process(jack_nframes_t nframes)
params->drums[i].samples[0].p += nframes;
}
*/
+
return 0;
}
diff --git a/src/jackclient.h b/src/jackclient.h
index 02d74e9..cf32eb0 100644
--- a/src/jackclient.h
+++ b/src/jackclient.h
@@ -32,6 +32,13 @@
#include <jack/jack.h>
#include <jack/midiport.h>
+#include "event.h"
+#include "sample.h"
+
+#define TEST_MIDI
+
+typedef std::vector< jack_port_t *> Ports;
+
class JackClient {
public:
JackClient(size_t num_inputs = 16, size_t num_outputs = 16);
@@ -52,9 +59,12 @@ public:
private:
jack_client_t *jack_client;
- std::vector< jack_port_t *> input_ports;
- std::vector< jack_port_t *> output_ports;
+ Ports input_ports;
+ Ports output_ports;
jack_port_t *midi_port;
+
+ Sample *sample;
+ Events events;
};
#endif/*__DRUMGIZMO_JACKCLIENT_H__*/
diff --git a/src/sample.cc b/src/sample.cc
new file mode 100644
index 0000000..c375645
--- /dev/null
+++ b/src/sample.cc
@@ -0,0 +1,55 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/***************************************************************************
+ * sample.cc
+ *
+ * Mon Jul 21 10:23:20 CEST 2008
+ * Copyright 2008 Bent Bisballe Nyeng
+ * deva@aasimon.org
+ ****************************************************************************/
+
+/*
+ * This file is part of DrumGizmo.
+ *
+ * DrumGizmo 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 2 of the License, or
+ * (at your option) any later version.
+ *
+ * DrumGizmo 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 DrumGizmo; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+ */
+#include "sample.h"
+
+#include <stdlib.h>
+#include <unistd.h>
+
+#include <sndfile.h>
+
+Sample::Sample(char *file)
+{
+ SF_INFO sf_info;
+ SNDFILE *fh = sf_open(file, SFM_READ, &sf_info);
+
+ size = sf_seek(fh, 0, SEEK_END);
+ data = (jack_default_audio_sample_t*)malloc(sizeof(jack_default_audio_sample_t)*size);
+
+ printf("Loading %s, %d samples\n", file, size);
+
+ sf_seek(fh, 0, SEEK_SET);
+ sf_read_float(fh, data, size);
+
+ sf_close(fh);
+}
+
+Sample::~Sample()
+{
+ free(data);
+ data = NULL;
+ size = 0;
+}
diff --git a/src/sample.h b/src/sample.h
new file mode 100644
index 0000000..16ff2fe
--- /dev/null
+++ b/src/sample.h
@@ -0,0 +1,41 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/***************************************************************************
+ * sample.h
+ *
+ * Mon Jul 21 10:23:20 CEST 2008
+ * Copyright 2008 Bent Bisballe Nyeng
+ * deva@aasimon.org
+ ****************************************************************************/
+
+/*
+ * This file is part of DrumGizmo.
+ *
+ * DrumGizmo 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 2 of the License, or
+ * (at your option) any later version.
+ *
+ * DrumGizmo 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 DrumGizmo; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+ */
+#ifndef __DRUMGIZMO_SAMPLE_H__
+#define __DRUMGIZMO_SAMPLE_H__
+
+#include <jack/jack.h>
+
+class Sample {
+public:
+ Sample(char *file);
+ ~Sample();
+
+ jack_default_audio_sample_t *data;
+ size_t size;
+};
+
+#endif/*__DRUMGIZMO_SAMPLE_H__*/