Index: ChangeLog
===================================================================
--- ChangeLog	(revision 4844)
+++ ChangeLog	(revision 4846)
@@ -12,4 +12,5 @@
 	* Added support for HTTP Basic Auth
 	* Fixed time display of roarvorbis if file has unknown playback length
+	* Auto select a stream if no stream has sync flag. (Closes: #30)
 
 v. 0.4beta4 - Sun Mar 20 2011 12:15 CET
Index: roard/driver_oss.c
===================================================================
--- roard/driver_oss.c	(revision 4819)
+++ roard/driver_oss.c	(revision 4846)
@@ -426,11 +426,19 @@
 
 int     driver_oss_nonblock(struct roar_vio_calls * vio, int state) {
- if ( roar_socket_nonblock(_get(vio,fh), state) == -1 )
-  return -1;
-
- if ( state == ROAR_SOCKET_NONBLOCK )
+ ROAR_DBG("driver_oss_nonblock(vio=%p, state=%i) = ?", vio, state);
+
+ if ( roar_socket_nonblock(_get(vio,fh), state) == -1 ) {
+  ROAR_DBG("driver_oss_nonblock(vio=%p, state=%i) = -1", vio, state);
+  return -1;
+ }
+
+ if ( state == ROAR_SOCKET_NONBLOCK ) {
+  ROAR_DBG("driver_oss_nonblock(vio=%p, state=%i) = 0", vio, state);
   return 0;
+ }
 
  roar_vio_sync(vio);
+
+ ROAR_DBG("driver_oss_nonblock(vio=%p, state=%i) = 0", vio, state);
 
  return 0;
Index: roard/include/streams.h
===================================================================
--- roard/include/streams.h	(revision 4819)
+++ roard/include/streams.h	(revision 4846)
@@ -119,5 +119,8 @@
 
 int streams_thru_num;
+int streams_sync_num;
 int streams_recsource_id;
+
+void streams_change_sync_num(int id, int diff);
 
 int streams_init   (void);
Index: roard/roard.c
===================================================================
--- roard/roard.c	(revision 4842)
+++ roard/roard.c	(revision 4846)
@@ -2860,4 +2860,7 @@
 #endif
 
+ // update sync counter.
+ streams_change_sync_num(-1, 0);
+
  ROAR_INFO("Startup complet", ROAR_DBG_INFO_INFO);
 
Index: roard/streams.c
===================================================================
--- roard/streams.c	(revision 4819)
+++ roard/streams.c	(revision 4846)
@@ -30,4 +30,5 @@
 
 int streams_thru_num     =  0;
+int streams_sync_num     =  0;
 int streams_recsource_id = -1;
 
@@ -48,4 +49,73 @@
 
  roar_notify_core_emit_simple(ROAR_OE_BASICS_CHANGE_STATE, -1, id, ROAR_OT_STREAM, old, new, NULL, 0);
+}
+
+void streams_change_sync_num(int id, int diff) {
+ struct roar_stream_server * ss;
+ int i;
+
+ if ( diff != 0 )
+  if ( streams_get_dir(id) != ROAR_DIR_OUTPUT )
+   return;
+
+ ROAR_INFO("streams_change_sync_num(id=%i, diff=%i): Number of sync streams changed from %i to %i",
+           ROAR_DBG_INFO_VERBOSE,
+           id, diff,
+           streams_sync_num, streams_sync_num + diff);
+ streams_sync_num += diff;
+
+ if ( !streams_sync_num && alive ) {
+  ROAR_INFO("streams_change_sync_num(id=%i, diff=%i): Number of sync streams changed to zero. Bad.",
+            ROAR_DBG_INFO_VERBOSE, id, diff
+            );
+
+  for (i = 0; i < ROAR_STREAMS_MAX; i++) {
+   if ( (ss = g_streams[i]) == NULL )
+    continue;
+
+   if ( ROAR_STREAM(ss)->dir != ROAR_DIR_OUTPUT )
+    continue;
+
+   if ( !ss->ready )
+    continue;
+
+   if ( ss->state == ROAR_STREAMSTATE_CLOSING )
+    continue;
+
+   if ( streams_get_flag(i, ROAR_FLAG_PRIMARY) ) {
+    ROAR_DBG("streams_change_sync_num(*): try to set sync on primary stream %i", i);
+    streams_set_flag(i, ROAR_FLAG_SYNC);
+    if ( streams_sync_num )
+     return;
+   }
+  }
+
+  for (i = 0; i < ROAR_STREAMS_MAX; i++) {
+   if ( (ss = g_streams[i]) == NULL )
+    continue;
+
+   if ( ROAR_STREAM(ss)->dir != ROAR_DIR_OUTPUT )
+    continue;
+
+   if ( !ss->ready )
+    continue;
+
+   if ( ss->state == ROAR_STREAMSTATE_CLOSING )
+    continue;
+
+   if ( !streams_get_flag(i, ROAR_FLAG_PRIMARY) ) {
+    ROAR_DBG("streams_change_sync_num(*): try to set sync on non-primary stream %i", i);
+    streams_set_flag(i, ROAR_FLAG_SYNC);
+    if ( streams_sync_num )
+     return;
+   }
+  }
+
+  ROAR_INFO("streams_change_sync_num(id=%i, diff=%i): Can not auto set sync flag to an output. Very Bad",
+            ROAR_DBG_INFO_VERBOSE, id, diff
+            );
+  ROAR_WARN("streams_change_sync_num(id=%i, diff=%i): Lost all sync streams and failed to set a new one. Very Bad.",
+            id, diff);
+ }
 }
 
@@ -289,4 +359,7 @@
 */
 
+ if ( s->flags & ROAR_FLAG_SYNC )
+  streams_change_sync_num(id, -1);
+
  if ( !no_vio_close )
   roar_vio_close(s->viop);
@@ -781,7 +854,9 @@
  int fh = streams_get_fh(id);
 
- _CHECK_SID(id);
-
- if ( fh != -1 ) {
+ ROAR_DBG("streams_set_sync(id=%i, sync=%i) = ?", id, sync);
+
+ _CHECK_SID(id);
+
+ if ( fh > -1 ) {
   if ( roar_socket_nonblock(fh, sync ? ROAR_SOCKET_BLOCK : ROAR_SOCKET_NONBLOCK) == -1 )
    return -1;
@@ -910,5 +985,9 @@
  int tmp;
 
- _CHECK_SID(id);
+ ROAR_DBG("streams_set_flag(id=%i, flag=0x%.8X) = ?", id, flag);
+
+ _CHECK_SID(id);
+
+ ROAR_DBG("streams_set_flag(id=%i, flag=0x%.8X) = ?", id, flag);
 
  if ( flag & ROAR_FLAG_IMMUTABLE )
@@ -916,8 +995,14 @@
 
 
+ ROAR_DBG("streams_set_flag(id=%i, flag=0x%.8X) = ?", id, flag);
+
  // check if flags we are going to change are protected:
  if ( g_streams[id]->flags_protection & flag )
   return -1;
 
+ flag |= g_streams[id]->flags;
+ flag -= g_streams[id]->flags;
+
+ ROAR_DBG("streams_set_flag(id=%i, flag=0x%.8X) = ?", id, flag);
 
  if ( flag & ROAR_FLAG_MMAP ) {
@@ -928,4 +1013,6 @@
  }
 
+ ROAR_DBG("streams_set_flag(id=%i, flag=0x%.8X) = ?", id, flag);
+
  if ( flag & ROAR_FLAG_PRIMARY ) {
   streams_set_primary(id, 1);
@@ -933,4 +1020,6 @@
  }
 
+ ROAR_DBG("streams_set_flag(id=%i, flag=0x%.8X) = ?", id, flag);
+
  if ( flag & ROAR_FLAG_SINGLESINK ) {
   if ( streams_set_single_sink(id, 0) == -1 ) {
@@ -940,4 +1029,6 @@
  }
 
+ ROAR_DBG("streams_set_flag(id=%i, flag=0x%.8X) = ?", id, flag);
+
  if ( flag & ROAR_FLAG_VIRTUAL ) {
   if ( (parent = ROAR_STREAM(g_streams[id])->pos_rel_id) == -1 )
@@ -954,5 +1045,8 @@
  }
 
+ ROAR_DBG("streams_set_flag(id=%i, flag=0x%.8X) = ?", id, flag);
+
  if ( flag & ROAR_FLAG_SYNC ) {
+  ROAR_DBG("streams_set_flag(id=%i, flag=0x%.8X) = ?", id, flag);
   switch (ROAR_STREAM(g_streams[id])->dir) {
    // for this stream types the flag is used in the subsystem:
@@ -963,11 +1057,24 @@
    // normal behavor (vio blocking):
    default:
+     ROAR_DBG("streams_set_flag(id=%i, flag=0x%.8X) = ?", id, flag);
      // the fh is updated as soon as the fh get ready in case the default ask to set sync
-     if ( !g_streams[id]->ready && !(g_config->streams[ROAR_STREAM(g_streams[id])->dir].flags & ROAR_FLAG_SYNC) ) {
-      if ( streams_set_sync(id, 1) == -1 )
+     if ( g_streams[id]->ready || (!g_streams[id]->ready && !(g_config->streams[ROAR_STREAM(g_streams[id])->dir].flags & ROAR_FLAG_SYNC)) ) {
+      ROAR_DBG("streams_set_flag(id=%i, flag=0x%.8X) = ?", id, flag);
+      if ( streams_set_sync(id, 1) == -1 ) {
+       ROAR_WARN("streams_set_flag(id=%i, flag=0x%.8X): Can not set SYNC flag.", id, flag);
        flag -= ROAR_FLAG_SYNC;
+      }
      }
-  }
- }
+    break;
+  }
+  ROAR_DBG("streams_set_flag(id=%i, flag=0x%.8X) = ?", id, flag);
+
+  if ( flag & ROAR_FLAG_SYNC ) {
+   g_streams[id]->flags |= ROAR_FLAG_SYNC;
+   streams_change_sync_num(id, +1);
+  }
+ }
+
+ ROAR_DBG("streams_set_flag(id=%i, flag=0x%.8X) = ?", id, flag);
 
  if ( flag & ROAR_FLAG_HWMIXER ) { // currently not supported -> ignored
@@ -979,4 +1086,6 @@
  }
 
+ ROAR_DBG("streams_set_flag(id=%i, flag=0x%.8X) = ?", id, flag);
+
  if ( flag & ROAR_FLAG_RECSOURCE ) {
   if ( streams_recsource_id != -1 ) {
@@ -994,4 +1103,6 @@
  }
 
+ ROAR_DBG("streams_set_flag(id=%i, flag=0x%.8X) = ?", id, flag);
+
  g_streams[id]->flags |= flag;
 
@@ -1001,4 +1112,6 @@
 #endif
 
+ ROAR_DBG("streams_set_flag(id=%i, flag=0x%.8X) = ?", id, flag);
+
  return 0;
 }
@@ -1008,4 +1121,7 @@
 
  g_streams[id]->flags |= flag;
+
+ if ( flag & ROAR_FLAG_SYNC )
+  streams_change_sync_num(id, +1);
 
  return 0;
@@ -1025,4 +1141,6 @@
   flag -= ROAR_FLAG_PRIMARY;
  }
+
+ flag &= g_streams[id]->flags;
 
  if ( (flag & ROAR_FLAG_RECSOURCE) && streams_recsource_id == id ) {
@@ -1062,5 +1180,11 @@
    return -1;
   } else {
-   streams_set_sync(id, 0);
+   if ( streams_set_sync(id, 0) == -1 )
+    return -1;
+
+   g_streams[id]->flags |= ROAR_FLAG_SYNC;
+   g_streams[id]->flags -= ROAR_FLAG_SYNC;
+   flag -= ROAR_FLAG_SYNC;
+   streams_change_sync_num(id, -1);
   }
  }
