michael@0: /* michael@0: * Copyright © 2011 Mozilla Foundation michael@0: * michael@0: * This program is made available under an ISC-style license. See the michael@0: * accompanying file LICENSE for details. michael@0: */ michael@0: michael@0: /* libcubeb api/function test. Plays a simple tone. */ michael@0: #ifdef NDEBUG michael@0: #undef NDEBUG michael@0: #endif michael@0: #define _XOPEN_SOURCE 500 michael@0: #include michael@0: #include michael@0: #include michael@0: #include michael@0: michael@0: #include "cubeb/cubeb.h" michael@0: #include "common.h" michael@0: michael@0: #define SAMPLE_FREQUENCY 48000 michael@0: michael@0: /* store the phase of the generated waveform */ michael@0: struct cb_user_data { michael@0: long position; michael@0: }; michael@0: michael@0: long data_cb(cubeb_stream *stream, void *user, void *buffer, long nframes) michael@0: { michael@0: struct cb_user_data *u = (struct cb_user_data *)user; michael@0: short *b = (short *)buffer; michael@0: int i; michael@0: michael@0: if (stream == NULL || u == NULL) michael@0: return CUBEB_ERROR; michael@0: michael@0: /* generate our test tone on the fly */ michael@0: for (i = 0; i < nframes; i++) { michael@0: /* North American dial tone */ michael@0: b[i] = 16000*sin(2*M_PI*(i + u->position)*350/SAMPLE_FREQUENCY); michael@0: b[i] += 16000*sin(2*M_PI*(i + u->position)*440/SAMPLE_FREQUENCY); michael@0: /* European dial tone */ michael@0: /*b[i] = 30000*sin(2*M_PI*(i + u->position)*425/SAMPLE_FREQUENCY);*/ michael@0: } michael@0: /* remember our phase to avoid clicking on buffer transitions */ michael@0: /* we'll still click if position overflows */ michael@0: u->position += nframes; michael@0: michael@0: return nframes; michael@0: } michael@0: michael@0: void state_cb(cubeb_stream *stream, void *user, cubeb_state state) michael@0: { michael@0: struct cb_user_data *u = (struct cb_user_data *)user; michael@0: michael@0: if (stream == NULL || u == NULL) michael@0: return; michael@0: michael@0: switch (state) { michael@0: case CUBEB_STATE_STARTED: michael@0: printf("stream started\n"); break; michael@0: case CUBEB_STATE_STOPPED: michael@0: printf("stream stopped\n"); break; michael@0: case CUBEB_STATE_DRAINED: michael@0: printf("stream drained\n"); break; michael@0: default: michael@0: printf("unknown stream state %d\n", state); michael@0: } michael@0: michael@0: return; michael@0: } michael@0: michael@0: int main(int argc, char *argv[]) michael@0: { michael@0: cubeb *ctx; michael@0: cubeb_stream *stream; michael@0: cubeb_stream_params params; michael@0: struct cb_user_data *user_data; michael@0: int ret; michael@0: michael@0: ret = cubeb_init(&ctx, "Cubeb tone example"); michael@0: if (ret != CUBEB_OK) { michael@0: fprintf(stderr, "Error initializing cubeb library\n"); michael@0: return ret; michael@0: } michael@0: michael@0: params.format = CUBEB_SAMPLE_S16NE; michael@0: params.rate = SAMPLE_FREQUENCY; michael@0: params.channels = 1; michael@0: michael@0: user_data = (struct cb_user_data *) malloc(sizeof(*user_data)); michael@0: if (user_data == NULL) { michael@0: fprintf(stderr, "Error allocating user data\n"); michael@0: return CUBEB_ERROR; michael@0: } michael@0: user_data->position = 0; michael@0: michael@0: ret = cubeb_stream_init(ctx, &stream, "Cubeb tone (mono)", params, michael@0: 250, data_cb, state_cb, user_data); michael@0: if (ret != CUBEB_OK) { michael@0: fprintf(stderr, "Error initializing cubeb stream\n"); michael@0: return ret; michael@0: } michael@0: michael@0: cubeb_stream_start(stream); michael@0: delay(500); michael@0: cubeb_stream_stop(stream); michael@0: michael@0: cubeb_stream_destroy(stream); michael@0: cubeb_destroy(ctx); michael@0: michael@0: assert(user_data->position); michael@0: michael@0: free(user_data); michael@0: michael@0: return CUBEB_OK; michael@0: }