splited into modules, added wav: and alsa: prefix for filename

This commit is contained in:
Ahmet İnan 2011-09-07 21:47:12 +02:00
parent 2842fa7f61
commit 15b01cf36c
12 changed files with 474 additions and 291 deletions

1
.gitignore vendored
View file

@ -1,5 +1,6 @@
encode
decode
*.o
11025.ppm
11025.wav
40000.ppm

View file

@ -1,25 +1,26 @@
CC = gcc
CFLAGS = -D_GNU_SOURCE= -W -Wall -O3 -std=c99 -lm -ffast-math
CFLAGS = -D_GNU_SOURCE= -W -Wall -O3 -std=c99 -ffast-math -DDN=1 -DUP=1
LDFLAGS = $(CFLAGS) -lm -lasound
all: encode decode
# ./encode smpte.ppm 8000.wav 8000
# ./encode smpte.ppm 11025.wav 11025
# ./encode smpte.ppm 40000.wav 40000
# ./encode smpte.ppm 44100.wav 44100
# ./encode smpte.ppm 48000.wav 48000
# ./decode 8000.wav 8000.ppm
# ./decode 11025.wav 11025.ppm
# ./decode 40000.wav 40000.ppm
# ./decode 44100.wav 44100.ppm
# ./decode 48000.wav 48000.ppm
test: all
./encode smpte.ppm 8000.wav 8000
./encode smpte.ppm 11025.wav 11025
./encode smpte.ppm 40000.wav 40000
./encode smpte.ppm 44100.wav 44100
./encode smpte.ppm 48000.wav 48000
./decode wav:8000.wav 8000.ppm
./decode wav:11025.wav 11025.ppm
./decode wav:40000.wav 40000.ppm
./decode wav:44100.wav 44100.ppm
./decode wav:48000.wav 48000.ppm
clean:
rm -f encode decode {8000,11025,40000,44100,48000}.{ppm,wav}
rm -f encode decode *.o {8000,11025,40000,44100,48000}.{ppm,wav}
encode: encode.c Makefile
$(CC) -o $@ $< $(CFLAGS)
encode: encode.o mmap_file.o
decode: decode.c Makefile
$(CC) -o $@ $< $(CFLAGS) -lasound -DDN=1 -DUP=1
decode: decode.o mmap_file.o pcm.o wav.o alsa.o

127
alsa.c Normal file
View file

