Index: roard/codecfilter.c
===================================================================
--- roard/codecfilter.c	(revision 998)
+++ roard/codecfilter.c	(revision 1012)
@@ -28,11 +28,13 @@
  {-1,                     "null", "null codec filter", NULL, ROAR_CODECFILTER_NONE, NULL, NULL, NULL, NULL, NULL, NULL},
 
+/*
 #ifdef ROAR_HAVE_LIBSNDFILE
- {ROAR_CODEC_RIFF_WAVE, "sndfile", "libsndfile codec filter", NULL, ROAR_CODECFILTER_READ,
-  cf_sndfile_open, cf_sndfile_close, NULL, NULL, cf_sndfile_read, NULL},
-#else
+ {ROAR_CODEC_RIFF_WAVE, "sndfile", "libsndfile codec filter", NULL, ROAR_CODECFILTER_READ|ROAR_CODECFILTER_WRITE,
+  cf_sndfile_open, cf_sndfile_close, NULL, cf_sndfile_write, cf_sndfile_read, NULL},
+#else
+*/
  {ROAR_CODEC_RIFF_WAVE, "RIFF/WAVE", "RIFF/WAVE", NULL, ROAR_CODECFILTER_READ,
-  cf_wave_open, cf_wave_close, NULL, NULL, cf_wave_read, NULL},
-#endif
+  cf_wave_open, cf_wave_close, NULL, cf_wave_write, cf_wave_read, NULL},
+//#endif
 
  {ROAR_CODEC_ALAW, "alaw", "A-Law", NULL, ROAR_CODECFILTER_READ|ROAR_CODECFILTER_WRITE,
Index: roard/codecfilter_sndfile.c
===================================================================
--- roard/codecfilter_sndfile.c	(revision 928)
+++ roard/codecfilter_sndfile.c	(revision 1012)
@@ -39,4 +39,6 @@
  obj->stream = info;
 
+ ROAR_STREAM(info)->info.codec = ROAR_CODEC_DEFAULT;
+
  *inst = (CODECFILTER_USERDATA_T) obj;
 
@@ -45,4 +47,6 @@
  s->info.codec = ROAR_CODEC_DEFAULT;
 */
+
+ ROAR_WARN("cf_sndfile_open(*) = 0");
 
  return 0;
@@ -85,4 +89,5 @@
    return -1;
   }
+  ROAR_WARN("cf_sndfile_read(*): obj->info={.format=0x%.8x, .samplerate=%i, .channels=%i}", obj->info.format, obj->info.samplerate, obj->info.channels);
 
   s->info.codec    = ROAR_CODEC_DEFAULT;
@@ -106,5 +111,65 @@
 
 int cf_sndfile_write(CODECFILTER_USERDATA_T   inst, char * buf, int len) {
- return -1;
+ struct codecfilter_sndfile_inst * obj = (struct codecfilter_sndfile_inst *) inst;
+ struct roar_stream * s = ROAR_STREAM(obj->stream);
+ int ret;
+
+ ROAR_WARN("cf_sndfile_write(*): obj->opened=%i", obj->opened);
+
+ if ( !obj->opened ) {
+  if ( s->fh == -1 ) {
+   errno = EAGAIN;
+   return -1;
+  }
+
+  switch (s->info.codec) {
+   case ROAR_CODEC_PCM_S_LE:
+   case ROAR_CODEC_PCM_S_BE:
+     switch (s->info.bits) {
+      case  8:
+        obj->info.format = SF_FORMAT_PCM_S8;
+       break;
+      case 16:
+        obj->info.format = SF_FORMAT_PCM_16;
+       break;
+      case 24:
+        obj->info.format = SF_FORMAT_PCM_24;
+       break;
+      case 32:
+        obj->info.format = SF_FORMAT_PCM_32;
+       break;
+     }
+     //obj->info.format |= s->info.codec == ROAR_CODEC_PCM_S_LE ? SF_ENDIAN_LITTLE : SF_ENDIAN_BIG;
+     obj->info.format |= SF_ENDIAN_FILE;
+     obj->info.format |= SF_FORMAT_WAV;
+    break;
+   default:
+     ROAR_ERR("cf_sndfile_write(*): codec(%s) not supported!", roar_codec2str(s->info.bits));
+     return -1;
+    break;
+  }
+
+  obj->info.samplerate = s->info.rate;
+  obj->info.channels   = s->info.channels;
+  obj->info.sections   = 1;
+  obj->info.frames     = 182592; // 2147483647;
+  obj->info.seekable   = 1;
+  obj->info.format     = 0x00010002;
+
+  if ( (obj->state = sf_open_fd(s->fh, SFM_WRITE, &(obj->info), 0)) == NULL ) {
+   ROAR_ERR("cf_sndfile_write(*): can not sf_open_fd(*)!");
+   ROAR_ERR("cf_sndfile_write(*): s->fh=%i", s->fh);
+   ROAR_ERR("cf_sndfile_write(*): obj->info={.format=0x%.8x, .samplerate=%i, .channels=%i}", obj->info.format, obj->info.samplerate, obj->info.channels);
+   return -1;
+  }
+
+  obj->opened = 1;
+//  errno = EAGAIN;
+ }
+
+ ROAR_WARN("cf_sndfile_write(*): obj->opened=%i", obj->opened);
+ ret = sf_write_raw(obj->state, (void*) buf, len);
+ ROAR_WARN("cf_sndfile_write(inst=%p, buf=%p, len=%i) = %i", inst, buf, len, ret);
+ return ret;
 }
 
