OSDN Git Service

Add readme
[cinnamon-audio/cinnamon.git] / sine_test.c
1 /*
2  * Any copyright is dedicated to the Public Domain.
3  * http://creativecommons.org/publicdomain/zero/1.0/
4  */
5
6 #define _POSIX_C_SOURCE 199309L
7
8 #include "cin_driver.h"
9 #include "cin_loader.h"
10 #include "cin_sound.h"
11
12 #include <assert.h>
13 #include <stdlib.h>
14 #include <stdio.h>
15 #include <math.h>
16
17 /* Get a sleep function. */
18 #ifdef _WIN32
19 #define WIN32_LEAN_AND_MEAN
20 #include <Windows.h>
21 #else
22 #include <time.h>
23 #include <unistd.h>
24 #endif
25
26 #ifndef M_PI
27 #define M_PI 3.14159265f
28 #endif
29
30 int main(int argc, char **argv){
31     struct Cin_Driver *const driver = malloc(Cin_StructDriverSize());
32     if(driver == NULL){
33         puts("Could not allocate driver.");
34         return EXIT_FAILURE;
35     }
36     
37     (void)argc;
38     (void)argv;
39     
40     assert(Cin_StructDriverSize() > 0);
41     assert(Cin_StructLoaderSize() > 0);
42     assert(Cin_StructSoundSize() > 0);
43     
44     if(driver == NULL || Cin_CreateDriver(driver) == Cin_eDriverSuccess){
45         struct Cin_Loader *const loader = malloc(Cin_StructLoaderSize());
46         struct Cin_Sound *const sound = malloc(Cin_StructSoundSize());
47         
48         /* TODO: Make these configurable */
49         unsigned num_channels = 2,
50             sample_rate = 48000,
51             sin_frequency = 440,
52             num_seconds = 11;
53         
54         /* Times two for the size of int16_t */
55         const unsigned data_size = sample_rate * num_channels << 1;
56         short *const data = malloc(data_size);
57         
58         if(!(loader != NULL && sound != NULL && data != NULL)){
59             if(!loader)
60                 puts("Could not allocate loader.");
61             if(!sound)
62                 puts("Could not allocate sound.");
63             if(!data)
64                 puts("Could not allocate buffer for generating audio.");
65             free(loader);
66             free(sound);
67             free(data);
68             Cin_DestroyDriver(driver);
69             free(driver);
70             return EXIT_FAILURE;
71         }
72         
73         {
74             const enum Cin_LoaderError err =
75                 Cin_CreateLoader(loader,
76                     driver,
77                     sample_rate,
78                     num_channels,
79                     Cin_eFormatS16);
80             if(err != Cin_eLoaderSuccess){
81                 free(loader);
82                 free(sound);
83                 free(data);
84                 Cin_DestroyDriver(driver);
85                 free(driver);
86                 puts("Could not create loader.");
87                 return EXIT_FAILURE;
88             }
89         }
90         
91         {
92             const float multiplier = M_PI * 2 * (float)sin_frequency;
93             unsigned i;
94             /* Create one second of 44100 Hz audio */
95             /* We want to cycle sequence 440 times a second. */
96             for(i = 0; i < sample_rate; i++){
97                 const float sequence =
98                     multiplier * (float)i / (float)sample_rate;
99                 const float sample = sinf(sequence) * (float)(0xFFFF >> 1);
100                 const unsigned at = i * num_channels;
101                 data[at] = data[at + 1] = (short)(sample * 0.1);
102             }
103             
104             /* Put the second once for each second of data we want to play. */
105             for(i = 0; i < num_seconds; i++){
106                 Cin_LoaderPut(loader, data, data_size);
107             }
108         }
109         
110         /* Create a new sound from this loader. */
111         {
112             const enum Cin_LoaderError err =
113                 Cin_LoaderFinalize(loader, sound);
114             
115             free(loader);
116             free(data);
117             
118             if(err != Cin_eLoaderSuccess){
119                 free(sound);
120                 Cin_DestroyDriver(driver);
121                 free(driver);
122                 puts("Could not create sound.");
123                 return EXIT_FAILURE;
124             }
125         }
126         
127         puts("Playing");
128         Cin_SoundPlay(sound);
129         
130 #ifdef _WIN32
131         Sleep((1000 * num_seconds) + 1);
132 #else
133         {
134             struct timespec t;
135             t.tv_sec = num_seconds;
136             t.tv_nsec = 1;
137             nanosleep(&t, NULL);
138         }
139 #endif
140         
141         Cin_SoundStop(sound);
142         Cin_DestroySound(sound);
143         free(sound);
144     }
145     else{
146         puts("Could not create driver.");
147         return EXIT_FAILURE;
148     }
149     
150     Cin_DestroyDriver(driver);
151     free(driver);
152     return EXIT_SUCCESS;
153 }