@ -0,0 +1,127 @@
#include <stdio.h>
#include <malloc.h>
#include <alsa/asoundlib.h>
#include "alsa.h"
typedef struct {
void (*close)(pcm_t *);
void (*info)(pcm_t *);
int (*rate)(pcm_t *);
int (*channels)(pcm_t *);
int (*read)(struct pcm *, short *, int);
snd_pcm_t *pcm;
int r;
int c;
} alsa_t;
void close_alsa(pcm_t *pcm)
{
alsa_t *alsa = (alsa_t *)pcm;
snd_pcm_close(alsa->pcm);
}
void info_alsa(pcm_t *pcm)
{
alsa_t *alsa = (alsa_t *)pcm;
fprintf(stderr, "%d channel(s), %d rate\n", alsa->c, alsa->r);
}
int rate_alsa(pcm_t *pcm)
{
alsa_t *alsa = (alsa_t *)pcm;
return alsa->r;
}
int channels_alsa(pcm_t *pcm)
{
alsa_t *alsa = (alsa_t *)pcm;
return alsa->c;
}
int read_alsa(pcm_t *pcm, short *buff, int frames)
{
alsa_t *alsa = (alsa_t *)pcm;
int got = 0;
while (0 < frames) {
while ((got = snd_pcm_readi(alsa->pcm, buff, frames)) < 0) {
snd_pcm_prepare(alsa->pcm);
fprintf(stderr, "<<<<<<<<<<<<<<< Buffer Overrun >>>>>>>>>>>>>>>\n");
}
buff += got * alsa->c;
frames -= got;
}
return 1;
}
int open_alsa(pcm_t **p, char *name)
{
alsa_t *alsa = (alsa_t *)malloc(sizeof(alsa_t));
alsa->close = close_alsa;
alsa->info = info_alsa;
alsa->rate = rate_alsa;
alsa->channels = channels_alsa;
alsa->read = read_alsa;
snd_pcm_t *pcm;
snd_pcm_hw_params_t *params;
snd_pcm_hw_params_alloca(&params);
if (snd_pcm_open(&pcm, name, SND_PCM_STREAM_CAPTURE, 0) < 0) {
fprintf(stderr, "Error opening PCM device %s\n", name);
free(alsa);
return 0;
}
if (snd_pcm_hw_params_any(pcm, params) < 0) {
fprintf(stderr, "Can not configure this PCM device.\n");
snd_pcm_close(alsa->pcm);
free(alsa);
return 0;
}
if (snd_pcm_hw_params_set_access(pcm, params, SND_PCM_ACCESS_RW_INTERLEAVED) < 0) {
fprintf(stderr, "Error setting access.\n");
snd_pcm_close(alsa->pcm);
free(alsa);
return 0;
}
if (snd_pcm_hw_params_set_format(pcm, params, SND_PCM_FORMAT_S16_LE) < 0) {
fprintf(stderr, "Error setting S16_LE format.\n");
snd_pcm_close(alsa->pcm);
free(alsa);
return 0;
}
if (snd_pcm_hw_params_set_rate_resample(pcm, params, 0) < 0) {
fprintf(stderr, "Error disabling resampling.\n");
snd_pcm_close(alsa->pcm);
free(alsa);
return 0;
}
if (snd_pcm_hw_params(pcm, params) < 0) {
fprintf(stderr, "Error setting HW params.\n");
snd_pcm_close(alsa->pcm);
free(alsa);
return 0;
}
unsigned int rate = 0;
if (snd_pcm_hw_params_get_rate(params, &rate, 0) < 0) {
fprintf(stderr, "Error getting rate.\n");
snd_pcm_close(alsa->pcm);
free(alsa);
return 0;
}
unsigned int channels = 0;
if (snd_pcm_hw_params_get_channels(params, &channels) < 0) {
fprintf(stderr, "Error getting channels.\n");
snd_pcm_close(alsa->pcm);
free(alsa);
return 0;
}
alsa->pcm = pcm;
alsa->r = rate;
alsa->c = channels;
*p = (pcm_t *)alsa;
return 1;
}

7
alsa.h Normal file
View file

@ -0,0 +1,7 @@
#ifndef ALSA_H
#define ALSA_H
#include "pcm.h"
int open_alsa(pcm_t **, char *);
#endif

210
decode.c
View file

