Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > C/C++: Общие вопросы > Структура в wav


Автор: NwinIX 20.8.2005, 00:51
У меня вопрос вот по такому делу.
Пишу программу по работе с wav-файлом(не суть важно) в общем есть в нем такая функция
DWORD get_wav_header(FILE *fp, WAVE_HEADER *wav_hdr), которая принимает указатель на сам файл и на его структуру(функция не моя, диктовали на лекциях). Сама функция делает проверку на корректность wav-файла(заголовка) и возращает код ошибки
Структура самого файла что то в роде typedef struct
{
DWORD riffsize;
BYTE riff[4];
BYTE wavefmt[8];
DWORD fmtsize;
WORD wFormatTag;
WORD nChannels;
DWORD nSamplesPerSec;
DWORD nAvgBytesPerSec;
WORD nBlockAligh;
WORD wBitsPerSample;
BYTE data[4];
DWORD datasize;
}WAVE_HEADER;
Так у меня не получается передать в эту функцию саму структуру из wav-файла, вот в этом и заключается проблема, будь то даже работа с bmp, не могу передать структуру в функцию для какой-либо проверки. I NEED HELP/

Автор: Step 20.8.2005, 00:55
NwinIX, для начало надобы писать код ошибочки...
или хотябы сказать, какого типа ошибка компиляци, сборки или выполнения

или ошибок нету, но не работает...


а во вторых в этом случаи нужно поставить выравнивание равное 1 байту...

Автор: NwinIX 20.8.2005, 01:06
Код

#include <windows.h>
#include <stdio.h>
#include <stdlib.h>
#include "wavhdr.h"
#include"Resourse_NIX.h"
typedef struct
{
    BYTE data[4];
    DWORD datasize;
}DATA_CHUNK;

#define NO_ERRORS 0;
#define ILLEGAL_HEADER 1;
#define ILLEGAL_FORMAT 2;
#define READ_ERROR 3;
#define MAXHDRLEN 1000 ;
 
DWORD get_wav_header(FILE *fp, WAVE_HEADER *wav_hdr)
{
    BYTE Buf[4];
    DWORD i,r,j;
    DWORD bytecnt=0;
    DATA_CHUNK data_hdr;
    if(fread(wav_hdr,sizeof(WAVE_HEADER)-sizeof(data_hdr),1,fp)!=1)
        return READ_ERROR;
    //if(strncmp(wav_hdr->riff,"RIFF",4))
    //    return ILLEGAL_HEADER;
//    if(strncmp(wav_hdr->wavefmt,"WAVE,fmt ",8))
    //    return ILLEGAL_HEADER;
    if(wav_hdr->wFormatTag!=WAVE_FORMAT_PCM)
        return ILLEGAL_FORMAT;
    if(wav_hdr->fmtsize>16)
    {
        if(fread(Buf,2,1,fp)!=1)
        {
            return READ_ERROR;
        }
        else
        {
        }
         
        wav_hdr->fmtsize=16;

    }
    else
    {
    }
    while (bytecnt < MAXHDRLEN)
    {
        if(fread(&data_hdr, sizeof(data_hdr),1,fp)!=1)
            return READ_ERROR;
        i=data_hdr.datasize;
        if(strncmp(data_hdr.data,"data",4)==0)
        {
            memcpy(wav_hdr->data, data_hdr.data,4);
            wav_hdr->datasize=data_hdr.datasize;
            return NO_ERRORS;
        }
        bytecnt+=i;
        for(j=0;j<i;j++)
        {
            fread(Buf,1,1,fp);
        }
    }
    return ILLEGAL_HEADER;
}

//#define MAXBUF 256
void ConsOut(char *tbuf)
{
    char buf[MAXBUF];
    CharToOem(tbuf,buf);
    printf("%s\n",buf);
}
 
