Example #1
0
///FIXME perhaps support extensible wav format
FXbool WavOutput::configure(const AudioFormat & fmt) {
  FXushort format;

  // Can't handle big endian yet, neither does the output thread handle byteorder swaps
  if (fmt.byteorder() != Format::Little)
    return false;

  // Extensible Wav Format not yet supported
  if (fmt.channels>2)
    return false;

  // Determine format
  switch(fmt.datatype()) {
    case Format::Unsigned :
    case Format::Signed   : format = WAV_FORMAT_PCM;  break;
    case Format::Float    : format = WAV_FORMAT_FLOAT; break;
    default               : return false; break;
    }

  FXString path=FXPath::unique("gap.wav");
  if (file.open(path,FXIO::Writing)) {
    GM_DEBUG_PRINT("[wav] opened output file: %s\n",path.text());
    af=fmt;
    FXuint chunksize=0;
    FXlong ldata=0;

    /// riff chunk
    file.writeBlock("RIFF",4);
    file.writeBlock(&chunksize,4); // empty for now
    file.writeBlock("WAVE",4);

    /// junk chunk
    chunksize=28;
    file.writeBlock("JUNK",4);
    file.writeBlock(&chunksize,4);
    file.writeBlock(&ldata,8);
    file.writeBlock(&ldata,8);
    file.writeBlock(&ldata,8);
    chunksize=0;
    file.writeBlock(&chunksize,4);

    /// fmt
    file.writeBlock("fmt ",4);
    chunksize=16;
    file.writeBlock(&chunksize,4);
    file.writeBlock(&format,2);

    FXushort channels=fmt.channels;
    FXuint   rate=fmt.rate;
    FXuint   byterate=fmt.rate*fmt.channels*fmt.packing();
    FXushort blockalign=fmt.framesize();
    FXushort bitspersample=fmt.bps();

    file.writeBlock(&channels,2);
    file.writeBlock(&rate,4);
    file.writeBlock(&byterate,4);
    file.writeBlock(&blockalign,2);
    file.writeBlock(&bitspersample,2);

    file.writeBlock("data",4);
    chunksize=0xFFFFFFFF;
    data_pos=file.position();
    file.writeBlock(&chunksize,4);
    return true;
    }
  GM_DEBUG_PRINT("[wav] failed to open output file: %s\n",path.text());
  return false;
  }