On Thursday 05 January 2012, Dave Stikkolorum wrote:
> On 05-01-12 15:31, Pedro Lopez-Cabanillas wrote:
> > The problem in loop.c is that you are using the function
snd_seq_ev_set_note()
> > that includes a duration as the 5th parameter. This function will create
two
> > MIDI events in a queue, the first one will be the noteon event, and the
second
> > one will be a noteoff event, scheduled adding the specified duration to
the
> > start time of the former noteon event. That requires a queue for event
> > scheduling.
> So in fact with a message that contains a duration for a note is always
> a queue involved?
Yes, but this macro snd_seq_ev_set_note() is the only one that includes a
duration parameter. It is not really a MIDI message, but the sequencer event
is converted into two MIDI messages (noteOn + noteOff). There aren't MIDI
messages containing durations.
OTOH any event using the macros snd_seq_ev_schedule_real() or
snd_seq_ev_schedule_tick() requires a queue as well, because the message
delivering time will be scheduled in the future.
Events using the macros snd_seq_ev_set_queue_control(),
snd_seq_ev_set_queue_start(), snd_seq_ev_set_queue_stop(),
snd_seq_ev_set_queue_continue() or snd_seq_ev_set_queue_tempo() also require a
queue, because all these macros have a queue parameter.
Regards,
Pedro
Hi all,
I try to write a c program that sends midi notes to the Hydrogen drum
sequencer.
I use the alsa library to create a client with an output port.
I attached two files.
loopqueue.c works but loop.c doesn't.
A base drum (note:28) is being send.
I am not succeeding to use direct delivery,
but it only works with the queue.
Any ideas why?
Regards,
Dave
Hi all,
I have been looking into ye olde denormal problem a little, lately.
Particularly with respect to Ardour and plugins. I've assembled what I
believe to be a coherent statement of what is going on, but I'd very much
appreciate any corrections and clarifications that anyone can offer.
Here's how it seems to me:
If you compile your code (e.g. a plugin) without -msse and -mfpmath=sse on
the GCC command line you get *no* protection from denormals from the CPU.
If they occur in your code, they will be very much slower than normal
floating point numbers (~49 times slower on my Core 2 Duo, ~7 times slower
on a Core i3). As far as I can see, it does not matter that Ardour has
been built with those flags: if a plugin has not, you have no protection.
If you compile your code with -msse and -mfpmath=sse, you have Ardour's
protection from denormals. If the user's CPU supports it, you get
there is no significant slowdown with denormals using this mode. However
CPU support is "some later processors with SSE2", according to Intel.
The problem, I guess, is that we cannot really distribute plugins with SSE
instructions, otherwise we do not support people with older CPUs. In this
case, I think the plugin code must avoid denormals, otherwise there will
be a significant performance hit if they arise.
I've been testing behaviour using a very dumb program which you can get
from http://carlh.net/software/denormals.tar.gz
I've also been testing plugins using a primitive torture tester that you
can get from http://carlh.net/software/ or on github via
git@github.com:cth103/plugin-torture.git
Any comments?
Best
Carl
Hi folks, wondering if anyone might be able to point me at the way to sort
this out, my latest queue is segfaulting when written to or read from,
while the rest ( which are supposed to be identical except for message type
) are working great, and have been tested with full stack runs fine. I'm
banging my head on the desk at this point trying to find the difference,
but perhaps others have seen similar behaviour?
I've made a template class for a queue, that internally uses a jack
ringbuffer. I have four of them, some of my data message struct, one for a
csound note message struct, and a new one for my raw midi message struct
which looks this this:
struct MidiMessage {
char status;
char data_1;
char data_2;
int time; // time in samples when midi message arrived
};
I instantiate them before anything else and pass them into the components
that need them in their constructors
MessageQueue<DataMessage> *toEngineDataQueue = new
MessageQueue<DataMessage>();
MessageQueue<DataMessage> *fromEngineDataQueue = new
MessageQueue<DataMessage>();
MessageQueue<NoteMessage> *toEngineNoteQueue = new
MessageQueue<NoteMessage>();
MessageQueue<MidiMessage> *fromEngineMidiQueue = new
MessageQueue<MidiMessage>();
All instantiation is working fine, app starts up, and the first three
queues are working. As soon as I either write to or read from the midi
queue, I segfault. Not sure how to debug this, hints welcome! Below is the
cue code in case anyone wants to look at it. I can't see anything wrong,
but maybe I've been doing something wrong and just gotten lucky so far??
thanks
Iain
template <class Type>
class MessageQueue {
private:
// pointer to the ring buffer the ring buffer
jack_ringbuffer_t *mRingBuffer;
int mQueueLength;
public:
MessageQueue();
~MessageQueue();
// put a msg on the queue, returns 0 or error code
void push( Type msg );
// store message in msg, returns true if message
bool tryPop( Type *msg );
};
template <class Type>
MessageQueue<Type>::MessageQueue(){
mQueueLength = DEFAULT_QUEUE_LENGTH;
// create our ringbuffer, sized by Type
mRingBuffer = jack_ringbuffer_create( mQueueLength * sizeof(Type) );
// lock the buffer into memory, this is *NOT* realtime safe
int errorLocking = jack_ringbuffer_mlock(mRingBuffer);
if( errorLocking ){
std::cout << "MessageQueue - Error locking memory when creating
ringbuffer\n";
// XXX raise an exception or something?? how do we fail here??
}
}
template <class Type>
MessageQueue<Type>::~MessageQueue(){
cout << "MessageQueue destructor\n";
// free the memory allocated for the ring buffer
ack_ringbuffer_free( mRingBuffer );
}
template <class Type>
void MessageQueue<Type>::push( Type msg ){
// write to the ring buffer, converting Type to a string
unsigned int written = jack_ringbuffer_write( mRingBuffer, (const char
*) &msg , sizeof(Type) );
// XXX: what to do if it fails anyway??
if( written < sizeof(Type) ){
cout << "Error, unable to write full message to ring buffer\n";
// do something else here yo!
}
}
// if a message is on the queue, get it
// returns True if it got a message
template <class Type>
bool MessageQueue<Type>::tryPop( Type *msgBuf ){
// if there is a message on the ring buffer, copy contents into msg
if( jack_ringbuffer_read_space( mRingBuffer) >= sizeof(Type) ){
jack_ringbuffer_read( mRingBuffer, (char *)msgBuf, sizeof(Type) );
// return True because a msg was read
return 1;
}else{
// return False, no msg read
return 0;
}
}
Hey folks, what is the easiest way to deal with midi input in a jack app?
I'm confused by the difference in jack midi and alsa midi, because I have
two midi inputs, one is a usb input, so it appears at a low level as an
alsa device, but the other is the midi input on a firewire unit, and it
appears as a jack midi device. I'd like to make sure that whatever I do is
easy to port to other systems. Does it make sense to use portmidi or rtmidi
to get input or should I stick to the jack api entirely?
thanks
Iain
Hey all,
I've been writing a scope the last while, and I'm intrested in how other
people have approached plotting the data.
Currently I'm taking every 50th sample, and drawing a line from the
previous sample to there, and so on. Not particulary neat.
So is there a resample, or smoothing of the samples, or how does one plot a
"smooth" waveform like Ardour / QTractor?
My other question is about RMS, is calculating it in its literal sense
best? Or perhaps only taking every 5th sample?
Resampling the signal from 44.1 or 48k to say 11025? I'm not really sure
which way to go.
Cheers, -Harry
Hi there,
I could use some advise.
You may or may not heard of replaygain. It's reasonably widely used in
consumer audio, but sometimes I wish it was available for video as well.
By this I mean I wish it was available for the audio part of the video.
Well, I need a programming project for a university course and this is
just one of my ideas that I want to propose to my teacher and
prospective teammates. In order to do this I'd like to narrow it down a
bit further and especially want to find out whether I have the right
idea of how it can be achieved.
Scanning/tagging
Since replaygain works on whole audio files I think I need to extract
the whole audio track from the container. How easily this can be
achieved I don't know. After that, the scanning process should work as
with any audio file. Afterwards the calculated replaygain values have to
be added to the metadata of the file. I have no idea how hard it is to
add new metadata fields to video formats.
Playback
Video players need to be aware of those tags, read the metadata and scale
the playback volume accordingly. This is probably not hard per se, but
there are many players out there. However, I plan to start with a single
player, even with a single file format, and go from there.
Question 1: Is there anything better than replaygain that should be used
instead?
Question 2: Which player would be easiest to hack to add such
functionality? Could it be a gstreamer plugin? mplayer?
Question 3: How much work would it be?
The project should be done in C++ if possible, otherwise C. Group size
2-4 Students, all rather new at C/C++ and rather inexperienced in
general.
Other ideas I have are in short:
- A CLI (using readline) connection manager for jack audio/midi and alsa
midi that can handle large numbers of ports. More detailed ideas exist
thanks to Julien Claasen.
- A simple but hopefully sane mplayer GUI
- A new GUI for ecasound
Another problem I might have is that most students in the course are
Windows users, not sure whether I can go solo.
Thanks for any advice,
regards,
Philipp
Hi everyone. I'm starting to write a simple filter and I want to expose it
as an lv2 plugin.
My development environment is very simple right now: vim editor, gcc
compiler, package the lv2 manually (will write a script for that in a day
or two) and then load the plugin in ardour to test it.
I've found this setup to be a bit unconfortable because once I load the
plugin in ardour I don't know how to get debug information from it (print
statements or breakpoints with gdb).
What does a lv2 development environment typically looks like? what are you
guys using?
Thanks!
--
Rafael Vega
email.rafa(a)gmail.com