rf64_write_header (SF_PRIVATE *psf, int calc_length)
{	sf_count_t	current, pad_size ;
	int 		error = 0, has_data = SF_FALSE, add_fact_chunk = 0 ;
	WAVLIKE_PRIVATE	*wpriv ;

	if ((wpriv = psf->container_data) == NULL)
		return SFE_INTERNAL ;

	current = psf_ftell (psf) ;

	if (psf->dataoffset > 0 && current > psf->dataoffset)
		has_data = SF_TRUE ;

	if (calc_length)
	{	psf->filelength = psf_get_filelen (psf) ;
		psf->datalength = psf->filelength - psf->dataoffset ;

		if (psf->dataend)
			psf->datalength -= psf->filelength - psf->dataend ;

		if (psf->bytewidth > 0)
			psf->sf.frames = psf->datalength / (psf->bytewidth * psf->sf.channels) ;
		} ;

	/* Reset the current header length to zero. */
	psf->header.ptr [0] = 0 ;
	psf->header.indx = 0 ;
	psf_fseek (psf, 0, SEEK_SET) ;

	if (wpriv->rf64_downgrade && psf->filelength < RIFF_DOWNGRADE_BYTES)
	{	psf_binheader_writef (psf, "etm8m", BHWm (RIFF_MARKER), BHW8 ((psf->filelength < 8) ? 8 : psf->filelength - 8), BHWm (WAVE_MARKER)) ;
		psf_binheader_writef (psf, "m4z", BHWm (JUNK_MARKER), BHW4 (24), BHWz (24)) ;
		add_fact_chunk = 1 ;
		}
	else
	{	psf_binheader_writef (psf, "em4m", BHWm (RF64_MARKER), BHW4 (0xffffffff), BHWm (WAVE_MARKER)) ;
		/* Currently no table. */
		psf_binheader_writef (psf, "m48884", BHWm (ds64_MARKER), BHW4 (28), BHW8 (psf->filelength - 8), BHW8 (psf->datalength), BHW8 (psf->sf.frames), BHW4 (0)) ;
		} ;

	/* WAVE and 'fmt ' markers. */
	psf_binheader_writef (psf, "m", BHWm (fmt_MARKER)) ;

	/* Write the 'fmt ' chunk. */
	switch (psf->sf.format & SF_FORMAT_TYPEMASK)
	{	case SF_FORMAT_WAV :
				psf_log_printf (psf, "ooops SF_FORMAT_WAV\n") ;
				return SFE_UNIMPLEMENTED ;
				break ;

		case SF_FORMAT_WAVEX :
		case SF_FORMAT_RF64 :
				if ((error = rf64_write_fmt_chunk (psf)) != 0)
					return error ;
				if (add_fact_chunk)
					psf_binheader_writef (psf, "tm48", BHWm (fact_MARKER), BHW4 (4), BHW8 (psf->sf.frames)) ;
				break ;

		default :
				return SFE_UNIMPLEMENTED ;
		} ;

	if (psf->broadcast_16k != NULL)
		wavlike_write_bext_chunk (psf) ;

	if (psf->cart_16k != NULL)
		wavlike_write_cart_chunk (psf) ;

	/* The LIST/INFO chunk. */
	if (psf->strings.flags & SF_STR_LOCATE_START)
		wavlike_write_strings (psf, SF_STR_LOCATE_START) ;

	if (psf->peak_info != NULL && psf->peak_info->peak_loc == SF_PEAK_START)
		wavlike_write_peak_chunk (psf) ;

	/* Write custom headers. */
	if (psf->wchunks.used > 0)
		wavlike_write_custom_chunks (psf) ;

#if 0
	if (psf->instrument != NULL)
	{	int		tmp ;
		double	dtune = (double) (0x40000000) / 25.0 ;

		psf_binheader_writef (psf, "m4", BHWm (smpl_MARKER), BHW4 (9 * 4 + psf->instrument->loop_count * 6 * 4)) ;
		psf_binheader_writef (psf, "44", BHW4 (0), BHW4 (0)) ; /* Manufacturer zero is everyone */
		tmp = (int) (1.0e9 / psf->sf.samplerate) ; /* Sample period in nano seconds */
		psf_binheader_writef (psf, "44", BHW4 (tmp), BHW4 (psf->instrument->basenote)) ;
		tmp = (unsigned int) (psf->instrument->detune * dtune + 0.5) ;
		psf_binheader_writef (psf, "4", BHW4 (tmp)) ;
		psf_binheader_writef (psf, "44", BHW4 (0), BHW4 (0)) ; /* SMTPE format */
		psf_binheader_writef (psf, "44", BHW4 (psf->instrument->loop_count), BHW4 (0)) ;

		for (tmp = 0 ; tmp < psf->instrument->loop_count ; tmp++)
		{	int type ;

			type = psf->instrument->loops [tmp].mode ;
			type = (type == SF_LOOP_FORWARD ? 0 : type == SF_LOOP_BACKWARD ? 2 : type == SF_LOOP_ALTERNATING ? 1 : 32) ;

			psf_binheader_writef (psf, "44", BHW4 (tmp), BHW4 (type)) ;
			psf_binheader_writef (psf, "44", BHW4 (psf->instrument->loops [tmp].start), BHW4 (psf->instrument->loops [tmp].end)) ;
			psf_binheader_writef (psf, "44", BHW4 (0), BHW4 (psf->instrument->loops [tmp].count)) ;
			} ;
		} ;

#endif

	/* Padding may be needed if string data sizes change. */
	pad_size = psf->dataoffset - 16 - psf->header.indx ;
	if (pad_size >= 0)
		psf_binheader_writef (psf, "m4z", BHWm (PAD_MARKER), BHW4 ((unsigned int) pad_size), BHWz (pad_size)) ;

	if (wpriv->rf64_downgrade && (psf->filelength < RIFF_DOWNGRADE_BYTES))
		psf_binheader_writef (psf, "tm8", BHWm (data_MARKER), BHW8 (psf->datalength)) ;
	else
		psf_binheader_writef (psf, "m4", BHWm (data_MARKER), BHW4 (0xffffffff)) ;

	psf_fwrite (psf->header.ptr, psf->header.indx, 1, psf) ;
	if (psf->error)
		return psf->error ;

	if (has_data && psf->dataoffset != psf->header.indx)
	{	psf_log_printf (psf, "Oooops : has_data && psf->dataoffset != psf->header.indx\n") ;
		return psf->error = SFE_INTERNAL ;
		} ;

	psf->dataoffset = psf->header.indx ;

	if (NOT (has_data))
		psf_fseek (psf, psf->dataoffset, SEEK_SET) ;
	else if (current > 0)
		psf_fseek (psf, current, SEEK_SET) ;

	return psf->error ;
} /* rf64_write_header */