def write_header(sample_frame_count)
      extensible = @format.channels > 2 ||
                   (@format.sample_format == :pcm && @format.bits_per_sample != 8 && @format.bits_per_sample != 16) ||
                   (@format.channels == 1 && @format.speaker_mapping != [:front_center]) ||
                   (@format.channels == 2 && @format.speaker_mapping != [:front_left, :front_right])
      format_code = extensible ? :extensible : @format.sample_format
      requires_fact_chunk = (format_code != :pcm)

      sample_data_byte_count = sample_frame_count * @format.block_align
      riff_chunk_size = CANONICAL_HEADER_BYTE_LENGTH[format_code] + sample_data_byte_count
      if sample_data_byte_count.odd?
        riff_chunk_size += 1
      end

      # Write the header for the RIFF chunk
      header = CHUNK_IDS[:riff]
      header += [riff_chunk_size].pack(UNSIGNED_INT_32)
      header += WAVEFILE_FORMAT_CODE

      # Write the format chunk
      header += CHUNK_IDS[:format]
      header += [FORMAT_CHUNK_BYTE_LENGTH[format_code]].pack(UNSIGNED_INT_32)
      header += [FORMAT_CODES[format_code]].pack(UNSIGNED_INT_16)
      header += [@format.channels].pack(UNSIGNED_INT_16)
      header += [@format.sample_rate].pack(UNSIGNED_INT_32)
      header += [@format.byte_rate].pack(UNSIGNED_INT_32)
      header += [@format.block_align].pack(UNSIGNED_INT_16)
      header += [@format.bits_per_sample].pack(UNSIGNED_INT_16)
      if format_code == :float
        header += [0].pack(UNSIGNED_INT_16)
      end

      if extensible
        header += [22].pack(UNSIGNED_INT_16)
        header += [@format.bits_per_sample].pack(UNSIGNED_INT_16)
        header += [pack_speaker_mapping(@format.speaker_mapping)].pack(UNSIGNED_INT_32)

        if @format.sample_format == :pcm
          format_guid = WaveFile::SUB_FORMAT_GUID_PCM
        elsif @format.sample_format == :float
          format_guid = WaveFile::SUB_FORMAT_GUID_FLOAT
        end

        header += format_guid
      end

      # Write the FACT chunk, if necessary
      if requires_fact_chunk
        header += CHUNK_IDS[:fact]
        header += [4].pack(UNSIGNED_INT_32)
        header += [sample_frame_count].pack(UNSIGNED_INT_32)
      end

      # Write the header for the data chunk
      header += CHUNK_IDS[:data]
      header += [sample_data_byte_count].pack(UNSIGNED_INT_32)

      @io.write(header)
    end
def write_header(sample_frame_count)
      extensible = @format.channels > 2 ||
                   (@format.sample_format == :pcm && @format.bits_per_sample != 8 && @format.bits_per_sample != 16) ||
                   (@format.channels == 1 && @format.speaker_mapping != [:front_center]) ||
                   (@format.channels == 2 && @format.speaker_mapping != [:front_left, :front_right])
      format_code = extensible ? :extensible : @format.sample_format
      requires_fact_chunk = (format_code != :pcm)

      sample_data_byte_count = sample_frame_count * @format.block_align
      riff_chunk_size = CANONICAL_HEADER_BYTE_LENGTH[format_code] + sample_data_byte_count
      if sample_data_byte_count.odd?
        riff_chunk_size += 1
      end

      # Write the header for the RIFF chunk
      header = CHUNK_IDS[:riff]
      header += [riff_chunk_size].pack(UNSIGNED_INT_32)
      header += WAVEFILE_FORMAT_CODE

      # Write the format chunk
      header += CHUNK_IDS[:format]
      header += [FORMAT_CHUNK_BYTE_LENGTH[format_code]].pack(UNSIGNED_INT_32)
      header += [FORMAT_CODES[format_code]].pack(UNSIGNED_INT_16)
      header += [@format.channels].pack(UNSIGNED_INT_16)
      header += [@format.sample_rate].pack(UNSIGNED_INT_32)
      header += [@format.byte_rate].pack(UNSIGNED_INT_32)
      header += [@format.block_align].pack(UNSIGNED_INT_16)
      header += [@format.bits_per_sample].pack(UNSIGNED_INT_16)
      if format_code == :float
        header += [0].pack(UNSIGNED_INT_16)
      end

      if extensible
        header += [22].pack(UNSIGNED_INT_16)
        header += [@format.bits_per_sample].pack(UNSIGNED_INT_16)
        header += [pack_speaker_mapping(@format.speaker_mapping)].pack(UNSIGNED_INT_32)

        if @format.sample_format == :pcm
          format_guid = WaveFile::SUB_FORMAT_GUID_PCM
        elsif @format.sample_format == :float
          format_guid = WaveFile::SUB_FORMAT_GUID_FLOAT
        end

        header += format_guid
      end

      # Write the FACT chunk, if necessary
      if requires_fact_chunk
        header += CHUNK_IDS[:fact]
        header += [4].pack(UNSIGNED_INT_32)
        header += [sample_frame_count].pack(UNSIGNED_INT_32)
      end

      # Write the header for the data chunk
      header += CHUNK_IDS[:data]
      header += [sample_data_byte_count].pack(UNSIGNED_INT_32)

      @io.write(header)
    end
Internal
 Writes the RIFF chunk header, format chunk, and the header for the data chunk. After this
 method is called the file will be "queued up" and ready for writing actual sample data.