Skip to content

Commit

Permalink
add simple MIDI synthesizer
Browse files Browse the repository at this point in the history
  • Loading branch information
gisogrimm committed Sep 24, 2024
1 parent 77cad51 commit cc7f58c
Show file tree
Hide file tree
Showing 11 changed files with 427 additions and 7 deletions.
10 changes: 10 additions & 0 deletions examples/simplesynth.tsc
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
<?xml version="1.0"?>
<session license="CC0">
<modules>
<route name="synth" channels="1" connect_out="system:playback_[12]">
<plugins>
<simplesynth autoconnect="true"/>
</plugins>
</route>
</modules>
</session>
16 changes: 16 additions & 0 deletions libtascar/include/alsamidicc.h
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
#include <alsa/asoundlib.h>
#include <alsa/seq_event.h>
#include <string>
#include <vector>

namespace TASCAR {

Expand Down Expand Up @@ -69,6 +70,21 @@ namespace TASCAR {
\param velocity Note velocity
*/
void send_midi_note(int channel, int pitch, int velocity);
/**
\brief Get current number of clients
*/
int get_cur_clients();
/**
\brief Get maximum number of clients
*/
int get_max_clients();
/**
\brief Get number of ports of client
*/
int client_get_num_ports(int client);
std::vector<int> client_get_ports(int client, unsigned int cap = 0);
std::vector<int> get_client_ids();
int get_client_id();

protected:
void service();
Expand Down
107 changes: 106 additions & 1 deletion libtascar/src/alsamidicc.cc
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,9 @@ void TASCAR::midi_ctl_t::service()
(ev->type == SND_SEQ_EVENT_NOTEON) ||
(ev->type == SND_SEQ_EVENT_NOTEOFF))) {
emit_event_note(ev->data.note.channel, ev->data.note.note,
ev->data.note.velocity);
((ev->type == SND_SEQ_EVENT_NOTEOFF)
? 0
: (ev->data.note.velocity)));
}
}
usleep(10);
Expand Down Expand Up @@ -165,6 +167,109 @@ void TASCAR::midi_ctl_t::connect_output(const std::string& src,
}
}

int TASCAR::midi_ctl_t::get_max_clients()
{
int clients = 0;
snd_seq_system_info_t* info;
int err = snd_seq_system_info_malloc(&info);
if(err == 0) {
int err = snd_seq_system_info(seq, info);
if(err == 0)
clients = snd_seq_system_info_get_clients(info);
snd_seq_system_info_free(info);
}
return clients;
}

int TASCAR::midi_ctl_t::get_cur_clients()
{
int clients = 0;
snd_seq_system_info_t* info;
int err = snd_seq_system_info_malloc(&info);
if(err == 0) {
int err = snd_seq_system_info(seq, info);
if(err == 0)
clients = snd_seq_system_info_get_cur_clients(info);
snd_seq_system_info_free(info);
}
return clients;
}

int TASCAR::midi_ctl_t::client_get_num_ports(int client)
{
int numports = 0;
snd_seq_client_info_t* info;
int err = 0;
err = snd_seq_client_info_malloc(&info);
if(err == 0) {
err = snd_seq_get_any_client_info(seq, client, info);
if(err == 0) {
numports = snd_seq_client_info_get_num_ports(info);
}
}
return numports;
}

std::vector<int> TASCAR::midi_ctl_t::get_client_ids()
{
std::vector<int> clients;
snd_seq_client_info_t* info;
int err = 0;
err = snd_seq_client_info_malloc(&info);
if(err == 0) {
err = snd_seq_get_any_client_info(seq, 0, info);
if(err == 0) {
clients.push_back(0);
while(snd_seq_query_next_client(seq, info) == 0) {
clients.push_back(snd_seq_client_info_get_client(info));
}
}
}
return clients;
}

std::vector<int> TASCAR::midi_ctl_t::client_get_ports(int client,
unsigned int cap)
{
std::vector<int> ports;
if(client_get_num_ports(client) > 0) {
snd_seq_port_info_t* info;
int err = 0;
err = snd_seq_port_info_malloc(&info);
if(err == 0) {
err = snd_seq_get_any_port_info(seq, client, 0, info);
if(err == 0) {
unsigned int pcap = 0;
pcap = snd_seq_port_info_get_capability(info);
if((cap == 0) || (cap & pcap))
ports.push_back(0);
while(snd_seq_query_next_port(seq, info) == 0) {
int port = snd_seq_port_info_get_port(info);
pcap = snd_seq_port_info_get_capability(info);
if((cap == 0) || (cap & pcap))
ports.push_back(port);
}
}
}
}
return ports;
}

