
Новичок
Профиль
Группа: Участник
Сообщений: 30
Регистрация: 1.10.2007
Репутация: нет Всего: нет
|
Здравствуйте Эксперты!) Требуется из Моно Wav-файла сделать стерео. Как удвоить каждый Чанк, на сколько я понимаю с созданием нового делать невозможно? А без создания тоже не работает верно. На обычном массиве это так, работает: Код | for(int i=9; i>=0; i--) {a[2*i]=a[i];} for(int i=0;i<10; i++) a[2*i+1]=a[2*i]; for (int i=0; i<100; i++) cout<<a[i]<<endl;
|
Как сделать размер результирующего больше исходного чтоб поместить Отсчеты? Весь код в стадии: Код | #include <stdio.h> #include <stdlib.h> #include <iostream>
#include <windows.h> /* в этом файле определены типы BYTE, WORD, DWORD,... */ /* и тип WAVE_FORMAT_PCM */ /* коды завершения функции get_wav_header() */
using namespace std;
#define NO_ERRORS 0 #define ILLEGAL_HEADER 1 #define ILLEGAL_FORMAT 2 #define READ_ERROR 3 #define MAXHDRLEN 1000
// определение типа WAVE_HEADER // Это простейший заголовок, реально может быть более сложным, но мы учтем // это при чтении и проверке заголовка typedef struct { /* подзаголовок RIFF */ BYTE riff[4]; // тут должны бфть буквы RIFF DWORD riffsize; // размер файла - 8 /* подзаголовок FORMAT, описывает формат WAV файла */ char wavefmt[8]; // тут должны быть буквы "WAVEfmt " DWORD fmtsize; // размер подзаголовка FORMAT - может быть только 16 или 18 // для минимального заголовка WAV достаточно значения 16 WORD wFormatTag; // формат файла , нас интересует только WAVE_FORMAT_PCM ( == 1 ) WORD nChannels; // число каналов ( 1 или 2 ) DWORD nSamplesPerSec; // число отсчетов в секунду ( 8000, 11025, 22050 или 44100 ) DWORD nAvgBytesPerSec; // число байт в секунду. WORD nBlockAlign; // выравнивание блока данных SHORT wBitsPerSample; // число бит на отсчет ( 8 или 16 )
/* DATA chunk ( chunk == кусок ) */ BYTE data[4]; // тут должны быть буквы "data" DWORD datasize; // размер данных в байтах /* далее в файле идут данные, размер которых == datasize */ /* к сожалению, могут встречаться и другие чанки, не только data во многих файлах перед data чанком идет fact чанк, который содержит информацию о кодере и дате создания файла. Такие куски нам надо будет пропустить */ } WAVE_HEADER, *LPWAVE_HEADER;
// определение тип DATA_CHUNK typedef struct { BYTE data[4]; DWORD datasize;
} DATA_CHUNK;
WAVE_HEADER wav_hdr;
/* чтение заголовка WAV файла */ DWORD get_wav_header( FILE *file, WAVE_HEADER *whd ) { // читает WAVE_HEADER, контролирует его корректность и возвращает код ошибки, // или 0, если все в порядке char buf[4]; DWORD i; DWORD j; DWORD bytecnt = 0; // счетчик прочитанных из файла байт DATA_CHUNK dat_hdr; //
// читаем часть заголовка, без дополнительних байтов в формате и без DATA_CHUNK if( fread( (char *)whd, sizeof(WAVE_HEADER) - sizeof(DATA_CHUNK), 1, file )!= 1) return READ_ERROR; // выход по ошибке чтения
if( strncmp( whd->wavefmt, "WAVEfmt ", 8) != 0 ) return ILLEGAL_HEADER; // поле wavefmt не содержит символов "WAVEfmt "
if( whd->wFormatTag != WAVE_FORMAT_PCM ) return ILLEGAL_FORMAT; // формат файла - не WAVE_FORMAT_PCM, это может быть один из сжатых // файлов - MP3 , ADPCM , ...
if (whd->fmtsize > 16) // у прочитанной части заголовка более длинный формат, { // надо прочитать лишние байты, они нас не интересуют i = (SHORT)whd->fmtsize; while (i > 16) { j = min(sizeof( buf ), i - 16); if( fread( buf, j, 1, file )!= 1) return READ_ERROR; i -= j; } whd->fmtsize = 16L; // наш WAVEFORMAT будет иметь длину 16 байт } // ищем "data" чанк while( bytecnt <= MAXHDRLEN ) // искать до бесконечности мы не будем { /* прочитать заголовок очередного chunk'a */ if( fread( (char *)&dat_hdr, sizeof( DATA_CHUNK ), 1, file )!= 1) return READ_ERROR; // ошибка чтения i = dat_hdr.datasize; // размер
/* проверим, является ли прочитанных подзаголовок началом data-чанка*/ if( strncmp( (char*)&dat_hdr.data, "data", 4 ) == 0 ) { // нашли data chunk memcpy( (char*)&whd->data, "data", 4 ); // копируем символы "data" в наш header whd->datasize = dat_hdr.datasize; // копируем размер данных return NO_ERRORS; // нормальный выход, header прочитан } // это не "data" chunk, пропускаем bytecnt += i; // считаем байты до DATA_CHUNK while ( i > 0 ) { j = min(sizeof( buf ), i ); if( fread( buf, j, 1, file )!= 1) return READ_ERROR; i -= j; }
} return ILLEGAL_HEADER; // искали-искали, и не нашли }
/* Написать программу, уменьшающую амплитуду файла в 2 раза, если максимальная амплитуда > 30000, и в 1.5 раза в противном случае Предполагается, что файл содержит 16-битные отсчеты, файл - моно ( 1 канал ) */ void main( int argc, char *argv[] ) { FILE *fin, *fout; DWORD nsamples; short *nsamples2; DWORD datasize; WORD nChannels; short *samples; WORD maxval; DWORD i; DWORD j; double coeff; DWORD RetCode; int Channels = 2; // число каналов int Maxnsaples;
if( argc < 3 ) { printf("Run: wav_exm.exe <src_wav> <dst_wav>\n"); exit(1); }
/* открыть исходный файл */ if( (fin = fopen(argv[1],"rb"))==NULL ) { printf("File %s open error\n", argv[1] ); exit(1); }
/* открыть результирующий файл */ if( (fout=fopen(argv[2],"wb"))==NULL) { printf("File %s open error\n", argv[2] ); exit(1); }
// читаем заголовок входного файла и определяем количество данных RetCode = get_wav_header( fin, &wav_hdr ); /* анализируем код возврата */ switch( RetCode ) { case READ_ERROR: printf("Source file read error\n"); exit(1); case ILLEGAL_FORMAT: printf("Illegal header format\n"); exit(1); case ILLEGAL_HEADER: printf("Illegal hrader\n"); exit(1); } // приходим, если RetCode == NO_ERRORS datasize = wav_hdr.datasize; // размер данных в байтах nsamples = datasize /2; // число отсчетов ( для 16-битных отсчетов ) wav_hdr.nChannels=2; /* закажем память для данных */ samples = (short*)malloc( datasize ); nsamples2= (short*)malloc( datasize*2 ); if( samples == NULL ) { printf("Allocation error\n"); exit(1); } // читаем весь файл в память if( fread( samples, datasize, 1, fin ) != 1 ) { printf("read file error\n"); exit(1); } nChannels=2; // нормализация for(i=0;i<nsamples;i++) { nsamples2[2*i] = samples[i]; nsamples2[2*i+i] = samples[i]; }
// записать выходной файл samples = (short*)malloc( datasize ); nsamples = datasize /2; /* корректируем riffsize, т.к. он мог измениться, если в исходном файле был более сложный header */ wav_hdr.riffsize = wav_hdr.datasize + 36; /* сначала записываем заголовок */ fwrite( &wav_hdr, sizeof( wav_hdr), 1, fout ); fwrite( samples, (datasize), 1, fout );
/* закрываем файлы */ fclose( fin); fclose(fout); printf("Done.\n"); }
|
|