@ -3,15 +3,11 @@
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/mman.h>
#include <math.h>
#include <complex.h>
#include <alsa/asoundlib.h>
#include <time.h>
#include "mmap_file.h"
#include "pcm.h"
float lerp(float a, float b, float x)
{
@ -190,92 +186,6 @@ void free_delay(delay_t *delay)
free(delay);
}
void *mmap_file_ro(char *name, size_t *size)
{
*size = 0;
int fd = open(name, O_RDONLY);
if (fd == -1) {
perror("open");
return 0;
}
struct stat sb;
if (fstat(fd, &sb) == -1) {
perror("fstat");
return 0;
}
if (!S_ISREG(sb.st_mode)) {
fprintf(stderr, "%s not a file\n", name);
return 0;
}
void *p = mmap(0, sb.st_size, PROT_READ, MAP_SHARED, fd, 0);
if (p == MAP_FAILED) {
perror("mmap");
return 0;
}
if (close(fd) == -1) {
perror("close");
return 0;
}
*size = sb.st_size;
fprintf(stderr, "opened %s (ro)\n", name);
return p;
}
void *mmap_file_rw(char *name, size_t size)
{
int fd = open(name, O_RDWR|O_CREAT|O_TRUNC, S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH);
if (fd == -1) {
perror("open");
return 0;
}
struct stat sb;
if (fstat(fd, &sb) == -1) {
perror("fstat");
return 0;
}
if (!S_ISREG(sb.st_mode)) {
fprintf(stderr, "%s not a file\n", name);
return 0;
}
if (lseek(fd, size - 1, SEEK_SET) == -1) {
perror("lseek");
return 0;
}
if (write(fd, "", 1) != 1) {
perror("write");
return 0;
}
void *p = mmap(0, size, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0);
if (p == MAP_FAILED) {
perror("mmap");
return 0;
}
if (close(fd) == -1) {
perror ("close");
return 0;
}
fprintf(stderr, "opened %s (rw)\n", name);
return p;
}
int munmap_file(void *p, size_t size)
{
if (munmap(p, size) == -1) {
perror("munmap");
return 0;
}
return 1;
}
typedef struct {
uint32_t ChunkID;
uint32_t ChunkSize;
@ -324,82 +234,6 @@ void process_line(uint8_t *pixel, uint8_t *y_pixel, uint8_t *uv_pixel, int y_wid
}
}
typedef struct {
snd_pcm_t *pcm;
int rate;
int channels;
} pcm_t;
pcm_t *open_pcm(char *name)
{
snd_pcm_t *pcm;
snd_pcm_hw_params_t *params;
snd_pcm_hw_params_alloca(&params);
if (snd_pcm_open(&pcm, name, SND_PCM_STREAM_CAPTURE, 0) < 0) {
fprintf(stderr, "Error opening PCM device\n");
return 0;
}
if (snd_pcm_hw_params_any(pcm, params) < 0) {
fprintf(stderr, "Can not configure this PCM device.\n");
return 0;
}
if (snd_pcm_hw_params_set_access(pcm, params, SND_PCM_ACCESS_RW_INTERLEAVED) < 0) {
fprintf(stderr, "Error setting access.\n");
return 0;
}
if (snd_pcm_hw_params_set_format(pcm, params, SND_PCM_FORMAT_S16_LE) < 0) {
fprintf(stderr, "Error setting format.\n");
return 0;
}
if (snd_pcm_hw_params_set_rate_resample(pcm, params, 0) < 0) {
fprintf(stderr, "Error disabling resampling.\n");
return 0;
}
if (snd_pcm_hw_params(pcm, params) < 0) {
fprintf(stderr, "Error setting HW params.\n");
return 0;
}
unsigned int rate = 0;
if (snd_pcm_hw_params_get_rate(params, &rate, 0) < 0) {
fprintf(stderr, "Error getting rate.\n");
return 0;
}
unsigned int channels = 0;
if (snd_pcm_hw_params_get_channels(params, &channels) < 0) {
fprintf(stderr, "Error getting channels.\n");
return 0;
}
pcm_t *p = (pcm_t *)malloc(sizeof(pcm_t));
p->pcm = pcm;
p->rate = rate;
p->channels = channels;
return p;
}
void close_pcm(pcm_t *p)
{
snd_pcm_close(p->pcm);
free(p);
}
void read_pcm(pcm_t *p, short *buff, int frames)
{
int got = 0;
while (0 < frames) {
while ((got = snd_pcm_readi(p->pcm, buff, frames)) < 0) {
snd_pcm_prepare(p->pcm);
fprintf(stderr, "<<<<<<<<<<<<<<< Buffer Overrun >>>>>>>>>>>>>>>\n");
}
buff += got * p->channels;
frames -= got;
}
}
char *string_time(char *fmt)
{
static char s[64];
@ -411,22 +245,26 @@ char *string_time(char *fmt)
int main(int argc, char **argv)
{
pcm_t *pcm;
if (argc == 1)
pcm = open_pcm("default");
else
pcm = open_pcm(argv[1]);
char *name = "alsa:default";
if (argc != 1)
name = argv[1];
if (!pcm)
if (!open_pcm(&pcm, name)) {
fprintf(stderr, "couldnt open %s\n", name);
return 1;
}
float rate = pcm->rate;
info_pcm(pcm);
float rate = rate_pcm(pcm);
if (rate * 0.088 < 320.0) {
fprintf(stderr, "%.0fhz samplerate too low\n", rate);
return 1;
}
fprintf(stderr, "%.0fhz samplerate\n", rate);
if (pcm->channels > 1)
fprintf(stderr, "using first of %d channels\n", pcm->channels);
int channels = channels_pcm(pcm);
if (channels > 1)
fprintf(stderr, "using first of %d channels\n", channels);
const float step = 1.0 / rate;
float complex cnt_last = -I;
@ -488,7 +326,7 @@ int main(int argc, char **argv)
delay_t *cnt_delay = alloc_delay((dat_taps - 1) / (2 * factor_L));
delay_t *dat_delay = alloc_delay((cnt_taps - 1) / (2 * factor_L));
short *buff = (short *)malloc(sizeof(short) * pcm->channels * factor_M);
short *buff = (short *)malloc(sizeof(short) * channels * factor_M);
const float sync_porch_len = 0.003;
const float porch_len = 0.0015; (void)porch_len;
@ -504,7 +342,7 @@ int main(int argc, char **argv)
char ppm_head[32];
snprintf(ppm_head, 32, "P6 %d %d 255\n", width, height);
size_t ppm_size = strlen(ppm_head) + width * height * 3;
char *ppm_p = 0;
void *ppm_p = 0;
uint8_t *pixel = 0;
int hor_ticks = 0;
@ -520,9 +358,10 @@ int main(int argc, char **argv)
for (int out = factor_L;; out++, hor_ticks++, cal_ticks++, vis_ticks++) {
if (out >= factor_L) {
out = 0;
read_pcm(pcm, buff, factor_M);
if (!read_pcm(pcm, buff, factor_M))
break;
for (int j = 0; j < factor_M; j++) {
float amp = (float)buff[j * pcm->channels] / 32767.0;
float amp = (float)buff[j * channels] / 32767.0;
cnt_amp[j] = do_delay(cnt_delay, amp);
dat_amp[j] = do_delay(dat_delay, amp);
}
@ -647,7 +486,7 @@ int main(int argc, char **argv)
missing_sync = 0;
seperator_correction = 0;
}
ppm_p = mmap_file_rw(string_time("%F_%T.ppm"), ppm_size);
mmap_file_rw(&ppm_p, string_time("%F_%T.ppm"), ppm_size);
memcpy(ppm_p, ppm_head, strlen(ppm_head));
pixel = (uint8_t *)ppm_p + strlen(ppm_head);
memset(pixel, 0, width * height * 3);
@ -734,6 +573,13 @@ int main(int argc, char **argv)
uv_pixel[uv_pixel_x++ + odd * uv_width] = limit(0.0, 255.0, 255.0 * (dat_freq - 1500.0) / 800.0);
}
if (pixel) {
munmap_file(ppm_p, ppm_size);
fprintf(stderr, "%d missing sync's and %d corrections from seperator\n", missing_sync, seperator_correction);
missing_sync = 0;
seperator_correction = 0;
}
close_pcm(pcm);
free_ddc(cnt_ddc);

103
encode.c
View file

@ -3,14 +3,10 @@
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/mman.h>
#include <math.h>
#include <complex.h>
#include <limits.h>
#include "mmap_file.h"
float limit(float min, float max, float x)
{
@ -49,91 +45,6 @@ uint8_t U_RGB(uint8_t R, uint8_t G, uint8_t B)
return limit(0.0, 255.0, 128.0 + (0.003906 * ((-37.945 * R) + (-74.494 * G) + (112.439 * B))));
}
void *mmap_file_ro(char *name, size_t *size)
{
*size = 0;
int fd = open(name, O_RDONLY);
if (fd == -1) {
perror("open");
return 0;
}
struct stat sb;
if (fstat(fd, &sb) == -1) {
perror("fstat");
return 0;
}
if (!S_ISREG(sb.st_mode)) {
fprintf(stderr, "%s not a file\n", name);
return 0;
}
void *p = mmap(0, sb.st_size, PROT_READ, MAP_SHARED, fd, 0);
if (p == MAP_FAILED) {
perror("mmap");
return 0;
}
if (close(fd) == -1) {
perror ("close");
return 0;
}
*size = sb.st_size;
return p;
}
void *mmap_file_rw(char *name, size_t size)
{
int fd = open(name, O_RDWR|O_CREAT|O_TRUNC, S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH);
if (fd == -1) {
perror("open");
return 0;
}
struct stat sb;
if (fstat(fd, &sb) == -1) {
perror("fstat");
return 0;
}
if (!S_ISREG(sb.st_mode)) {
fprintf(stderr, "%s not a file\n", name);
return 0;
}
if (lseek(fd, size - 1, SEEK_SET) == -1) {
perror("lseek");
return 0;
}
if (write(fd, "", 1) != 1) {
perror("write");
return 0;
}
void *p = mmap(0, size, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0);
if (p == MAP_FAILED) {
perror("mmap");
return 0;
}
if (close(fd) == -1) {
perror ("close");
return 0;
}
return p;
}
int munmap_file(void *p, size_t size)
{
if (munmap(p, size) == -1) {
perror("munmap");
return 0;
}
return 1;
}
typedef struct {
uint32_t ChunkID;
uint32_t ChunkSize;
@ -176,7 +87,11 @@ int main(int argc, char **argv)
}
size_t ppm_size;
char *ppm_p = mmap_file_ro(argv[1], &ppm_size);
void *ppm_p;
if (!mmap_file_ro(&ppm_p, argv[1], &ppm_size)) {
fprintf(stderr, "couldnt open ppm file\n");
return 1;
}
const int width = 320;
const int height = 240;
const char *ppm_head = "P6 320 240 255\n";
@ -201,9 +116,11 @@ int main(int argc, char **argv)
size_t wav_size = 4096 * ((size_t)(37.5 * rate * 2 + 44 + 4095) / 4096);
int samples = (wav_size - 44) / 2;
char *wav_p = mmap_file_rw(argv[2], wav_size);
if (!wav_p)
void *wav_p;
if (!mmap_file_rw(&wav_p, argv[2], wav_size)) {
fprintf(stderr, "couldnt open wav file\n");
return 1;
}
buffer = (short *)(wav_p + sizeof(wav_t));

100
mmap_file.c Normal file
View file

@ -0,0 +1,100 @@
#include <stdio.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <sys/mman.h>
#include <unistd.h>
#include "mmap_file.h"
int mmap_file_ro(void **p, char *name, size_t *size)
{
*size = 0;
int fd = open(name, O_RDONLY);
if (fd == -1) {
perror("open");
return 0;
}
struct stat sb;
if (fstat(fd, &sb) == -1) {
perror("fstat");
close(fd);
return 0;
}
if (!S_ISREG(sb.st_mode)) {
fprintf(stderr, "%s not a file\n", name);
close(fd);
return 0;
}
*p = mmap(0, sb.st_size, PROT_READ, MAP_SHARED, fd, 0);
if (*p == MAP_FAILED) {
perror("mmap");
close(fd);
return 0;
}
if (close(fd) == -1) {
perror ("close");
return 0;
}
*size = sb.st_size;
return 1;
}
int mmap_file_rw(void **p, char *name, size_t size)
{
int fd = open(name, O_RDWR|O_CREAT|O_TRUNC, S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH);
if (fd == -1) {
perror("open");
return 0;
}
struct stat sb;
if (fstat(fd, &sb) == -1) {
perror("fstat");
close(fd);
return 0;
}
if (!S_ISREG(sb.st_mode)) {
fprintf(stderr, "%s not a file\n", name);
close(fd);
return 0;
}
if (lseek(fd, size - 1, SEEK_SET) == -1) {
perror("lseek");
close(fd);
return 0;
}
if (write(fd, "", 1) != 1) {
perror("write");
close(fd);
return 0;
}
*p = mmap(0, size, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0);
if (*p == MAP_FAILED) {
perror("mmap");
close(fd);
return 0;
}
if (close(fd) == -1) {
perror ("close");
return 0;
}
return 1;
}
int munmap_file(void *p, size_t size)
{
if (munmap(p, size) == -1) {
perror("munmap");
return 0;
}
return 1;
}

6
mmap_file.h Normal file
View file

@ -0,0 +1,6 @@
#ifndef MMAP_FILE_H
#define MMAP_FILE_H
int mmap_file_ro(void **, char *, size_t *);
int mmap_file_rw(void **, char *, size_t);
int munmap_file(void *, size_t);
#endif

43
pcm.c Normal file
View file

@ -0,0 +1,43 @@
#include <stdint.h>
#include <string.h>
#include <malloc.h>
#include "pcm.h"
#include "alsa.h"
#include "wav.h"
void close_pcm(pcm_t *pcm)
{
pcm->close(pcm);
free(pcm);
}
void info_pcm(pcm_t *pcm)
{
pcm->info(pcm);
}
int rate_pcm(pcm_t *pcm)
{
return pcm->rate(pcm);
}
int channels_pcm(pcm_t *pcm)
{
return pcm->channels(pcm);
}
int read_pcm(pcm_t *pcm, short *buff, int frames)
{
return pcm->read(pcm, buff, frames);
}
int open_pcm(pcm_t **p, char *name)
{
if (strstr(name, "alsa:"))
return open_alsa(p, name + strlen("alsa:"));
if (strstr(name, "wav:"))
return open_wav(p, name + strlen("wav:"));
return 0;
}

21
pcm.h Normal file
View file

@ -0,0 +1,21 @@
#ifndef PCM_H
#define PCM_H
typedef struct pcm {
void (*close)(struct pcm *);
void (*info)(struct pcm *);
int (*rate)(struct pcm *);
int (*channels)(struct pcm *);
int (*read)(struct pcm *, short *, int);
} pcm_t;
void close_pcm(pcm_t *);
void info_pcm(pcm_t *);
int rate_pcm(pcm_t *);
int channels_pcm(pcm_t *);
int read_pcm(pcm_t *, short *, int);
int open_pcm(pcm_t **, char *);
#endif

108
wav.c Normal file
View file

@ -0,0 +1,108 @@
#include <stdio.h>
#include <stdint.h>
#include <string.h>
#include <malloc.h>
#include "wav.h"
#include "mmap_file.h"
typedef struct {
uint32_t ChunkID;
uint32_t ChunkSize;
uint32_t Format;
uint32_t Subchunk1ID;
uint32_t Subchunk1Size;
uint16_t AudioFormat;
uint16_t NumChannels;
uint32_t SampleRate;
uint32_t ByteRate;
uint16_t BlockAlign;
uint16_t BitsPerSample;
uint32_t Subchunk2ID;
uint32_t Subchunk2Size;
} wav_head_t;
typedef struct {
void (*close)(pcm_t *);
void (*info)(pcm_t *);
int (*rate)(pcm_t *);
int (*channels)(pcm_t *);
int (*read)(struct pcm *, short *, int);
void *p;
short *b;
size_t size;
int r;
int c;
int samples;
int index;
} wav_t;
void close_wav(pcm_t *pcm)
{
wav_t *wav = (wav_t *)pcm;
munmap_file(wav->p, wav->size);
}
void info_wav(pcm_t *pcm)
{
wav_t *wav = (wav_t *)pcm;
fprintf(stderr, "%d channel(s), %d rate, %d samples\n", wav->c, wav->r, wav->samples);
}
int rate_wav(pcm_t *pcm)
{
wav_t *wav = (wav_t *)pcm;
return wav->r;
}
int channels_wav(pcm_t *pcm)
{
wav_t *wav = (wav_t *)pcm;
return wav->c;
}
int read_wav(pcm_t *pcm, short *buff, int frames)
{
wav_t *wav = (wav_t *)pcm;
if ((wav->index + frames * wav->c) > wav->samples)
return 0;
memcpy(buff, wav->b + wav->index, sizeof(short) * frames * wav->c);
wav->index += frames * wav->c;
return 1;
}
int open_wav(pcm_t **p, char *name)
{
wav_t *wav = (wav_t *)malloc(sizeof(wav_t));
wav->close = close_wav;
wav->info = info_wav;
wav->rate = rate_wav;
wav->channels = channels_wav;
wav->read = read_wav;
if (!mmap_file_ro(&wav->p, name, &wav->size)) {
fprintf(stderr, "couldnt open wav file %s!\n", name);
free(wav);
return 0;
}
wav_head_t *head = (wav_head_t *)wav->p;
wav->b = (short *)(wav->p + sizeof(wav_head_t));
if (head->ChunkID != 0x46464952 || head->Format != 0x45564157 ||
head->Subchunk1ID != 0x20746d66 || head->Subchunk1Size != 16 ||
head->AudioFormat != 1 || head->Subchunk2ID != 0x61746164) {
fprintf(stderr, "unsupported WAV file!\n");
munmap_file(wav->p, wav->size);
free(wav);
return 0;
}
if (head->BitsPerSample != 16) {
fprintf(stderr, "only 16bit WAV supported!\n");
munmap_file(wav->p, wav->size);
free(wav);
return 0;
}
wav->c = head->NumChannels;
wav->samples = head->Subchunk2Size / 2;
wav->index = 0;
wav->r = head->SampleRate;
*p = (pcm_t *)wav;
return 1;
}

6
wav.h Normal file
View file

@ -0,0 +1,6 @@
#ifndef WAV_H
#define WAV_H
#include "pcm.h"
int open_wav(pcm_t **, char *);
#endif