This project has moved. For the latest updates, please go here.

Aiff and Wav writer anomalies in 8 bit wav format data

Aug 23, 2014 at 3:08 PM
I tried to use the AiffWriter method for the first time and found something odd. Maybe someone can see what it might be.

I read in an 8 bit mono 22050Hz wav file. And wrote it back out using both an AiffFileWriter, and the WavFileWriter. The results of the AiffFileWriter showed that the sign of the waveform data got all goofed up. See linked pic.
TEXT

Image

Is this an inherent issue with the Aiff conversion, that it might not know what to make of 8 bit files in their conversion to Big Endian or something? That's what it looks like to me.

Thanks.
Aug 23, 2014 at 4:44 PM
I hacked at the source a bit and ended up with the following solution for 8bit AIFF writes:

NAudio's AIFF writer did not seem to handle 8bit files (as you see above). So I loaded the source code of AiffFileWriter, and re-wrote the Write() method to remove the part where it plays around with 'swapped data' which I think gummed it up. If you look at that waveform above, the only thing wrong is that it's offset -127 bits compared with the byte[] it was being sent. I removed the swapped data re-alignment code, and added that offset back, and viola. Sine waves again.

I did not check how WaveFileWriter deals with that offset, it probably adds it back as well.

Edited from AiffFileWriter.cs
  public override void Write(byte[] data, int offset, int count)
        {
            byte[] swappedData = new byte[data.Length];

            for (int i = 0; i < data.Length; i++)
            {
                swappedData[i] = (byte)(data[i]+128); // just adding back the offset. 
            }
            outStream.Write(swappedData, offset, count);
            dataChunkSize += count;
        }
Aug 25, 2014 at 6:18 PM
Edited Aug 25, 2014 at 6:40 PM
I think this is more of a general issue with the Aiff functions overall.

I tried to use AiffFileReader to read an 8-bit .aif file, and got a byte[] array full of garbage. It has essentially the same issue as the AiffFileWriter had. It doesn't deal with the signed 8-bit value very well.

To fix it, on line 244 of AiffFileReader.cs, I converted the value back to a signed 8bit. Now it works. See what you think.
                    if (WaveFormat.BitsPerSample == 8)
                    {
                        array[i] = (byte)(buffer[i]+128);
                    }
Aug 26, 2014 at 10:01 AM
Hi!

Please forgive me for answering without any real indepth knowledge, but I got curious and had nothing better to do (-:

Hm, checking AIFF and WAV specification on the net on the fly, they state that (8bit) samples are stored as unsigned byte values

From: http://amigan.1emu.net/reg/AIFF.txt (via http://wayback.archive.org/)
AIFF: Audio Interchange File Format File

[...]
Sound Data Chunk
The Sound Data Chunk contains the actual sample frames.
#define SoundDataID 'SSND' / ckID for Sound Data Chunk /
typedef struct {
ID ckID;
long ckSize;

unsigned long offset;
unsigned long blockSize;
unsigned char SoundData []; <-----------------
} SoundDataChunk;
From http://www-mmsp.ece.mcgill.ca/Documents/AudioFormats/WAVE/Docs/riffmci.pdf
Multimedia Programming Interface and Data Specifications 1.0 (~ Page 58)

WAVE FORMAT CATEGORIES

PCM( FORMAT
Data Format of the Samples
Sample  Size                  Data Format                   Maximum Value                             Minimum Value
One to eight bits           Unsigned integer                  255 (0xFF)                                       0
Nine or more bits          Signed integer i            Largest positive value of i             Most negative value of i
(consider this reply as obsolete if they changed the format definitions in the meantime)

Hope that helps,

Harry