kopia lustrzana https://github.com/xdsopl/robot36
cleaned up, specify frames on open_pcm_write
rodzic
9ff748c42e
commit
bca74fb55f
4
pcm.c
4
pcm.c
|
@ -53,12 +53,12 @@ int open_pcm_read(pcm_t **p, char *name)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int open_pcm_write(pcm_t **p, char *name, int rate, int channels)
|
int open_pcm_write(pcm_t **p, char *name, int rate, int channels, int frames)
|
||||||
{
|
{
|
||||||
if (strstr(name, "plughw:") == name || strstr(name, "hw:") == name || strstr(name, "default") == name)
|
if (strstr(name, "plughw:") == name || strstr(name, "hw:") == name || strstr(name, "default") == name)
|
||||||
return open_alsa_write(p, name, rate, channels);
|
return open_alsa_write(p, name, rate, channels);
|
||||||
if (strstr(name, ".wav") == (name + (strlen(name) - strlen(".wav"))))
|
if (strstr(name, ".wav") == (name + (strlen(name) - strlen(".wav"))))
|
||||||
return open_wav_write(p, name, rate, channels);
|
return open_wav_write(p, name, rate, channels, frames);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
2
pcm.h
2
pcm.h
|
@ -24,7 +24,7 @@ int channels_pcm(pcm_t *);
|
||||||
int read_pcm(pcm_t *, short *, int);
|
int read_pcm(pcm_t *, short *, int);
|
||||||
int write_pcm(pcm_t *, short *, int);
|
int write_pcm(pcm_t *, short *, int);
|
||||||
int open_pcm_read(pcm_t **, char *);
|
int open_pcm_read(pcm_t **, char *);
|
||||||
int open_pcm_write(pcm_t **, char *, int, int);
|
int open_pcm_write(pcm_t **, char *, int, int, int);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
54
wav.c
54
wav.c
|
@ -36,10 +36,12 @@ typedef struct {
|
||||||
int (*channels)(pcm_t *);
|
int (*channels)(pcm_t *);
|
||||||
int (*rw)(struct pcm *, short *, int);
|
int (*rw)(struct pcm *, short *, int);
|
||||||
void *p;
|
void *p;
|
||||||
wav_head_t *head;
|
|
||||||
short *b;
|
short *b;
|
||||||
size_t size;
|
size_t size;
|
||||||
unsigned int index;
|
int index;
|
||||||
|
int frames;
|
||||||
|
int r;
|
||||||
|
int c;
|
||||||
} wav_t;
|
} wav_t;
|
||||||
|
|
||||||
void close_wav(pcm_t *pcm)
|
void close_wav(pcm_t *pcm)
|
||||||
|
@ -51,34 +53,34 @@ void close_wav(pcm_t *pcm)
|
||||||
void info_wav(pcm_t *pcm)
|
void info_wav(pcm_t *pcm)
|
||||||
{
|
{
|
||||||
wav_t *wav = (wav_t *)pcm;
|
wav_t *wav = (wav_t *)pcm;
|
||||||
fprintf(stderr, "%d channel(s), %d rate, %d samples\n", wav->head->NumChannels, wav->head->SampleRate, wav->head->Subchunk2Size / 2);
|
fprintf(stderr, "%d channel(s), %d rate, %d frames\n", wav->c, wav->r, wav->frames);
|
||||||
}
|
}
|
||||||
int rate_wav(pcm_t *pcm)
|
int rate_wav(pcm_t *pcm)
|
||||||
{
|
{
|
||||||
wav_t *wav = (wav_t *)pcm;
|
wav_t *wav = (wav_t *)pcm;
|
||||||
return wav->head->SampleRate;
|
return wav->r;
|
||||||
}
|
}
|
||||||
int channels_wav(pcm_t *pcm)
|
int channels_wav(pcm_t *pcm)
|
||||||
{
|
{
|
||||||
wav_t *wav = (wav_t *)pcm;
|
wav_t *wav = (wav_t *)pcm;
|
||||||
return wav->head->NumChannels;
|
return wav->c;
|
||||||
}
|
}
|
||||||
int read_wav(pcm_t *pcm, short *buff, int frames)
|
int read_wav(pcm_t *pcm, short *buff, int frames)
|
||||||
{
|
{
|
||||||
wav_t *wav = (wav_t *)pcm;
|
wav_t *wav = (wav_t *)pcm;
|
||||||
if ((wav->index + frames * wav->head->NumChannels) > (wav->head->Subchunk2Size / 2))
|
if ((wav->index + frames) > wav->frames)
|
||||||
return 0;
|
return 0;
|
||||||
memcpy(buff, wav->b + wav->index, sizeof(short) * frames * wav->head->NumChannels);
|
memcpy(buff, wav->b + wav->index * wav->c, sizeof(short) * frames * wav->c);
|
||||||
wav->index += frames * wav->head->NumChannels;
|
wav->index += frames;
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
int write_wav(pcm_t *pcm, short *buff, int frames)
|
int write_wav(pcm_t *pcm, short *buff, int frames)
|
||||||
{
|
{
|
||||||
wav_t *wav = (wav_t *)pcm;
|
wav_t *wav = (wav_t *)pcm;
|
||||||
if ((wav->index + frames * wav->head->NumChannels) > (wav->head->Subchunk2Size / 2))
|
if ((wav->index + frames) > wav->frames)
|
||||||
return 0;
|
return 0;
|
||||||
memcpy(wav->b + wav->index, buff, sizeof(short) * frames * wav->head->NumChannels);
|
memcpy(wav->b + wav->index * wav->c, buff, sizeof(short) * frames * wav->c);
|
||||||
wav->index += frames * wav->head->NumChannels;
|
wav->index += frames;
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -95,29 +97,33 @@ int open_wav_read(pcm_t **p, char *name)
|
||||||
free(wav);
|
free(wav);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
wav->head = (wav_head_t *)wav->p;
|
wav_head_t *head = (wav_head_t *)wav->p;
|
||||||
wav->b = (short *)(wav->p + sizeof(wav_head_t));
|
wav->b = (short *)(wav->p + sizeof(wav_head_t));
|
||||||
|
|
||||||
if (wav->head->ChunkID != 0x46464952 || wav->head->Format != 0x45564157 ||
|
if (head->ChunkID != 0x46464952 || head->Format != 0x45564157 ||
|
||||||
wav->head->Subchunk1ID != 0x20746d66 || wav->head->Subchunk1Size != 16 ||
|
head->Subchunk1ID != 0x20746d66 || head->Subchunk1Size != 16 ||
|
||||||
wav->head->AudioFormat != 1 || wav->head->Subchunk2ID != 0x61746164) {
|
head->AudioFormat != 1 || head->Subchunk2ID != 0x61746164 ||
|
||||||
|
head->ChunkSize != (head->Subchunk2Size + 36)) {
|
||||||
fprintf(stderr, "unsupported WAV file!\n");
|
fprintf(stderr, "unsupported WAV file!\n");
|
||||||
munmap_file(wav->p, wav->size);
|
munmap_file(wav->p, wav->size);
|
||||||
free(wav);
|
free(wav);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
if (wav->head->BitsPerSample != 16) {
|
if (head->BitsPerSample != 16) {
|
||||||
fprintf(stderr, "only 16bit WAV supported!\n");
|
fprintf(stderr, "only 16bit WAV supported!\n");
|
||||||
munmap_file(wav->p, wav->size);
|
munmap_file(wav->p, wav->size);
|
||||||
free(wav);
|
free(wav);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
wav->index = 0;
|
wav->index = 0;
|
||||||
|
wav->frames = head->Subchunk2Size / (sizeof(short) * head->NumChannels);
|
||||||
|
wav->r = head->SampleRate;
|
||||||
|
wav->c = head->NumChannels;
|
||||||
*p = (pcm_t *)wav;
|
*p = (pcm_t *)wav;
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
int open_wav_write(pcm_t **p, char *name, int rate, int channels)
|
int open_wav_write(pcm_t **p, char *name, int rate, int channels, int frames)
|
||||||
{
|
{
|
||||||
wav_t *wav = (wav_t *)malloc(sizeof(wav_t));
|
wav_t *wav = (wav_t *)malloc(sizeof(wav_t));
|
||||||
wav->close = close_wav;
|
wav->close = close_wav;
|
||||||
|
@ -125,7 +131,7 @@ int open_wav_write(pcm_t **p, char *name, int rate, int channels)
|
||||||
wav->rate = rate_wav;
|
wav->rate = rate_wav;
|
||||||
wav->channels = channels_wav;
|
wav->channels = channels_wav;
|
||||||
wav->rw = write_wav;
|
wav->rw = write_wav;
|
||||||
wav->size = 4096;
|
wav->size = frames * channels * sizeof(short) + sizeof(wav_head_t);
|
||||||
if (!mmap_file_rw(&wav->p, name, wav->size)) {
|
if (!mmap_file_rw(&wav->p, name, wav->size)) {
|
||||||
fprintf(stderr, "couldnt open wav file %s!\n", name);
|
fprintf(stderr, "couldnt open wav file %s!\n", name);
|
||||||
free(wav);
|
free(wav);
|
||||||
|
@ -134,11 +140,8 @@ int open_wav_write(pcm_t **p, char *name, int rate, int channels)
|
||||||
wav_head_t *head = (wav_head_t *)wav->p;
|
wav_head_t *head = (wav_head_t *)wav->p;
|
||||||
wav->b = (short *)(wav->p + sizeof(wav_head_t));
|
wav->b = (short *)(wav->p + sizeof(wav_head_t));
|
||||||
|
|
||||||
int samples = (wav->size - 44) / 2;
|
|
||||||
wav->index = 0;
|
|
||||||
|
|
||||||
head->ChunkID = 0x46464952;
|
head->ChunkID = 0x46464952;
|
||||||
head->ChunkSize = 36 + 2 * samples;
|
head->ChunkSize = 36 + frames * sizeof(short) * channels;
|
||||||
head->Format = 0x45564157;
|
head->Format = 0x45564157;
|
||||||
head->Subchunk1ID = 0x20746d66;
|
head->Subchunk1ID = 0x20746d66;
|
||||||
head->Subchunk1Size = 16;
|
head->Subchunk1Size = 16;
|
||||||
|
@ -149,7 +152,12 @@ int open_wav_write(pcm_t **p, char *name, int rate, int channels)
|
||||||
head->BlockAlign = 2;
|
head->BlockAlign = 2;
|
||||||
head->BitsPerSample = 16;
|
head->BitsPerSample = 16;
|
||||||
head->Subchunk2ID = 0x61746164;
|
head->Subchunk2ID = 0x61746164;
|
||||||
head->Subchunk2Size = 2 * samples;
|
head->Subchunk2Size = frames * sizeof(short) * channels;
|
||||||
|
|
||||||
|
wav->r = rate;
|
||||||
|
wav->c = channels;
|
||||||
|
wav->frames = frames;
|
||||||
|
wav->index = 0;
|
||||||
|
|
||||||
*p = (pcm_t *)wav;
|
*p = (pcm_t *)wav;
|
||||||
return 1;
|
return 1;
|
||||||
|
|
2
wav.h
2
wav.h
|
@ -10,5 +10,5 @@ You should have received a copy of the CC0 Public Domain Dedication along with t
|
||||||
#define WAV_H
|
#define WAV_H
|
||||||
#include "pcm.h"
|
#include "pcm.h"
|
||||||
int open_wav_read(pcm_t **, char *);
|
int open_wav_read(pcm_t **, char *);
|
||||||
int open_wav_write(pcm_t **, char *, int, int);
|
int open_wav_write(pcm_t **, char *, int, int, int);
|
||||||
#endif
|
#endif
|
||||||
|
|
Ładowanie…
Reference in New Issue