1 // ------------------------------------------------------------------------
2 // audioio-mp3.cpp: Interface for mp3 decoders and encoders that support
3 //                  input/output using standard streams. Defaults to
4 //                  mpg123 and lame.
5 // Copyright (C) 1999-2006,2008,2009,2015 Kai Vehmanen
6 // Note! Routines for parsing mp3 header information were taken from XMMS
7 //       1.2.5's mpg123 plugin. Improvements to parsing logic were
8 //       contributed by Julian Dobson.
9 //
10 // Attributes:
11 //     eca-style-version: 3 (see Ecasound Programmer's Guide)
12 //
13 // References:
14 //     http://www.mp3-tech.org/programmer/frame_header.html
15 //     http://www.mpg123.de/
16 //
17 // This program is free software; you can redistribute it and/or modify
18 // it under the terms of the GNU General Public License as published by
19 // the Free Software Foundation; either version 2 of the License, or
20 // (at your option) any later version.
21 //
22 // This program is distributed in the hope that it will be useful,
23 // but WITHOUT ANY WARRANTY; without even the implied warranty of
24 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
25 // GNU General Public License for more details.
26 //
27 // You should have received a copy of the GNU General Public License
28 // along with this program; if not, write to the Free Software
29 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307  USA
30 // ------------------------------------------------------------------------
31 
32 #ifdef HAVE_CONFIG_H
33 #include <config.h>
34 #endif
35 
36 #include <string>
37 #include <cmath>
38 #include <cstring>
39 #include <cstdlib> /* atol() */
40 
41 #include <signal.h>
42 #include <unistd.h> /* stat() */
43 #include <sys/stat.h> /* stat() */
44 #include <sys/wait.h>
45 
46 #include <kvu_inttypes.h>
47 #include <kvu_message_item.h>
48 #include <kvu_numtostr.h>
49 
50 #include "audioio-mp3.h"
51 #include "audioio-mp3_impl.h"
52 #include "samplebuffer.h"
53 #include "audioio.h"
54 
55 #include "eca-logger.h"
56 
57 const char *default_input_cmd = "mpg123 --stereo -q -s -k %o %f";
58 const char *default_output_cmd = "lame -b %B -s %S -r --big-endian -S - %f";
59 const long int default_output_bitrate = 128000;
60 
61 std::string MP3FILE::conf_input_cmd = std::string(default_input_cmd);
62 std::string MP3FILE::conf_output_cmd = std::string(default_output_cmd);
63 
64 long int MP3FILE::conf_default_output_bitrate = default_output_bitrate;
65 
set_input_cmd(const std::string & value)66 void MP3FILE::set_input_cmd(const std::string& value) { MP3FILE::conf_input_cmd = value; }
set_output_cmd(const std::string & value)67 void MP3FILE::set_output_cmd(const std::string& value) { MP3FILE::conf_output_cmd = value; }
68 
69 /***************************************************************
70  * Routines for parsing mp3 header information. Taken from XMMS
71  * 1.2.5's mpg123 plugin.
72  **************************************************************/
73 
74 #define         MAXFRAMESIZE            1792
75 #define         MPG_MD_STEREO           0
76 #define         MPG_MD_JOINT_STEREO     1
77 #define         MPG_MD_DUAL_CHANNEL     2
78 #define         MPG_MD_MONO             3
79 
80 int tabsel_123[2][3][16] =
81   {
82     {
83       {0, 32, 64, 96, 128, 160, 192, 224, 256, 288, 320, 352, 384, 416, 448,},
84       {0, 32, 48, 56, 64, 80, 96, 112, 128, 160, 192, 224, 256, 320, 384,},
85       {0, 32, 40, 48, 56, 64, 80, 96, 112, 128, 160, 192, 224, 256, 320,}},
86 
87     {
88       {0, 32, 48, 56, 64, 80, 96, 112, 128, 144, 160, 176, 192, 224, 256,},
89       {0, 8, 16, 24, 32, 40, 48, 56, 64, 80, 96, 112, 128, 144, 160,},
90       {0, 8, 16, 24, 32, 40, 48, 56, 64, 80, 96, 112, 128, 144, 160,}}
91   };
92 
93 long mpg123_freqs[9] =
94   {44100, 48000, 32000, 22050, 24000, 16000, 11025, 12000, 8000};
95 
96 struct frame
97 {
98   int stereo;
99   int jsbound;
100   int single;
101   int II_sblimit;
102   int down_sample_sblimit;
103   int lsf;
104   int mpeg25;
105   int down_sample;
106   int header_change;
107   int lay;
108   int error_protection;
109   int bitrate_index;
110   int sampling_frequency;
111   int padding;
112   int extension;
113   int mode;
114   int mode_ext;
115   int copyright;
116   int original;
117   int emphasis;
118   int framesize;		/* computed framesize */
119 };
120 
mpg123_head_check(unsigned long head)121 static bool mpg123_head_check(unsigned long head)
122 {
123   /* ref: http://www.mp3-tech.org/programmer/frame_header.html */
124 
125   /* frame sync must be 0xffe (11bits) */
126   if ((head & 0xffe00000) != 0xffe00000) return false;
127   /* layer must be non-null (2bits) */
128   if (!((head >> 17) & 3)) return false;
129   /* invalid bitrate index: all-ones (4bit) */
130   if (((head >> 12) & 0xf) == 0xf) return false;
131   /* invalid bitrate index: null (4bit) */
132   if (!((head >> 12) & 0xf)) return false;
133   /* invalid srate index: all-ones (2bit) */
134   if (((head >> 10) & 0x3) == 0x3) return false;
135 #if 0
136   /* invalid: mpeg2/2.5, layer I, protection bit off */
137   if (((head >> 19) & 1) == 1 && ((head >> 17) & 3) == 3 && ((head >> 16) & 1) == 1) return false;
138   /* - mpeg version 1, CRC protection bit */
139   if ((head & 0xffff0000) == 0xfffe0000) return false;
140 #endif
141 
142   return true;
143 }
144 
mpg123_compute_bpf(struct frame * fr)145 static double mpg123_compute_bpf(struct frame *fr)
146 {
147   double bpf;
148 
149   switch (fr->lay)
150     {
151     case 1:
152       bpf = tabsel_123[fr->lsf][0][fr->bitrate_index];
153       bpf *= 12000.0 * 4.0;
154       bpf /= mpg123_freqs[fr->sampling_frequency] << (fr->lsf);
155       break;
156     case 2:
157     case 3:
158       bpf = tabsel_123[fr->lsf][fr->lay - 1][fr->bitrate_index];
159       bpf *= 144000;
160       bpf /= mpg123_freqs[fr->sampling_frequency] << (fr->lsf);
161       break;
162     default:
163       bpf = 1.0;
164     }
165 
166   return bpf;
167 }
168 
mpg123_compute_tpf(struct frame * fr)169 static double mpg123_compute_tpf(struct frame *fr)
170 {
171   static int bs[4] =
172     {0, 384, 1152, 1152};
173   double tpf;
174 
175   tpf = (double) bs[fr->lay];
176   tpf /= mpg123_freqs[fr->sampling_frequency] << (fr->lsf);
177   return tpf;
178 }
179 
180 /*
181  * the code a header and write the information
182  * into the frame structure
183  */
mpg123_decode_header(struct frame * fr,unsigned long newhead)184 static bool mpg123_decode_header(struct frame *fr, unsigned long newhead)
185 {
186   if (newhead & (1 << 20))
187     {
188       fr->lsf = (newhead & (1 << 19)) ? 0x0 : 0x1;
189       fr->mpeg25 = 0;
190     }
191   else
192     {
193       fr->lsf = 1;
194       fr->mpeg25 = 1;
195     }
196   fr->lay = 4 - ((newhead >> 17) & 3);
197   if (fr->mpeg25)
198     {
199       fr->sampling_frequency = 6 + ((newhead >> 10) & 0x3);
200     }
201   else
202     fr->sampling_frequency = ((newhead >> 10) & 0x3) + (fr->lsf * 3);
203   fr->error_protection = ((newhead >> 16) & 0x1) ^ 0x1;
204 
205   if (fr->mpeg25)		/* allow Bitrate change for 2.5 ... */
206     fr->bitrate_index = ((newhead >> 12) & 0xf);
207 
208   fr->bitrate_index = ((newhead >> 12) & 0xf);
209   fr->padding = ((newhead >> 9) & 0x1);
210   fr->extension = ((newhead >> 8) & 0x1);
211   fr->mode = ((newhead >> 6) & 0x3);
212   fr->mode_ext = ((newhead >> 4) & 0x3);
213   fr->copyright = ((newhead >> 3) & 0x1);
214   fr->original = ((newhead >> 2) & 0x1);
215   fr->emphasis = newhead & 0x3;
216 
217   fr->stereo = (fr->mode == MPG_MD_MONO) ? 1 : 2;
218 
219   if (!fr->bitrate_index) {
220     ECA_LOG_MSG(ECA_LOGGER::errors, "Invalid bitrate!");
221     return false;
222   }
223 
224   int ssize = 0;
225   switch (fr->lay)
226     {
227     case 1:
228       //  	    fr->do_layer = mpg123_do_layer1;
229       //  	    mpg123_init_layer2();
230       fr->framesize = (long) tabsel_123[fr->lsf][0][fr->bitrate_index] * 12000;
231       fr->framesize /= mpg123_freqs[fr->sampling_frequency];
232       fr->framesize = ((fr->framesize + fr->padding) << 2) - 4;
233       break;
234     case 2:
235       //  	    fr->do_layer = mpg123_do_layer2;
236       //  	    mpg123_init_layer2();
237       fr->framesize = (long) tabsel_123[fr->lsf][1][fr->bitrate_index] * 144000;
238       fr->framesize /= mpg123_freqs[fr->sampling_frequency];
239       fr->framesize += fr->padding - 4;
240       break;
241     case 3:
242       //  	    fr->do_layer = mpg123_do_layer3;
243       if (fr->lsf)
244 	ssize = (fr->stereo == 1) ? 9 : 17;
245       else
246 	ssize = (fr->stereo == 1) ? 17 : 32;
247       if (fr->error_protection)
248 	ssize += 2;
249       fr->framesize = (long) tabsel_123[fr->lsf][2][fr->bitrate_index] * 144000;
250       fr->framesize /= mpg123_freqs[fr->sampling_frequency] << (fr->lsf);
251       fr->framesize = fr->framesize + fr->padding - 4;
252       break;
253     default:
254       return false;
255     }
256 
257   if(fr->framesize > MAXFRAMESIZE) {
258     ECA_LOG_MSG(ECA_LOGGER::errors, "Invalid framesize!");
259     return false;
260   }
261 
262   return true;
263 }
264 
265 /* not used anymore, kaiv 2005/03 */
266 #if 0
267 static uint32_t convert_to_header(uint8_t * buf)
268 {
269 
270   return (buf[0] << 24) + (buf[1] << 16) + (buf[2] << 8) + buf[3];
271 }
272 #endif
273 
mpg123_detect_by_content(const char * filename,struct frame * frp)274 static bool mpg123_detect_by_content(const char* filename, struct frame* frp)
275 {
276   FILE *file;
277   uint8_t tmp[4]; /* room for the 32bit head */
278   uint32_t head = 0;
279   bool data_left = true;
280   bool header_found = false;
281   size_t offset = 0;
282 
283   if((file = std::fopen(filename, "rb")) == NULL) {
284     ECA_LOG_MSG(ECA_LOGGER::errors, string("Unable to open file ") + filename + ".");
285     data_left = false;
286   }
287   /* search for headers in the first 262kB of data */
288   while(data_left == true && offset < (1<<18)) {
289     /* octet-by-octet search */
290     if (std::fread(tmp, 1, 1, file) != 1) {
291       ECA_LOG_MSG(ECA_LOGGER::errors, "End of mp3 file, no valid header data found.");
292       data_left = false;
293       break;
294     }
295 
296     head <<= 8;
297     head |= tmp[0];
298     offset += 1;
299 
300     if (offset > 3) {
301       /* verify the header and if ok, fetch mp3 parameters and store
302 	 them to 'frp' */
303       if (mpg123_head_check(head) && mpg123_decode_header(frp, head)) {
304 	if (header_found == true) {
305 	  /* two headers found, stop searching */
306 	  data_left = false;
307 	}
308 	else {
309 	  /* after the first header is found, skip to the next
310 	     valid frame to verify that the first frame is not
311 	     dummy frame (id3 or something similar) */
312 	  if (std::fseek(file, frp->framesize, SEEK_CUR) != 0) {
313 	    data_left = false;
314 	  }
315 	  header_found = true;
316 	}
317 	ECA_LOG_MSG(ECA_LOGGER::user_objects, "Found mp3 header at offset " +
318 		    kvu_numtostr(static_cast<int>(offset - 4)));
319       }
320     }
321   }
322 
323   return header_found;
324 }
325 
326 /***************************************************************
327  * MP3FILE specific parts.
328  **************************************************************/
329 
MP3FILE(const std::string & name)330 MP3FILE::MP3FILE(const std::string& name)
331   :  finished_rep(false),
332      triggered_rep(false)
333 {
334   set_label(name);
335   filedes_rep = -1;
336   filehandle_rep = 0;
337   mono_input_rep = false;
338   pcm_rep = 1;
339   bitrate_rep = MP3FILE::conf_default_output_bitrate;
340 }
341 
~MP3FILE(void)342 MP3FILE::~MP3FILE(void)
343 {
344   /* see notes in stop_io() */
345   clean_child(io_mode() == io_read ? true : false);
346   if (is_open() == true) {
347     close();
348   }
349 }
350 
open(void)351 void MP3FILE::open(void) throw(AUDIO_IO::SETUP_ERROR &)
352 {
353   if (io_mode() == io_read) {
354     /* decoder supports: fixed channel count and sample format,
355                          sample rate set by parsing mp3 header */
356     get_mp3_params(label());
357   }
358   else {
359     /* encoder supports: srate configurable, fixed channel
360                          count and sample format */
361     set_channels(2);
362     set_sample_format(ECA_AUDIO_FORMAT::sfmt_s16_le);
363 
364     /* note: 'lame' command-line syntax, and default related to them,
365      *       have changed slightly in lame 3.98, so we need this hack
366      *       to support both old and new versions. In the past,
367      *       Ecasound wrote little-endian samples and used lame
368      *       option "-x". Newer lame versions (3.97) introduced
369      *       "--litle-endian" and "--big-endian", but these were
370      *       buggy still in 3.97 (fixed in 3.98). And with 3.98,
371      *       additional options (e.g. "-r") need to be passed, or
372      *       otherwise lame will exit with an error.
373      *
374      *       In addition to above problems, we also need to remember
375      *       people updating to a newer Ecasound, but who do not update
376      *       their custom 'lame' launch commands in
377      *       ~/.ecasound/ecasoundrc (ecasound must continue to output
378      *       little-endian samples by default).
379      */
380     if (MP3FILE::conf_output_cmd.find("lame ") != std::string::npos &&
381 	MP3FILE::conf_output_cmd.find(" --big-endian ") != std::string::npos) {
382       set_sample_format(ECA_AUDIO_FORMAT::sfmt_s16_be);
383     }
384   }
385 
386   triggered_rep = false;
387 
388   AUDIO_IO::open();
389 }
390 
close(void)391 void MP3FILE::close(void)
392 {
393   if (pid_of_child() > 0) {
394       ECA_LOG_MSG(ECA_LOGGER::user_objects, "Cleaning child process pid=" + kvu_numtostr(pid_of_child()) + ".");
395       /* note: mp3 input/output can handle SIGTERM */
396       clean_child(true);
397       triggered_rep = false;
398   }
399 
400   AUDIO_IO::close();
401 }
402 
process_mono_fix(char * target_buffer,long int bytes)403 void MP3FILE::process_mono_fix(char* target_buffer, long int bytes) {
404   for(long int n = 0; n < bytes;) {
405     target_buffer[n + 2] = target_buffer[n];
406     target_buffer[n + 3] = target_buffer[n + 1];
407     n += 4;
408   }
409 }
410 
read_samples(void * target_buffer,long int samples)411 long int MP3FILE::read_samples(void* target_buffer, long int samples)
412 {
413   if (triggered_rep != true) {
414     ECA_LOG_MSG(ECA_LOGGER::info, "WARNING: triggering an external program in real-time context");
415     triggered_rep = true;
416     fork_input_process();
417   }
418 
419   bytes_rep = std::fread(target_buffer, 1, frame_size() * samples, filehandle_rep);
420   if (bytes_rep < samples * frame_size() || bytes_rep == 0) {
421     if (position_in_samples() == 0)
422       ECA_LOG_MSG(ECA_LOGGER::errors, "Can't start process \"" + MP3FILE::conf_input_cmd + "\". Please check your ~/.ecasound/ecasoundrc.");
423     finished_rep = true;
424     triggered_rep = false;
425   }
426   else
427     finished_rep = false;
428 
429   last_position_rep += (bytes_rep / frame_size());
430 
431   return bytes_rep / frame_size();
432 }
433 
write_samples(void * target_buffer,long int samples)434 void MP3FILE::write_samples(void* target_buffer, long int samples)
435 {
436   if (triggered_rep != true) {
437     triggered_rep = true;
438     fork_output_process();
439   }
440 
441   if (wait_for_child() != true) {
442     finished_rep = true;
443     triggered_rep = false;
444     ECA_LOG_MSG(ECA_LOGGER::errors, "Attempt to write after child process has terminated.");
445   }
446   else {
447     bytes_rep = ::write(filedes_rep, target_buffer, frame_size() * samples);
448 
449     if (bytes_rep < frame_size() * samples) {
450       if (position_in_samples() == 0)
451 	ECA_LOG_MSG(ECA_LOGGER::errors, "Can't start process \"" + MP3FILE::conf_output_cmd + "\". Please check your ~/.ecasound/ecasoundrc.");
452       else
453 	ECA_LOG_MSG(ECA_LOGGER::errors,
454 		    "Error in writing to child process (to write "
455 		    + kvu_numtostr(frame_size() * samples)
456 		    + ", result "
457 		    + kvu_numtostr(bytes_rep)
458 		    + ").");
459 
460       finished_rep = true;
461     }
462     else
463       finished_rep = false;
464   }
465 }
466 
seek_position(SAMPLE_SPECS::sample_pos_t pos)467 SAMPLE_SPECS::sample_pos_t MP3FILE::seek_position(SAMPLE_SPECS::sample_pos_t pos)
468 {
469   finished_rep = false;
470   if (triggered_rep == true &&
471       last_position_rep != pos) {
472     if (is_open() == true) {
473       ECA_LOG_MSG(ECA_LOGGER::user_objects, "Cleaning child process pid=" + kvu_numtostr(pid_of_child()) + ".");
474       clean_child(true);
475       triggered_rep = false;
476     }
477   }
478   return pos;
479 }
480 
set_parameter(int param,std::string value)481 void MP3FILE::set_parameter(int param, std::string value)
482 {
483   switch (param) {
484   case 1:
485     set_label(value);
486     break;
487 
488   case 2:
489     long int numvalue = atol(value.c_str());
490     if (numvalue > 0)
491       bitrate_rep = numvalue;
492     else
493       bitrate_rep = MP3FILE::conf_default_output_bitrate;
494     break;
495   }
496 }
497 
get_parameter(int param) const498 std::string MP3FILE::get_parameter(int param) const
499 {
500   switch (param) {
501   case 1:
502     return label();
503 
504   case 2:
505     return kvu_numtostr(bitrate_rep);
506   }
507   return "";
508 }
509 
get_mp3_params(const std::string & fname)510 void MP3FILE::get_mp3_params(const std::string& fname) throw(AUDIO_IO::SETUP_ERROR&)
511 {
512   std::string urlprefix;
513   struct frame fr = { 0 };
514 
515   if (mpg123_detect_by_content(fname.c_str(), &fr) != true) {
516     /* not a file, next search for an URL */
517     size_t offset = fname.find_first_of("://");
518     if (offset == std::string::npos) {
519       throw(SETUP_ERROR(SETUP_ERROR::io_mode, "AUDIOIO-MP3: Can't open " + label() + " for reading."));
520     }
521     else {
522       urlprefix = std::string(fname, 0, offset);
523       ECA_LOG_MSG(ECA_LOGGER::user_objects, "Found url; protocol '" + urlprefix + "'.");
524     }
525   }
526   else {
527     /* file size */
528     struct stat buf;
529     ::stat(fname.c_str(), &buf);
530     double fsize = (double)buf.st_size;
531     ECA_LOG_MSG(ECA_LOGGER::user_objects, "Total file size (bytes): " + kvu_numtostr(fsize));
532 
533     /* bitrate */
534     double bitrate = tabsel_123[fr.lsf][fr.lay - 1][fr.bitrate_index] * 1000;
535     ECA_LOG_MSG(ECA_LOGGER::user_objects, "Bitrate (bits/s): " + kvu_numtostr(bitrate));
536 
537     /* sample freq */
538     double sfreq = mpg123_freqs[fr.sampling_frequency];
539     ECA_LOG_MSG(ECA_LOGGER::user_objects, "Sampling frequncy (Hz): " + kvu_numtostr(sfreq));
540     set_samples_per_second(static_cast<SAMPLE_SPECS::sample_rate_t>(sfreq));
541 
542     /* channels */
543     // notice! mpg123 always outputs 16bit samples, stereo
544     mono_input_rep = (fr.mode == MPG_MD_MONO) ? true : false;
545 
546     /* temporal length */
547     long int numframes =  static_cast<long int>((fsize / mpg123_compute_bpf(&fr)));
548     ECA_LOG_MSG(ECA_LOGGER::user_objects, "Total length (frames): " + kvu_numtostr(numframes));
549     double tpf = mpg123_compute_tpf(&fr);
550     set_length_in_seconds(tpf * numframes);
551     ECA_LOG_MSG(ECA_LOGGER::user_objects, "Total length (seconds): " + kvu_numtostr(length_in_seconds()));
552 
553     /* set pcm per frame value */
554     static int bs[4] = {0, 384, 1152, 1152};
555     pcm_rep = bs[fr.lay];
556     ECA_LOG_MSG(ECA_LOGGER::user_objects, "Pcm per mp3 frames: " + kvu_numtostr(pcm_rep));
557   }
558 
559   /* sample format (this comes from mpg123) */
560   set_channels(2);
561   set_sample_format(ECA_AUDIO_FORMAT::sfmt_s16_le);
562 }
563 
start_io(void)564 void MP3FILE::start_io(void)
565 {
566   if (triggered_rep != true) {
567     if (io_mode() == io_read)
568       fork_input_process();
569     else
570       fork_output_process();
571 
572     triggered_rep = true;
573   }
574 }
575 
stop_io(void)576 void MP3FILE::stop_io(void)
577 {
578   if (triggered_rep == true) {
579     /* note: it's safe to send a SIGTERM if the client is
580      *       an input and we know its PID (otherwise
581      *       cleanup will still work but will take more time, which
582      *       is nasty if we are in a middle of a seek */
583     if (io_mode() == io_read)
584       clean_child(true);
585     else
586       clean_child(false);
587 
588     triggered_rep = false;
589   }
590 }
591 
fork_input_process(void)592 void MP3FILE::fork_input_process(void)
593 {
594   std::string cmd = MP3FILE::conf_input_cmd;
595   if (cmd.find("%o") != std::string::npos) {
596     cmd.replace(cmd.find("%o"), 2, kvu_numtostr((long)(position_in_samples() / pcm_rep)));
597   }
598   last_position_rep = position_in_samples();
599   ECA_LOG_MSG(ECA_LOGGER::user_objects, "" + cmd);
600   set_fork_command(cmd);
601   set_fork_file_name(label());
602 
603   set_fork_bits(bits());
604   set_fork_channels(channels());
605   set_fork_sample_rate(samples_per_second()); /* for old mpg123 */
606 
607   fork_child_for_read();
608   if (child_fork_succeeded() == true) {
609 
610     /* NOTE: the file description will be closed by
611      *       AUDIO_IO_FORKED_STREAM::clean_child() */
612     filedes_rep = file_descriptor();
613     filehandle_rep = fdopen(filedes_rep, "r"); /* not part of <cstdio> */
614     if (filehandle_rep == 0) {
615       finished_rep = true;
616       triggered_rep = false;
617     }
618   }
619 }
620 
fork_output_process(void)621 void MP3FILE::fork_output_process(void)
622 {
623   ECA_LOG_MSG(ECA_LOGGER::info, "Starting to encode " + label() + " with lame.");
624   last_position_rep = position_in_samples();
625   std::string cmd = MP3FILE::conf_output_cmd;
626   if (cmd.find("%B") != std::string::npos) {
627     cmd.replace(cmd.find("%B"), 2, kvu_numtostr((long int)(bitrate_rep / 1000)));
628   }
629 
630   set_fork_command(cmd);
631 
632   set_fork_file_name(label());
633   set_fork_bits(bits());
634   set_fork_channels(channels());
635 
636   set_fork_sample_rate(samples_per_second());
637   fork_child_for_write();
638   if (child_fork_succeeded() == true) {
639     filedes_rep = file_descriptor();
640   }
641 }
642