RDK Documentation (Open Sourced RDK Components)
acm_iarm_interface.cpp
1 /*
2  * If not stated otherwise in this file or this component's Licenses.txt file the
3  * following copyright and licenses apply:
4  *
5  * Copyright 2016 RDK Management
6  *
7  * Licensed under the Apache License, Version 2.0 (the "License");
8  * you may not use this file except in compliance with the License.
9  * You may obtain a copy of the License at
10  *
11  * http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18 */
19 #include "acm_iarm_interface.h"
20 #include "audiocapturemgr_iarm.h"
21 #include <string>
22 #include <string.h>
23 #include <sstream>
24 #include "libIARM.h"
25 #include "libIBus.h"
26 #include "safec_lib.h"
27 
28 using namespace audiocapturemgr;
29 
30 
31 
32 static acm_iarm_interface g_singleton;
33 
34 static unsigned int ticker = 0;
35 std::string audio_filename_prefix = AUDIOCAPTUREMGR_FILENAME_PREFIX;
36 std::string audio_file_path = AUDIOCAPTUREMGR_FILE_PATH;
37 static std::string get_suffix()
38 {
39  std::ostringstream stream;
40  stream << ticker++;
41  std::string outstring = stream.str();
42  return outstring;
43 }
44 
45 static void request_callback(void * data, std::string &file, int result)
46 {
47  errno_t rc = -1;
48  if(0 != result)
49  {
50  ERROR("Failed to grab sample.\n");
51  }
52  else
53  {
55  rc = strcpy_s(payload.dataLocator, sizeof(payload.dataLocator), file.c_str());
56  if(rc == EOK)
57  {
58  int ret = IARM_Bus_BroadcastEvent(IARMBUS_AUDIOCAPTUREMGR_NAME, DATA_CAPTURE_IARM_EVENT_AUDIO_CLIP_READY, &payload, sizeof(payload));
59  REPORT_IF_UNEQUAL(IARM_RESULT_SUCCESS, ret);
60  }
61  else
62  {
63  ERR_CHK(rc);
64  WARN("Incoming filename is too big for payload buffer.\n");
65  }
66  }
67 }
68 
69 static IARM_Result_t enable_capture(void * arg)
70 {
71  g_singleton.enable_capture_handler(arg);
72  return IARM_RESULT_SUCCESS;
73 }
74 static IARM_Result_t request_sample(void * arg)
75 {
76  g_singleton.get_sample_handler(arg);
77  return IARM_RESULT_SUCCESS;
78 }
79 
80 acm_iarm_interface::acm_iarm_interface() : m_is_active(false), m_enable_audio_input(false), m_client(NULL)
81 {
82  INFO("Enter\n");
83 }
84 acm_iarm_interface::~acm_iarm_interface()
85 {
86  INFO("Enter\n");
87 }
88 
89 acm_iarm_interface * acm_iarm_interface::get_instance()
90 {
91  return &g_singleton;
92 }
93 
95 {
96  int ret;
97  INFO("Enter\n");
98  if(NULL != m_client)
99  {
100  ERROR("ACM IARM interface is already in use by another client.\n");
101  ret = -1;
102  }
103  else
104  {
105  m_client = client;
106  }
107 
108  //TODO: add early exit for each of the failures below
109  ret = IARM_Bus_Init(IARMBUS_AUDIOCAPTUREMGR_NAME);
110  REPORT_IF_UNEQUAL(IARM_RESULT_SUCCESS, ret);
111 
112  ret = IARM_Bus_Connect();
113  REPORT_IF_UNEQUAL(IARM_RESULT_SUCCESS, ret);
114 
115  ret = IARM_Bus_RegisterEvent(IARMBUS_MAX_ACM_EVENT);
116  REPORT_IF_UNEQUAL(IARM_RESULT_SUCCESS, ret);
117 
118  ret = IARM_Bus_RegisterCall(IARMBUS_AUDIOCAPTUREMGR_ENABLE, enable_capture);
119  REPORT_IF_UNEQUAL(IARM_RESULT_SUCCESS, ret);
120 
121  ret = IARM_Bus_RegisterCall(IARMBUS_AUDIOCAPTUREMGR_REQUEST_SAMPLE, request_sample);
122  REPORT_IF_UNEQUAL(IARM_RESULT_SUCCESS, ret);
123 
124  return ret;
125 }
127 {
128  int ret;
129  INFO("Enter\n");
130  ret = IARM_Bus_Disconnect();
131  REPORT_IF_UNEQUAL(IARM_RESULT_SUCCESS, ret);
132  ret = IARM_Bus_Term();
133  REPORT_IF_UNEQUAL(IARM_RESULT_SUCCESS, ret);
134  if(m_enable_audio_input)
135  {
136  m_client->stop();
137  m_enable_audio_input = false;
138  }
139  m_client = NULL;
140  return ret;
141 }
142 
144 {
145  iarmbus_enable_payload_t *data = static_cast <iarmbus_enable_payload_t *> (arg);
146  unsigned int incoming_duration = static_cast <int> (data->max_duration);
147  unsigned int max_supported_duration = m_client->get_max_supported_duration();
148 
149  if(incoming_duration > max_supported_duration)
150  {
151  ERROR("Incoming duration %d is too long.\n", incoming_duration);
152  data->result = max_supported_duration; // Return the max supported duration if incoming value is too high.
153  }
154  else
155  {
156  //TODO: if incoming is 0, turn off precapturing. If it isn't, turn it back on and set duration.
157  m_client->set_precapture_duration(incoming_duration);
158  if(0 == incoming_duration)
159  {
160  if(true == m_enable_audio_input)
161  {
162  INFO("Disabling audio capture.\n");
163  m_client->stop();
164  m_enable_audio_input = false;
165  }
166  }
167  else if(false == m_enable_audio_input)
168  {
169  INFO("Enabling audio capture.\n");
170  m_client->start();
171  m_enable_audio_input = true;
172  }
173  data->result = ACM_RESULT_SUCCESS;
174  }
175  return 0;
176 }
177 
178 
180 {
181  int ret = 0;
182  iarmbus_request_payload_t *data = static_cast <iarmbus_request_payload_t *> (arg);
183  if(false == m_enable_audio_input)
184  {
185  ERROR("Audio capture is currently disabled!\n");
186  data->result = ACM_RESULT_DURATION_OUT_OF_BOUNDS;
187  return 0;
188  }
189  data->result = ACM_RESULT_SUCCESS;
190  std::string filename = audio_file_path + audio_filename_prefix + get_suffix();
191 
192  if(data->is_precapture)
193  {
194  ret = m_client->grab_precaptured_sample(filename);
195  if(0 == ret)
196  {
197  /* Precapture is immediate. Notify now.*/
198  request_callback(NULL, filename, 0);
199  }
200  }
201  else
202  {
203  unsigned int duration = static_cast <unsigned int> (data->duration);
204  if(duration <= m_client->get_max_supported_duration())
205  {
206  ret = m_client->grab_fresh_sample(filename, duration, &request_callback, NULL);
207  }
208  else
209  {
210  ERROR("Duration out of bounds!\n");
211  data->result = ACM_RESULT_DURATION_OUT_OF_BOUNDS;
212  }
213  }
214  /*Note: tricky condition check. ret is also zero if it's an out-of-bounds error,
215  * but in that case, result is already updated.*/
216  if(0 != ret)
217  {
218  data->result = ACM_RESULT_GENERAL_FAILURE;
219  }
220  return 0;
221 }
222 
224 {
225  audio_filename_prefix = prefix;
226 }
music_id_client::grab_fresh_sample
request_id_t grab_fresh_sample(unsigned int seconds, const std::string &filename=nullptr, request_complete_callback_t cb=nullptr, void *cb_data=nullptr)
This API requests for new sample.
Definition: music_id.cpp:285
music_id_client
Definition: music_id.h:37
IARM_Bus_Term
IARM_Result_t IARM_Bus_Term(void)
This API is used to terminate the IARM-Bus library.
acm_iarm_interface::deactivate
int deactivate()
This API disconnects application from the message bus, releases memory.
Definition: acm_iarm_interface.cpp:126
music_id_client::set_precapture_duration
int set_precapture_duration(unsigned int seconds)
This API is used to set the precapture duration.
Definition: music_id.cpp:100
acm_iarm_interface::activate
int activate(music_id_client *client)
This API initialize the message bus, registers event, RPC methods that can be used by other applicati...
Definition: acm_iarm_interface.cpp:94
acm_iarm_interface::set_filename_prefix
void set_filename_prefix(std::string &prefix)
Function to add prefix to the audio filename.
Definition: acm_iarm_interface.cpp:223
music_id_client::grab_precaptured_sample
int grab_precaptured_sample(const std::string &filename=nullptr)
This API writes the precaptured sample to a file for file mode and in socket mode,...
Definition: music_id.cpp:185
IARM_Bus_RegisterEvent
IARM_Result_t IARM_Bus_RegisterEvent(IARM_EventId_t maxEventId)
This API is used to register all the events that are published by the application.
IARM_Bus_RegisterCall
IARM_Result_t IARM_Bus_RegisterCall(const char *methodName, IARM_BusCall_t handler)
This API is used to register an RPC method that can be invoked by other applications.
acm_iarm_interface
Definition: acm_iarm_interface.h:26
acm_iarm_interface::enable_capture_handler
int enable_capture_handler(void *arg)
This API starts the audio capture.
Definition: acm_iarm_interface.cpp:143
IARM_Bus_Disconnect
IARM_Result_t IARM_Bus_Disconnect(void)
This API disconnect Application from IARM Bus so the application will not receive any IARM event or R...
IARM_Bus_BroadcastEvent
IARM_Result_t IARM_Bus_BroadcastEvent(const char *ownerName, IARM_EventId_t eventId, void *data, size_t len)
This API is used to publish an Asynchronous event to all IARM client registered for this perticular e...
libIBus.h
RDK IARM-Bus API Declarations.
iarmbus_notification_payload_t
Definition: audiocapturemgr_iarm.h:130
music_id_client::get_max_supported_duration
unsigned int get_max_supported_duration()
This API returns maximum precaptured length.
Definition: music_id.cpp:490
iarmbus_enable_payload_t
Definition: audiocapturemgr_iarm.h:107
acm_iarm_interface::get_sample_handler
int get_sample_handler(void *arg)
This API grabs the precaptured sample, if the requested data has precapture flag true....
Definition: acm_iarm_interface.cpp:179
IARM_Bus_Connect
IARM_Result_t IARM_Bus_Connect(void)
This API is used to connect application to the IARM bus daemon. After connected, the application can ...
Definition: iarmMgrMocks.cpp:33
iarmbus_request_payload_t
Definition: audiocapturemgr_iarm.h:124
IARM_Bus_Init
IARM_Result_t IARM_Bus_Init(const char *name)
This API is used to initialize the IARM-Bus library.
Definition: iarmMgrMocks.cpp:38