Torna indietro   Hardware Upgrade Forum > Software > Programmazione

iPhone 17 Pro: più di uno smartphone. È uno studio di produzione in formato tascabile
iPhone 17 Pro: più di uno smartphone. È uno studio di produzione in formato tascabile
C'è tanta sostanza nel nuovo smartphone della Mela dedicato ai creator digitali. Nuovo telaio in alluminio, sistema di raffreddamento vapor chamber e tre fotocamere da 48 megapixel: non è un semplice smartphone, ma uno studio di produzione digitale on-the-go
Intel Panther Lake: i processori per i notebook del 2026
Intel Panther Lake: i processori per i notebook del 2026
Panther Lake è il nome in codice della prossima generazione di processori Intel Core Ultra, che vedremo al debutto da inizio 2026 nei notebook e nei sistemi desktop più compatti. Nuovi core, nuove GPU e soprattutto una struttura a tile che vede per la prima volta l'utilizzo della tecnologia produttiva Intel 18A: tanta potenza in più, ma senza perdere in efficienza
Intel Xeon 6+: è tempo di Clearwater Forest
Intel Xeon 6+: è tempo di Clearwater Forest
Intel ha annunciato la prossima generazione di processori Xeon dotati di E-Core, quelli per la massima efficienza energetica e densità di elaborazione. Grazie al processo produttivo Intel 18A, i core passano a un massimo di 288 per ogni socket, con aumento della potenza di calcolo e dell'efficienza complessiva.
Tutti gli articoli Tutte le news

Vai al Forum
Rispondi
 
Strumenti
Old 08-12-2005, 15:54   #1
mfonz85
Member
 
L'Avatar di mfonz85
 
Iscritto dal: Sep 2005
Città: Bus PCI 1, periferica 0, funzione 0 (Torino)
Messaggi: 213
[C] leggere un file wave bit a bit

Ciao a tutti, ho un problema che mi assilla da qualche giorno, e non riesco a trovare la soluzione...
Vorrei leggere un file .wav bit a bit, proprio fisicamente come è scritto sull'hdd, ma ho problemi quando si tratta di andare a leggere il file, il massimo che riesco a fare è un fread() ma praticamente mi vengono letti dei numeri interi positivi (che credo sia codice ascii ma non sono sicuro)...
Ho provato anche ad aprire il file in modalità binaria con fopen(file,"rb") ma niente da fare, non cambia nulla...
C'è qualcuno che potrebbe dirmi come implementare una cosa del genere con C ?? (Io utilizzo Dev-Cpp per lo sviluppo)
Grazie 1000 anticipatamente
__________________
Ho concluso affari con: Ippo 2001, Klintf, albert78, Piripikkio, starsky, oldfield e IL0V€INT€R. da EVITARE zarovat
mfonz85 è offline   Rispondi citando il messaggio o parte di esso
Old 08-12-2005, 21:00   #2
andbin
Senior Member
 
L'Avatar di andbin
 
Iscritto dal: Nov 2005
Città: TO
Messaggi: 5206
Quote:
Originariamente inviato da mfonz85
Vorrei leggere un file .wav bit a bit, proprio fisicamente come è scritto sull'hdd, ma ho problemi quando si tratta di andare a leggere il file, il massimo che riesco a fare è un fread() ma praticamente mi vengono letti dei numeri interi positivi (che credo sia codice ascii ma non sono sicuro)...
Ciao, allora ... per cominciare bisognerebbe innanzitutto sapere che cosa ci vuoi fare con un file wave. Se vuoi solo fare un "dump" dei dati binari nel file, se vuoi estrarre i campioni audio per riprodurli con una scheda audio, ecc...

