1 /*
2  * Copyright 2018 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #ifndef MEGADRONE_SYNTH_H
18 #define MEGADRONE_SYNTH_H
19 
20 #include <array>
21 #include <TappableAudioSource.h>
22 
23 #include <Oscillator.h>
24 #include <Mixer.h>
25 #include <MonoToStereo.h>
26 
27 constexpr int kNumOscillators = 100;
28 constexpr float kOscBaseFrequency = 116.0;
29 constexpr float kOscDivisor = 33;
30 constexpr float kOscAmplitude = 0.009;
31 
32 
33 class Synth : public TappableAudioSource {
34 public:
35 
Synth(int32_t sampleRate,int32_t channelCount)36     Synth(int32_t sampleRate, int32_t channelCount) :
37     TappableAudioSource(sampleRate, channelCount) {
38         for (int i = 0; i < kNumOscillators; ++i) {
39             mOscs[i].setSampleRate(mSampleRate);
40             mOscs[i].setFrequency(kOscBaseFrequency + (static_cast<float>(i) / kOscDivisor));
41             mOscs[i].setAmplitude(kOscAmplitude);
42             mMixer.addTrack(&mOscs[i]);
43         }
44         if (mChannelCount == oboe::ChannelCount::Stereo) {
45             mOutputStage =  &mConverter;
46         } else {
47             mOutputStage = &mMixer;
48         }
49     }
50 
tap(bool isOn)51     void tap(bool isOn) override {
52         for (auto &osc : mOscs) osc.setWaveOn(isOn);
53     };
54 
55     // From IRenderableAudio
renderAudio(float * audioData,int32_t numFrames)56     void renderAudio(float *audioData, int32_t numFrames) override {
57         mOutputStage->renderAudio(audioData, numFrames);
58     };
59 
~Synth()60     virtual ~Synth() {
61     }
62 private:
63     // Rendering objects
64     std::array<Oscillator, kNumOscillators> mOscs;
65     Mixer mMixer;
66     MonoToStereo mConverter = MonoToStereo(&mMixer);
67     IRenderableAudio *mOutputStage; // This will point to either the mixer or converter, so it needs to be raw
68 };
69 
70 
71 #endif //MEGADRONE_SYNTH_H
72