void main(int argc, char *argv[])
{
FILE *fin, *fout;
DWORD nsamples;
DWORD datasize;
short *samples;
WORD maxval;
DWORD i;
double coeff;
DWORD RedCode;
char tbuf[20];
//WAVE_HEADER wav_hdr;
 
//char tbuf[MAXBUF];
 
if(argc<3)
{
    RusOut("?????? wav_exe  ");
    //ConsOut(tbuf);
}
if((fin=fopen(argv[1],"rb"))==NULL)
{
    RusOut("?????? ??? ???????? ????? ");
    exit(1);
}
if((fout=fopen(argv[2],"wb"))==NULL)
{
    RusOut("?????? ??? ???????? ????? ");
    exit(1);
}
 
[color=red] RedCode=get_wav_header(fin,&wav_hdr); [/color]/*тут пытаюсь передать указатель на структуру, короче как было в лекциях(примерно), короче не знаю что еще можно впихнуть вместо &wav_hdr
 пишет undeclared identifier */
switch(RedCode)
{
case  3: // READ_ERROR
        ConsOut("?????? ??????");
        exit(1);
     
case 1 ://ILLEGAL_HEADER
        ConsOut("????????? ??????");
        exit(1);
case  2 :  //ILLEGAL_FORMAT
        ConsOut("????????? ??????");
        exit(1);
}
 
        

datasize=wav_hdr->datasize;
nsamples=datasize/2;
samples=(short*)malloc(datasize);
if (samples=NULL)
{
    ConsOut("??? ?????? ??? ??????");
    exit(1);
}
if(fread(samples,datasize,1,fin)!=1)
{
    RusOut("?????? ??? ?????? ?????");
    exit(1);
}
WORD t;
maxval=abs(samples[0]);
for(i=0;i<nsamples;i++)
{
      t= abs(samples[i]);
    if(t>samples)
    {
         maxval=t;//???? ????? ?????? ???? ???????? ??? ??? maxval=t;
    }
}
if(maxval>3000)
{
    coeff=0,5;
}
else
{
    coeff=1,5;
}
 
for(i=0;i<nsamples;i++)
{
    samples[i]=(short)(samples[i]*coeff);
}
wav_hdr->riffsize=datasize+36;
fwrite(&wav_hdr,sizeof(wav_hdr),1,fout);
fwrite(samples,datasize,1,fout);
fclose(fin);
fclose(fout);
ConsOut("???????!");
}

М
 
вот так будет лучше, используйте code

Автор: Step 20.8.2005, 01:11
ошибка какая,

не получаеться передать - компилятор ругаеться, или уже ваша программа при выполнении???


Автор: NwinIX 20.8.2005, 01:15
Короче набрана программа(по лекции) В строке с функцией RedCode=get_wav_header(fin,&wav_hdr); /&wav_hdr----- undeclared identifier . Не знаю что делать. Может еще есть какие способы по проверке корректности wav-заголовка....

Автор: Step 20.8.2005, 01:23
ошибка в строке 107

wav_hdr и так указатель так что & не нужен

Автор: NwinIX 20.8.2005, 01:26
error C2065: 'wav_hdr' : undeclared identifier

Автор: Step 20.8.2005, 01:35
тю блин, а я думал у меня глюки, или слепну, а оно в натури нету, думал может в глобале лежит smile

ну да ладно

вы конда считаете синус пишите вот так
Код

float angle;
float var_sin;
angle=1.23;
var_sin=sin(angle)


так вот, вот такого
Код
float angle;


у вас нету, для вашего wav_hdr

более того, оно должно быть в таком виде
Код

WAVE_HEADER * wav_hdr=new  WAVE_HEADER;

где то так...


Автор: NwinIX 20.8.2005, 01:46
Вроде работает, хех а я и сам не заметил. Ну а если по смыслу так подумать, то мы передаем указатель на совершенно пустую структуру, которая у нас в хедаре висит, так как же тогда из совершенно пустой структуры мы сможем узнать формат или размер фактических данных? Или это у меня уже приступ паранои, или злостный лектор специально падлянку оставил smile Разве не должны эту структуру из самого файла извлекать?

Автор: Step 20.8.2005, 01:52
NwinIX, это параноя smile

а что по вашему вы делаете когда из файл читаете данные в некое место....

и как раз на это место указывает указатель.. а теперь если почитать, или вспомнить что такое переменные структуры и как они распологаються в памяти то многое станет понятно, и даже станет понятно зачем необходимо делать выравнивание по 1

Автор: NwinIX 20.8.2005, 12:52
smile Респект

Автор: NwinIX 20.8.2005, 14:02
На строку WAVE_HEADER * wav_hdr=new  WAVE_HEADER;
выдает аж 5 ошибок: error C2018: unknown character '0xa0'
Что это ваще значит smile

Автор: Step 20.8.2005, 15:02
NwinIX, а это прикол для лентяев, вы ее удалите и ручками введите smile

а не копируйте с форума

