#ifndef WAVE_H #define WAVE_H /* * @(#)Wave.h * * This file is part of webCDwriter - Network CD Writing. * * Copyright (C) 2002-2003 Jörg P. M. Haeger * * webCDwriter is free software. See CDWserver.cpp for details. */ #include "File.h" #include "FileInputStream.h" typedef unsigned long uint32; typedef unsigned short uint16; /** * WAV file header * * see * http://ccrma-www.stanford.edu/CCRMA/Courses/422/projects/WaveFormat/ * * @version 20030221 * @author Jörg P. M. Haeger */ struct WaveHeader { char chunkID[4]; // "RIFF" uint32 chunkSize; // length of file char format[4]; // "WAVE" char subchunk1ID[4]; // "fmt " uint32 subchunk1Size; // always 16 bytes uint16 audioFormat; // always 1 = PCM-code uint16 numChannels; // 1 = mono, 2 = stereo uint32 sampleRate; uint32 byteRate; uint16 blockAlign; uint16 bitsPerSample; char subchunk2ID[4]; // "data" uint32 subchunk2Size; // length of data WaveHeader() { strncpy(chunkID, "RIFF", 4); strncpy(format, "WAVE", 4); strncpy(subchunk1ID, "fmt ", 4); subchunk1Size = 16; audioFormat = 1; numChannels = 2; sampleRate = 44100; byteRate = 44100 * 4; blockAlign = 4; bitsPerSample = 16; strncpy(subchunk2ID, "data", 4); setLength(0); } int getLength() { return subchunk2Size; } void setLength(int n) { subchunk2Size = n; chunkSize = subchunk2Size + 36; } }; /** * A class to handle WAV files. * * @version 20030220 * @author Jörg P. M. Haeger */ class Wave { private: int format; int channels; long frequency; long bytesPerSecond; int bytesPerSample; long dataLength; public: Wave(File &file) { FileInputStream inStream = new FileInputStream(file); char bs[44]; if (inStream.read(bs, 0, 44) < 44 || bs[0] != 'R' || bs[1] != 'I' || bs[2] != 'F' || bs[3] != 'F' || bs[8] != 'W' || bs[9] != 'A' || bs[10] != 'V' || bs[11] != 'E') throw new Exception("is not a WAV"); // inStream.close(); format = uint16(bs, 20); if (format != 1) throw new Exception("has an invalid format"); channels = uint16(bs, 22); frequency = uint32(bs, 24); bytesPerSecond = uint32(bs, 28); bytesPerSample = uint16(bs, 32); dataLength = uint32(bs, 40); } public: int getAudioChannels() { return channels; } public: int getAudioSampleBits() { return 8 * bytesPerSample / channels; } public: int getAudioSampleRate() { return frequency; } public: long getSeconds() { return dataLength / bytesPerSecond; } private: static int uint16(char *bs, int offset) { return ((bs[offset + 1] & 0xff) << 8) | (bs[offset] & 0xff); } private: static long uint32(char *bs, int offset) { return ((bs[offset + 3] & 0xff) << 24) | ((bs[offset + 2] & 0xff) << 16) | ((bs[offset + 1] & 0xff) << 8) | (bs[offset] & 0xff); } }; #endif