View Full Version : [C] File audio WAV: devo leggerne l'Header x saperne la lunghezza in tempo?!
Matrixbob
16-05-2007, 11:07
... ho dei file WAV da utilizzare, ma devo usare il C per capire quanti secondi/minuti/ore/ecc ... durano in modo da impiegarli nel modo migliore.
Qualcuno lo ha già fatto per caso?! :stordita: :fagiano:
Matrixbob
16-05-2007, 11:09
Utilizzare qualcosa tipo questo: :confused: :mbe: :confused: :eek: :confused:
/* *********************************************
controllo che il file sia un file WAV in "Canonical Wave Format"
leggo i primi 12 bytes in cui c'e' il primo header di tipo RIFF */
if(*plenfile<12) {
fprintf(stderr, "lunghezza file troppo piccola, non c'e' il primo
header\n");
fclose(f);
return(0);
}
ris=fread(buf,1,12,f);
if(ris<12) {
fprintf(stderr, "letti solo %d byte invece di 12\ntermino\n", ris);
fclose(f);
return(0);
}
/* nei primi 4 byte ci deve essere "RIFF" */
ris=strncmp(buf,"RIFF",4);
if(ris!=0) {
fprintf(stderr, "il primo campo del file non e' RIFF, non e' un file
WAV\ntermino\n");
fclose(f);
return(0);
}
/* nei byte dal 5 all 8 ci deve essere la lunghezza totale del file */
filelendentroilfile=littleendian32bit2littleendian(buf+4);
fprintf(stderr, "filelendentroilfile %ld\n", filelendentroilfile);
if(filelendentroilfile!=*plenfile) {
fprintf(stderr, "WARNING: filelendentroilfile=%ld != *plenfile=%ld
\n", filelendentroilfile, *plenfile );
fprintf(stderr, "ma continuo lo stesso\n" );
/*
fclose(f);
return(0);
*/
}
/* nei byte dal 9 al 12 ci deve essere "WAVE" */
ris=strncmp(buf+8,"WAVE",4);
if(ris!=0) {
fprintf(stderr, "il terzo campo del file non e' WAVE, non e' un file
WAV\ntermino\n");
fclose(f);
return(0);
}
io non ho mai gestito il formato WAV, ma per i file formats wotsit.org è la fonte: http://www.wotsit.org/list.asp?search=wav&button=GO%21
ciao :)
edit: questo link dovrebbe fare al caso tuo: http://www.wotsit.org/getfile.asp?file=wave&sc=232612309
Utilizzare qualcosa tipo questo: :confused: :mbe: :confused: :eek: :confused:
/* *********************************************
controllo che il file sia un file WAV in "Canonical Wave Format"
leggo i primi 12 bytes in cui c'e' il primo header di tipo RIFF */
if(*plenfile<12) {
fprintf(stderr, "lunghezza file troppo piccola, non c'e' il primo
header\n");
fclose(f);
return(0);
}
ris=fread(buf,1,12,f);
if(ris<12) {
fprintf(stderr, "letti solo %d byte invece di 12\ntermino\n", ris);
fclose(f);
return(0);
}
/* nei primi 4 byte ci deve essere "RIFF" */
ris=strncmp(buf,"RIFF",4);
if(ris!=0) {
fprintf(stderr, "il primo campo del file non e' RIFF, non e' un file
WAV\ntermino\n");
fclose(f);
return(0);
}
/* nei byte dal 5 all 8 ci deve essere la lunghezza totale del file */
filelendentroilfile=littleendian32bit2littleendian(buf+4);
fprintf(stderr, "filelendentroilfile %ld\n", filelendentroilfile);
if(filelendentroilfile!=*plenfile) {
fprintf(stderr, "WARNING: filelendentroilfile=%ld != *plenfile=%ld
\n", filelendentroilfile, *plenfile );
fprintf(stderr, "ma continuo lo stesso\n" );
/*
fclose(f);
return(0);
*/
}
/* nei byte dal 9 al 12 ci deve essere "WAVE" */
ris=strncmp(buf+8,"WAVE",4);
if(ris!=0) {
fprintf(stderr, "il terzo campo del file non e' WAVE, non e' un file
WAV\ntermino\n");
fclose(f);
return(0);
}
http://msdn2.microsoft.com/en-us/library/ms713497.aspx
ciao
Matrixbob
16-05-2007, 15:22
OK, grazie.
Adesso vedo se ci capisco qualcosa.
Ma voi non utilizzate mai:
http://www.google.com/codesearch?hl=it
?!
Matrixbob
16-05-2007, 21:28
O_O
Si, x cercare codice da riutilizzare o vedere gli altri come fanno le cose tanto per migliorarsi o 1000 altri usi.
Insomma: è inutile reinventare la ruota. NO?
OK, grazie.
Adesso vedo se ci capisco qualcosa.
Ma voi non utilizzate mai:
http://www.google.com/codesearch?hl=it
?!
cavolo non lo conoscevo, MITICO :cool:
io di solito scarico i sorgenti che possono interessarmi e uso cscope, ma così si fa più in fretta
Matrixbob
16-05-2007, 22:19
cavolo non lo conoscevo, MITICO :cool:
io di solito scarico i sorgenti che possono interessarmi e uso cscope, ma così si fa più in fretta
Si infatti, ma aiutiamo a vicenda.
Quindi sbizzarritevi ad aiutarmi plz:
... ho dei file WAV da utilizzare, ma devo usare il C per capire quanti secondi/minuti/ore/ecc ... durano in modo da impiegarli nel modo migliore.
Qualcuno lo ha già fatto per caso?! :stordita: :fagiano:
Matrixbob
21-05-2007, 08:54
http://www.google.com/codesearch?q=wav+reader&hl=it
Matrixbob
22-05-2007, 20:54
edit: questo link dovrebbe fare al caso tuo: http://www.wotsit.org/getfile.asp?file=wave&sc=232612309
Link inesistente.
Tra l'altro da tutti questi link sembra non uscire un campo di TOT bytes per indicare il tempo.
Come lo ricavo?!
Io pensavo che data la frequenza di campionamento costante si potesse tentare qualcosa del tipo:
frequenza di campionamento * numero di campioni?!
Con un MP3 la vita sarebbe + semplice?!
C'è 1 campo esplicito x la lunghezza del file audio?!
Matrixbob
22-05-2007, 21:05
O almeno trovare un programma che posso lanciare con la funzione "System(STRINGA DI COMANDO)" che mi possa restituire come risultato la lunghezza del file audio.
Link inesistente.
Tra l'altro da tutti questi link sembra non uscire un campo di TOT bytes per indicare il tempo.
Come lo ricavo?!
Io pensavo che data la frequenza di campionamento costante si potesse tentare qualcosa del tipo:
frequenza di campionamento * numero di campioni?!
Con un MP3 la vita sarebbe + semplice?!
C'è 1 campo esplicito x la lunghezza del file audio?!
certo che c'è:
//
TimeWav=Lunghezzafile/W.persec;
//controllo bit
if(W.wBitsPerSample==16)
TimeWav=TimeWav/2;
//numero canali
TimeWav=TimeWav/W.Canali;
forse se guardi il link sopra capiresti meglio...
Matrixbob
22-05-2007, 21:17
certo che c'è:
//
TimeWav=Lunghezzafile/W.persec;
//controllo bit
if(W.wBitsPerSample==16)
TimeWav=TimeWav/2;
//numero canali
TimeWav=TimeWav/W.Canali;
forse se guardi il link sopra capiresti meglio...
Ti giuro che ho guardato, magari sono io che non capisco, ma guardare ho guardato.
Mi son fatto anche 1 raccolta di quello che ho trovato:
LINK della raccolta (http://oasi.asti.it/Homes/Borrino/formato%20wave.zip).
Ma tu a quale link in particolare stai facendo riferimento?!:mbe: :stordita:
Link inesistente. ops, è vero: il link è divenuto invalido subito dopo che io ho chiuso il browser, si vede che era correlato alla ricerca che ho fatto. comunque non ho fatto nulla di chè: ho solo cercato "WAV" su wotsit.org.
Io pensavo che data la frequenza di campionamento costante si potesse tentare qualcosa del tipo:
frequenza di campionamento * numero di campioni?! veramente sarebbe una divisione, non una moltiplicazione. esempio: 2 campioni al secondo, totale 4 campioni, risultato 2 secondi; però 2*4 fa 8 :D
dovresti fare 4 / 2, cioè numero di campioni / frequenza (intesa come campioni al secondo).
Matrixbob
25-05-2007, 18:31
certo che c'è:
//
TimeWav=Lunghezzafile/W.persec;
//controllo bit
if(W.wBitsPerSample==16)
TimeWav=TimeWav/2;
//numero canali
TimeWav=TimeWav/W.Canali;
forse se guardi il link sopra capiresti meglio...
Non riesco proprio a capire a che documento stai facendo riferimento.
Io leggendo:
, mi sono fatto questa idea del file wave:
http://img403.imageshack.us/img403/8839/headerwavesl3.gif
Matrixbob
25-05-2007, 18:41
Per una migliore soluzione del problema ho incrociato le informazioni:
HELP: devo leggere la lunghezza di files audio WAV con un programmino in C. (http://www.hwupgrade.it/forum/showthread.php?t=1478002)
... per il ricavo della lunghezza del file audio (in secondi) attraverso algoritmo.
Questo nel qualcaso non riusci a identificare ed ad accedere al fantasmagorico "campo" TimeWav.
[EDIT]
Ok, capito, io ti dico come trovarla poi la applichi tu!
Allora ti spiego come si trova il peso poi con una formula inversa ricavi il tempo.
Prendiamo per esempio un file Wav campionato a 16bit,44.100Hz,stereo(sono 2 canali).
16(bit) x 44.100 (freq.) x 2(canali) x Y (secondi) = peso in bite.
chiaramente se hai un campione con freq. e bit canali diversi basta che li cambi,
es. 8(bit) x 48Khz (freq.) x 1(canale) x Y (secondi) = peso in bite
http://www.lcnet.it/priv/erioforo/mhlpmp3.html qui c'è una buona spiegazione ;)
Per una migliore soluzione del problema ho incrociato le informazioni:
HELP: devo leggere la lunghezza di files audio WAV con un programmino in C. (http://www.hwupgrade.it/forum/showthread.php?t=1478002)
... per il ricavo della lunghezza del file audio (in secondi) attraverso algoritmo.
Questo nel qualcaso non riusci a identificare ed ad accedere al fantasmagorico "campo" TimeWav.
l'include:
#include <mmsystem.h>
apertura file:
HMMIO hmmio;
MMCKINFO mmckinfoParent;
MMCKINFO mmckinfoSubchunk;
/* Apertura file*/
if ((hmmio = mmioOpen(&WaveName[0], 0, MMIO_READ|MMIO_ALLOCBUF)))
{
/* prendi la lunghezza */
WaveDataSize = mmckinfoSubchunk.cksize;
/* chiudi il file */
mmioClose(hmmio, 0);
}
printf WaveDataSize
ciao
tomminno
25-05-2007, 21:09
Un pò di riferimenti alla struttura degli Wav
http://www.sonicspot.com/guide/wavefiles.html
http://ccrma.stanford.edu/courses/422/projects/WaveFormat
Devi andare a trovare il Chunk chiamato 'data' e prendere i 4 byte successivi.
A me però risulta che il campo "datasize" sia in big endian (verificabile aprendo un file wave con un editor esadecimale)
Ecco quì:
#include "stdafx.h"
#include <windows.h>
#include <stdio.h>
#include <conio.h>
#include <mmsystem.h>
#include <malloc.h>
#include <tchar.h>
#include <stdlib.h>
TCHAR WaveName[] = "stereo.wav";
WAVEFORMATEX WaveFormat;
DWORD WaveDataSize;
int _tmain(int argc, _TCHAR* argv[])
{
HMMIO hmmio;
MMCKINFO mmckinfoParent;
MMCKINFO mmckinfoSubchunk;
//prima intestazione
if ((hmmio = mmioOpen(&WaveName[0], 0, MMIO_READ|MMIO_ALLOCBUF)))
{
mmckinfoParent.fccType = mmioFOURCC('W', 'A', 'V', 'E');
if (mmioDescend(hmmio, (LPMMCKINFO)&mmckinfoParent, 0, MMIO_FINDRIFF))
{
return(-2);
}
...code
WaveDataSize = mmckinfoSubchunk.cksize;
printf("Wave size = %u\n", WaveDataSize);
mmioClose(hmmio, 0);
system("pause");
return(0);
}
return(-1);
}
così me lo sono imparato anche io
Matrixbob
26-05-2007, 08:28
Ecco quì:
#include "stdafx.h"
#include <windows.h>
#include <stdio.h>
#include <conio.h>
#include <mmsystem.h>
#include <malloc.h>
#include <tchar.h>
#include <stdlib.h>
TCHAR WaveName[] = "stereo.wav";
WAVEFORMATEX WaveFormat;
DWORD WaveDataSize;
int _tmain(int argc, _TCHAR* argv[])
{
HMMIO hmmio;
MMCKINFO mmckinfoParent;
MMCKINFO mmckinfoSubchunk;
//prima intestazione
if ((hmmio = mmioOpen(&WaveName[0], 0, MMIO_READ|MMIO_ALLOCBUF)))
{
mmckinfoParent.fccType = mmioFOURCC('W', 'A', 'V', 'E');
if (mmioDescend(hmmio, (LPMMCKINFO)&mmckinfoParent, 0, MMIO_FINDRIFF))
{
return(-2);
}
...code
WaveDataSize = mmckinfoSubchunk.cksize;
printf("Wave size = %u\n", WaveDataSize);
mmioClose(hmmio, 0);
system("pause");
return(0);
}
return(-1);
}
così me lo sono imparato anche io
:ave: :nera:
Faccio 2 commisioni e poi vedo se riesco a capirlo.
Matrixbob
26-05-2007, 13:39
Per completezza e per gli utenti interessati futuri, ho trovato alcuni codici indicativi:
SDL_mixer-1.2.6/mikmod/mwav.c di:
http://gentoo.osuosl.org/distfiles/SDL_mixer-1.2.6.tar.gz
libmikmod-3.1.11/playercode/mwav.c di:
http://ftp.osuosl.org/pub/nslu2/sources/libmikmod-3.1.11.tar.gz
uqm-0.3/src/sc2code/libs/sound/decoders/mikmod/mwav.c di:
http://familiar.handhelds.org/source/v0.8.2/uqm-0.3-source.tgz
pysol-sound-server-3.01/src/mikmod/mwav.c di:
http://www.pysol.org/download/pysol/pysol-sound-server-3.01.tar.bz2
mpeg4ip-0.9/server/lib/sndfile/src/wav.c di:
http://internap.dl.sourceforge.net/sourceforge/mpeg4ip/mpeg4ip-0.9.tar.gz
xmovie-1.9.13/libsndfile-1.0.5/src/wav.c di:
http://prdownloads.sourceforge.net/heroines/xmovie-1.9.13-src.tar.bz2
vorbis-tools-1.0.1/oggenc/audio.c di:
http://ftp.osuosl.org/pub/nslu2/sources/vorbis-tools-1.0.1.tar.gz
gtkwave-2.0.0pre2/src/reader.c di:
ftp://ftp.cs.man.ac.uk/pub/amulet/gtkwave/2.0/gtkwave-2.0.0pre2.tar.gz
arnold/src/cpc/wav.c di:
http://www.portal-to-web.de/pub/pkgsrc/distfiles/arnsrc27012002.zip
linphone-0.12.2/ffmpeg/libav/wav.c di:
http://familiar.handhelds.org/source/v0.8.2/linphone-0.12.2.tar.gz
wavplay-1.4/wavfile.c di:
http://www.sunsite.unc.edu/pub/Linux/apps/sound/players/wavplay-1.4.tar.gz
libcdio-0.74/src/cd-paranoia/header.c di:
http://ftp.gnu.org/gnu/libcdio/libcdio-0.74.tar.gz
release/IoFull-2006-01-27/libs/libsndfile/libsndfile/src/wav.c di:
ftp://ftp.freebsd.org/pub/FreeBSD/ports/distfiles/IoFull-2006-01-27.tar.gz
Max-0.7.1-source/Frameworks/sndfile/libsndfile/src/wav.c di:
http://prdownloads.sourceforge.net/macaudiox/Max-0.7.1-source.tar.bz2
libao-0.8.4/src/ao_wav.c di:
http://downloads.xiph.org/releases/ao/libao-0.8.4.tar.gz
a52dec-0.7.4/libao/audio_out_wav.c di:
http://freshmeat.net/redir/liba52/17799/url_tgz/a52dec-0.7.4.tar.gz
audacity-src-1.3.2-beta/lib-src/libsndfile/src/wav.c di:
http://gentoo.osuosl.org/distfiles/audacity-src-1.3.2.tar.gz
libsndfile-1.0.12/src/wav.c di:
http://www.mega-nerd.com/libsndfile/libsndfile-1.0.12.tar.gz
smirc-0.70/libsndfile-0.0.12/src/wav.c di:
http://fresh.t-systems-sfr.com/linux/src/smirc-0.70.tar.gz
spPlugin-0.8.3/spPlugin/input_sndfile/libsndfile/src/wav.c di:
http://www.sp.m.is.nagoya-u.ac.jp/people/banno/archive/spPlugin-0.8.3-3.zip
by okay
#include "stdafx.h"
#include <windows.h>
#include <stdio.h>
#include <conio.h>
#include <mmsystem.h>
#include <malloc.h>
#include <tchar.h>
#include <stdlib.h>
TCHAR WaveName[] = "stereo.wav";
WAVEFORMATEX WaveFormat;
DWORD WaveDataSize;
int _tmain(int argc, _TCHAR* argv[])
{
HMMIO hmmio;
MMCKINFO mmckinfoParent;
MMCKINFO mmckinfoSubchunk;
if ((hmmio = mmioOpen(&WaveName[0], 0, MMIO_READ|MMIO_ALLOCBUF)))
{
mmckinfoParent.fccType = mmioFOURCC('W', 'A', 'V', 'E');
if (mmioDescend(hmmio, (LPMMCKINFO)&mmckinfoParent, 0, MMIO_FINDRIFF))
{
return(-2);
}
mmckinfoSubchunk.ckid = mmioFOURCC('f', 'm', 't', ' ');
if (mmioDescend(hmmio, &mmckinfoSubchunk, &mmckinfoParent, MMIO_FINDCHUNK))
{
return(-2);
}
if (mmioRead(hmmio, (HPSTR)&WaveFormat, mmckinfoSubchunk.cksize) != (LRESULT)mmckinfoSubchunk.cksize)
{
return(-2);
}
mmioAscend(hmmio, &mmckinfoSubchunk, 0);
mmckinfoSubchunk.ckid = mmioFOURCC('d', 'a', 't', 'a');
if (mmioDescend(hmmio, &mmckinfoSubchunk, &mmckinfoParent, MMIO_FINDCHUNK))
{
return(-2);
}
WaveDataSize = mmckinfoSubchunk.cksize;
printf("Wave size = %u\n", WaveDataSize);
mmioClose(hmmio, 0);
system("pause");
return(0);
}
return(-1);
}
buon studio
... di niente figurati
Matrixbob
26-05-2007, 17:21
buon studio
... di niente figurati
Mi ricordi vagamente quei sistemi bot di AI che rispondono alle chat tipo mirc. :)
Sintetico e pragmatico, quasi monosillabo (codice a parte).
CMQ quello che hai postato è tutto merito della tua conoscienza, ma mi sapresti anche indicare 1 documento dove posso accolturarmi anche io?!
Io del C ho il manuale Kernighan ed ho fatto solo programmi come parser, sistemi di prenotazione con semafori, mutex, qualche lista pila (ma ricordo poco), quindi certa cose che usi sicuramente non mi saranno chiare.
Al max se non ti è troppo disturbo ti chiederò chiarimenti ancora, ammesso che per te non sia una fatica ed un fastitio rispondermi. :stordita:
CMQ tu, Andbin, cionci e ChristinaAmeliana siete sicuramente quelli che mi aiutate D+ sul forum.
Una volta erano D+ ad aiutare, CMQ pochi ma buoni. :sofico:
Grazie. :fagiano:
tomminno
27-05-2007, 11:13
Per completezza e per gli utenti interessati futuri, ho trovato alcuni codici indicativi:
io includerei anche libsndfile, legge molti formati non compressi e anche i flac se linkata alla libreria.
www.mega-nerd.com/libsndfile/
Matrixbob
28-05-2007, 11:00
io includerei anche libsndfile, legge molti formati non compressi e anche i flac se linkata alla libreria.
Ragazzi fate conto: l'unico C che conosco è quello ANSI che ho "imparato" basandomi sul Kernighan.
http://www2.polito.it/didattica/polymath/ICT/Htmls/Informazioni/BiblioId/Img/kernighan_ritchie_c.jpg
Quindi del codice postato da OKAY non capisco tutto, io uso MinGW o al max CygWin x compilare in Windows, ma vorrei più compatibilità possibile con gli altri SO.
Non capisco ad esempio:
--
la funzione principale "_tmain", ma che è roba "moddata" di Micro$oft?
--
il tipo tchar (che mi pare praticamente in tipo char ANSI)
--
queste librerie stdafx.h, windows.h, mmsystem.h e tchar.h.
--
Capisco ad esempio:
--
il nome del tipo HMMIO indicherà approssimativamente qualcosa del tipo "header mm(multimediale?!) input-output"
--
MMCHKINFO sarà 1 sorta di struttura in cui potro controllaredelle informazioni del file multimendiale
--
tutto quello che fa riferimento a "mm" suppongo siano derivate dalla libreria "mmsystem.h"
--
Diciamo che non tutti siamo MdT e che un minimo di spiegazione del codice può dare una mano enorme.
D'altronde siamo nella sezione programmazione, non nella sezione "copia&incolla".
tomminno
28-05-2007, 14:09
Ragazzi fate conto: l'unico C che conosco è quello ANSI che ho "imparato" basandomi sul Kernighan.
Allora guardati la documentazione delle libsndfile che sono in C, multipiattaforma e con una interfaccia molto semplice.
Per aprire e leggere un file bastano poche righe:
SF_INFO sfInfo;
sfInfo.format = 0;
SNDFILE * sndFile = sf_open ("file.wav", SFM_READ, &sfInfo) ;
if (sndFile != NULL)
{
int readed = 0;
int readSize = 4096;
short * buffer = new short[readSize * sfInfo.channels];
while(readed < sfInfo.frames)
{
readed += sf_readf_short(sndFile,buffer,readSize);
...
}
delete [] buffer;
}
Ragazzi fate conto: l'unico C che conosco è quello ANSI che ho "imparato" basandomi sul Kernighan.
http://www2.polito.it/didattica/polymath/ICT/Htmls/Informazioni/BiblioId/Img/kernighan_ritchie_c.jpg
Quindi del codice postato da OKAY non capisco tutto, io uso MinGW o al max CygWin x compilare in Windows, ma vorrei più compatibilità possibile con gli altri SO.
Non capisco ad esempio:
--
la funzione principale "_tmain", ma che è roba "moddata" di Micro$oft?
--
il tipo tchar (che mi pare praticamente in tipo char ANSI)
--
queste librerie stdafx.h, windows.h, mmsystem.h e tchar.h.
--
Capisco ad esempio:
--
il nome del tipo HMMIO indicherà approssimativamente qualcosa del tipo "header mm(multimediale?!) input-output"
--
MMCHKINFO sarà 1 sorta di struttura in cui potro controllaredelle informazioni del file multimendiale
--
tutto quello che fa riferimento a "mm" suppongo siano derivate dalla libreria "mmsystem.h"
--
Diciamo che non tutti siamo MdT e che un minimo di spiegazione del codice può dare una mano enorme.
D'altronde siamo nella sezione programmazione, non nella sezione "copia&incolla".
quello postato è un normale progetto console win32 fatto con vs net 2005.
per le var puoi documentarti su msdn della m$.
Le API sotto windows non le inventa nessuno... sono state già inventate e implementate dagli ingegneri della m$.
Se vuoi sapere cosa fanno le API in windows ti devi documentare tu stesso a meno che non trovi un anima pia che lo faccia per te.
io non ci penso proprio a farlo. Ho 1000 altre cose da fare e non ne ho proprio voglia di farlo per te.
Edit: per farlo funzionare devi includere nelle opzioni di progetto del tool 2005 o 2003 in particolar modo in:
"Linker"-->"input" devi includere la winmm.lib per il sound.
Edit2: L'ho fatto per me stesso la prossima volta ti vai a vedere la documentazione dell'msdn, cosa che già avevo fatto nel post precedente. Se hai voglia di tutorial sull'argomento impara ad usare google non certo un forum.
se scrivi su google: "hmmio"
il secondo link ti porterebbe quì:
http://www.borg.com/~jglatt/tech/mmio.htm
le API/IO di windows.
Leggitelo e studiatelo!
stammi bene...
ciao
Matrixbob
28-05-2007, 17:58
Quotando il General RIFF File Background.
RIFF is a Windows file format for storing chunks of multi-media data, associated descriptions, formats, playlists, etc.
The Waveform Audio File Format (.WAV) description below provides a precise description of the data unique to .WAV files, but does not describe the RIFF file structure within which the .WAV data is stored.
http://img237.imageshack.us/img237/4409/headerqy4.gif
Quindi anche questo mi vincola a Windows?!
I file WAV che io vado ad aprire sono file creati con DSpeech, ma avrei potuto scegliere anche altri tool di TTS se AVISynth girasse anche su Linux.
Voi che dite, questo vincolo mi ostacolerà?!
Non c'è come JPEG/MPEG 1 standard di riferimento?!
tomminno
29-05-2007, 10:00
Quindi anche questo mi vincola a Windows?!
Ma leggi le risposte che ti vengono date oppure no?
Gli wave non sono altro che un formato di dati pubblico, chiunque implementi un parser per quella struttura può leggerli (e scriverli), non a caso sono letti da tutti e ci sono decine di librerie multipiattaforma che leggono gli wav.
Matrixbob
29-05-2007, 10:41
Ma leggi le risposte che ti vengono date oppure no?
Gli wave non sono altro che un formato di dati pubblico, chiunque implementi un parser per quella struttura può leggerli (e scriverli), non a caso sono letti da tutti e ci sono decine di librerie multipiattaforma che leggono gli wav.
Perchè da qualche parte mi hanno scritto che WAV è 1 formato pubblico, OS o FREE?! :stordita:
Io ho visto solo dei grandi link al sito Micro$oft, allora pensavo fosse 1 suo formato. :mbe:
Poi se in quel documento parla di "INCAPSULAMENTO IN RIFF DEL WAVE" tu cosa capiresti?! :boh:
CMQ non sto ancora agendo, sto solo raccogliendo le informazioni x sapere come meglio muovermi, vorrei eliminare qualunque ambiguità prima di muovermi e magari capire di essermi infilato in un vicolo T.
http://it.wikipedia.org/wiki/WAV
http://en.wikipedia.org/wiki/WAV
WAV (o WAVE), contrazione di WAVEform audio format (formato audio per la forma d'onda) è un formato audio sviluppato da Microsoft e IBM
Matrixbob
30-05-2007, 14:45
Dove trovo il file "stdafx.h" per compilare il III pezzo di codice scritto da Okay?!
Lo sto compilando con MinGW e per ora quando faccio:
gcc okay3.c -o okay3.exe
si lamente di non trovare "stdafx.h".
Per ora solo quel problema, speriamo bene.
#include "stdafx.h"
#include <windows.h>
#include <stdio.h>
#include <conio.h>
#include <mmsystem.h>
#include <malloc.h>
#include <tchar.h>
#include <stdlib.h>
TCHAR WaveName[] = "stereo.wav";
WAVEFORMATEX WaveFormat;
DWORD WaveDataSize;
int _tmain(int argc, _TCHAR* argv[])
{
HMMIO hmmio;
MMCKINFO mmckinfoParent;
MMCKINFO mmckinfoSubchunk;
if ((hmmio = mmioOpen(&WaveName[0], 0, MMIO_READ|MMIO_ALLOCBUF)))
{
mmckinfoParent.fccType = mmioFOURCC('W', 'A', 'V', 'E');
if (mmioDescend(hmmio, (LPMMCKINFO)&mmckinfoParent, 0, MMIO_FINDRIFF))
{
return(-2);
}
mmckinfoSubchunk.ckid = mmioFOURCC('f', 'm', 't', ' ');
if (mmioDescend(hmmio, &mmckinfoSubchunk, &mmckinfoParent, MMIO_FINDCHUNK))
{
return(-2);
}
if (mmioRead(hmmio, (HPSTR)&WaveFormat, mmckinfoSubchunk.cksize) != (LRESULT)mmckinfoSubchunk.cksize)
{
return(-2);
}
mmioAscend(hmmio, &mmckinfoSubchunk, 0);
mmckinfoSubchunk.ckid = mmioFOURCC('d', 'a', 't', 'a');
if (mmioDescend(hmmio, &mmckinfoSubchunk, &mmckinfoParent, MMIO_FINDCHUNK))
{
return(-2);
}
WaveDataSize = mmckinfoSubchunk.cksize;
printf("Wave size = %u\n", WaveDataSize);
mmioClose(hmmio, 0);
system("pause");
return(0);
}
return(-1);
}
Matrixbob
30-05-2007, 14:52
L'ho cercato qui:
http://www.google.com/codesearch?q=stdafx.h&hl=it&btnG=Ricerca+Codici
, ma con quello che ho preso alla compilazione da problemi:
http://img115.imageshack.us/img115/2351/errorjn1.gif
[EDIT]
Presuppongo di avere SICURAMENTE sbagliato file!!! :(
Matrixbob
30-05-2007, 18:22
PREMESSA
OK, stavolta ho studiato ed incrociato le informazioni che mi avete passato.
ANDIAMO AL PUNTO
Abbiamo assodato quello che segue, mi pare.
[1]
Quello che mi serve del file.wav, per determinarne la durata in tempo,
è contenuto nel chunk di format "fmt":
- Bit di campionamento, con byte range da 22 a 23.
- Frequenza di campionamento, con byte range da 12 a 15.
- Numero di canali, con byte range da 10 a 11.
, e nel chunk di dati "data":
- Lunghezza dei dati effettivi, con byte range da 4 a 7, in bytes.
[2]
Calcolo il tempo agoritmicamente con questa formula:
Secondi di file.wav = (Lunghezza dei dati effettivi * 8) / (Bit di campionamento * Frequenza dicampionamento * Numero di canali);
[3]
Procedo a estrapolare le informazioni di cui ho bisogno dai loro campi utilizzando due strade:
[a] Utilizzando le librerie Windows' MultiMedia (File) I/O (MMIO) REFER1 (http://www.borg.com/~jglatt/tech/mmio.htm) o REFER2 (http://msdn2.microsoft.com/en-us/library/ms712636.aspx)
Utilizzando le librerie Llibsndfile (http://www.mega-nerd.com/libsndfile/)
[B][4]
Finalmente ci sono?! :confused: :stordita:
DOMANDONE:
... posso usare lo stesso con MinGW o CygWin le HMMIO?!
Se si dove le prendo?! :)
PREMESSA
OK, stavolta ho studiato ed incrociato le informazioni che mi avete passato.
ANDIAMO AL PUNTO
Abbiamo assodato quello che segue, mi pare.
[1]
Quello che mi serve del file.wav, per determinarne la durata in tempo,
è contenuto nel chunk di format fmt:
- Bit di campionamento, con byte range da 22 a 23.
- Frequenza di campionamento, con byte range da 12 a 15.
- Numero di canali, con byte range da 10 a 11.
, e nel chunk di dati data:
- Lunghezza dei dati effettivi, con byte range da 4 a 7, in bytes.
[2]
Calcolo il tempo agoritmicamente con questa formula:
Secondi di file.wav = (Lunghezza dei dati effettivi * 8) / (Bit di campionamento * Frequenza dicampionamento * Numero di canali);
asd
//algoritmo
Secondi di file.wav = Lunghezzafile/Frequenza dicampionamento;//khz es: 44100
//controllo bit
if(BitsPerSample==16)//è 8 o 16 bit
Secondi di file.wav=Secondi di file.wav/2;
//numero canali 1 o 2 ovvero mono o stereo
Secondi di file.wav=Secondi di file.wav/Canali;
printf Secondi di file.wav
Matrixbob
31-05-2007, 10:37
Purtroppo non sono un programmatore smaliziato, ma sto cercando d'imparare e purtroppo mi vien da rompervi le scatole, portate pazienza. :(
Altrimenti non saprei proprio in che altro modo imparare. :cry:
Non riesco a trovarli i file delle librerie HMMIO
Se li avete me li mandi a:
matrixbob@tin.it
?!
Posso usarli anche con MinGW e CygWin o sono 1 esclusiva della suite Visual di MS?!
Grazie infinite,
mi dispiace rompervi.
:(
Purtroppo non sono un programmatore smaliziato, ma sto cercando d'imparare e purtroppo mi vien da rompervi le scatole, portate pazienza. :(
Altrimenti non saprei proprio in che altro modo imparare. :cry:
Non riesco a trovarli i file delle librerie HMMIO
Se li avete me li mandi a:
matrixbob@tin.it
?!
Posso usarli anche con MinGW e CygWin o sono 1 esclusiva della suite Visual di MS?!
Grazie infinite,
mi dispiace rompervi
:(
per MinGW ti può aiutare cionci (ciao fratellone!)
per CygWin non sò cosa è... e non mi va di saperlo!
Se vuoi essere un dilettante e studiare per proprio divertimento e raggiungere l'obbiettivo in + anni usa MinGW.
Se vuoi essere professionale e rendere da subito installa vsNET 2005 quello integrale.
Come diceva Little Tony: Se vuoi cantare rock&blues idossa il giubbino con le frange (Hit). Oppure canta in mutande e con una chitarra sgangherata solo per te e per passione.
Ovvero se vuoi essere produttivo usa vsNET 2005 integrale oppure impieghi un pò + di tempo usando MingGW o altri toolletti.
Con un pò di tempo riesci a cavartela anche con MingGW... ma io, purtroppo per te, non lo uso.
Edit:
#include "stdafx.h" lo puoi anche togliere usando vc 6.0 ma vale anche per vsNET 2005.
Ho preparato un progettino di default... mi dispiace che mi abbia incluso anche "stdafx.h"
Matrixbob
31-05-2007, 12:53
Ho esortato l'intervento del saggio cionci, sono in attesa della sua venuta. :)
CMQ facendo 1 ricerca ho trovato:
http://img112.imageshack.us/img112/2696/ric1ho4.gif
http://img112.imageshack.us/img112/5420/ric2yd3.gif
Posso provare sto PM a viluppare l'applicazione x trovare il time di 1 wave con quelle librerie?!
Matrixbob
31-05-2007, 12:57
per MinGW ti può aiutare cionci (ciao fratellone!)
per CygWin non sò cosa è... e non mi va di saperlo!
...
Edit:
#include "stdafx.h" lo puoi anche togliere usando vc 6.0 ma vale anche per vsNET 2005.
Ho preparato un progettino di default... mi dispiace che mi abbia incluso anche "stdafx.h"
MinGW è il compilatore GPL Unix GCC.
CygWin è 1 ambiente GPL Unix per Windows e quindi porta il GCC, ma anche altre "cose" di Unix.
Li uso xkè cerco di essere il + ortodosso possibile coi linguaggi, questo perchè vedo lo scempio che MS hanno apportato con le loro MOD. Tutto li.
DOMANDA:
Sto cavolo di "stdafx.h" posso anche non metterlo allora, non è basilare vero?
Il basilare sono quei 2 file sopra riportati nella ricerca giusto?!
---
Oggi mi chiuderò in biblioteca 4 orette e proverò a realizzare l'applicazione con le informazioni raccolte in questo 3D,
pregate per me. :sofico:
Matrixbob
31-05-2007, 13:11
Piccolo link complementare:
[c++] wav calcolare la dyrata del sound (http://www.hwupgrade.it/forum/showthread.php?t=1423368)
Ecco il sorgente per una applicazione "console" che ho appena scritto per visualizzare numero di campioni, frequenza di campionamento e durata di un file WAV in formato PCM.
Naturalmente il sorgente non ha la pretesa di essere perfetto al 100%. In ogni caso può essere un ottimo punto di partenza!
Compilato con VC++.net 2003 e testato sui diversi file WAV forniti con Windows (per verificare, ho aperto i file anche con il "registratore di suoni" di Windows che mostra la durata).
#define STRICT
#include <windows.h>
#include <stdio.h>
#define WAVINFO_SUCCESS 0 /* Successo */
#define WAVINFO_IOERROR 1 /* Errore di I/O */
#define WAVINFO_BADFMT 2 /* Formato file non adatto */
#define WAVEFMT_SIZE (sizeof (WAVEFORMATEX) - 2)
INT ReadWavInfo (LPSTR lpszFilename, LPDWORD lpdwSamples, LPDWORD lpdwFrequency)
{
HMMIO hmmio;
MMCKINFO mmckinfoWave;
MMCKINFO mmckinfoFmt;
MMCKINFO mmckinfoData;
WAVEFORMATEX wavefmt;
hmmio = mmioOpen (lpszFilename, NULL, MMIO_READ);
if (hmmio == NULL)
return WAVINFO_IOERROR;
mmckinfoWave.fccType = mmioFOURCC ('W', 'A', 'V', 'E');
if (mmioDescend (hmmio, &mmckinfoWave, NULL, MMIO_FINDRIFF) != MMSYSERR_NOERROR)
{
mmioClose (hmmio, 0);
return WAVINFO_IOERROR;
}
mmckinfoFmt.ckid = mmioFOURCC ('f', 'm', 't', ' ');
if (mmioDescend (hmmio, &mmckinfoFmt, &mmckinfoWave, MMIO_FINDCHUNK) != MMSYSERR_NOERROR)
{
mmioClose (hmmio, 0);
return WAVINFO_IOERROR;
}
if (mmckinfoFmt.cksize < WAVEFMT_SIZE)
{
mmioClose (hmmio, 0);
return WAVINFO_BADFMT;
}
if (mmioRead (hmmio, (HPSTR) &wavefmt, WAVEFMT_SIZE) != WAVEFMT_SIZE)
{
mmioClose (hmmio, 0);
return WAVINFO_IOERROR;
}
if (wavefmt.wFormatTag != WAVE_FORMAT_PCM)
{
mmioClose (hmmio, 0);
return WAVINFO_BADFMT;
}
if (mmioAscend (hmmio, &mmckinfoFmt, 0) != MMSYSERR_NOERROR)
{
mmioClose (hmmio, 0);
return WAVINFO_IOERROR;
}
mmckinfoData.ckid = mmioFOURCC ('d', 'a', 't', 'a');
if (mmioDescend (hmmio, &mmckinfoData, &mmckinfoWave, MMIO_FINDCHUNK) != MMSYSERR_NOERROR)
{
mmioClose (hmmio, 0);
return WAVINFO_IOERROR;
}
*lpdwSamples = mmckinfoData.cksize / (wavefmt.nChannels * (wavefmt.wBitsPerSample / 8));
*lpdwFrequency = wavefmt.nSamplesPerSec;
mmioClose (hmmio, 0);
return WAVINFO_SUCCESS;
}
int main (int argc, char *argv[])
{
INT iRet;
DWORD dwSamples, dwFrequency;
if (argc == 2)
{
iRet = ReadWavInfo (argv[1], &dwSamples, &dwFrequency);
switch (iRet)
{
case WAVINFO_SUCCESS:
printf ("Numero campioni = %lu\n", dwSamples);
printf ("Frequenza campionamento = %lu Hz\n", dwFrequency);
printf ("Durata = %.3f secondi\n", ((double) dwSamples) / dwFrequency);
break;
case WAVINFO_IOERROR:
printf ("Errore di I/O\n");
break;
case WAVINFO_BADFMT:
printf ("Formato del file non adatto\n");
break;
}
}
return 0;
}
EDIT: ho nuovamente apportato qualche miglioramento.
Matrixbob
31-05-2007, 15:09
Grazie vado a cercare d'elaborare una soluzione al mio problema.
Matrixbob
31-05-2007, 18:40
OK, problemi in compilazione.
Errore 1]
Che ho risolto in seguito:
http://img245.imageshack.us/img245/1438/errorandbinpc2.gif
, linkando nelle proprietà del compilatore di CodeBlocks, il file: "libwinmm.a".
L'ho fatto in CodeBlocks perchè col GCC non mi ricordo + come si linka. :)
Errore 2]
Che non sono ancora riuscito ad evitare:
http://img245.imageshack.us/img245/6671/errorwaveparser2en5.gif
CPU_FEATURES_INIT :mbe: :confused: :stordita:
, usando CodeBlocks sul codice sia di Andbin, sia di Okay, che del WevParser d'esempio HMMIO esce quel errore.
Magari quando capisco come linkare in GCC, provo a vedere se è 1 errore relativo a CodeBlocks
Matrixbob
02-06-2007, 15:20
ADESSO LE COMPILAZIONI VANNO A BUON FINE, MA...
... al momento di leggere 1 file creato con lo strumento di Text To Speech (TTS) "DSpeech" di Dimitrios, il programmino di Andbin, mi dice che è mal formato, e questo è strano perchè Dimio mi ha detto di aver usato le API di Windows x il suo lavoro. :boh:
http://img125.imageshack.us/img125/5580/andbinnonadattofl7.gif
Quello di Okay va a segno:
http://img117.imageshack.us/img117/9602/okaystranowj4.gif
Anche il codice dimostrativo di HMMIO:
http://img125.imageshack.us/img125/5152/waveparseokmp2.gif
Queste sono le impostazioni di DSpeech:
http://img125.imageshack.us/img125/4356/dseechnj2.gif
... al momento di leggere 1 file creato con lo strumento di Text To Speech (TTS) "DSpeech" di Dimitrios, il programmino di Andbin, mi dice che è mal formato, e questo è strano perchè Dimio mi ha detto di aver usato le API di Windows x il suo lavoro. :boh:Il problema non è il file .wav, ma il mio sorgente. Inizialmente avevo fatto un controllo troppo rigoroso sulla dimensione del chunk "fmt". Leggendo meglio della documentazione sul formato WAV che ho trovato in rete, ho riscontrato che il contenuto di questo chunk può anche essere più lungo dei 16 byte "tipici".
Ho corretto/migliorato e quindi ripostato il sorgente nel mio post #41. Come avevo ben detto, non avevo alcuna pretesa che fosse perfetto al 100%. ;)
Matrixbob
04-06-2007, 09:53
Andbin, come mai al inizio del tuo sorgente non trovo l'include delle include <mmsystem.h>?
#define STRICT
#include <windows.h>
#include <stdio.h>
Perchè la includo io col -lwinmm in compilazione?!
Fare l'include o l'opz -lwinmm è la stessa cosa?!
Invece questa
#define STRICT
a che serve?
Io le DEFINE sono abituato a vederle associare delle costanti a dei nomi. :boh:
Andbin, come mai al inizio del tuo sorgente non trovo l'include delle include <mmsystem.h>?Perché la documentazione su MSDN per le varie funzioni mmioXXX dice:
Header: Declared in Mmsystem.h; include Windows.h.
Cioè sono effettivamente dichiarate in Mmsystem.h ma è sufficiente includere Windows.h
#define STRICT
a che serve?
Io le DEFINE sono abituato a vederle associare delle costanti a dei nomi. :boh:La macro STRICT serve per fare in modo che negli header del PSDK certi tipi di dati (principalmente gli handle ma anche altri) vengano definiti in modo che siano distinti e non assegnabili tra di loro (senza un cast esplicito).
Comunque leggi <qui> (http://msdn2.microsoft.com/en-gb/library/aa383732.aspx) che spiega bene la cosa.
Matrixbob
04-06-2007, 10:33
Ok, TNX.
Altra cosa che ho notato è che usi dei tipi
INT e int, c'è differenza?
Altra cosa che ho notato è che usi dei tipi
INT e int, c'è differenza?Negli header del PSDK vengono definiti molti tipi di dati, come INT, DWORD, LPBYTE, ecc....
Poi se vai a vedere in WinDef.h, INT è un semplice typedef per int, BYTE è un typedef per unsigned char, ecc...
Quando si programma a livello Win32 in genere è preferibile usare i suoi tipi di dati.
Matrixbob
04-06-2007, 16:46
Negli header del PSDK vengono definiti molti tipi di dati, come INT, DWORD, LPBYTE, ecc....
Poi se vai a vedere in WinDef.h, INT è un semplice typedef per int, BYTE è un typedef per unsigned char, ecc...
Quando si programma a livello Win32 in genere è preferibile usare i suoi tipi di dati.
Ok ho imparato anche questo che mi suonava nuovo.
CMQ vedere 1 define prima degli include fa effetto.
Matrixbob
13-06-2007, 22:03
Per chi è rimasto sottoscritto a questo 3D segnalo il suo gemello:
[C] File audio MP3: devo leggerne l'Header x saperne la lunghezza in tempo?! (http://www.hwupgrade.it/forum/showthread.php?t=1492710)
vBulletin® v3.6.4, Copyright ©2000-2025, Jelsoft Enterprises Ltd.