Index: roard/driver_jack.c
===================================================================
--- roard/driver_jack.c	(revision 4708)
+++ roard/driver_jack.c	(revision 4825)
@@ -3,4 +3,5 @@
 /*
  *      Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2009-2011
+ *      Copyright (C) Nedko Arnaudov <nedko@arnaudov.name> - 2010
  *
  *  This file is part of roard a part of RoarAudio,
@@ -27,4 +28,17 @@
 
 #ifdef ROAR_HAVE_LIBJACK
+
+static void unregister_ports(struct driver_jack * self)
+{
+ while(self->channels--)
+ {
+  if ( self->ports_in != NULL )
+   if ( self->ports_in [self->channels] != NULL )
+    jack_port_unregister(self->client, self->ports_in [self->channels]);
+  if ( self->ports_out[self->channels] != NULL )
+   jack_port_unregister(self->client, self->ports_out[self->channels]);
+ }
+}
+
 int driver_jack_open_vio  (struct roar_vio_calls * inst,
                            char * device,
@@ -33,8 +47,17 @@
                            struct roar_stream_server * sstream) {
  struct driver_jack * self;
+ char port_name[128];
+ jack_nframes_t new_rate;
+ int autoconfig            = 0;
+ int recsource             = 0;
 
  // we are not FH Safe, return error if fh != -1:
  if ( fh != -1 )
   return -1;
+
+ if ( sstream != NULL ) {
+  autoconfig = streams_get_flag(ROAR_STREAM(sstream)->id, ROAR_FLAG_AUTOCONF);
+  recsource  = streams_get_flag(ROAR_STREAM(sstream)->id, ROAR_FLAG_RECSOURCE);
+ }
 
  // set up VIO:
@@ -57,11 +80,67 @@
  inst->inst     = self;
 
- if ( (self->client = jack_client_new("roard")) == NULL ) {
+ if ( (self->client = jack_client_open("roard", JackNullOption, NULL)) == NULL ) {
   roar_mm_free(self);
   return -1;
  }
 
- // return -1 on error or 0 on no error.
+ new_rate = jack_get_sample_rate(self->client);
+
+ // need to check if we need to change stream's parameters:
+ if ( info->rate != new_rate || info->bits != 32 || info->codec != ROAR_CODEC_DEFAULT ) {
+  if ( autoconfig ) {
+   // we are allowed to change the parameters
+   info->rate  = new_rate;
+   info->bits  = 32;
+   info->codec = ROAR_CODEC_DEFAULT;
+  } else {
+   // we are not allowed to change the parameters
+   ROAR_WARN("driver_jack_open_vio(*): Can not open jack driver with given parameters, try -oO ...,autoconf");
+   goto free_close;
+  }
+ }
+
+ if ( recsource )
+  if ( (self->ports_in = roar_mm_malloc(sizeof(jack_port_t *) * info->channels)) == NULL )
+   goto free_close;
+
+ if ( (self->ports_out = roar_mm_malloc(sizeof(jack_port_t *) * info->channels)) == NULL )
+  goto free_ins;
+
+ // NULL ports so we do not segfaul if something goes wrong.
+ if ( self->ports_in != NULL )
+  memset(self->ports_in, 0, sizeof(jack_port_t *) * info->channels);
+ memset(self->ports_in, 0, sizeof(jack_port_t *) * info->channels);
+
+ for (self->channels = 0; self->channels < info->channels; self->channels++) {
+  if ( recsource ) {
+   sprintf(port_name, "in_%03u", self->channels);
+   if ( (self->ports_in [self->channels] = jack_port_register(self->client, port_name,
+                                                              JACK_DEFAULT_AUDIO_TYPE, JackPortIsInput, 0)) == NULL )
+    goto unregister_ports;
+  }
+
+  sprintf(port_name, "out_%03u", self->channels);
+  if ( (self->ports_out[self->channels] = jack_port_register(self->client, port_name,
+                                                             JACK_DEFAULT_AUDIO_TYPE, JackPortIsOutput, 0)) == NULL ) {
+   jack_port_unregister(self->client, self->ports_in[self->channels]);
+   goto unregister_ports;
+  }
+ }
+
+ if (jack_activate(self->client) != 0)
+  goto unregister_ports;
+
  return 0;
+
+unregister_ports:
+ unregister_ports(self);
+free_ins:
+ if ( self->ports_in != NULL )
+  roar_mm_free(self->ports_in);
+free_close:
+ jack_client_close(self->client);
+ roar_mm_free(self);
+ return -1; // error
 }
 
@@ -165,4 +244,6 @@
  // close and free everything in here...
 
+ jack_deactivate(self->client);
+ unregister_ports(self);
  jack_client_close(self->client);
 
