Главная » Программирование звука » Чтение файлов AU

0

Все  классы  чтения  аудиофайлов,  которые  мы  построим,  имеют  схожую  основу.  Как  было  показано  на  рис.  10.1,  когда  у  класса  файла  запрашиваются  отсчеты, он направляет заброс к объекту декодера.

Листинг 15.4. Члены класса AuRead

private:

istream &_stream;

AbstractDecompressor *_decoder;

public:

AuRead(istream &input = cin):AudioAbstract(),_stream(input) {

// Формат   файла: Sun AU

// (также  известен как NeXT SND).

cerr << "File Format: Sun AU (also known as NeXT SND)\n";

_headerRead = false;   // Заголовок еще  не   читали.

_decoder = 0;

}

~AuRead() {

if (_decoder) delete _decoder;

}

size_t GetSamples(AudioSample *buffer, size_t numSamples) {

return _decoder->GetSamples(buffer,numSamples);

}

Объект  декодера  будет,  в  свою  очередь,  вызывать  метод  ReadBytes  для  получения  необработанных  байтов  из  файла.  Для  файлов  AU  метод  ReadBytes  прост: он запрашивает из потока данные и ведет их подсчет, гарантируя тем самым, что после окончания данных считывание не производится.

Листинг 15.4. Члены класса AuRead (продолжение)

private:

size_t _dataLength;

public:

size_t ReadBytes(AudioByte *buffer, size_t length);

Листинг 15.5. Реализация класса AuRead

size_t AuRead::ReadBytes(AudioByte *buffer, size_t length) {

if (length > _dataLength) { length = _dataLength; }

_stream.read(reinterpret_cast<char *>(buffer),length);

size_t lengthRead = _stream.gcount();

_dataLength = lengthRead;

return lengthRead;

}

Единственное,  что  остается,   прочитать  заголовок  файла  и  провести  согласо-

вание в соответствии с параметрами файла.

Листинг 15.4. Члены класса AuRead (продолжение)

private:

bool _headerRead;     // Истина, если заголовок  уже   прочтен.

int _headerChannels; // Каналы из  заголовка.

int _headerRate;      // Частота дискретизации из  заголовка.

void ReadHeader(void);

Проводя   согласование   формата   данных   между   объектами,   я   устанавливаю параметры в соответствии с характеристиками читаемого файла.

Листинг 15.4. Члены класса AuRead (продолжение)

protected:

void MinMaxSamplingRate(long *min, long *max, long *preferred)

{

ReadHeader();

*min = *max = *preferred = _headerRate;

}

void MinMaxChannels(int *min, int *max, int *preferred) { ReadHeader();

*min = *max = *preferred = _headerChannels;

}

};

Помимо   чтения   соответствующих   данных   из   заголовка   важно   пропустить любые  данные,  которые  следуют  за  стандартной  информацией.  Формат  AU  использовался  как  основа  для  ряда  других  форматов,  просто  добавляющих  специфичные  для  них  данные  в  конец  стандартного  заголовка  AU.  Исходить  из  предположения, что заголовок составит ровно 28 байт, небезопасно.

Листинг 15.5. Реализация класса AuRead (продолжение)

void AuRead::ReadHeader(void) {

if (_headerRead) return;

_headerRead = true;

char header[24];

_stream.read(header,24);

long magic = BytesToIntMsb(header+0,4);

if (magic != 0x2E736E64) {     // ".snd".

// Формат   исходного  файла

// отличается от AU.

cerr << "Input file is not an AU file.\n";

exit(1);

}

long headerLength = BytesToIntMsb(header+4,4);

_dataLength = BytesToIntMsb(header+8,4);

int format = BytesToIntMsb(header+12,4);

_headerRate = BytesToIntMsb(header+16,4);

_headerChannels = BytesToIntMsb(header+20,4); SkipBytes(_stream,headerLength 24);     // Отбрасываем

// оставшуюся

// часть заголовка.

// Создаем  подходящий объект-декомпрессор.

switch(format) {

case 1:      // ITU G.711 мю-функция.

_decoder = new DecompressG711MuLaw(*this);

break;

case 2:      // 8-битный  линейный.

_decoder = new DecompressPcm8Unsigned(*this);

break;

case 3:      // 16-битный  линейный.

_decoder = new DecompressPcm16MsbSigned(*this);

break;

default:

// AU формат  …. не   поддерживается.

cerr << "AU format " << format << " not supported.\n";

exit(1);

}

// Частота дискретизации:

cerr << "Sampling Rate: " << _headerRate;

// Каналы:

cerr << " Channels: " << _headerChannels;

cerr << "\n";

Источник: Кинтцель Т.  Руководство программиста по работе со звуком = A Programmer’s Guide to Sound: Пер. с англ. М.: ДМК Пресс, 2000. 432 с, ил. (Серия «Для программистов»).

По теме:

  • Комментарии