Index: roard/codecfilter_wave.c
===================================================================
--- roard/codecfilter_wave.c	(revision 668)
+++ roard/codecfilter_wave.c	(revision 1012)
@@ -83,6 +83,68 @@
 int cf_wave_write(CODECFILTER_USERDATA_T   inst, char * buf, int len) {
  struct codecfilter_wave_inst * self = (struct codecfilter_wave_inst *) inst;
+ struct roar_stream           * s    = ROAR_STREAM(self->stream);
+ char header[44];
+ int32_t  tmp32;
+ int16_t  tmp16;
+ int16_t  bits;
+ int16_t  codec;
 
- return 0;
+ ROAR_WARN("cf_wave_write(inst=%p, buf=%p, len=%i) = ?", inst, buf, len);
+ ROAR_WARN("cf_wave_write(inst=%p, buf=%p, len=%i): self->opened=%i", inst, buf, len, self->opened);
+
+ if ( self->opened ) {
+  return stream_vio_s_write(self->stream, buf, len);
+ } else {
+
+  if ( s->fh == -1 ) {
+   errno = EAGAIN;
+   return -1;
+  }
+
+  memcpy(header   , "RIFF\367\377\377\177WAVEfmt \020", 17);
+  memcpy(header+36, "data\313\377\377\177", 8);
+
+  switch (s->info.codec) {
+   case ROAR_CODEC_PCM_S_LE:
+     codec = 0x0001;
+    break;
+   default:
+     ROAR_ERR("cf_wave_write(*) Codec not supported!");
+     return -1;
+    break;
+  }
+
+  ROAR_WARN("cf_wave_write(*) Codec supported!");
+
+  bits = s->info.bits;
+  memcpy(header+24, &(s->info.rate    ), 4);
+  memcpy(header+22, &(s->info.channels), 2);
+  memcpy(header+34, &bits, 2);
+
+  tmp16 = s->info.channels * bits / 8;
+  memcpy(header+32, &tmp16, 2);
+  tmp32 = tmp16 * s->info.rate;
+  memcpy(header+28, &tmp32, 4);
+  memcpy(header+20, &codec, 2);
+
+  if ( stream_vio_s_write(self->stream, header, 44) != 44 )
+   return -1;
+
+  self->opened = 1;
+
+  errno = EAGAIN;
+//  return -1;
+
+  len = stream_vio_s_write(self->stream, buf, len);
+
+  cf_wave_close(inst);
+  ROAR_STREAM_SERVER(s)->codecfilter = -1;
+
+  return len;
+
+//  return stream_vio_s_write(self->stream, buf, len);
+ }
+
+ return -1;
 }
 
Index: roard/streams.c
===================================================================
--- roard/streams.c	(revision 981)
+++ roard/streams.c	(revision 1012)
@@ -738,4 +738,5 @@
   }
  } else {
+  errno = 0;
   if ( codecfilter_write(ss->codecfilter_inst, ss->codecfilter, obuf, olen)
             == olen ) {
@@ -744,7 +745,9 @@
    return 0;
   } else { // we cann't retry on codec filetered streams
-   if ( need_to_free ) free(obuf);
-   streams_delete(id);
-   return -1;
+   if ( errno != EAGAIN ) {
+    if ( need_to_free ) free(obuf);
+    streams_delete(id);
+    return -1;
+   }
   }
  }
