• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 SOUNDBOARD_SYNTH_H
18 #define SOUNDBOARD_SYNTH_H
19 
20 #include <array>
21 #include <TappableAudioSource.h>
22 
23 #include <SynthSound.h>
24 #include <Mixer.h>
25 #include <MonoToStereo.h>
26 
27 constexpr float kOscBaseFrequency = 196.00; // Start at G3
28 constexpr float kOscFrequencyMultiplier = 1.05946309436;
29 constexpr float kOscBaseAmplitude = 0.20;
30 constexpr float kOscAmplitudeMultiplier = 0.96;
31 
32 class Synth : public IRenderableAudio, public ITappable {
33 public:
create(const int32_t sampleRate,const int32_t channelCount,const int32_t numSignals)34     static ::std::shared_ptr<Synth> create(const int32_t sampleRate, const int32_t channelCount, const int32_t numSignals) {
35         return ::std::make_shared<Synth>(sampleRate, channelCount, numSignals);
36     }
37 
Synth(const int32_t sampleRate,const int32_t channelCount,const int32_t numSignals)38     Synth(const int32_t sampleRate, const int32_t channelCount, const int32_t numSignals) {
39         float curFrequency = kOscBaseFrequency;
40         float curAmplitude = kOscBaseAmplitude;
41         for (int i = 0; i < numSignals; ++i) {
42             mOscs[i].setSampleRate(sampleRate);
43             mOscs[i].setFrequency(curFrequency);
44             curFrequency *= kOscFrequencyMultiplier;
45             mOscs[i].setAmplitude(curAmplitude);
46             curAmplitude *= kOscAmplitudeMultiplier;
47             mMixer.addTrack(&mOscs[i]);
48         }
49 
50         if (channelCount == oboe::ChannelCount::Stereo) {
51             mOutputStage =  &mConverter;
52         } else {
53             mOutputStage = &mMixer;
54         }
55     }
56 
noteOff(int32_t noteIndex)57     void noteOff(int32_t noteIndex) {
58         mOscs[noteIndex].noteOff();
59     }
60 
noteOn(int32_t noteIndex)61     void noteOn(int32_t noteIndex) {
62         mOscs[noteIndex].noteOn();
63     }
64 
tap(bool isOn)65     void tap(bool isOn) override {
66         for (int i = 0; i < mNumSignals; i++) {
67             if (isOn) {
68                 mOscs[i].noteOn();
69             } else {
70                 mOscs[i].noteOff();
71             }
72         }
73     };
74 
75     // From IRenderableAudio
renderAudio(float * audioData,int32_t numFrames)76     void renderAudio(float *audioData, int32_t numFrames) override {
77         mOutputStage->renderAudio(audioData, numFrames);
78     };
79 
~Synth()80     virtual ~Synth() {
81     }
82 private:
83     // Rendering objects
84     int32_t mNumSignals;
85     std::array<SynthSound, kMaxTracks> mOscs;
86     Mixer mMixer;
87     MonoToStereo mConverter = MonoToStereo(&mMixer);
88     IRenderableAudio *mOutputStage; // This will point to either the mixer or converter, so it needs to be raw
89 };
90 
91 
92 #endif //SOUNDBOARD_SYNTH_H
93