Skip to content

Commit

Permalink
Added alsa.writeback to control if a MIDI command is written back to …
Browse files Browse the repository at this point in the history
…the same card number it came from (issue #75)

Corrected logging of config items if at debug level. This was calling logging functions before logging was initialised.
  • Loading branch information
ravelox committed May 1, 2020
1 parent 45cc322 commit 047a95a
Show file tree
Hide file tree
Showing 15 changed files with 194 additions and 68 deletions.
3 changes: 3 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -221,4 +221,7 @@ alsa.input_device
alsa.input_buffer_size
Size of the buffer to use for reading data from the input device.
Default is 4096. Maximum is 65535.
alsa.writeback
If a MIDI command is received from an inbound ALSA device, this option controls whether that event is written to an ALSA output device if it has the same card number.
This is a yes/no option. Default is no.
```
8 changes: 7 additions & 1 deletion raveloxmidi/include/kv_table.h
Original file line number Diff line number Diff line change
Expand Up @@ -30,13 +30,19 @@ typedef struct kv_table_t {
char *name;
size_t count;
kv_item_t **items;
pthread_mutex_t lock;
} kv_table_t;

kv_table_t *kv_table_create( char *name );
void kv_table_dump( kv_table_t *table );
void kv_table_reset( kv_table_t *table );
void kv_table_destroy( kv_table_t **table );
kv_item_t *kv_find_item( kv_table_t *table, char *key );
char *kv_get_value( kv_table_t *table, char *key );
void kv_add_item( kv_table_t *table, char *key, char *value );
void kv_get_item_by_index( kv_table_t *table, size_t index, char **key, char **value );
size_t kv_item_count( kv_table_t *table );

void kv_table_lock( kv_table_t *table );
void kv_table_unlock( kv_table_t *table );

#endif
1 change: 1 addition & 0 deletions raveloxmidi/include/logging.h
Original file line number Diff line number Diff line change
Expand Up @@ -48,5 +48,6 @@ void logging_init(void);
void logging_teardown(void);
void logging_prefix_enable(void);
void logging_prefix_disable(void);
int logging_get_threshold(void);

#endif
2 changes: 1 addition & 1 deletion raveloxmidi/include/net_distribute.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,6 @@

#include "midi_state.h"

void net_distribute_midi( midi_state_t *state, uint32_t originator_ssrc );
void net_distribute_midi( midi_state_t *state, uint32_t originator_ssrc , int originator_card );

#endif
1 change: 1 addition & 0 deletions raveloxmidi/include/net_socket.h
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ typedef struct raveloxmidi_socket_t {
size_t packet_size;
midi_state_t *state;
pthread_mutex_t lock;
int card_number;
#ifdef HAVE_ALSA
snd_rawmidi_t *handle;
#endif
Expand Down
3 changes: 2 additions & 1 deletion raveloxmidi/include/raveloxmidi_alsa.h
Original file line number Diff line number Diff line change
Expand Up @@ -30,12 +30,13 @@ void raveloxmidi_alsa_init( char *input_name, char *output_name , size_t buffer_
void raveloxmidi_alsa_handle_destroy( void **rawmidi );
void raveloxmidi_alsa_teardown( void );

int raveloxmidi_alsa_card_number( snd_rawmidi_t *rawmidi );
void raveloxmidi_alsa_dump_rawmidi( void *data );

int raveloxmidi_alsa_out_available( void );
int raveloxmidi_alsa_in_available( void );

int raveloxmidi_alsa_write( unsigned char *buffer, size_t buffer_size );
int raveloxmidi_alsa_write( unsigned char *buffer, size_t buffer_size, int originator_card);
int raveloxmidi_alsa_read( snd_rawmidi_t *handle, unsigned char *buffer, size_t read_size);
int raveloxmidi_alsa_poll( int timeout );
void raveloxmidi_alsa_set_poll_fds( snd_rawmidi_t *handle );
Expand Down
4 changes: 3 additions & 1 deletion raveloxmidi/include/raveloxmidi_config.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@

#include "kv_table.h"

void config_init( int argc, char *argv[] );
int config_init( int argc, char *argv[] );
void config_teardown( void );

char *config_string_get( char *key );
Expand Down Expand Up @@ -54,4 +54,6 @@ int config_iter_is_set( raveloxmidi_config_iter_t *iter );

#define MAX_ITER_INDEX 10000

#define CONFIG_DUMP 1
#define CONFIG_DUMP_EXIT 2
#endif
5 changes: 5 additions & 0 deletions raveloxmidi/man/raveloxmidi.1.in
Original file line number Diff line number Diff line change
Expand Up @@ -200,6 +200,11 @@ This is a multi-value configuration option. See the \fBNOTES\fP section above fo
Size of the buffer to use for reading data from the input device.
.br
Default is 4096. Maximum is 65535.
.TP
.B alsa.writeback
If a MIDI command is received from an inbound ALSA device, this option controls whether that event is written to an ALSA output device if it has the same card number.
.br
This is a yes/no option. Default is no.
.fi
.SH AUTHOR
.B raveloxmidi
Expand Down
93 changes: 75 additions & 18 deletions raveloxmidi/src/kv_table.c
Original file line number Diff line number Diff line change
Expand Up @@ -21,10 +21,23 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <pthread.h>

#include "kv_table.h"
#include "logging.h"

void kv_table_lock( kv_table_t *table )
{
if( ! table ) return;

pthread_mutex_lock( &(table->lock) );
}

void kv_table_unlock( kv_table_t *table )
{
pthread_mutex_unlock( &(table->lock) );
}

kv_table_t *kv_table_create( char *name )
{
kv_table_t *new_table = NULL;
Expand All @@ -40,6 +53,8 @@ kv_table_t *kv_table_create( char *name )
new_table->items = NULL;
new_table->count = 0;

pthread_mutex_init( &new_table->lock, NULL );

return new_table;
}

Expand Down Expand Up @@ -67,39 +82,51 @@ void kv_table_dump( kv_table_t *table )
}
}

void kv_table_reset( kv_table_t *table )
void kv_table_destroy( kv_table_t **table )
{
int i = 0;

if( ! table ) return;
if( ! table->items) return;
if( table->count <= 0 ) return;
if( ! *table ) return;

kv_table_lock( *table );

if( ! (*table)->items) goto kv_table_destroy_end;
if( (*table)->count <= 0 ) goto kv_table_destroy_end;

for(i=0; i < table->count; i++)
for(i=0; i < (*table)->count; i++)
{
if( table->items[i] )
if( (*table)->items[i] )
{
if( table->items[i]->key )
if( (*table)->items[i]->key )
{
free( table->items[i]->key );
table->items[i]->key = NULL;
free( (*table)->items[i]->key );
(*table)->items[i]->key = NULL;
}
if( table->items[i]->value )
if( (*table)->items[i]->value )
{
free( table->items[i]->value );
table->items[i]->value = NULL;
free( (*table)->items[i]->value );
(*table)->items[i]->value = NULL;
}
free( table->items[i] );
table->items[i] = NULL;
free( (*table)->items[i] );
(*table)->items[i] = NULL;
}
}

free( table->items);
table->items = NULL;
free( (*table)->items);
(*table)->items = NULL;

(*table)->count = 0;
if( (*table)->name ) free( (*table)->name );
(*table)->name = NULL;

kv_table_destroy_end:
kv_table_unlock( *table );

pthread_mutex_destroy( &( (*table)->lock ) );

table->count = 0;
if( table->name ) free( table->name);
table->name = NULL;
free( *table );
*table = NULL;
}

kv_item_t *kv_find_item( kv_table_t *table, char *key )
Expand Down Expand Up @@ -182,3 +209,33 @@ void kv_add_item( kv_table_t *table, char *key, char *value )
}
}
}

size_t kv_item_count( kv_table_t *table )
{
size_t item_count = 0;
if( ! table ) return 0;

kv_table_lock( table );
item_count = table->count;
kv_table_unlock( table );

return item_count;
}

void kv_get_item_by_index( kv_table_t *table, size_t index, char **key, char **value )
{
*key = NULL;
*value = NULL;

if( ! table ) return;

kv_table_lock( table );

if( index > table->count ) goto kv_get_item_by_index_end;

*key = table->items[ index ]->key;
*value = table->items[ index ]->value;

kv_get_item_by_index_end:
kv_table_unlock( table );
}
41 changes: 31 additions & 10 deletions raveloxmidi/src/logging.c
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,16 @@ static int logging_enabled = 0;
static char *logging_file_name = NULL;
static unsigned char prefix_disabled = 0;

void logging_lock( void )
{
pthread_mutex_lock( &logging_mutex );
}

void logging_unlock( void )
{
pthread_mutex_unlock( &logging_mutex );
}

int logging_name_to_value(name_map_t *map, const char *name)
{
int value = -1;
Expand Down Expand Up @@ -97,24 +107,24 @@ char *logging_value_to_name(name_map_t *map, int value)

void logging_prefix_disable( void )
{
pthread_mutex_lock( &logging_mutex );
logging_lock();
prefix_disabled = 1;
pthread_mutex_unlock( &logging_mutex );
logging_unlock();
}

void logging_prefix_enable( void )
{
pthread_mutex_lock( &logging_mutex );
logging_lock();
prefix_disabled = 0;
pthread_mutex_unlock( &logging_mutex );
logging_unlock();
}

void logging_printf(int level, const char *format, ...)
{
FILE *logging_fp = NULL;
va_list ap;

pthread_mutex_lock( &logging_mutex );
logging_lock();

if( logging_enabled == 0 )
{
Expand Down Expand Up @@ -155,7 +165,7 @@ void logging_printf(int level, const char *format, ...)
}

logging_end:
pthread_mutex_unlock( &logging_mutex );
logging_unlock();
}

void logging_init(void)
Expand All @@ -164,7 +174,7 @@ void logging_init(void)

pthread_mutex_init( &logging_mutex, NULL );

pthread_mutex_lock( &logging_mutex );
logging_lock();

if( is_yes( config_string_get("logging.enabled") ) )
{
Expand All @@ -188,12 +198,12 @@ void logging_init(void)
logging_enabled = 1;
}

pthread_mutex_unlock( &logging_mutex );
logging_unlock();
}

void logging_teardown(void)
{
pthread_mutex_lock( &logging_mutex);
logging_lock();

if( logging_file_name )
{
Expand All @@ -203,7 +213,18 @@ void logging_teardown(void)

logging_enabled = 0;

pthread_mutex_unlock( &logging_mutex );
logging_unlock();

pthread_mutex_destroy( &logging_mutex );
}

int logging_get_threshold( void )
{
int return_value = 0;

logging_lock();
return_value = logging_threshold;
logging_unlock();

return return_value;
}
13 changes: 9 additions & 4 deletions raveloxmidi/src/net_distribute.c
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ extern int errno;
extern int inbound_midi_fd;

/* Send MIDI commands to all connections */
void net_distribute_midi( midi_state_t *state, uint32_t originator_ssrc )
void net_distribute_midi( midi_state_t *state, uint32_t originator_ssrc , int alsa_originator_card )
{
rtp_packet_t *rtp_packet = NULL;
unsigned char *packed_rtp_buffer = NULL;
Expand All @@ -87,13 +87,17 @@ void net_distribute_midi( midi_state_t *state, uint32_t originator_ssrc )
int total_connections = 0;

unsigned char *raw_buffer = NULL;

char output_available = 0;

if( ! state ) return;

logging_printf( LOGGING_DEBUG, "net_distribute_midi: state=%p\n", state );
midi_state_dump( state );

output_available = ( inbound_midi_fd >= 0 );
#ifdef HAVE_ALSA
output_available |= raveloxmidi_alsa_out_available();
#endif
// Convert the buffer into a set of commands
midi_state_to_commands( state, &midi_commands, 0);

Expand Down Expand Up @@ -227,8 +231,9 @@ void net_distribute_midi( midi_state_t *state, uint32_t originator_ssrc )
}

// Determine if the MIDI commands need to be written out to ALSA or the local MIDI file descriptor
raw_buffer = (unsigned char *)malloc( 2 + command->data_len );
if( !output_available ) continue;

raw_buffer = (unsigned char *)malloc( 2 + command->data_len );
if( raw_buffer )
{
size_t bytes_written = 0;
Expand All @@ -252,7 +257,7 @@ void net_distribute_midi( midi_state_t *state, uint32_t originator_ssrc )

#ifdef HAVE_ALSA
net_socket_send_lock();
raveloxmidi_alsa_write( raw_buffer, 1 + command->data_len );
raveloxmidi_alsa_write( raw_buffer, 1 + command->data_len , alsa_originator_card );
net_socket_send_unlock();
#endif
free( raw_buffer );
Expand Down
Loading

0 comments on commit 047a95a

Please sign in to comment.