Wave recording and playback now uses multi channels

This commit is contained in:
Andreas Eversberg
2017-01-13 07:31:15 +01:00
parent 2d8d7e62c1
commit 19b396ab4d
7 changed files with 201 additions and 67 deletions

View File

@@ -33,7 +33,7 @@ struct fmt {
uint16_t bits_sample; /* bits per sample (one channel) */
};
int wave_create_record(wave_rec_t *rec, const char *filename, int samplerate)
int wave_create_record(wave_rec_t *rec, const char *filename, int samplerate, int channels)
{
/* RIFFxxxxWAVEfmt xxxx(fmt size)dataxxxx... */
char dummyheader[4 + 4 + 4 + 4 + 4 + sizeof(struct fmt) + 4 + 4];
@@ -41,6 +41,7 @@ int wave_create_record(wave_rec_t *rec, const char *filename, int samplerate)
memset(rec, 0, sizeof(*rec));
rec->samplerate = samplerate;
rec->channels = channels;
rec->fp = fopen(filename, "w");
if (!rec->fp) {
@@ -56,7 +57,7 @@ int wave_create_record(wave_rec_t *rec, const char *filename, int samplerate)
return 0;
}
int wave_create_playback(wave_play_t *play, const char *filename, int samplerate)
int wave_create_playback(wave_play_t *play, const char *filename, int samplerate, int channels)
{
uint8_t buffer[256];
struct fmt fmt;
@@ -65,6 +66,7 @@ int wave_create_playback(wave_play_t *play, const char *filename, int samplerate
int rc = -EINVAL;
memset(play, 0, sizeof(*play));
play->channels = channels;
play->fp = fopen(filename, "r");
if (!play->fp) {
@@ -153,8 +155,8 @@ int wave_create_playback(wave_play_t *play, const char *filename, int samplerate
rc = -EINVAL;
goto error;
}
if (fmt.channels != 1) {
fprintf(stderr, "WAVE error: We support only mono files!\n");
if (fmt.channels !=channels) {
fprintf(stderr, "WAVE error: We expect %d cannel(s), but wave file only has %d channel(s)\n", channels, fmt.channels);
rc = -EINVAL;
goto error;
}
@@ -163,13 +165,23 @@ int wave_create_playback(wave_play_t *play, const char *filename, int samplerate
rc = -EINVAL;
goto error;
}
if ((int)fmt.data_rate != 2 * channels * samplerate) {
fprintf(stderr, "WAVE error: The WAVE file's data rate is only %d bytes per second, but we expect %d bytes per second (2 bytes per sample * channels * samplerate)!\n", fmt.data_rate, 2 * channels * samplerate);
rc = -EINVAL;
goto error;
}
if (fmt.bytes_sample != 2 * channels) {
fprintf(stderr, "WAVE error: The WAVE file's bytes per sample is only %d, but we expect %d bytes sample (2 bytes per sample * channels)!\n", fmt.bytes_sample, 2 * channels);
rc = -EINVAL;
goto error;
}
if (fmt.bits_sample != 16) {
fprintf(stderr, "WAVE error: We support only 16 bit files!\n");
rc = -EINVAL;
goto error;
}
play->left = chunk >> 1;
play->left = chunk / 2 / channels;
printf("*** Replacing received audio by %s.\n", filename);
@@ -181,14 +193,15 @@ error:
return rc;
}
int wave_read(wave_play_t *play, int16_t *samples, int length)
int wave_read(wave_play_t *play, int16_t **samples, int length)
{
uint8_t *buffer = (uint8_t *)samples;
uint8_t buff[2 * length * play->channels];
int __attribute__((__unused__)) len;
int i;
int i, j, c;
if (length > (int)play->left) {
memset(samples, 0, length << 1);
for (c = 0; c < play->channels; c++)
memset(samples[c], 0, 2 * length);
length = play->left;
}
if (!length)
@@ -199,28 +212,31 @@ int wave_read(wave_play_t *play, int16_t *samples, int length)
printf("*** Finished reading WAVE file.\n");
/* read and correct endiness */
len = fread(samples, 1, length << 1, play->fp);
for (i = 0; i < length; i++) {
*samples++ = buffer[0] + (buffer[1] << 8);
buffer += 2;
len = fread(buff, 1, 2 * length * play->channels, play->fp);
for (i = 0, j = 0; i < length; i++) {
for (c = 0; c < play->channels; c++) {
samples[c][i] = buff[j] + (buff[j + 1] << 8);
j += 2;
}
}
return length;
}
int wave_write(wave_rec_t *rec, int16_t *samples, int length)
int wave_write(wave_rec_t *rec, int16_t **samples, int length)
{
uint8_t buffer[length << 1];
uint8_t buff[2 * length * rec->channels];
int __attribute__((__unused__)) len;
int i, j;
int i, j, c;
/* write and correct endiness */
for (i = 0, j = 0; i < length; i++) {
buffer[j++] = *samples;
buffer[j++] = (*samples) >> 8;
samples++;
for (c = 0; c < rec->channels; c++) {
buff[j++] = samples[c][i];
buff[j++] = samples[c][i] >> 8;
}
}
len = fwrite(buffer, 1, length << 1, rec->fp);
len = fwrite(buff, 1, 2 * length * rec->channels, rec->fp);
rec->written += length;
return length;
@@ -245,7 +261,7 @@ void wave_destroy_record(wave_rec_t *rec)
/* go to header */
fseek(rec->fp, 0, SEEK_SET);
size = rec->written << 1;
size = 2 * rec->written * rec->channels;
wsize = 4 + 8 + sizeof(fmt) + 8 + size + 8 + 4 + 8 + 4;
/* RIFF */
@@ -257,10 +273,10 @@ void wave_destroy_record(wave_rec_t *rec)
/* fmt */
fprintf(rec->fp, "fmt %c%c%c%c", (uint8_t)sizeof(fmt), 0, 0, 0);
fmt.format = 1;
fmt.channels = 1;
fmt.channels = rec->channels;
fmt.sample_rate = rec->samplerate; /* samples/sec */
fmt.data_rate = rec->samplerate * 2; /* full data rate */
fmt.bytes_sample = 2; /* all channels */
fmt.data_rate = rec->samplerate * 2 * rec->channels; /* full data rate */
fmt.bytes_sample = 2 * rec->channels; /* all channels */
fmt.bits_sample = 16; /* one channel */
buffer[0] = fmt.format;
buffer[1] = fmt.format >> 8;