Am Fri, 12 Mar 2010 21:50:10 -0500
schrieb Dave Allan <dal...@redhat.com>: 

> On 03/12/2010 05:58 PM, Gabriel M. Beddingfield wrote:
> >
> > Hi Dave,
> >
> > On Fri, 12 Mar 2010, Dave Allan wrote:
> >
> >>>      * Implement some variable that maintains state
> >>>        (e.g. an enum with OPEN and CLOSED).  We'll
> >>>        call it pedal_state.  The variable needs to
> >>>        be accessible to the MidiInput class.
> >>
> >> It'd need to be 128 steps to support continuous hihat control, I think.
> >
> > IIRC, the OP said the foot-pedal sends only 0 and 127...
> > that's why I suggested a boolean-like enum.  Are there
> > hi-hat controllers that send 128 steps?
> The OP did say 0 and 127, but others do send more fine grained messages.

Okay, then. I will test what my Roland drumbrain gives ... see a later post.
This is now about the initial issue with the Alesis Control Pad, which has 
(almost) no brain.
I thought that I can use just note on/off of the hihat pedal, but that is 
wrong: The pad sends immediate note off for everything, including the pedal.
CC04 message is the way to go, that goes to 127 on closing, and back to 0 on 
opening.

I am attaching (inline... hm, would normal attachments be allowed here?) a 
hacked MIDI filter that enables hihat play with hydrogen with opening and 
closing.

> > To get similar sort of behavior from Hydrogen, you would
> > probably need to implement sort of a 2D-layered instrument
> > (select sample based on velocity and a 0.0-1.0 controller
> > value).  The controller value can be mapped to anything
> > (like CC#4).  Currently Hydrogen only has 1D-layered
> > instruments (select sample based on velocity).
> 
> I think that's right.  It's probably only really relevant for hihat at 
> this point, but I don't see any reason to limit it to hihat in the code. 

Of course the proper way would be to have full 2D instruments, but as this 
obviously is quite some work to code and also complicates the processing 
hydrogen has to do for every note, I would like to go for special treatment of 
hihat, or hihat-like things along a simple map of the hihat to a configurable 
number of hydrogen instruments.
Simplest case is open and closed, complicated would be, say, 8 steps of openess.
I really don't think my Roland drum brain (TD10+TDW-1) does more for its 
synthesis.

There are other projects that have multiple dimensions per instrument 
(linuxsampler) for sophisticated sampling... but they have a different scope 
than a drum machine. Hydrogen is for Drums, and unless one comes up with 
another (typical?) drum instrument that changes state according to some 
controller, I don't see a pressing need to add full 2D samples.
Getting proper, configurable mapping of MIDI notes to drums is more important, 
I think.

Though, I found several MIDI apps that can map notes... so strictly, you get 
that functionality already by hooking them in between the controller and 
hydrogen. I am wary about how far to go with the UNIX principle here.
Strictly, one should let MIDI mappers do the mapping and hydrogen the drum 
playing. But then, there is demand for hydrogen to just work out of the box and 
compared to what is already there, there is only a tiny amount of code to be 
added for muchly increased usability. Since Hydrogen does drums, it at least 
should deal with special handling of the Hihat. It's an esential part of 
drumming.
Note that while I found MIDI mappers, I didn't found mappers that change their 
map according to controller changes... well not trivial to configure, at least. 
I think http://das.nasophon.de/mididings/ can do it, but coding the script for 
it might be more work than hacking hydrogen.

> I'm going to be the studio in about two weeks.  I'll get 2D of hihat 
> samples for a test kit, even if they don't sound all that great.

Have fun recording... I have so far closed / halfopen / dangling open.
I intend to map the halfopen part together with some new recordings I did with 
varying intensity to velocities of the closed hihat: When I hit the closed 
hihat hard, I also lift the foot a bit...
I also intend not to use the totally open/dangling Hihat in hydrogen, rather 
one with very light pressure on the pedal.

That should be pretty fine for lo-fi MIDI playback. Mind, I don't intend to 
replace my real drum set with hydrogen, it's just for occasions where the real 
one would be too big and too loud;-)

Anyhow, here is my proof of concept, put into the MIDI chain using aconnect to 
feed hydrogen with closed or opened hihat notes. It is built using

cc -o hihatmap hihatmap.c -lasound

I tested it with the Control Pad -- it works;-)

As I see just how little of that code deals with the specific mapping, I really 
think that it should be fine to add it to hydrogen instead of doing a 
standalone app.


Alrighty then,

Thomas.

