1 //
2 // Copyright (C) 2020 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 #pragma once
16 
17 #include <atomic>
18 #include <cinttypes>
19 #include <functional>
20 
21 #include "host/libs/audio_connector/shm_layout.h"
22 
23 namespace cuttlefish {
24 
25 enum class Status : uint32_t {
26   Ok = 0x8000,
27   BadMessage,
28   NotSupported,
29   IOError,
30 };
31 
32 using OnConsumedCb = std::function<void(AudioStatus, uint32_t /*latency*/,
33                                         uint32_t /*consumed length*/)>;
34 
35 // Wraps and provides access to audio buffers sent by the client.
36 // Objects of this class can only be moved, not copied. Destroying a buffer
37 // without sending the status to the client is a bug so the program aborts in
38 // those cases.
39 // This class is NOT thread safe despite its use of atomic variables.
40 class ShmBuffer {
41  public:
42   ShmBuffer(const virtio_snd_pcm_xfer& header, volatile uint8_t* buffer,
43             uint32_t len, OnConsumedCb on_consumed);
44   ShmBuffer(const ShmBuffer& other) = delete;
45   ShmBuffer(ShmBuffer&& other);
46   ShmBuffer& operator=(const ShmBuffer& other) = delete;
47 
48   ~ShmBuffer();
49 
50   uint32_t stream_id() const;
len()51   uint32_t len() const { return len_; }
52 
53   void SendStatus(AudioStatus status, uint32_t latency_bytes,
54                   uint32_t consumed_len);
55 
get()56   const uint8_t* get() const { return buffer_; }
57 
58  private:
59   const virtio_snd_pcm_xfer header_;
60   const uint32_t len_;
61   OnConsumedCb on_consumed_;
62   std::atomic<bool> status_sent_ = false;
63 
64  protected:
65   uint8_t* buffer_;
66 };
67 
68 using TxBuffer = ShmBuffer;
69 // Only RxBuffer can be written to
70 class RxBuffer : public ShmBuffer {
71  public:
RxBuffer(const virtio_snd_pcm_xfer & header,volatile uint8_t * buffer,uint32_t len,OnConsumedCb on_consumed)72   RxBuffer(const virtio_snd_pcm_xfer& header, volatile uint8_t* buffer,
73            uint32_t len, OnConsumedCb on_consumed)
74       : ShmBuffer(header, buffer, len, on_consumed) {}
75 
get()76   uint8_t* get() { return buffer_; }
77 };
78 
79 }  // namespace cuttlefish
80