Sappi che non è comunque banalissimo leggere un file wave (ma neanche complicatissimo!). I file wave hanno un formato e una struttura ben precisa. I dati e le informazioni contenute in un file wave sono suddivise in quelli che vengono chiamati chunk. Un tipico file wave ha in genere come minimo 3 chunks: un chunk iniziale di tipo "RIFF" che è la testata del file, un altro chunk di tipo "fmt" che contiene le informazioni generali sui campioni audio e un terzo chunk di tipo "data" che contiene i campioni audio veri e propri.

Le specifiche del formato wave le trovi facilmente su internet. Ecco alcuni link:

1) Wotsit (cerca poi lì dentro il formato wave)
2) Wave Files - The Sonic Spot
3) WAVE PCM soundfile format

A questo punto capisci che bisognerebbe sapere cosa vuoi fare di preciso.
Ci sono sostanzialmente almeno 2 possibilità per estrarre i dati da un file wave. La prima è quella di imparare le specifiche e la struttura dei file wave ed usare le funzioni di base dell'I/O (fopen, fread, ecc...) per leggere e decodificare i dati contenuti nel file. La seconda è quella di utilizzare funzioni o meglio librerie già fatte per leggere i dati in un file wave.
La Microsoft mette a disposizione una serie di funzioni Win32 per gestire proprio i file audio. Tutta la documentazione relativa alla gestione dei multimedia file in Win32 la trovi a partire da questo link:

MSDN - Multimedia File I/O

Quote:
Originariamente inviato da mfonz85
Ho provato anche ad aprire il file in modalità binaria con fopen(file,"rb") ma niente da fare, non cambia nulla...
La funzione fread() non è influenzata dal modo di apertura ("r" o "rb") specificato nella fopen. fread legge sempre un blocco di byte e basta.
__________________
Andrea, SCJP 5 (91%) - SCWCD 5 (94%)
andbin è offline   Rispondi citando il messaggio o parte di esso
Old 08-12-2005, 22:54   #3
mfonz85
Member
 
L'Avatar di mfonz85
 
Iscritto dal: Sep 2005
Città: Bus PCI 1, periferica 0, funzione 0 (Torino)
Messaggi: 213
L'idea è venuta fuori ad un mio amico che deve stendere una monografia che fa vedere come da un file .wav si può campionarlo e quantizzarlo emulando praticamente quello che è un mp3, con la teoria studiata ai corsi di Elaborazione dei Segnali...
Praticamente se non ho capito male a lui servirebbe lo stream di bit da campionare e quantizzare, però da quanto ho capito da quello che mi hai scritto i file wav hanno una struttura particolare...
Ok allora dò un'occhiata e ti faccio sapere...
Ma in particolare, poi avendo a portata di mano la struttura del file wav e il formato con cui devo leggere i dati, quindi poi va bene l'uso di fread() giusto?
Ho dato meglio un'occhiata alla fread e ho letto che è fatta così
size_t fread(void *ptr, size_t dim, size_t nmemb, FILE *stream)
solo che non riesco a capire bene come devo usare "dim" e "nmemb"...ho anche spulciato fra gli header, ma ho trovato niente sullo struct "size_t"...
__________________
Ho concluso affari con: Ippo 2001, Klintf, albert78, Piripikkio, starsky, oldfield e IL0V€INT€R. da EVITARE zarovat
mfonz85 è offline   Rispondi citando il messaggio o parte di esso
Old 09-12-2005, 11:11   #4
andbin
Senior Member
 
L'Avatar di andbin
 
Iscritto dal: Nov 2005
Città: TO
Messaggi: 5206
Quote:
Originariamente inviato da mfonz85
Ma in particolare, poi avendo a portata di mano la struttura del file wav e il formato con cui devo leggere i dati, quindi poi va bene l'uso di fread() giusto?
Se hai scelto la strada "fai da te" , va benissimo usare la funzione fread().

