|
1 /* |
|
2 * Copyright © 2011 Mozilla Foundation |
|
3 * |
|
4 * This program is made available under an ISC-style license. See the |
|
5 * accompanying file LICENSE for details. |
|
6 */ |
|
7 |
|
8 /* libcubeb api/function test. Plays a simple tone. */ |
|
9 #ifdef NDEBUG |
|
10 #undef NDEBUG |
|
11 #endif |
|
12 #define _XOPEN_SOURCE 500 |
|
13 #include <stdio.h> |
|
14 #include <stdlib.h> |
|
15 #include <math.h> |
|
16 #include <assert.h> |
|
17 |
|
18 #include "cubeb/cubeb.h" |
|
19 #include "common.h" |
|
20 |
|
21 #define SAMPLE_FREQUENCY 48000 |
|
22 |
|
23 /* store the phase of the generated waveform */ |
|
24 struct cb_user_data { |
|
25 long position; |
|
26 }; |
|
27 |
|
28 long data_cb(cubeb_stream *stream, void *user, void *buffer, long nframes) |
|
29 { |
|
30 struct cb_user_data *u = (struct cb_user_data *)user; |
|
31 short *b = (short *)buffer; |
|
32 int i; |
|
33 |
|
34 if (stream == NULL || u == NULL) |
|
35 return CUBEB_ERROR; |
|
36 |
|
37 /* generate our test tone on the fly */ |
|
38 for (i = 0; i < nframes; i++) { |
|
39 /* North American dial tone */ |
|
40 b[i] = 16000*sin(2*M_PI*(i + u->position)*350/SAMPLE_FREQUENCY); |
|
41 b[i] += 16000*sin(2*M_PI*(i + u->position)*440/SAMPLE_FREQUENCY); |
|
42 /* European dial tone */ |
|
43 /*b[i] = 30000*sin(2*M_PI*(i + u->position)*425/SAMPLE_FREQUENCY);*/ |
|
44 } |
|
45 /* remember our phase to avoid clicking on buffer transitions */ |
|
46 /* we'll still click if position overflows */ |
|
47 u->position += nframes; |
|
48 |
|
49 return nframes; |
|
50 } |
|
51 |
|
52 void state_cb(cubeb_stream *stream, void *user, cubeb_state state) |
|
53 { |
|
54 struct cb_user_data *u = (struct cb_user_data *)user; |
|
55 |
|
56 if (stream == NULL || u == NULL) |
|
57 return; |
|
58 |
|
59 switch (state) { |
|
60 case CUBEB_STATE_STARTED: |
|
61 printf("stream started\n"); break; |
|
62 case CUBEB_STATE_STOPPED: |
|
63 printf("stream stopped\n"); break; |
|
64 case CUBEB_STATE_DRAINED: |
|
65 printf("stream drained\n"); break; |
|
66 default: |
|
67 printf("unknown stream state %d\n", state); |
|
68 } |
|
69 |
|
70 return; |
|
71 } |
|
72 |
|
73 int main(int argc, char *argv[]) |
|
74 { |
|
75 cubeb *ctx; |
|
76 cubeb_stream *stream; |
|
77 cubeb_stream_params params; |
|
78 struct cb_user_data *user_data; |
|
79 int ret; |
|
80 |
|
81 ret = cubeb_init(&ctx, "Cubeb tone example"); |
|
82 if (ret != CUBEB_OK) { |
|
83 fprintf(stderr, "Error initializing cubeb library\n"); |
|
84 return ret; |
|
85 } |
|
86 |
|
87 params.format = CUBEB_SAMPLE_S16NE; |
|
88 params.rate = SAMPLE_FREQUENCY; |
|
89 params.channels = 1; |
|
90 |
|
91 user_data = (struct cb_user_data *) malloc(sizeof(*user_data)); |
|
92 if (user_data == NULL) { |
|
93 fprintf(stderr, "Error allocating user data\n"); |
|
94 return CUBEB_ERROR; |
|
95 } |
|
96 user_data->position = 0; |
|
97 |
|
98 ret = cubeb_stream_init(ctx, &stream, "Cubeb tone (mono)", params, |
|
99 250, data_cb, state_cb, user_data); |
|
100 if (ret != CUBEB_OK) { |
|
101 fprintf(stderr, "Error initializing cubeb stream\n"); |
|
102 return ret; |
|
103 } |
|
104 |
|
105 cubeb_stream_start(stream); |
|
106 delay(500); |
|
107 cubeb_stream_stop(stream); |
|
108 |
|
109 cubeb_stream_destroy(stream); |
|
110 cubeb_destroy(ctx); |
|
111 |
|
112 assert(user_data->position); |
|
113 |
|
114 free(user_data); |
|
115 |
|
116 return CUBEB_OK; |
|
117 } |