Автор: NwinIX 20.8.2005, 16:22
}{ех, вот хохма, пробел чертов smile И вправду smile

Автор: Step 20.8.2005, 22:08
ну и че, заработало

Автор: NwinIX 21.8.2005, 01:11
Почти, там еще кое-что доработать надо-это всего лишь костяк. А так да, теперь не ругается smile smile

Автор: Step 21.8.2005, 01:15
С тебя бутылка smile

Автор: NwinIX 21.8.2005, 02:42
Хех, вот еще вопросик тогда, связанный с эхо. Я в массив(указатель) samples писал данные из файла(кроме самого заголовка, его я формировал отдельно). В этом массиве я могу оперировать данными, повышая и понижая амплитуду-следовательно громкость. А как можно сделать, чтобы оперировать со временем? Ну например сдвинуть весь исходный сигнал на 1 или 0,1 секунды, и потом этот сдвинутый сигнал слить с исходным, чтобы как бы образовался сигнал со своим эхо(с небольшой задержкой) smile smile

Автор: Step 21.8.2005, 13:53
NwinIX, как сдвинуть берешь и делаешь копию сигнала в памяти со свдигом и потом накладЫваешь, правый лишний край удаляешь, или увеличиваешь длительность...

Автор: NwinIX 21.8.2005, 14:21
Со сдвигом разобрался но вот с наложением не очень. Ну вот есть у меня samples[]-оригинальный сигнал, samples_resize[]-все данные сдвинуты на 2 i-х позиции, размер такой же, следствие из этого, два последних значения не влезут..... Но вот как их слить не догоняю, это типа samples_resize[] вписать в samples[] или как, мож создать новый массив и в него все это записать, вот тока как smile

Автор: Step 21.8.2005, 14:27
последнии два удаляете

да вписать через какуюто операцию
попробуйте в тупую сплюсовать и откоректировать амплитуду что бы не фонило

Автор: NwinIX 21.8.2005, 14:53
В тупую не получается, не могу выравнять, да и не катит этот вариант, мне нужен конечный сигнал с точностью до бита как оригинал слитый с своим эхо, просто пишу программу по стеганографии, так боюсь что потом при декодировании данных не те значения будут извлекаться....А как можно еще слить? Можно на небольшом примере? smile smile

Автор: Step 21.8.2005, 15:59
что значит не получаеться, что значит с точностью до бита, такое понятие применять как то глупо в єтом случае, нужно с точностью до отсчета или чето в этом роде



что значит выровнять, что к чему ты выравниваешь

Автор: NwinIX 25.8.2005, 17:26
Деху ступил.....

Код


for(i=0,j=2;j<nsamples;i++,j++)
{
    samples_edit_2[j]=samples[i]; //здвиг на 2 отсчета
}

for(i=0,j=3;j<nsamples;i++,j++)
{
    samples_edit_3[j]=samples[i]; //Здвиг на 3 отсчета
}



Где nsamples-колличество отсчетов в массиве samples. Создал еще два мас для записи этого же сигнала но с небольшой задержкой, а как теперь слить не знаю. NEED HELP(т.е. как слить samples_edit_3+samples или samples_edit_2+samples, чтоб сохранился и оригинал и его эхо?,то есть один равный сумме исходного и задержанного по времени.
Если можно то примерчих хотя быб малюханький. smile smile

Автор: DrLazy 25.8.2005, 21:42
Если у тебя амплитуды знаковые, то
Код

for(i=0;i<nsamples;i++)
{
samples[i] += samples_edit_2[i] +samples_edit_3[i];
}


эхо правда обрежется по длине первого звука. Если надо по другому надеюсь сообразишь
Если будет перегрузка ( short int overflow ) то подели на 3 перед записью в массив.

Автор: NwinIX 25.8.2005, 23:47
Я Впринципе так пробовал, тока складывал вот так
Код


samples = (short*)malloc( datasize );
samplesRes= (short*)malloc( datasize );
 /*
тут куски кода не важно какие(извлечение заголовка и формирование нового)
*/
for(i=0,j=8;j<nsamples;i++,j++)      
    {    
      samplesRes[j]=samples[i];  //делаем задержку в 0,001 секунды
    }
//Эхо файл само собой получается обрезаный как раз на 8 отсчетов(0,001 секунду)
while(i<nsamples)
    {
        samples[i]=samples[i]+samplesRes[i];
    }
wav_hdr.riffsize = wav_hdr.datasize + 36;
    /*  пишем заголовок */
    fwrite( &wav_hdr, sizeof( wav_hdr), 1, fout );
    /* пишем сам файл */
    fwrite( samples, datasize, 1, fout );  



вот тока ничего хорошего не получилось, файл создает выходной а данными не заполняет
Если записывать просто nsamples без всяких преобразований то все работает а так не пашет.
А может стоит увеличить колличество памяти в выходной файл как минимум в двое, вот тока как вычесть эти восемь отсчетов на которые я сдвинул?

Автор: Guest 26.8.2005, 22:08
Всем спасибо за советы, сам все сделал, во всем разобрался smile smile

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)