Quote:
Originariamente inviato da mfonz85
Ho dato meglio un'occhiata alla fread e ho letto che è fatta così
size_t fread(void *ptr, size_t dim, size_t nmemb, FILE *stream)
solo che non riesco a capire bene come devo usare "dim" e "nmemb"...ho anche spulciato fra gli header, ma ho trovato niente sullo struct "size_t"...
Innanzitutto size_t non è una struttura. È un tipo di dato (definito in genere con una typedef negli include della libreria standard del "C") che rappresenta un numero intero senza segno. È il tipo restituito dall'operatore sizeof.

Per quanto riguarda la fread() ed anche l'opposta fwrite(), i due parametri dim e nmemb servono per specificare alle due funzioni quanti byte leggere/scrivere secondo la seguente formula: dim * nmemb;
In pratica leggono un certo numero di blocchi specificato da nmemb, ognuno di lunghezza dim. Nota importante: le due funzioni restituiscono un valore di tipo size_t che indica il numero di elementi letti. Se metti dim=10 e nmemb=2 e la fread va a buon fine cioè legge 20 bytes, ti restituisce 2 (non 20!!).

Ti faccio subito un esempio per la lettura del primo blocco RIFF del file wave (nota, presuppongo l'utilizzo in Windows, poiché userò dei tipi di dati definiti nel Platform SDK di Windows):

Codice:
#pragma pack(1)

typedef struct
{
    CHAR  id[4];
    DWORD length;
} RIFF_HEADER;

#pragma pack()



RIFF_HEADER riff_hdr;
size_t len_read;

len_read = fread (&riff_hdr, 1, sizeof (RIFF_HEADER), f);

if (len_read == sizeof (RIFF_HEADER))
{
    ..ok lettura corretta..
}
__________________
Andrea, SCJP 5 (91%) - SCWCD 5 (94%)
andbin è offline   Rispondi citando il messaggio o parte di esso
Old 09-12-2005, 11:53   #5
mfonz85
Member
 
L'Avatar di mfonz85
 
Iscritto dal: Sep 2005
Città: Bus PCI 1, periferica 0, funzione 0 (Torino)
Messaggi: 213
Perfetto...
Cercando in internet sulla base di quello che mi hai scritto ho trovato questo codice...
Codice:
void Load_Wave_File(char *fname)
{
    FILE *fp;

    fp = fopen(fname,"rb);
    if (fp)
    {
        BYTE id[4], *sound_buffer; //four bytes to hold 'RIFF'
        DWORD size; //32 bit value to hold file size
        short format_tag, channels, block_align, bits_per_sample; //our 16 values
        DWORD format_length, sample_rate, avg_bytes_sec, data_size, i; //our 32 bit values

        fread(id, sizeof(BYTE), 4, fp); //read in first four bytes
        if (strcmp(id, "RIFF"))
        { //we had 'RIFF' let's continue
            fread(&size, sizeof(DWORD), 1, fp); //read in 32bit size value
            fread(id, sizeof(BYTE), 4, fp); //read in 4 byte string now
            if (strcmp(id,"WAVE"))
            { //this is probably a wave file since it contained "WAVE"
                fread(id, sizeof(BYTE), 4, fp); //read in 4 bytes "fmt ";
                fread(&format_length, sizeof(DWORD),1,fp);
                fread(&format_tag, sizeof(short), 1, fp); //check mmreg.h (i think?) for other 
                                                              // possible format tags like ADPCM
                fread(&channels, sizeof(short),1,fp); //1 mono, 2 stereo
                fread(&sample_rate, sizeof(DWORD), 1, fp); //like 44100, 22050, etc...
                fread(&avg_bytes_sec, sizeof(short), 1, fp); //probably won't need this
                fread(&block_align, sizeof(short), 1, fp); //probably won't need this
                fread(&bits_per_sample, sizeof(short), 1, fp); //8 bit or 16 bit file?
                fread(id, sizeof(BYTE), 4, fp); //read in 'data'
                fread(&data_size, sizeof(DWORD), 1, fp); //how many bytes of sound data we have
                sound_buffer = (BYTE *) malloc (sizeof(BYTE) * data_size); //set aside sound buffer space
                fread(sound_buffer, sizeof(BYTE), data_size, fp); //read in our whole sound data chunk
            }
            else
                printf("Error: RIFF file but not a wave file\n");
        }
        else
            printf("Error: not a RIFF file\n");
    }
}
L'ho provato e sembra funzionare, dovrebbero esserci solo un pò di errori nell'allocazione dello stream in memoria, adesso debuggo un pochettino e cerco di farlo andare...
Domanda extra:
E se volessi sentire questo file wave, (una volta streamizzato in memoria) dovrei andare ad utilizzare funzioni proprie di windows perchè sarebbe praticamente impossibile scrivere da zero una procedura che faccia riprodurre alla scheda audio lo stream giusto?
Grazie ancora!
__________________
Ho concluso affari con: Ippo 2001, Klintf, albert78, Piripikkio, starsky, oldfield e IL0V€INT€R. da EVITARE zarovat
mfonz85 è offline   Rispondi citando il messaggio o parte di esso
Old 09-12-2005, 17:28   #6
andbin
Senior Member
 
L'Avatar di andbin
 
Iscritto dal: Nov 2005
Città: TO
Messaggi: 5206
Quote:
Originariamente inviato da mfonz85
Perfetto...
Cercando in internet sulla base di quello che mi hai scritto ho trovato questo codice...

....

L'ho provato e sembra funzionare, dovrebbero esserci solo un pò di errori nell'allocazione dello stream in memoria, adesso debuggo un pochettino e cerco di farlo andare...
Questo sorgente non so ovviamente dove l'hai preso ma mi sembra un tantino semplicciotto, nel senso che è buttato giù alla buona. Fa troppe fread per prendersi ogni singolo campo di informazione (non ha senso così). Mi viene quasi da pensare che chi l'ha scritto non conosca le struct.
Il mio consiglio è quello di creare delle strutture per gestire gli header dei chunk. Poi comunque fai tu ...

Quote:
Originariamente inviato da mfonz85
Domanda extra:
E se volessi sentire questo file wave, (una volta streamizzato in memoria) dovrei andare ad utilizzare funzioni proprie di windows perchè sarebbe praticamente impossibile scrivere da zero una procedura che faccia riprodurre alla scheda audio lo stream giusto?
Grazie ancora!
Windows offre il supporto per "suonare" i file wave a diversi livelli. Il modo più semplice per riprodurre un file wave è quello di utilizzare la funzione <PlaySound>. Puoi passargli direttamente il nome del file wave e lui ... te lo suona!

Altrimenti c'è l'approccio a basso livello. Tu leggi e decodifichi il file per conto tuo e tramite un sistema di buffering basato su callback/eventi puoi passare a Windows i campioni da riprodurre man mano che servono.
Tenersi tutto l'intero file wave in memoria va bene solo se il file è davvero piccolo. Tieni presente infatti che i file wave sono abbastanza "spreconi" in fatto di spazio occupato, proprio perché tipicamente non sono compressi.
Comunque trovi tutte le informazioni <qui>.
__________________
Andrea, SCJP 5 (91%) - SCWCD 5 (94%)
andbin è offline   Rispondi citando il messaggio o parte di esso
Old 09-12-2005, 17:51   #7
andbin
Senior Member
 
L'Avatar di andbin
 
Iscritto dal: Nov 2005
Città: TO
Messaggi: 5206
Quote:
Originariamente inviato da mfonz85
Codice:
...
        fread(id, sizeof(BYTE), 4, fp); //read in first four bytes
        if (strcmp(id, "RIFF"))
        { //we had 'RIFF' let's continue
...
Anzi ... tra l'altro è pure sballatissimo! Viene usata la strcmp che presuppone che id sia una stringa terminata dal carattere nullo, cosa che invece non è vera. E il test è comunque sbagliato. Come minimo si dovrebbe fare:

if (strncmp (id, "RIFF", 4) == 0)
__________________
Andrea, SCJP 5 (91%) - SCWCD 5 (94%)
andbin è offline   Rispondi citando il messaggio o parte di esso
Old 10-12-2005, 18:08   #8
mfonz85
Member
 
L'Avatar di mfonz85
 
Iscritto dal: Sep 2005
Città: Bus PCI 1, periferica 0, funzione 0 (Torino)
Messaggi: 213
Quote:
Originariamente inviato da andbin
Anzi ... tra l'altro è pure sballatissimo! Viene usata la strcmp che presuppone che id sia una stringa terminata dal carattere nullo, cosa che invece non è vera. E il test è comunque sbagliato. Come minimo si dovrebbe fare:

if (strncmp (id, "RIFF", 4) == 0)
Sì sì hai ragione, infatti prima di farlo funzionare ho dovuto fare un bel pò di debugging e capire come funzionava il programma (e la struttura del WAVE)...
Comunque ora sono riuscito a mettere in memoria il mio bel file wave, proprio come volevo, adesso mi metterò a pensare come posso realizzare una funzione a basso livello per "suonare" la memoria
Grazie ancora andbin, sei un mago
__________________
Ho concluso affari con: Ippo 2001, Klintf, albert78, Piripikkio, starsky, oldfield e IL0V€INT€R. da EVITARE zarovat
mfonz85 è offline   Rispondi citando il messaggio o parte di esso
 Rispondi


iPhone 17 Pro: più di uno smartphone. È uno studio di produzione in formato tascabile iPhone 17 Pro: più di uno smartphone. &Eg...
Intel Panther Lake: i processori per i notebook del 2026 Intel Panther Lake: i processori per i notebook ...
Intel Xeon 6+: è tempo di Clearwater Forest Intel Xeon 6+: è tempo di Clearwater Fore...
4K a 160Hz o Full HD a 320Hz? Titan Army P2712V, a un prezzo molto basso 4K a 160Hz o Full HD a 320Hz? Titan Army P2712V,...
Recensione Google Pixel Watch 4: basta sollevarlo e si ha Gemini sempre al polso Recensione Google Pixel Watch 4: basta sollevarl...
In Cina Xiaomi SU7 Ultra prende fuoco do...
Apple Smart Glass: display integrato e d...
Mortal Kombat 3 si farà: la confe...
iPhone 18 Pro: prime indiscrezioni sulle...
Vai all'università? Hai un anno d...
Rubrik accelera su IA e sicurezza: tra c...
Nuovo Nothing Phone (3) in offerta su Am...
Roborock Qrevo Edge in offerta su Amazon...
Polizia statunitense mette in guardia: s...
EUREKA J15 Ultra ed Evo Ultra in offerta...
L'Olanda 'nazionalizza' il produttore di...
Robot Lefant M2 Pro in offerta su Amazon...
Ultimi 2 giorni di sconti sui dispositiv...
TP-Link è già proiettata a...
Colpo grosso di Zuckerberg: Meta assume ...
Chromium
GPU-Z
OCCT
LibreOffice Portable
Opera One Portable
Opera One 106
CCleaner Portable
CCleaner Standard
Cpu-Z
Driver NVIDIA GeForce 546.65 WHQL
SmartFTP
Trillian
Google Chrome Portable
Google Chrome 120
VirtualBox
Tutti gli articoli Tutte le news Tutti i download

Strumenti

Regole
Non Puoi aprire nuove discussioni
Non Puoi rispondere ai messaggi
Non Puoi allegare file
Non Puoi modificare i tuoi messaggi

Il codice vB è On
Le Faccine sono On
Il codice [IMG] è On
Il codice HTML è Off
Vai al Forum


Tutti gli orari sono GMT +1. Ora sono le: 10:49.


Powered by vBulletin® Version 3.6.4
Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
Served by www3v