Home | History | Annotate | Download | only in audio
      1 // Copyright 2014 The Chromium Authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style license that can be
      3 // found in the LICENSE file.
      4 
      5 #ifndef COMPONENTS_COPRESENCE_HANDLERS_AUDIO_AUDIO_DIRECTIVE_HANDLER_H_
      6 #define COMPONENTS_COPRESENCE_HANDLERS_AUDIO_AUDIO_DIRECTIVE_HANDLER_H_
      7 
      8 #include <string>
      9 
     10 #include "base/basictypes.h"
     11 #include "base/macros.h"
     12 #include "base/memory/ref_counted.h"
     13 #include "base/time/time.h"
     14 #include "base/timer/timer.h"
     15 #include "components/copresence/handlers/audio/audio_directive_list.h"
     16 #include "components/copresence/mediums/audio/audio_recorder.h"
     17 #include "components/copresence/proto/data.pb.h"
     18 #include "components/copresence/timed_map.h"
     19 
     20 namespace media {
     21 class AudioBusRefCounted;
     22 }
     23 
     24 namespace copresence {
     25 
     26 class AudioPlayer;
     27 
     28 // The AudioDirectiveHandler handles audio transmit and receive instructions.
     29 // TODO(rkc): Currently since WhispernetClient can only have one token encoded
     30 // callback at a time, we need to have both the audible and inaudible in this
     31 // class. Investigate a better way to do this; a few options are abstracting
     32 // out token encoding to a separate class, or allowing whispernet to have
     33 // multiple callbacks for encoded tokens being sent back and have two versions
     34 // of this class.
     35 class AudioDirectiveHandler {
     36  public:
     37   typedef base::Callback<void(const std::string&,
     38                               bool,
     39                               const scoped_refptr<media::AudioBusRefCounted>&)>
     40       SamplesCallback;
     41   typedef base::Callback<void(const std::string&, bool, const SamplesCallback&)>
     42       EncodeTokenCallback;
     43 
     44   AudioDirectiveHandler(
     45       const AudioRecorder::DecodeSamplesCallback& decode_cb,
     46       const AudioDirectiveHandler::EncodeTokenCallback& encode_cb);
     47   virtual ~AudioDirectiveHandler();
     48 
     49   // Do not use this class before calling this.
     50   void Initialize();
     51 
     52   // Adds an instruction to our handler. The instruction will execute and be
     53   // removed after the ttl expires.
     54   void AddInstruction(const copresence::TokenInstruction& instruction,
     55                       const std::string& op_id,
     56                       base::TimeDelta ttl_ms);
     57 
     58   // Removes all instructions associated with this operation id.
     59   void RemoveInstructions(const std::string& op_id);
     60 
     61   // Returns the currently playing DTMF token.
     62   const std::string& PlayingAudibleToken() const {
     63     return current_token_audible_;
     64   }
     65 
     66   // Returns the currently playing DSSS token.
     67   const std::string& PlayingInaudibleToken() const {
     68     return current_token_inaudible_;
     69   }
     70 
     71   void set_player_audible_for_testing(AudioPlayer* player) {
     72     player_audible_ = player;
     73   }
     74 
     75   void set_player_inaudible_for_testing(AudioPlayer* player) {
     76     player_inaudible_ = player;
     77   }
     78 
     79   void set_recorder_for_testing(AudioRecorder* recorder) {
     80     recorder_ = recorder;
     81   }
     82 
     83  private:
     84   FRIEND_TEST_ALL_PREFIXES(AudioDirectiveHandlerTest, Basic);
     85 
     86   typedef TimedMap<std::string, scoped_refptr<media::AudioBusRefCounted>>
     87       SamplesMap;
     88 
     89   // Processes the next active transmit instruction.
     90   void ProcessNextTransmit();
     91   // Processes the next active receive instruction.
     92   void ProcessNextReceive();
     93 
     94   void PlayToken(const std::string token, bool audible);
     95 
     96   // This is the method that the whispernet client needs to call to return
     97   // samples to us.
     98   void PlayEncodedToken(
     99       const std::string& token,
    100       bool audible,
    101       const scoped_refptr<media::AudioBusRefCounted>& samples);
    102 
    103   AudioDirectiveList transmits_list_audible_;
    104   AudioDirectiveList transmits_list_inaudible_;
    105   AudioDirectiveList receives_list_;
    106 
    107   // Currently playing tokens.
    108   std::string current_token_audible_;
    109   std::string current_token_inaudible_;
    110 
    111   // AudioPlayer and AudioRecorder objects are self-deleting. When we call
    112   // Finalize on them, they clean themselves up on the Audio thread.
    113   AudioPlayer* player_audible_;
    114   AudioPlayer* player_inaudible_;
    115   AudioRecorder* recorder_;
    116 
    117   AudioRecorder::DecodeSamplesCallback decode_cb_;
    118   EncodeTokenCallback encode_cb_;
    119 
    120   base::OneShotTimer<AudioDirectiveHandler> stop_audible_playback_timer_;
    121   base::OneShotTimer<AudioDirectiveHandler> stop_inaudible_playback_timer_;
    122   base::OneShotTimer<AudioDirectiveHandler> stop_recording_timer_;
    123 
    124   // Cache that holds the encoded samples. After reaching its limit, the cache
    125   // expires the oldest samples first.
    126   SamplesMap samples_cache_audible_;
    127   SamplesMap samples_cache_inaudible_;
    128 
    129   DISALLOW_COPY_AND_ASSIGN(AudioDirectiveHandler);
    130 };
    131 
    132 }  // namespace copresence
    133 
    134 #endif  // COMPONENTS_COPRESENCE_HANDLERS_AUDIO_AUDIO_DIRECTIVE_HANDLER_H_
    135