int TASCAR::midi_ctl_t::get_client_id()
{
int client = 0;
snd_seq_client_info_t* info;
int err = 0;
err = snd_seq_client_info_malloc(&info);
if(err == 0) {
err = snd_seq_get_client_info(seq, info);
if(err == 0) {
client = snd_seq_client_info_get_client(info);
}
}
return client;
}

/*
* Local Variables:
* mode: c++
Expand Down
5 changes: 5 additions & 0 deletions manual/apmodsimplesynth.tex
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
Simple MIDI synthesizer.

\input{tabsimplesynth.tex}

\input{oscdoc_tascar_ap_simplesynth.tex}
3 changes: 2 additions & 1 deletion manual/documentation.tsc
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@
<loopmachine/>
<metronome/>
<noise/>
<simplesynth/>
<onsetdetector/>
<!--<openmha plugin="identity" config=""/>-->
<pink/>
Expand Down Expand Up @@ -125,7 +126,7 @@
<f/><i/><s/>
</motemsg>
</mididispatch>
<route/>
<route name="route"/>
<!--<ovheadtracker/>-->
<oscheadtracker/>
<osceog srate="860" eogpath="/eog"/>
Expand Down
1 change: 1 addition & 0 deletions manual/oscdoc_face_t.tex
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
path & fmt. & range & r. & description\\
\hline
\attr{/.../damping} & f & [0,1[ & yes & Damping coefficient\\
\attr{/.../layers} & i & & yes & Number representing the layers. Each layer is represented by a bit, i.e., for layers 1+3 use 10\\
\attr{/.../reflectivity} & f & [0,1] & yes & Reflectivity of object\\
\attr{/.../scattering} & f & [0,1] & yes & Scattering coefficient\\
\hline
Expand Down
2 changes: 1 addition & 1 deletion manual/oscdoc_tascar_ap_metronome.tex
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
\hline
\attr{/.../a1} & f & [0,120] & yes & \\
\attr{/.../ao} & f & [0,120] & yes & \\
\attr{/.../bpb} & i & & yes & \\
\attr{/.../bpb} & i & & no & \\
\attr{/.../bpm} & f & & yes & \\
\attr{/.../bypass} & i & bool & yes & \\
\attr{/.../changeonone} & i & bool & yes & \\
Expand Down
22 changes: 22 additions & 0 deletions manual/oscdoc_tascar_ap_simplesynth.tex
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
\definecolor{shadecolor}{RGB}{236,236,255}\begin{snugshade}
{\footnotesize
\label{osctab:tascarapsimplesynth}
OSC variables:
\nopagebreak

\begin{tabularx}{\textwidth}{llllX}
\hline
path & fmt. & range & r. & description\\
\hline
\attr{/.../decaydamping} & f & [0,10] & yes & Damping decay in s\\
\attr{/.../decay} & f & ]0,20] & yes & Decay time in s\\
\attr{/.../decayoffset} & f & ]0,20] & yes & Offset decay time in s\\
\attr{/.../detune} & f & [-10,10] & yes & Detuning in Hz\\
\attr{/.../f0} & f & [100,1000] & yes & Tuning frequency in Hz\\
\attr{/.../level} & f & [0,100] & yes & Sound level in dB SPL\\
\attr{/.../onset} & f & [0,0.2] & yes & Onset duration in s\\
\hline
\end{tabularx}
}
\end{snugshade}
\definecolor{shadecolor}{RGB}{255,230,204}
4 changes: 2 additions & 2 deletions manual/oscdoc_tascarmod_rotator.tex
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,12 @@
\hline
path & fmt. & range & r. & description\\
\hline
\attr{/.../mode} & i & & yes & \\
\attr{/.../mode} & i & & yes & Operation mode\\
\attr{/.../phi0} & f & & yes & \\
\attr{/.../phi1} & f & & yes & \\
\attr{/.../t0} & f & & yes & \\
\attr{/.../t1} & f & & yes & \\
\attr{/.../w} & f & & yes & \\
\attr{/.../w} & f & & yes & Angular velocity in deg/s\\
\hline
\end{tabularx}
}
Expand Down
5 changes: 3 additions & 2 deletions plugins/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -37,8 +37,9 @@ MASKPLUGINS = fig8 multibeam sampledgain
ifneq ($(OS),Windows_NT)
UNAME_S := $(shell uname -s)
ifeq ($(UNAME_S),Linux)
TASCARMODS += midicc2osc midictl mididispatch joystick qualisystracker ltcgen lightctl ovheadtracker\
# ovheadtracker
TASCARMODS += midicc2osc midictl mididispatch joystick \
qualisystracker ltcgen lightctl ovheadtracker
AUDIOPLUGINS += simplesynth
endif
ifeq ($(UNAME_S),Darwin)
TASCARMODS += ltcgen \
Expand Down
Loading

0 comments on commit cc7f58c

Please sign in to comment.