fin Objectif 3
This commit is contained in:
parent
fb9def3d9d
commit
00ecb4e243
12 changed files with 193 additions and 313 deletions
BIN
GASSP72/Manuel_utilisateur_GASSP72_v7.pdf
Normal file
BIN
GASSP72/Manuel_utilisateur_GASSP72_v7.pdf
Normal file
Binary file not shown.
115
GASSP72/gassp72.h
Normal file
115
GASSP72/gassp72.h
Normal file
|
@ -0,0 +1,115 @@
|
|||
/**
|
||||
* Bibliotheque GASSP 2013-02-15
|
||||
*
|
||||
* GPIO - ADC - Sequenceur - System Timer - PWM - 72 MHz
|
||||
*
|
||||
*/
|
||||
|
||||
// STM32F10X_CL : pour le STM32F107 "Communication Line"
|
||||
// STM32F10X_MD : pour le STM32F103 "Medium Density"
|
||||
|
||||
//#define STM32F10X_MD // 2019 fix for Keil 5.23
|
||||
|
||||
#include "stm32f10x.h"
|
||||
|
||||
// horloge systeme (config statique a 72 MHz pour le STM32F103) ------------
|
||||
void CLOCK_Configure(void);
|
||||
|
||||
// Timers 1, 2, 3, 4 -------------------------------------------------------
|
||||
// la duree entre deux debordements successifs doit etre donnnee en periodes
|
||||
// d'horloge CPU (typiquement 72 MHz)
|
||||
void Timer_1234_Init_ff( TIM_TypeDef *Timer, u32 Duree_ticks );
|
||||
|
||||
// activation d'une fonction de traitement de l'interruption timer (callback)
|
||||
void Active_IT_Debordement_Timer( TIM_TypeDef *Timer, char Prio, void (*IT_function)(void) );
|
||||
|
||||
// bloque le timer
|
||||
#define Bloque_Timer(Timer) Timer->CR1=(Timer->CR1)&~(1<<0)
|
||||
|
||||
// Lance timer
|
||||
#define Run_Timer(Timer) Timer->CR1=(Timer->CR1)|(1<<0)
|
||||
|
||||
// PWM (basee sur un des Timers 1, 2, 3, 4 ---------------------------------
|
||||
// la periode doit etre donnee en periodes d'horloge CPU (typiquement 72 MHz)
|
||||
// la fonction rend la pleine echelle ou resolution, c'est a dire la plage
|
||||
// de valeurs acceptees pour moduler la largeur d'impulsion
|
||||
vu16 PWM_Init_ff( TIM_TypeDef *Timer, char Voie, u32 Periode_ticks );
|
||||
|
||||
// Timer systeme "SysTick" -------------------------------------------------
|
||||
|
||||
// la periode doit etre donnee en periodes d'horloge CPU (typiquement 72 MHz)
|
||||
void Systick_Period_ff( unsigned int Periode_ticks );
|
||||
|
||||
// activation d'une fonction de traitement de l'interruption timer (callback)
|
||||
void Systick_Prio_IT( char Prio, void (*Systick_function)(void) );
|
||||
|
||||
#define SysTick_On ((SysTick->CTRL)=(SysTick->CTRL)|1<<0)
|
||||
#define SysTick_Off ((SysTick->CTRL)=(SysTick->CTRL)& ~(1<<0))
|
||||
#define SysTick_Enable_IT ((SysTick->CTRL)=(SysTick->CTRL)|1<<1)
|
||||
#define SysTick_Disable_IT ((SysTick->CTRL)=(SysTick->CTRL)& ~(1<<1))
|
||||
|
||||
// ADC - DMA ---------------------------------------------------------------
|
||||
// Analog-to-Digital Conversion, Direct Memory Access
|
||||
|
||||
// la duree d'echantillonnage doit etre donnee en periodes d'horloge CPU (typiquement 72 MHz)
|
||||
// la fonction rend la duree totale de conversion (meme unites)
|
||||
u32 Init_TimingADC_ActiveADC_ff( ADC_TypeDef * ADC, u32 Duree_Ech_ticks );
|
||||
|
||||
// choix d'un canal ADC unique
|
||||
void Single_Channel_ADC( ADC_TypeDef * ADC, char Voie_ADC );
|
||||
|
||||
// la periode de repetition des acquisitions doit etre donnee en periodes d'horloge CPU
|
||||
// Les sources de déclenchement possibles :
|
||||
#define TIM1_CC1 0
|
||||
#define TIM1_CC2 1
|
||||
#define TIM1_CC3 2
|
||||
#define TIM2_CC2 3
|
||||
#define TIM4_CC4 5
|
||||
void Init_Conversion_On_Trig_Timer_ff( ADC_TypeDef * ADC, char Source, u32 Periode_ticks );
|
||||
|
||||
// initialisation d'acquisition en mode DMA
|
||||
// Ptr_Table_DMA doit pointer sur un espace memoire suffisant pour le nombre d'ech. demande
|
||||
void Init_ADC1_DMA1( char Circ, vu16 *Ptr_Table_DMA );
|
||||
|
||||
|
||||
// Lance une DMA sur le nombre de points spécifie. Les resultats seront stockes
|
||||
// dans la zone de RAM écrite est indiquée lors de l'appel de la fonction Init_ADC1_DMA1
|
||||
void Start_DMA1( u16 NbEchDMA );
|
||||
|
||||
// arret DMA
|
||||
#define Stop_DMA1 DMA1_Channel1->CCR =(DMA1_Channel1->CCR) &~0x1;
|
||||
|
||||
// fonction d'attente (bloquante)
|
||||
// la duree depend de la periode d'acquisition et du nombre d'echantillons
|
||||
void Wait_On_End_Of_DMA1(void);
|
||||
|
||||
|
||||
// GPIO --------------------------------------------------------------------
|
||||
|
||||
// Sens
|
||||
#define INPUT 'i'
|
||||
#define OUTPUT 'o'
|
||||
|
||||
// Techno pour pin en entrée (INPUT)
|
||||
#define ANALOG 0
|
||||
#define INPUT_FLOATING 1
|
||||
#define INPUT_PULL_DOWN_UP 2
|
||||
|
||||
// Techno pour pin en sortie (OUTPUT)
|
||||
#define OUTPUT_PPULL 0
|
||||
#define OUTPUT_OPDRAIN 1
|
||||
#define ALT_PPULL 2
|
||||
#define ALT_OPDRAIN 3
|
||||
|
||||
// La fonction initialise n'importe quelle broche de port (entrée, sortie, techno....)
|
||||
// Exemple :
|
||||
// Port_IO_Init(GPIOB, 8, OUTPUT, OUTPUT_PPULL);
|
||||
// Place le bit 8 du port B en sortie Push-pull
|
||||
// Renvoie 0 si tout est OK, et 1 s'il y a un problème (plage d'entrée non respectée)
|
||||
char GPIO_Configure(GPIO_TypeDef * Port, int Broche, int Sens, int Techno);
|
||||
|
||||
// Spécifier le numéro de broche (0 à 15)
|
||||
// exemple : Port_IO_Set(GPIOB,8);
|
||||
#define GPIO_Set(GPIO,Broche) GPIO->BSRR=(0x01<<Broche)
|
||||
|
||||
#define GPIO_Clear(GPIO,Broche) GPIO->BRR=(0x01<<Broche)
|
BIN
GASSP72/gassp72.lib
Normal file
BIN
GASSP72/gassp72.lib
Normal file
Binary file not shown.
|
@ -230,7 +230,7 @@
|
|||
<Wi>
|
||||
<IntNumber>0</IntNumber>
|
||||
<FirstString>`TIM3_CCR3</FirstString>
|
||||
<SecondString>0080000000000000000000000000E0FFFFFFEF410000000000000000000000000000000054494D335F4343523300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000001000000000000000000F03F1200000000000000000000000000000000000000BA1E0008</SecondString>
|
||||
<SecondString>00800000000000000000000000000000007076400000000000000000000000000000000054494D335F4343523300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000001000000000000000000F03F1100000000000000000000000000000000000000981E0008</SecondString>
|
||||
</Wi>
|
||||
</LogicAnalyzers>
|
||||
<DebugDescription>
|
||||
|
@ -268,8 +268,8 @@
|
|||
<tvExp>0</tvExp>
|
||||
<tvExpOptDlg>0</tvExpOptDlg>
|
||||
<bDave2>0</bDave2>
|
||||
<PathWithFileName>.\Src\signalCarre.s</PathWithFileName>
|
||||
<FilenameWithoutPath>signalCarre.s</FilenameWithoutPath>
|
||||
<PathWithFileName>.\Src\gestionSon.s</PathWithFileName>
|
||||
<FilenameWithoutPath>gestionSon.s</FilenameWithoutPath>
|
||||
<RteFlg>0</RteFlg>
|
||||
<bShared>0</bShared>
|
||||
</File>
|
||||
|
@ -316,18 +316,6 @@
|
|||
<File>
|
||||
<GroupNumber>3</GroupNumber>
|
||||
<FileNumber>5</FileNumber>
|
||||
<FileType>4</FileType>
|
||||
<tvExp>0</tvExp>
|
||||
<tvExpOptDlg>0</tvExpOptDlg>
|
||||
<bDave2>0</bDave2>
|
||||
<PathWithFileName>..\GASSP72\gassp72.lib</PathWithFileName>
|
||||
<FilenameWithoutPath>gassp72.lib</FilenameWithoutPath>
|
||||
<RteFlg>0</RteFlg>
|
||||
<bShared>0</bShared>
|
||||
</File>
|
||||
<File>
|
||||
<GroupNumber>3</GroupNumber>
|
||||
<FileNumber>6</FileNumber>
|
||||
<FileType>2</FileType>
|
||||
<tvExp>0</tvExp>
|
||||
<tvExpOptDlg>0</tvExpOptDlg>
|
||||
|
@ -337,6 +325,18 @@
|
|||
<RteFlg>0</RteFlg>
|
||||
<bShared>0</bShared>
|
||||
</File>
|
||||
<File>
|
||||
<GroupNumber>3</GroupNumber>
|
||||
<FileNumber>6</FileNumber>
|
||||
<FileType>4</FileType>
|
||||
<tvExp>0</tvExp>
|
||||
<tvExpOptDlg>0</tvExpOptDlg>
|
||||
<bDave2>0</bDave2>
|
||||
<PathWithFileName>.\GASSP72\gassp72.lib</PathWithFileName>
|
||||
<FilenameWithoutPath>gassp72.lib</FilenameWithoutPath>
|
||||
<RteFlg>0</RteFlg>
|
||||
<bShared>0</bShared>
|
||||
</File>
|
||||
</Group>
|
||||
|
||||
<Group>
|
||||
|
|
|
@ -338,7 +338,7 @@
|
|||
<MiscControls>--C99</MiscControls>
|
||||
<Define>STM32F103xB,USE_FULL_LL_DRIVER</Define>
|
||||
<Undefine></Undefine>
|
||||
<IncludePath>../GASSP72</IncludePath>
|
||||
<IncludePath>./GASSP72</IncludePath>
|
||||
</VariousControls>
|
||||
</Cads>
|
||||
<Aads>
|
||||
|
@ -388,9 +388,9 @@
|
|||
<FilePath>.\Src\principal.c</FilePath>
|
||||
</File>
|
||||
<File>
|
||||
<FileName>signalCarre.s</FileName>
|
||||
<FileName>gestionSon.s</FileName>
|
||||
<FileType>2</FileType>
|
||||
<FilePath>.\Src\signalCarre.s</FilePath>
|
||||
<FilePath>.\Src\gestionSon.s</FilePath>
|
||||
</File>
|
||||
</Files>
|
||||
</Group>
|
||||
|
@ -412,16 +412,16 @@
|
|||
<FileType>5</FileType>
|
||||
<FilePath>.\Src\etat.h</FilePath>
|
||||
</File>
|
||||
<File>
|
||||
<FileName>gassp72.lib</FileName>
|
||||
<FileType>4</FileType>
|
||||
<FilePath>..\GASSP72\gassp72.lib</FilePath>
|
||||
</File>
|
||||
<File>
|
||||
<FileName>son.asm</FileName>
|
||||
<FileType>2</FileType>
|
||||
<FilePath>.\Src\son.asm</FilePath>
|
||||
</File>
|
||||
<File>
|
||||
<FileName>gassp72.lib</FileName>
|
||||
<FileType>4</FileType>
|
||||
<FilePath>.\GASSP72\gassp72.lib</FilePath>
|
||||
</File>
|
||||
</Files>
|
||||
</Group>
|
||||
<Group>
|
||||
|
|
26
README.md
26
README.md
|
@ -4,27 +4,9 @@ Binôme : Cavailles Kévin / Dumaz Clément
|
|||
|
||||
Classe : 3_MIC_C
|
||||
|
||||
Objectif 2 DFT en réel et gestion du score des 6 joueurs :
|
||||
Objectif 3 Gestion du son :
|
||||
|
||||
-Le signal peut être réglé via le parametre Duree_Ech_ticks de Init_TimingADC_ActiveADC_ff().
|
||||
Ce parametre peut prendre les valeurs de 48 a 83 (0x30 a 0x53).
|
||||
|
||||
-Afin de visualiser le bon fonctionnement de la DFT en mode débogage, il est recommandé de mettre 2 points d’arrêts dans le fichier Src/calcul_dft.s. Un à la ligne 29 et un à la ligne 60.
|
||||
3 clicks sur “run” (F5), en mode débogage, correspondront à 1 DFT complète. Les 2 premiers “run” permettront de visualiser la partie réelle puis la partie imaginaire. Le 3ème “run” permettra de visualiser le résultat de la DFT.
|
||||
|
||||
-Afin de visualiser le bon fonctionnement du système de score, il est recommandé de ne mettre aucun point d'arrêt et d'observer
|
||||
la variable "scores" en mode débogage.
|
||||
Pour ce faire :
|
||||
- mode débogage -> Src/principal.c ligne 21 click droit sur scores -> Add 'scores[taille]' to ... -> Watch 1.
|
||||
- "scores[6]" devrait apparaître dans Watch 1. Retirez "[6]" afin de pouvoir visualiser le tableau en entier.
|
||||
- Cliquez sur "+" directement à droite de "scores".
|
||||
- Cliquez sur "run", vous devriez voir le tableau de score se remplir peu à peu (ou non) en fonction du signal choisi.
|
||||
|
||||
-En l'état (avec 0x33), les scores doivent être les suivants :
|
||||
* J1 (scores[0]) : 1
|
||||
* J2 (scores[1]) : 2
|
||||
* J3 (scores[2]) : 3
|
||||
* J4 (scores[3]) : 4
|
||||
* J5 (scores[4]) : 5
|
||||
* J6 (scores[5]) : 0
|
||||
-Afin de visualiser le bon fonctionnement de la gestion du son en mode débogage, il est recommandé de mettre 1 point d’arrêt dans le fichier Src/gestionSon.s. Un à la ligne 19.
|
||||
Cliquez 1 fois sur run afin que le programme s'arrête au point d'arrêt. En bas à droite de l'éditeur, il doit y avoir un chronomètre se présentant sous la forme "t1: x.xxx sec".
|
||||
Click droit sur ce chronomètre -> "Reset Stop Watch(t1)". Cliquez sur "Run" 1 fois, le chronomètre devrait afficher "t1 : 0.00009100 sec".
|
||||
|
||||
|
|
48
Src/gestionSon.s
Normal file
48
Src/gestionSon.s
Normal file
|
@ -0,0 +1,48 @@
|
|||
; ce programme est pour l'assembleur RealView (Keil)
|
||||
thumb
|
||||
area moncode, code, readonly
|
||||
export timer_callback
|
||||
extern etat
|
||||
;
|
||||
E_POS equ 0
|
||||
E_TAI equ 4
|
||||
E_SON equ 8
|
||||
E_RES equ 12
|
||||
E_PER equ 16
|
||||
|
||||
COMPOSANTE_CONTINUE equ 32768
|
||||
|
||||
TIM3_CCR3 equ 0x4000043C ; adresse registre PWM
|
||||
|
||||
timer_callback proc
|
||||
|
||||
push{r4}
|
||||
|
||||
ldr r1, =etat ;Chargement de la structure etat
|
||||
ldr r2, [r1, #E_POS] ;Récupération de la position actuelle
|
||||
|
||||
ldr r3, [r1,#E_TAI] ;Récupération de la taille du fichier de son
|
||||
cmp r2, r3 ;Si position >= taille
|
||||
bge silence ;On a lu tous les échantillons et on termine la procédure
|
||||
ldr r4, [r1, #E_RES] ;Sinon, on charge la résolution,
|
||||
ldr r3, [r1, #E_SON] ;Le tableau de son, puis l'échantillon
|
||||
ldrsh r3, [r3, r2,lsl #1]
|
||||
|
||||
|
||||
add r3, r3, #COMPOSANTE_CONTINUE ;On ajoute la composante continue
|
||||
mul r3, r3, r4 ;On multiplie par la résolution
|
||||
lsr r3, #16 ;Puis on divise par 2^16
|
||||
|
||||
ldr r4, =TIM3_CCR3 ;On stocke ensuite le résultat dans le TIM3_CCR3 de 32 bits
|
||||
str r3, [r4]
|
||||
|
||||
add r2,#1 ;On incrémente ensuite la position pour l'échantillon suivant
|
||||
str r2,[r1, #E_POS]
|
||||
|
||||
silence
|
||||
|
||||
pop{r4}
|
||||
bx lr
|
||||
endp
|
||||
end
|
||||
|
27
Src/makefile
27
Src/makefile
|
@ -1,27 +0,0 @@
|
|||
# makefile pour MinGW
|
||||
|
||||
CCOPT = -Wall -O2
|
||||
C_SRC = wav_head.c appli.c
|
||||
CPP_SRC =
|
||||
EXE = wav2asm.exe
|
||||
|
||||
OBJS = $(C_SRC:.c=.o) $(CPP_SRC:.cpp=.o)
|
||||
|
||||
# linkage
|
||||
$(EXE) : $(OBJS)
|
||||
g++ -o $(EXE) $(OBJS)
|
||||
|
||||
# compilage
|
||||
.c.o :
|
||||
gcc $(CCOPT) -c $<
|
||||
|
||||
.cpp.o :
|
||||
g++ $(CCOPT) -c $<
|
||||
# other
|
||||
|
||||
clean :
|
||||
del *.o; del *.exe
|
||||
|
||||
# dependances :
|
||||
wav_head.o : wav_head.h
|
||||
appli.o : wav_head.h
|
|
@ -5,7 +5,7 @@
|
|||
#include "etat.h"
|
||||
|
||||
|
||||
#define SYSTICK_PER 360 // (360000 ticks équivaut à 5ms)
|
||||
#define periode_tick_pwm 360 // (360000 ticks équivaut à 5ms)
|
||||
|
||||
|
||||
extern void timer_callback(void);
|
||||
|
@ -26,11 +26,12 @@ int main(void)
|
|||
// config port PB0 pour être utilisé par TIM3-CH3
|
||||
GPIO_Configure(GPIOB, 0, OUTPUT, ALT_PPULL);
|
||||
// config TIM3-CH3 en mode PWM
|
||||
etat.resolution = PWM_Init_ff( TIM3, 3, SYSTICK_PER);
|
||||
etat.resolution = PWM_Init_ff( TIM3, 3, periode_tick_pwm);
|
||||
|
||||
etat.taille = LongueurSon;
|
||||
etat.periode_ticks = PeriodeSonMicroSec*72;
|
||||
etat.son = Son;
|
||||
etat.position = 0;
|
||||
|
||||
// initialisation du timer 4
|
||||
// Periode_en_Tck doit fournir la durée entre interruptions,
|
||||
|
|
|
@ -1,48 +0,0 @@
|
|||
; ce programme est pour l'assembleur RealView (Keil)
|
||||
thumb
|
||||
area moncode, code, readonly
|
||||
export timer_callback
|
||||
extern etat
|
||||
;
|
||||
E_POS equ 0
|
||||
E_TAI equ 4
|
||||
E_SON equ 8
|
||||
E_RES equ 12
|
||||
E_PER equ 16
|
||||
|
||||
TIM3_CCR3 equ 0x4000043C ; adresse registre PWM
|
||||
|
||||
timer_callback proc
|
||||
|
||||
push{r4}
|
||||
|
||||
ldr r1, =etat
|
||||
ldr r2, [r1, #E_POS]
|
||||
|
||||
ldr r3, [r1,#E_TAI]
|
||||
cmp r2, r3
|
||||
beq silence
|
||||
bne son
|
||||
son ldr r4, [r1, #E_RES]
|
||||
ldr r3, [r1, #E_SON]
|
||||
ldrsh r3, [r3, r2,lsl #1]
|
||||
|
||||
add r3, r3, lsl #16
|
||||
mul r3, r3, r4
|
||||
lsr r3, #16
|
||||
;add r3, r3, r4
|
||||
;lsl r3, #1
|
||||
|
||||
ldr r4, =TIM3_CCR3
|
||||
str r3, [r4]
|
||||
|
||||
add r2,#1
|
||||
str r2,[r1, #E_POS]
|
||||
|
||||
silence
|
||||
|
||||
pop{r4}
|
||||
bx lr
|
||||
endp
|
||||
end
|
||||
|
173
Src/wav_head.c
173
Src/wav_head.c
|
@ -1,173 +0,0 @@
|
|||
/* -------------------- WAV specific stuff --------------------------- */
|
||||
|
||||
/* wav est un cas de fichier RIFF.
|
||||
* le fichier RIFF commence par "RIFF" (4 caracteres) suivi de la longueur
|
||||
* du reste du fichier en long (4 bytes ordre Intel)
|
||||
* puis on trouve "WAVE" suivi de chucks.
|
||||
* chaque chuck commence par 4 caracteres (minuscules) suivis de la longueur
|
||||
* du reste du chuck en long (4 bytes ordre Intel)
|
||||
* le chuck "fmt " contient les parametres, sa longueur n'est pas tres fixe,
|
||||
* il peut y avoir un chuck "fact" contenant le nombre de samples
|
||||
* le chuck "data" contient les samples,
|
||||
* tout autre doit etre ignore.
|
||||
|
||||
header mini :
|
||||
RIFF 4 ]
|
||||
filesize 4 ] == 12 bytes de pre-header
|
||||
WAVE 4 ]
|
||||
fmt 4 le chuck fmt coute au moins 24 bytes en tout
|
||||
chucksize 4 == 16 bytes utile
|
||||
type 2 ]
|
||||
chan 2 ]
|
||||
freq 4 ] == 16 bytes
|
||||
bps 4 ]
|
||||
block 2 ]
|
||||
resol 2 ]
|
||||
data 4
|
||||
chucksize 4 == 8 bytes de post-header
|
||||
--------------
|
||||
44 au total
|
||||
real filesize = chucksize + 44
|
||||
RIFF filesize = chucksize + 36
|
||||
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdarg.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "wav_head.h"
|
||||
|
||||
|
||||
unsigned long readlong( unsigned char *buf )
|
||||
{
|
||||
unsigned long l;
|
||||
l = (unsigned long)buf[3] << 24 ;
|
||||
l += (unsigned long)buf[2] << 16 ;
|
||||
l += (unsigned long)buf[1] << 8 ;
|
||||
l += buf[0];
|
||||
return(l);
|
||||
}
|
||||
unsigned int readshort( unsigned char *buf )
|
||||
{
|
||||
unsigned int s;
|
||||
s = buf[0] + ( buf[1] << 8 );
|
||||
return(s);
|
||||
}
|
||||
|
||||
void WAVreadHeader( wavpars *s, int hand )
|
||||
{
|
||||
unsigned char buf[256]; unsigned long filesize, chucksize, factsize;
|
||||
read( hand, buf, 4 );
|
||||
if ( strncmp( (char *)buf, "RIFF", 4 ) != 0 ) gasp("manque en-tete RIFF");
|
||||
read( hand, buf, 4 ); filesize = readlong( buf );
|
||||
read( hand, buf, 4 );
|
||||
if ( strncmp( (char *)buf, "WAVE", 4 ) != 0 ) gasp("manque en-tete WAVE");
|
||||
|
||||
read( hand, buf, 4 );
|
||||
if ( strncmp( (char *)buf, "fmt ", 4 ) != 0 ) gasp("manque chuck fmt");
|
||||
read( hand, buf, 4 ); chucksize = readlong( buf );
|
||||
if ( chucksize > (long)256 ) gasp("chuck fmt trop gros");
|
||||
read( hand, buf, (int)chucksize );
|
||||
if ( readshort(buf) != 1 ) gasp("fichier wave non PCM");
|
||||
s->chan = readshort( buf + 2 );
|
||||
s->freq = readlong( buf + 4 );
|
||||
s->bpsec = readlong( buf + 8 );
|
||||
s->block = readshort( buf + 12 );
|
||||
s->resol = readshort( buf + 14 );
|
||||
s->wavsize = 0L;
|
||||
factsize = 0L;
|
||||
|
||||
read( hand, buf, 4 );
|
||||
if ( strncmp( (char *)buf, "fact", 4 ) == 0 )
|
||||
{
|
||||
read( hand, buf, 4 ); chucksize = readlong( buf );
|
||||
if ( chucksize > (long)256 ) gasp("chuck fmt trop gros");
|
||||
read( hand, buf, (int)chucksize );
|
||||
factsize = readlong( buf );
|
||||
read( hand, buf, 4 );
|
||||
}
|
||||
if ( strncmp( (char *)buf, "data", 4 ) != 0 ) gasp("pas de chuck data");
|
||||
read( hand, buf, 4 ); chucksize = readlong( buf );
|
||||
|
||||
s->wavsize = chucksize / ( s->chan * ((s->resol)>>3) );
|
||||
|
||||
printf("%d canaux, %lu Hz, %lu bytes/s, %d bits\n",
|
||||
s->chan, s->freq, s->bpsec, s->resol );
|
||||
printf("%lu echantillons selon data chuck\n", s->wavsize );
|
||||
if ( factsize != 0L )
|
||||
{
|
||||
printf("%lu echantillons selon fact chuck\n", factsize );
|
||||
if ( s->wavsize != factsize )
|
||||
gasp("longueurs incoherentes");
|
||||
}
|
||||
printf("fichier %lu bytes, chuck data %lu bytes\n",
|
||||
filesize, chucksize );
|
||||
{
|
||||
double durs, dmn, ds; int mn;
|
||||
durs = s->wavsize; durs /= s->freq;
|
||||
dmn = durs / 60.0; mn = (int)dmn; ds = durs - 60.0 * mn;
|
||||
printf("duree %.3f s soit %d mn %.3f s\n", durs, mn, ds );
|
||||
}
|
||||
}
|
||||
|
||||
void writelong( unsigned char *buf, unsigned long l )
|
||||
{
|
||||
buf[0] = (unsigned char)l; l >>= 8;
|
||||
buf[1] = (unsigned char)l; l >>= 8;
|
||||
buf[2] = (unsigned char)l; l >>= 8;
|
||||
buf[3] = (unsigned char)l;
|
||||
}
|
||||
void writeshort( unsigned char *buf, unsigned int s )
|
||||
{
|
||||
buf[0] = (unsigned char)s; s >>= 8;
|
||||
buf[1] = (unsigned char)s;
|
||||
}
|
||||
void gulp()
|
||||
{ gasp("erreur ecriture fichier");
|
||||
}
|
||||
|
||||
void WAVwriteHeader( wavpars *d, int hand )
|
||||
{
|
||||
unsigned char buf[16]; long filesize, chucksize;
|
||||
|
||||
d->bpsec = d->freq * d->chan * ((d->resol)>>3);
|
||||
d->block = d->chan * ((d->resol)>>3);
|
||||
chucksize = d->wavsize * d->chan * ((d->resol)>>3);
|
||||
filesize = chucksize + 36;
|
||||
|
||||
if ( write( hand, "RIFF", 4 ) != 4 ) gulp();
|
||||
writelong( buf, filesize );
|
||||
if ( write( hand, buf, 4 ) != 4 ) gulp();
|
||||
|
||||
if ( write( hand, "WAVE", 4 ) != 4 ) gulp();
|
||||
if ( write( hand, "fmt ", 4 ) != 4 ) gulp();
|
||||
writelong( buf, 16L );
|
||||
if ( write( hand, buf, 4 ) != 4 ) gulp();
|
||||
|
||||
writeshort( buf, 1 ); /* PCM type id */
|
||||
writeshort( buf + 2, d->chan );
|
||||
writelong( buf + 4, d->freq );
|
||||
writelong( buf + 8, d->bpsec );
|
||||
writeshort( buf + 12, d->block );
|
||||
writeshort( buf + 14, d->resol );
|
||||
if ( write( hand, buf, 16 ) != 16 ) gulp();
|
||||
|
||||
if ( write( hand, "data", 4 ) != 4 ) gulp();
|
||||
writelong( buf, chucksize );
|
||||
if ( write( hand, buf, 4 ) != 4 ) gulp();
|
||||
}
|
||||
|
||||
/* --------------------------------------- traitement erreur fatale */
|
||||
|
||||
void gasp( char *fmt, ... )
|
||||
{
|
||||
char lbuf[2048];
|
||||
va_list argptr;
|
||||
va_start( argptr, fmt );
|
||||
vsprintf( lbuf, fmt, argptr );
|
||||
va_end( argptr );
|
||||
printf("STOP : %s\n", lbuf ); exit(1);
|
||||
}
|
|
@ -1,18 +0,0 @@
|
|||
typedef struct {
|
||||
int chan;
|
||||
unsigned long freq; /* frequence d'echantillonnage */
|
||||
unsigned long bpsec; /* bytes par seconde */
|
||||
int block;
|
||||
int resol; /* en bits */
|
||||
unsigned long wavsize; /* longueur en echantillons (par canal) */
|
||||
} wavpars;
|
||||
|
||||
#ifndef O_BINARY
|
||||
#define O_BINARY 0
|
||||
#endif
|
||||
|
||||
void WAVreadHeader( wavpars *s, int hand );
|
||||
|
||||
void WAVwriteHeader( wavpars *d, int hand );
|
||||
|
||||
void gasp( char *fmt, ... ); /* traitement erreur fatale */
|
Loading…
Reference in a new issue