libao 1.2.0 differing behaviour for 8bit audio
libao 1.1.0 behaves as expected: the amplitude is unsigned (0..255) libao 1.2.0 behaves differently: the amplitude is signed (-128..127) noticed when trying to mute a stream by using 0 for the samples for 1.2.0 you have to pass 127 to mute.
#include <unistd.h>
#include <ao/ao.h>
#include <stdlib.h>
#include <string.h>
struct AoWriter {
ao_device *device;
ao_sample_format format;
int aodriver;
};
int AoWriter_init(struct AoWriter *self) {
ao_initialize();
memset(self, 0, sizeof(*self));
self->format.bits = 8;
self->format.channels = 1;
self->format.rate = 11025;
self->format.byte_format = AO_FMT_LITTLE;
self->aodriver = ao_default_driver_id();
self->device = ao_open_live(self->aodriver, &self->format, NULL);
return self->device != NULL;
}
int AoWriter_write(struct AoWriter *self, void* buffer, size_t bufsize) {
return ao_play(self->device, buffer, bufsize);
}
int AoWriter_close(struct AoWriter *self) {
return ao_close(self->device);
}
static unsigned char blip[] = {0x52, 0x51, 0x51, 0x51, 0xC4, 0x4C, 0xF4, 0xF4, 0xF3,0xEF};
static int blip_frame(int idx) {
idx = idx % (2*sizeof(blip));
if(idx>=sizeof(blip)) idx=(2*sizeof(blip))-idx;
return blip[idx];
}
static void generate_blip(unsigned char* data, size_t bufsize, double volume) {
int i;
for(i=0;i<bufsize;i++)
/* libao 1.1.0 behaves as expected: the amplitude is unsigned (0..255)
libao 1.2.0 behaves differently: the amplitude is signed (-128..127) */
#if 1
data[i] = (blip_frame(i)-128)*volume+127;
#else
data[i] = blip_frame(i)*volume;
#endif
}
#define DEFAULT_VOLUME 0.02
int main() {
struct AoWriter ao;
AoWriter_init(&ao);
unsigned char buf[100];
generate_blip(buf, sizeof(buf), DEFAULT_VOLUME);
unsigned passed = 0;
while(1) {
usleep(1000);
passed++;
if(passed >= 200) {
passed=0;
AoWriter_write(&ao, buf, sizeof buf);
}
}
AoWriter_close(&ao);
return 0;
}