1 // Copyright 2014 Olivier Gillet.
2 //
3 // Author: Olivier Gillet (ol.gillet@gmail.com)
4 //
5 // Permission is hereby granted, free of charge, to any person obtaining a copy
6 // of this software and associated documentation files (the "Software"), to deal
7 // in the Software without restriction, including without limitation the rights
8 // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 // copies of the Software, and to permit persons to whom the Software is
10 // furnished to do so, subject to the following conditions:
11 //
12 // The above copyright notice and this permission notice shall be included in
13 // all copies or substantial portions of the Software.
14 //
15 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21 // THE SOFTWARE.
22 //
23 // See http://creativecommons.org/licenses/MIT/ for more information.
24 //
25 // -----------------------------------------------------------------------------
26
27
28 #include <cassert>
29 #include <cmath>
30 #include <cstdlib>
31 #include <cstring>
32 #include <vector>
33 #include <xmmintrin.h>
34
35 #include "clouds/dsp/granular_processor.h"
36 #include "clouds/resources.h"
37
38 using namespace clouds;
39 using namespace std;
40 using namespace stmlib;
41
42 const size_t kSampleRate = 32000;
43 const size_t kBlockSize = 32;
44
write_wav_header(FILE * fp,int num_samples,int num_channels)45 void write_wav_header(FILE* fp, int num_samples, int num_channels) {
46 uint32_t l;
47 uint16_t s;
48
49 fwrite("RIFF", 4, 1, fp);
50 l = 36 + num_samples * 2 * num_channels;
51 fwrite(&l, 4, 1, fp);
52 fwrite("WAVE", 4, 1, fp);
53
54 fwrite("fmt ", 4, 1, fp);
55 l = 16;
56 fwrite(&l, 4, 1, fp);
57 s = 1;
58 fwrite(&s, 2, 1, fp);
59 s = num_channels;
60 fwrite(&s, 2, 1, fp);
61 l = kSampleRate;
62 fwrite(&l, 4, 1, fp);
63 l = static_cast<uint32_t>(kSampleRate) * 2 * num_channels;
64 fwrite(&l, 4, 1, fp);
65 s = 2 * num_channels;
66 fwrite(&s, 2, 1, fp);
67 s = 16;
68 fwrite(&s, 2, 1, fp);
69
70 fwrite("data", 4, 1, fp);
71 l = num_samples * 2 * num_channels;
72 fwrite(&l, 4, 1, fp);
73 }
74
TestDSP()75 void TestDSP() {
76 size_t duration = 15;
77
78 FILE* fp_in = fopen("audio_samples/sine.wav", "rb");
79 FILE* fp_out = fopen("clouds.wav", "wb");
80
81 size_t remaining_samples = kSampleRate * duration;
82 write_wav_header(fp_out, remaining_samples, 2);
83 fseek(fp_in, 48, SEEK_SET);
84
85 uint8_t large_buffer[118784];
86 uint8_t small_buffer[65536 - 128];
87
88 GranularProcessor processor;
89 processor.Init(
90 &large_buffer[0], sizeof(large_buffer),
91 &small_buffer[0],sizeof(small_buffer));
92
93 processor.set_num_channels(2);
94 processor.set_low_fidelity(false);
95 processor.set_playback_mode(PLAYBACK_MODE_GRANULAR);
96
97 Parameters* p = processor.mutable_parameters();
98
99 size_t block_counter = 0;
100 float phase_ = 0.0f;
101 bool synthetic = false;
102 processor.Prepare();
103 float pot_noise = 0.0f;
104 while (remaining_samples) {
105 // uint16_t tri = (remaining_samples * 0.4);
106 // tri = tri > 32767 ? 65535 - tri : tri;
107 // float triangle = tri / 32768.0f;
108
109 p->gate = false;
110 p->trigger = false;// || (block_counter & 2047) > 1024;
111 p->freeze = false; // || (block_counter & 2047) > 1024;
112 p->granular.reverse = true;
113 pot_noise += 0.05f * ((Random::GetSample() / 32768.0f) * 0.05f - pot_noise);
114 p->position = Random::GetFloat();//triangle * 0.0f + 0.5f;
115 p->size = Random::GetFloat();//0.99f;
116 p->pitch = Random::GetFloat() * 24.0f; //0.0f + (triangle > 0.5f ? 1.0f : 0.0f) * 0.0f;
117 p->density = 0.99f;
118 p->texture = 0.7f;
119 p->dry_wet = 1.0f;
120 p->stereo_spread = 0.0f;
121 p->feedback = 0.0f;
122 p->reverb = 0.0f;
123
124 ++block_counter;
125 ShortFrame input[kBlockSize];
126 ShortFrame output[kBlockSize];
127
128 if (synthetic) {
129 for (size_t i = 0; i < kBlockSize; ++i) {
130 phase_ += 400.0f / kSampleRate; // (block_counter & 512 ? 110.0f : 220.0f) / kSampleRate;
131 while (phase_ >= 1.0) {
132 phase_ -= 1.0;
133 }
134 input[i].l = 16384.0f * sinf(phase_ * M_PI * 2);
135 input[i].r = 32768.0f * (phase_ - 0.5);
136 // input[i].r = input[i].l = 0;
137 }
138 remaining_samples -= kBlockSize;
139 } else {
140 if (fread(
141 input,
142 sizeof(ShortFrame),
143 kBlockSize,
144 fp_in) != kBlockSize) {
145 break;
146 }
147 remaining_samples -= kBlockSize;
148 }
149 processor.Process(input, output, kBlockSize);
150 processor.Prepare();
151 fwrite(output, sizeof(ShortFrame), kBlockSize, fp_out);
152 }
153 fclose(fp_out);
154 fclose(fp_in);
155 }
156
main(void)157 int main(void) {
158 _MM_SET_FLUSH_ZERO_MODE(_MM_FLUSH_ZERO_ON);
159 TestDSP();
160 // TestGrainSize();
161 }
162