/*
        Hacked guts out of:
        An ALSA MIDI mapper
        (C) 2002-2005 David Given

        This code just does one kind of mapping: Map hihat notes to open or 
closed, according to state of the hihat pedal controller.

        So you want those samples loaded for instrument numbers:
        38: hihat pedal
        39:  ... anything... some kind of hihat in case this mapper is not 
present
        40: open hihat
        41: closed hihat

        If the controller has values below 64, the hihat is open, for values 
above, it is closed.
*/
#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>
#include <ctype.h>
#include <sys/poll.h>
#include <alsa/asoundlib.h>

#define HIHAT_CONTROLLER 4
#define HIHAT_CYMBAL_NOTE 39
#define HIHAT_OPEN_NOTE 40
#define HIHAT_CLOSED_NOTE 41

int hihat_is_open = 1;

/* Define the input and output ports. */

int inport = 0;
int outport = 0;

/* The handle to the ALSA sequencer. */

snd_seq_t* sequencer = NULL;

/* ======================================================================= */
/*                                UTILITIES                                */
/* ======================================================================= */

void error(char* format, ...)
{
        va_list ap;
        va_start(ap, format);
        fprintf(stderr, "Error: ");
        vfprintf(stderr, format, ap);
        fprintf(stderr, "\n");
        va_end(ap);

        exit(1);
}

void printconditional(char* prefix, int value)
{
        if (value >= 0)
                printf("%s%d ", prefix, value);
}

/* ======================================================================= */
/*                                 ALSA                                    */
/* ======================================================================= */

void open_alsa_connection(void)
{
        int client;
        
        if (snd_seq_open(&sequencer, "default", SND_SEQ_OPEN_DUPLEX, 0) < 0)
                error("Couldn't open ALSA sequencer");
                
        snd_seq_set_client_name(sequencer, "hihatmap");
        client = snd_seq_client_id(sequencer);

        inport = snd_seq_create_simple_port(sequencer, "hihatmap IN",
                SND_SEQ_PORT_CAP_WRITE|SND_SEQ_PORT_CAP_SUBS_WRITE,
                SND_SEQ_PORT_TYPE_APPLICATION);
        if (inport < 0)
                error("Couldn't create input port");

        outport = snd_seq_create_simple_port(sequencer, "hihatmap OUT",
                SND_SEQ_PORT_CAP_READ|SND_SEQ_PORT_CAP_SUBS_READ,
                SND_SEQ_PORT_TYPE_APPLICATION);
        if (outport < 0)
                error("Couldn't create output port");

        printf("IN = %d:%d, OUT = %d:%d\n",
                client, inport,
                client, outport);
}

void process_events(void)
{
        int numpolldesc = snd_seq_poll_descriptors_count(sequencer, POLLIN);
        struct pollfd* pfd;
        snd_seq_event_t* event;
        int i;

        pfd = malloc(sizeof(struct pollfd) * numpolldesc);
        if (!pfd)
                error("Memory allocation failed");
        
        snd_seq_poll_descriptors(sequencer, pfd, numpolldesc, POLLIN);
        
        for (;;)
        {
                int oldnote = -1;
                if (snd_seq_event_input(sequencer, &event) < 0)
                {
                        poll(pfd, 1, 100000);
                        continue;
                }

                snd_seq_ev_set_subs(event);  
                snd_seq_ev_set_direct(event);

                switch (event->type)
                {
                        case SND_SEQ_EVENT_CONTROLLER:
                                if(event->data.control.param == 
HIHAT_CONTROLLER)
                                {
                                        hihat_is_open = 
(event->data.control.value < 64);

                                        fprintf(stderr, "Hihat status: %i\n", 
hihat_is_open);
                                }
                        break;
                        /* case SND_SEQ_EVENT_NOTE: */
                        case SND_SEQ_EVENT_NOTEON:
                        case SND_SEQ_EVENT_NOTEOFF:
                                if(event->data.note.note == HIHAT_CYMBAL_NOTE)
                                event->data.note.note = hihat_is_open ? 
HIHAT_OPEN_NOTE : HIHAT_CLOSED_NOTE;
                        break;
                }

                snd_seq_ev_set_source(event, outport);
                i = snd_seq_event_output_direct(sequencer, event);
                if (i < 0)
                        error("snd_seq_event_output_direct() failed: %s", 
snd_strerror(i));

                snd_seq_free_event(event);
        }
}

/* ======================================================================= */
/*                              MAIN PROGRAM                               */
/* ======================================================================= */


int main(int argc, char* argv[])
{
        open_alsa_connection();
        process_events();
        
        return 0;
}

Attachment: signature.asc
Description: PGP signature

------------------------------------------------------------------------------
Download Intel&#174; Parallel Studio Eval
Try the new software tools for yourself. Speed compiling, find bugs
proactively, and fine-tune applications for parallel performance.
See why Intel Parallel Studio got high marks during beta.
http://p.sf.net/sfu/intel-sw-dev
_______________________________________________
Hydrogen-devel mailing list
Hydrogen-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/hydrogen-devel

Reply via email to