Tizen 2.1 base
[sdk/ide/native-sample.git] / samples / native / cpp / Sample / Tizen C++ / MediaApp / MediaApp / project / src / Audio / AudioInOut.cpp
1 //
2 // Tizen C++ SDK
3 // Copyright (c) 2012 Samsung Electronics Co., Ltd.
4 //
5 // Licensed under the Flora License, Version 1.0 (the License);
6 // you may not use this file except in compliance with the License.
7 // You may obtain a copy of the License at
8 //
9 //     http://www.tizenopensource.org/license
10 //
11 // Unless required by applicable law or agreed to in writing, software
12 // distributed under the License is distributed on an AS IS BASIS,
13 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 // See the License for the specific language governing permissions and
15 // limitations under the License.
16 //
17
18 #include <FApp.h>
19 #include <iostream>
20
21 #include "AudioInOut.h"
22 #include "SafeMacros.h"
23 #include "UnitTestFactory.h"
24
25 using namespace Osp::Base;
26 using namespace Osp::Ui;
27 using namespace Osp::Ui::Controls;
28 using namespace Osp::Io;
29 using namespace Osp::System;
30 using namespace Osp::App;
31
32 #define ENABLE_PROGRESS_BAR
33
34 using namespace Osp::Media;
35
36 MULTI_FORM_REGISTER(AudioInOut, L"AudioInOut");
37 DECLARE_TC(L"Audio", L"2.AudioInOut", AudioInOut::TestFunc, 0);
38
39 static int sampleRate[] = { 0, 8000, 14025, 22050, 32000, 44056, 44100, 47250, 48000};
40
41
42 result
43 AudioInOut::TestFunc(void* pParam)
44 {
45         MultiForm::ActivateForm(L"AudioInOut", pParam, MultiForm::GetCurrentForm(), null);
46         return E_SUCCESS;
47 }
48
49 AudioInOut::AudioInOut(void)
50 {
51         AppLog("Enter");
52         __pAudioIn = null;
53         __pAudioOut = null;
54         __buffCnt = 0;
55         __buffIndex = 0;
56         __fileSize = 0;
57         __pFile = null;
58         __checkInitFiniPair = false;
59         __checkInitFiniPairOut = false;
60         __sampleBitDepth = AUDIO_TYPE_NONE;
61         __sampleChannelType = AUDIO_CHANNEL_TYPE_NONE;
62         __sampleRate = 0;
63         __maxFileSize = 0;
64         __pCheckButtonCT1 = null;
65         __pCheckButtonCT2 = null;
66         __pCheckButtonSB1 = null;
67         __pCheckButtonSB2 = null;
68         __pSlider = null;
69         __isRecording = false;
70         __recordedTime = 0;
71 #ifdef ENABLE_PROGRESS_BAR
72         __pProgress = null;
73         __pLabelTotatTime = null;
74         __pLabelInitialTime = null;
75 #endif
76         memset(__footerActionId, 0, sizeof(__footerActionId));
77 }
78
79 AudioInOut::~AudioInOut(void)
80 {
81         AppLog("Enter");
82         Finalize();
83         SAFE_DELETE(__pAudioIn);
84 }
85
86
87
88 bool
89 AudioInOut::Initialize()
90 {
91         AppLog("Enter");
92         // This is called at once when application is launched.
93         // Construct an XML form
94         Construct(L"IDF_AUDIOINOUT");
95         return true;
96 }
97
98
99 result
100 AudioInOut::InitializeAudioIn(void)
101 {
102         AppLog("Enter __checkInitFiniPair - %d", __checkInitFiniPair);
103
104         result r = E_SUCCESS;
105
106         if (__pAudioIn != null)
107         {
108                 if (__pAudioIn->GetState() == AUDIOIN_STATE_RECORDING)
109                 {
110                         __pAudioIn->Stop();
111                 }
112                 if (__pAudioIn->GetState() == AUDIOIN_STATE_STOPPED)
113                 {
114                         __pAudioIn->Reset();
115                 }
116         }
117
118         // This is called when AudioIn form is moving on the foreground.
119         if (__checkInitFiniPair == false)
120         {
121                 // Construct File
122                 __pFile = new (std::nothrow) File();
123                 if (__pFile == null)
124                 {
125                         AppLogException("[Error] out of memory can't create File");
126                         return E_OUT_OF_MEMORY;
127                 }
128
129                 r = __pFile->Construct(App::GetInstance()->GetAppRootPath() + L"data/sound.dat", L"wb");
130                 if (IsFailed(r))
131                 {
132                         AppLogException("[Error] m_File Construct failed : %d", r);
133                         return r;
134                 }
135
136                 // Preset AudioIn Properties
137                 if (!__sampleChannelType)
138                 {
139                         __sampleChannelType = AUDIO_CHANNEL_TYPE_MONO;
140                 }
141
142                 if (!__sampleBitDepth)
143                 {
144                         __sampleBitDepth = AUDIO_TYPE_PCM_S16_LE;
145                 }
146
147                 if (!__sampleRate)
148                 {
149                         __sampleRate = 44100;
150                 }
151
152                 // Preset UiContols
153                 if (__sampleChannelType == AUDIO_CHANNEL_TYPE_MONO)
154                 {
155                         __pCheckButtonCT1->SetSelected(true);
156                 }
157                 else
158                 {
159                         __pCheckButtonCT2->SetSelected(true);
160                 }
161
162                 if (__sampleBitDepth == AUDIO_TYPE_PCM_U8)
163                 {
164                         __pCheckButtonSB1->SetSelected(true);
165                 }
166                 else
167                 {
168                         __pCheckButtonSB2->SetSelected(true);
169                 }
170
171                 for (unsigned int i = 0; i < SIZEOF(sampleRate); i++)
172                 {
173                         if (__sampleRate == sampleRate[i])
174                         {
175                                 __pSlider->SetValue(i);
176                                 break;
177                         }
178                 }
179                 SetSampleRateText(__sampleRate);
180
181                 // Seek File description to the begin.
182                 __pFile->Seek(FILESEEKPOSITION_BEGIN, 0);
183                 __fileSize = 0;
184
185                 // Set CheckBox enabled
186                 SetCheckButtonEnabled(__pCheckButtonCT1, true);
187                 SetCheckButtonEnabled(__pCheckButtonCT2, true);
188                 SetCheckButtonEnabled(__pCheckButtonSB1, true);
189                 SetCheckButtonEnabled(__pCheckButtonSB2, true);
190                 // Set Slider enabled
191                 SetSliderEnabled(__pSlider, true);
192
193                 __buffCnt = 0;
194                 UpdateProgress(0);
195                 __maxFileSize = __sampleRate * MAX_REC_TIME;
196                 if (__sampleChannelType == AUDIO_CHANNEL_TYPE_STEREO)
197                 {
198                         __maxFileSize = __maxFileSize << 1;
199                 }
200                 if (__sampleBitDepth == AUDIO_TYPE_PCM_S16_LE)
201                 {
202                         __maxFileSize = __maxFileSize << 1;
203                 }
204                 __checkInitFiniPair = true;
205         }
206         else
207         {
208                 // Check double initializing
209                 AppLog("[WARNING] The application state is not proper");
210         }
211         return r;
212 }
213
214 result
215 AudioInOut::InitializeAudioOut()
216 {
217         AppLog("Enter");
218         result r = E_SUCCESS;
219
220         SetCheckButtonEnabled(__pCheckButtonCT1, false);
221         SetCheckButtonEnabled(__pCheckButtonCT2, false);
222         SetCheckButtonEnabled(__pCheckButtonSB1, false);
223         SetCheckButtonEnabled(__pCheckButtonSB2, false);
224
225         if (__recordedTime == 0)
226         {
227                 AppLog("Clip Too short so reset");
228                 MessageBox msgBox;
229                 int modalResult = 0;
230                 msgBox.Construct("Warning", "Clip too short so reseting the application", MSGBOX_STYLE_NONE, 3000);
231                 msgBox.ShowAndWait(modalResult);
232                 AppLog("modal Result - %d", modalResult);
233                 InitAudioInOut();
234                 Draw();
235                 return E_INVALID_ARG;
236         }
237 #ifdef ENABLE_PROGRESS_BAR
238         String maxTime;
239         maxTime.Append(__recordedTime);
240         maxTime.Append(" sec");
241         __pLabelTotatTime->SetText(maxTime);
242         __pProgress->SetRange(0, __maxFileSize);
243 #endif
244
245         SetSliderEnabled(__pSlider, false);
246
247         __pFile = new (std::nothrow) File;
248         r = __pFile->Construct(App::GetInstance()->GetAppRootPath() + L"data/sound.dat", L"rb");
249         if (IsFailed(r))
250         {
251                 AppLogException("[Error] m_File Construct failed : %d", r);
252                 return r;
253         }
254         __buffCnt = 0;
255         __buffIndex = 0;
256
257         r = __pAudioOut->Prepare(__sampleBitDepth, __sampleChannelType, __sampleRate);
258         TryCatch(r == E_SUCCESS, , "Prepare failed");
259         for (int i = 0; i < CirclularBufferCount; i++)
260         {
261                 __byteBuffer[i].Clear();
262                 r = __pFile->Read(__byteBuffer[i]);
263                 if (!IsFailed(r))
264                 {
265                         __pAudioOut->WriteBuffer(__byteBuffer[i]);
266                         __buffCnt++;
267                         __buffIndex = (__buffIndex + 1) % CirclularBufferCount;
268                 }
269                 else
270                 {
271                         AppLog("Clip Too short so reset");
272                         MessageBox msgBox;
273                         int modalResult = 0;
274                         msgBox.Construct("Warning", "Clip too short so reseting the applicaiton", MSGBOX_STYLE_NONE, 3000);
275                         msgBox.ShowAndWait(modalResult);
276                         AppLog("modal Result - %d", modalResult);
277                         InitAudioInOut();
278                         return E_INVALID_ARG;
279                 }
280         }
281
282         __checkInitFiniPairOut = true;
283         return E_SUCCESS;
284
285 CATCH:
286         return r;
287 }
288
289 result
290 AudioInOut::OnInitializing(void)
291 {
292         AppLog("Enter");
293         result r = E_SUCCESS;
294
295         // Initialize Recording form
296         SetHeaderText(L"AudioInOut Test");
297         SetFooterStyle(FOOTER_STYLE_BUTTON_TEXT, false, this);
298         AddFooterItem(L"Record", ID_BUTTON_RECORD);
299         AddFooterItem(L"Stop", ID_BUTTON_STOP);
300         AddFooterItem(L"Play", ID_BUTTON_PLAY);
301
302         EnableFooterItem(ID_BUTTON_RECORD, true);
303         EnableFooterItem(ID_BUTTON_STOP, false);
304         EnableFooterItem(ID_BUTTON_PLAY, false);
305
306         SetFormBackEventListener(this);
307         Footer* pfooter = GetFooter();
308         if (pfooter != null)
309         {
310                 pfooter->SetBackButton();
311         }
312
313         // Prepare Buffers
314         for (unsigned int i = 0; i < SIZEOF(__byteBuffer); i++)
315         {
316                 r = __byteBuffer[i].Construct(audio_buffer_size);
317                 TRY_CATCH(r == E_SUCCESS, , "[Error] __byteBuffer[%d].Construct failed: %s", i, GetErrorMessage(r));
318         }
319
320         // Create an AudioIn instance
321         __pAudioIn = new (std::nothrow) Osp::Media::AudioIn();
322         TRY_CATCH(__pAudioIn, r = GetLastResult(), "[Error] new (std::nothrow) AudioIn failed: %s", GetErrorMessage(GetLastResult()));
323
324         // Construct an AudioIn instance
325         r = __pAudioIn->Construct(*this);
326         TRY_CATCH(r == E_SUCCESS, , "[Error] __pAudioIn->Construct  failed: %s", GetErrorMessage(r));
327
328
329         __pAudioOut = new (std::nothrow) Osp::Media::AudioOut();
330         TRY_CATCH(__pAudioOut, r = GetLastResult(), "[Error] new (std::nothrow) AudioOut failed: %s", GetErrorMessage(GetLastResult()));
331
332         // Construct an AudioIn instance
333         r = __pAudioOut->Construct(*this);
334         TRY_CATCH(r == E_SUCCESS, , "[Error] __pAudioIn->Construct  failed: %s", GetErrorMessage(r));
335
336         // Construct Timer
337         r = __timer.Construct(*this);
338         TRY_CATCH(r == E_SUCCESS, , "[Error] __timer Construct failed : %s", GetErrorMessage(r));
339
340         // Sample Rate Label
341         __pLabelSampleRate = static_cast< Label* >(GetControl(L"IDC_LABEL_SAMPLE_RATE"));
342         TRY_CATCH(__pLabelSampleRate, r = GetLastResult(), "__pLabelSampleRate is null : %s", GetErrorMessage(GetLastResult()));
343         __sampleRateText = __pLabelSampleRate->GetText();
344
345         // CheckButton
346         __pCheckButtonCT1 = static_cast< CheckButton* >(GetControl(L"IDC_CHECKBUTTON_CT1"));
347         TRY_CATCH(__pCheckButtonCT1, r = GetLastResult(), "__pCheckButtonCT1 is null:%s", GetErrorMessage(GetLastResult()));
348         __pCheckButtonCT1->SetActionId(ID_CHECKBUTTON_CT1_CHECKED, ID_CHECKBUTTON_CT1_UNCHECKED, ID_CHECKBUTTON_CT1_SELECTED);
349         __pCheckButtonCT1->AddActionEventListener(*this);
350         __pCheckButtonCT1->SetSelected(true);
351
352         __pCheckButtonCT2 = static_cast< CheckButton* >(GetControl(L"IDC_CHECKBUTTON_CT2"));
353         TRY_CATCH(__pCheckButtonCT2, r = GetLastResult(), "__pCheckButtonCT2 is null:%s", GetErrorMessage(GetLastResult()));
354         __pCheckButtonCT2->SetActionId(ID_CHECKBUTTON_CT2_CHECKED, ID_CHECKBUTTON_CT2_UNCHECKED, ID_CHECKBUTTON_CT2_SELECTED);
355         __pCheckButtonCT2->AddActionEventListener(*this);
356
357         __pCheckButtonSB1 = static_cast< CheckButton* >(GetControl(L"IDC_CHECKBUTTON_SB1"));
358         TRY_CATCH(__pCheckButtonSB1, r = GetLastResult(), "__pCheckButtonBS1 is null:%s", GetErrorMessage(GetLastResult()));
359         __pCheckButtonSB1->SetActionId(ID_CHECKBUTTON_SB1_CHECKED, ID_CHECKBUTTON_SB1_UNCHECKED, ID_CHECKBUTTON_SB1_SELECTED);
360         __pCheckButtonSB1->AddActionEventListener(*this);
361
362         __pCheckButtonSB2 = static_cast< CheckButton* >(GetControl(L"IDC_CHECKBUTTON_SB2"));
363         TRY_CATCH(__pCheckButtonSB2, r = GetLastResult(), "__pCheckButtonSB2 is null:%s", GetErrorMessage(GetLastResult()));
364         __pCheckButtonSB2->SetActionId(ID_CHECKBUTTON_SB2_CHECKED, ID_CHECKBUTTON_SB2_UNCHECKED, ID_CHECKBUTTON_SB2_SELECTED);
365         __pCheckButtonSB2->AddActionEventListener(*this);
366         __pCheckButtonSB2->SetSelected(true);
367
368 #ifdef ENABLE_PROGRESS_BAR
369         // Progress Bar
370         __pProgress = static_cast< Progress* >(GetControl(L"IDC_PROGRESS"));
371         TRY_CATCH(__pProgress, r = GetLastResult(), "__pProgress is null : %s", GetErrorMessage(GetLastResult()));
372
373         __pProgress->SetShowState(true);
374
375         __pLabelTotatTime = static_cast< Label* >(GetControl(L"IDC_LABEL4"));
376         TRY_CATCH(__pLabelTotatTime, r = GetLastResult(), " __pLabelTotatTime is null : %s", GetErrorMessage(GetLastResult()));
377         __pLabelTotatTime->SetShowState(true);
378
379         __pLabelInitialTime = static_cast< Label* >(GetControl(L"IDC_LABEL3"));
380         TRY_CATCH(__pLabelInitialTime, r = GetLastResult(), " __pLabelTotatTime is null : %s", GetErrorMessage(GetLastResult()));
381         __pLabelInitialTime->SetShowState(true);
382 #endif
383
384         // Slider
385         __pSlider = static_cast< Slider* >(GetControl(L"IDC_SLIDER"));
386         TRY_CATCH(__pSlider, r = GetLastResult(), "__pSlider is null:%s", GetErrorMessage(GetLastResult()));
387         __pSlider->AddAdjustmentEventListener(*this);
388
389         // Add Key event listener
390         AddKeyEventListener(*this);
391         InitAudioInOut();
392
393 CATCH:
394         return r;
395 }
396
397 result
398 AudioInOut::OnActivate(void* pParam)
399 {
400         AppLog("OnActivate");
401         InitAudioInOut();
402         return E_SUCCESS;
403 }
404
405
406 result
407 AudioInOut::OnTerminating(void)
408 {
409         AppLog("Enter");
410         Finalize();
411         return E_SUCCESS;
412 }
413
414 void
415 AudioInOut::OnActionPerformed(const Osp::Ui::Control& source, int actionId)
416 {
417         AppLog("Enter");
418
419         switch (actionId)
420         {
421         case ID_BUTTON_RECORD:
422                 AppLog("Record Pressed");
423                 StartRecording();
424                 __isRecording = true;
425                 break;
426
427         case ID_BUTTON_STOP:
428                 AppLog("Stop Pressed");
429                 if (__isRecording)
430                 {
431                         StopRecording();
432                 }
433                 else
434                 {
435                         StopPlay();
436                 }
437                 break;
438
439         case ID_BUTTON_PLAY:
440                 AppLog("Play Pressed");
441                 if (StartPlay() == E_SUCCESS)
442                 {
443                         __isRecording = false;
444                 }
445                 break;
446
447         case ID_CHECKBUTTON_CT1_CHECKED:
448                 __sampleChannelType = AUDIO_CHANNEL_TYPE_MONO;
449                 SetPrepare();
450                 break;
451
452         case ID_CHECKBUTTON_CT1_UNCHECKED:
453                 //Do Noting
454                 break;
455
456         case ID_CHECKBUTTON_CT1_SELECTED:
457                 //Do noting
458                 break;
459
460         case ID_CHECKBUTTON_CT2_CHECKED:
461                 __sampleChannelType = AUDIO_CHANNEL_TYPE_STEREO;
462                 SetPrepare();
463                 break;
464
465         case ID_CHECKBUTTON_CT2_UNCHECKED:
466                 //Do Noting
467                 break;
468
469         case ID_CHECKBUTTON_CT2_SELECTED:
470                 //Do noting
471                 break;
472
473         case ID_CHECKBUTTON_SB1_CHECKED:
474                 __sampleBitDepth = AUDIO_TYPE_PCM_U8;
475                 break;
476
477         case ID_CHECKBUTTON_SB1_UNCHECKED:
478                 //Do Noitng
479                 break;
480
481         case ID_CHECKBUTTON_SB1_SELECTED:
482                 //Do noting
483                 break;
484
485         case ID_CHECKBUTTON_SB2_CHECKED:
486                 __sampleBitDepth = AUDIO_TYPE_PCM_S16_LE;
487                 break;
488
489         case ID_CHECKBUTTON_SB2_UNCHECKED:
490                 //Do noting
491                 break;
492
493         case ID_CHECKBUTTON_SB2_SELECTED:
494                 //Do noting
495                 break;
496
497         default:
498                 //Do noting
499                 AppLogException("Don't come here");
500                 break;
501         }
502 }
503
504 void
505 AudioInOut::OnAudioInBufferIsFilled(Osp::Base::ByteBuffer* pData)
506 {
507         result r = E_SUCCESS;
508
509         __buffCnt++;
510         if (__buffCnt == CirclularBufferCount)
511         {
512                 __buffCnt = 0;
513         }
514
515         r = __pAudioIn->AddBuffer(&__byteBuffer[__buffCnt]);
516         if (r != E_SUCCESS)
517         {
518                 AppLogException("[Error] __pAudioIn->AddBuffer  failed with %s", GetErrorMessage(r));
519         }
520
521         Save(pData, pData->GetLimit());
522         pData->Clear();
523 }
524
525 void
526 AudioInOut::OnAudioInInterrupted(void)
527 {
528         AppLog("Enter");
529         Finalize();
530 }
531
532 void
533 AudioInOut::OnAudioInReleased(void)
534 {
535         AppLog("Reset the Application");
536         InitAudioInOut();
537 }
538
539 void
540 AudioInOut::OnAudioOutBufferEndReached(Osp::Media::AudioOut& src)
541 {
542         result r = E_SUCCESS;
543         __fileSize = __fileSize + audio_buffer_size;
544         __buffCnt--;
545         __buffIndex = (__buffIndex + 1) % CirclularBufferCount;
546         __byteBuffer[__buffIndex].Clear();
547         r = __pFile->Read(__byteBuffer[__buffIndex]);
548         if (!IsFailed(r))
549         {
550                 __pAudioOut->WriteBuffer(__byteBuffer[__buffIndex]);
551                 __buffCnt++;
552         }
553         else
554         {
555                 AppLog("Buffer Count = %d", __buffCnt);
556                 if (__buffCnt <= 0)
557                 {
558                         r = StopPlay();
559                         if (IsFailed(r))
560                         {
561                                 AppLogException("StopPlay falied with %s", GetErrorMessage(r));
562                         }
563                 }
564         }
565 }
566 void
567 AudioInOut::OnAudioOutInterrupted(Osp::Media::AudioOut& src)
568 {
569         AppLog("Enter");
570         Finalize();
571 }
572 void
573 AudioInOut::OnAudioOutReleased(Osp::Media::AudioOut& src)
574 {
575         AppLog("Resting the Application");
576         InitAudioInOut();
577 }
578
579 void
580 AudioInOut::OnTimerExpired(Osp::Base::Runtime::Timer& timer)
581 {
582         if (__fileSize < __maxFileSize)
583         {
584 #ifdef ENABLE_PROGRESS_BAR
585                 UpdateProgress(__fileSize);
586 #endif
587                 //Update once in half a second.
588                 timer.Start(500);
589         }
590         else
591         {
592                 // Maximum time is 10 seconds. After 10 seconds, move to the playing form automatically
593 #ifdef ENABLE_PROGRESS_BAR
594                 UpdateProgress(__fileSize);
595 #endif
596                 if (__isRecording)
597                 {
598                         StopRecording();
599 #ifdef ENABLE_PROGRESS_BAR
600                         UpdateProgress(0);
601 #endif
602                 }
603
604         }
605 }
606
607 void
608 AudioInOut::StartRecording(void)
609 {
610         AppLog("Enter");
611         result r = E_SUCCESS;
612         r = InitializeAudioIn();
613         TRY_CATCH(r == E_SUCCESS, , "InitializeAudioIn failed:%s", GetErrorMessage(r));
614
615         SetPrepare();
616
617         if (__pAudioIn->GetState() == AUDIOIN_STATE_PREPARED)
618         {
619                 r = __pAudioIn->Start();
620                 if (r != E_SUCCESS)
621                 {
622                         AppLog("[Error][%s][%d] __pAudioIn->Start failed (May the microphone on the system is not installed, please check your microphone on your system)",
623                                    GetErrorMessage(r), __pAudioIn->GetState());
624
625                 }
626                 else
627                 {
628                         // Set Buttons
629                         EnableFooterItem(ID_BUTTON_RECORD, false);
630                         EnableFooterItem(ID_BUTTON_STOP, true);
631                         EnableFooterItem(ID_BUTTON_PLAY, false);
632
633                         // Set CheckBox
634                         SetCheckButtonEnabled(__pCheckButtonCT1, false);
635                         SetCheckButtonEnabled(__pCheckButtonCT2, false);
636                         SetCheckButtonEnabled(__pCheckButtonSB1, false);
637                         SetCheckButtonEnabled(__pCheckButtonSB2, false);
638
639                         // Set Slider
640                         SetSliderEnabled(__pSlider, false);
641
642                         // Start timer
643                         //Update once in Half a second
644                         __timer.Start(500);
645                         __fileSize = 0;
646 #ifdef ENABLE_PROGRESS_BAR
647                         __pProgress->SetRange(0, __maxFileSize); // 10 Seconds limitation
648                         __pProgress->SetValue(0);
649                         UpdateProgress(0);
650 #endif
651                 }
652         }
653         else
654         {
655                 AppLog("Audio In State", __pAudioIn->GetState());
656         }
657         Draw();
658 CATCH:
659         return;
660 }
661
662 void
663 AudioInOut::StopRecording(void)
664 {
665         AppLog("Enter");
666         result r = E_SUCCESS;
667         __timer.Cancel();
668
669         if (__pAudioIn->GetState() == AUDIOIN_STATE_RECORDING)
670         {
671                 r = __pAudioIn->Reset();
672                 if (r != E_SUCCESS)
673                 {
674                         AppLog("[Error] __pAudioIn->Reset failed..%d ", r);
675                 }
676         }
677
678         if (__pAudioIn->GetState() == AUDIOIN_STATE_PREPARED)
679         {
680                 r = __pAudioIn->Unprepare();
681                 if (r != E_SUCCESS)
682                 {
683                         AppLog("[Error] __pAudioIn->Unprepare  failed..%d ", r);
684                 }
685         }
686
687         // When stop recording, the result file has to be closed.
688         SAFE_DELETE(__pFile);
689         AppLog("File Size = %d", __fileSize);
690         __fileSize = 0;
691         FileAttributes opFileAttr;
692         r = File::GetAttributes(App::GetInstance()->GetAppRootPath() + L"data" + FILE_PATH, opFileAttr);
693         if (!IsFailed(r))
694         {
695                 __maxFileSize = opFileAttr.GetFileSize();
696                 int SampleSize = (__sampleBitDepth == AUDIO_TYPE_PCM_U8) ? 1 : 2;
697                 int channelSize = (__sampleChannelType == AUDIO_CHANNEL_TYPE_MONO) ? 1 : 2;
698                 __recordedTime = __maxFileSize / (SampleSize * channelSize * __sampleRate);
699                 AppLog("Recoded Time - %d - maxFileSize - %d", __recordedTime, __maxFileSize);
700         }
701         else
702         {
703                 __fileSize = 0;
704                 __recordedTime = 0;
705         }
706         EnableFooterItem(ID_BUTTON_RECORD, false);
707         EnableFooterItem(ID_BUTTON_STOP, false);
708         EnableFooterItem(ID_BUTTON_PLAY, true);
709 #ifdef ENABLE_PROGRESS_BAR
710         UpdateProgress(0);
711 #endif
712
713         // Check a pair
714         __checkInitFiniPair = false;
715         __isRecording = false;
716         Draw();
717 }
718
719 result
720 AudioInOut::StopPlay()
721 {
722         result r = E_SUCCESS;
723         __timer.Cancel();
724
725         r = __pAudioOut->Stop();
726         r = __pAudioOut->Reset();
727         r = __pAudioOut->Unprepare();
728         InitAudioInOut();
729         return r;
730 }
731 result
732 AudioInOut::StartPlay()
733 {
734         result r = E_SUCCESS;
735         r = InitializeAudioOut();
736         if (r != E_SUCCESS)
737         {
738                 AppLog("Clip is too short failed with -%s", GetErrorMessage(r));
739                 return r;
740         }
741         r = __pAudioOut->Start();
742         if (IsFailed(r))
743         {
744                 ShowMessageBox("Error", "Play failed\n(%s)", GetErrorMessage(r));
745                 return r;
746         }
747
748         EnableFooterItem(ID_BUTTON_RECORD, false);
749         EnableFooterItem(ID_BUTTON_STOP, true);
750         EnableFooterItem(ID_BUTTON_PLAY, false);
751
752         //Update once in half a second.
753         __timer.Start(500);
754 #ifdef ENABLE_PROGRESS_BAR
755         UpdateProgress(0);
756 #endif
757         Draw();
758         return r;
759
760 }
761
762 void
763 AudioInOut::Save(Osp::Base::ByteBuffer* pData, int size)
764 {
765         result r = E_SUCCESS;
766
767         if (__pFile != null)
768         {
769                 r = __pFile->Write((char*) (pData->GetPointer()), size);
770                 if (IsFailed(r))
771                 {
772                         AppLogException("[Error] File Write Failed with %s", GetErrorMessage(r));
773                 }
774
775                 __fileSize = __fileSize + size;
776         }
777 }
778
779 void
780 AudioInOut::UpdateProgress(int percent)
781 {
782         if (__pProgress != null)
783         {
784                 __pProgress->SetValue(percent);
785                 //Disabling progress bar for now
786                 __pProgress->Draw();
787         }
788 }
789
790 void
791 AudioInOut::SetButtonEnabled(Osp::Ui::Controls::Button* pControl, bool bEnabled)
792 {
793         pControl->SetEnabled(bEnabled);
794         pControl->Draw();
795 }
796
797 void
798 AudioInOut::SetCheckButtonEnabled(Osp::Ui::Controls::CheckButton* pControl, bool bEnabled)
799 {
800         pControl->SetEnabled(bEnabled);
801         pControl->Draw();
802 }
803
804 void
805 AudioInOut::SetSliderEnabled(Osp::Ui::Controls::Slider* pControl, bool bEnabled)
806 {
807         pControl->SetEnabled(bEnabled);
808         pControl->Draw();
809 }
810
811 void
812 AudioInOut::InitAudioInOut()
813 {
814 #ifdef ENABLE_PROGRESS_BAR
815         String maxTime("10");
816         maxTime.Append(" sec");
817         __pLabelTotatTime->SetText(maxTime);
818         //disabling slider for now
819         __pLabelTotatTime->Draw();
820         __pProgress->SetRange(0, __maxFileSize);
821         __timer.Cancel();
822         UpdateProgress(0);
823 #endif
824         __fileSize = 0;
825         __maxFileSize = 0;
826         EnableFooterItem(ID_BUTTON_RECORD, true);
827         EnableFooterItem(ID_BUTTON_STOP, false);
828         EnableFooterItem(ID_BUTTON_PLAY, false);
829         // Set CheckBox
830         SetCheckButtonEnabled(__pCheckButtonCT1, true);
831         SetCheckButtonEnabled(__pCheckButtonCT2, true);
832         SetCheckButtonEnabled(__pCheckButtonSB1, true);
833         SetCheckButtonEnabled(__pCheckButtonSB2, true);
834
835         // Set Slider
836         SetSliderEnabled(__pSlider, true);
837         Draw();
838 }
839
840 void
841 AudioInOut::Finalize(void)
842 {
843         AppLog("Enter");
844         result r = E_SUCCESS;
845         if (__checkInitFiniPair)
846         {
847                 result r = E_SUCCESS;
848                 __timer.Cancel();
849
850                 if (__pAudioIn->GetState() == AUDIOIN_STATE_RECORDING)
851                 {
852                         r = __pAudioIn->Reset();
853                         if (r != E_SUCCESS)
854                         {
855                                 AppLog("[Error] __pAudioIn->Reset failed..%d ", r);
856                         }
857                 }
858
859                 if (__pAudioIn->GetState() == AUDIOIN_STATE_PREPARED)
860                 {
861                         r = __pAudioIn->Unprepare();
862                         if (r != E_SUCCESS)
863                         {
864                                 AppLog("[Error] __pAudioIn->Unprepare  failed..%d ", r);
865                         }
866                 }
867
868                 // When stop recording, the result file has to be closed.
869                 if (__pFile != null)
870                 {
871                         delete __pFile;
872                         __pFile = null;
873                 }
874
875                 __checkInitFiniPair = false;
876
877         }
878         else
879         {
880                 // Check double finishing
881                 AppLog("[WARNING] The application state is not proper");
882         }
883
884         if (__checkInitFiniPairOut)
885         {
886                 if (__pAudioOut->GetState() == AUDIOOUT_STATE_PLAYING)
887                 {
888                         r = __pAudioOut->Reset();
889                         if (r != E_SUCCESS)
890                         {
891                                 AppLog("[Error] __pAudioIn->Reset failed..%d ", r);
892                         }
893                 }
894
895                 if (__pAudioOut->GetState() == AUDIOOUT_STATE_PREPARED)
896                 {
897                         r = __pAudioOut->Unprepare();
898                         if (r != E_SUCCESS)
899                         {
900                                 AppLog("[Error] __pAudioIn->Unprepare  failed..%d ", r);
901                         }
902                 }
903                 __checkInitFiniPairOut = false;
904         }
905         else
906         {
907                 AppLog("[WARNING] The application state is not proper");
908         }
909
910 }
911
912 Osp::Media::AudioInState
913 AudioInOut::GetState(void)
914 {
915         if (__pAudioIn != null)
916         {
917                 return __pAudioIn->GetState();
918         }
919         else
920         {
921                 return AUDIOIN_STATE_ERROR;
922         }
923 }
924
925
926 void
927 AudioInOut::OnAdjustmentValueChanged(const Osp::Ui::Control& source, int adjustment)
928 {
929
930         if (adjustment >= 1 && adjustment <= 8)
931         {
932                 __sampleRate = sampleRate[adjustment];
933                 AppLog("new SampleRate %d %d", __sampleRate, adjustment);
934                 SetSampleRateText(__sampleRate);
935         }
936         SetPrepare();
937 }
938
939
940 void
941 AudioInOut::GetRecordingProperty(int& sampleChannelType, int& sampleBit, int& sampleRate)
942 {
943         sampleChannelType = __sampleChannelType;
944         sampleBit = __sampleBitDepth;
945         sampleRate = __sampleRate;
946 }
947
948 void
949 AudioInOut::SetPrepare(void)
950 {
951         AppLog("Enter");
952         result r = E_SUCCESS;
953
954         AppLog("AudioOut preparation request value :  Bitdepth:ChannelType:SampleRate = %d:%d:%d", __sampleBitDepth, __sampleChannelType, __sampleRate);
955
956         __buffCnt = 0;
957         for (int i = 0; i < CirclularBufferCount; i++)
958         {
959                 __byteBuffer[i].Clear();
960         }
961
962         if (__pAudioIn->GetState() == AUDIOIN_STATE_PREPARED)
963         {
964                 //Unprepare for re-prepare
965                 r = __pAudioIn->Unprepare();
966                 if (IsFailed(r))
967                 {
968                         AppLog("[Error] AudioIn Unprepare failed");
969                 }
970
971                 // Prepare AudioIn
972                 r = __pAudioIn->Prepare(AUDIO_INPUT_DEVICE_MIC, __sampleBitDepth, __sampleChannelType, __sampleRate);
973                 if (IsFailed(r))
974                 {
975                         AppLog("[Error] __pAudioIn->Prepare failed..%d ", r);
976                 }
977                 else
978                 {
979                         AppLog("[INFO] AudioIn is prepared property (Channel : %d, Sample Rate: %d, Sample Bitdepth: %d)", __sampleChannelType, __sampleRate, __sampleBitDepth);
980                 }
981
982                 // Add buffer
983                 r = __pAudioIn->AddBuffer(&__byteBuffer[__buffCnt]);
984                 if (r != E_SUCCESS)
985                 {
986                         AppLog("[Error] __pAudioIn->AddBuffer  failed..%d ", r);
987                         r = __pAudioIn->Unprepare();
988                         if (IsFailed(r))
989                         {
990                                 AppLog("[Error] __pAudioIn->Unprepare  failed..%d ", r);
991                         }
992                 }
993
994         }
995         else if ((__pAudioIn->GetState() == AUDIOIN_STATE_INITIALIZED) || (__pAudioIn->GetState() == AUDIOIN_STATE_UNPREPARED))
996         {
997                 // Prepare AudioIn
998                 r = __pAudioIn->Prepare(AUDIO_INPUT_DEVICE_MIC, __sampleBitDepth, __sampleChannelType, __sampleRate);
999                 if (IsFailed(r))
1000                 {
1001                         AppLog("[Error] __pAudioIn->Prepare failed..%d ", r);
1002                 }
1003                 else
1004                 {
1005                         AppLog("[INFO] AudioIn is prepared property (Channel : %d, Sample Rate: %d, Sample Bitdepth: %d)", __sampleChannelType, __sampleRate, __sampleBitDepth);
1006                 }
1007
1008                 // Add buffer
1009                 r = __pAudioIn->AddBuffer(&__byteBuffer[__buffCnt]);
1010                 if (r != E_SUCCESS)
1011                 {
1012                         AppLog("[Error] __pAudioIn->AddBuffer  failed..%s", GetErrorMessage(r));
1013                         r = __pAudioIn->Unprepare();
1014                         if (IsFailed(r))
1015                         {
1016                                 AppLog("[Error] __pAudioIn->Unprepare  failed..%d ", r);
1017                         }
1018                 }
1019
1020         }
1021         else
1022         {
1023                 AppLog("[WARNNING] The state of AudioIn instance is not proper");
1024         }
1025 }
1026
1027 void
1028 AudioInOut::OnKeyPressed(const Control& source, Osp::Ui::KeyCode keyCode)
1029 {
1030         result r = E_SUCCESS;
1031         r = ConsumeInputEvent();
1032         if (IsFailed(r))
1033         {
1034                 AppLog("Consuming input event failed(%s)", GetErrorMessage(r));
1035         }
1036 }
1037
1038 void
1039 AudioInOut::OnKeyReleased(const Control& source, Osp::Ui::KeyCode keyCode)
1040 {
1041
1042 }
1043
1044 void
1045 AudioInOut::OnKeyLongPressed(const Control& source, Osp::Ui::KeyCode keyCode)
1046 {
1047
1048 }
1049
1050 result
1051 AudioInOut::SetHeaderText(const Osp::Base::String& title)
1052 {
1053         result r = E_SUCCESS;
1054         Header* pHeader = GetHeader();
1055
1056         TRY_CATCH(pHeader, r = GetLastResult(), "GetHeader failed:%s", GetErrorMessage(GetLastResult()));
1057
1058         pHeader->SetTitleText(title);
1059         pHeader->Draw();
1060
1061 CATCH:
1062         return r;
1063 }
1064
1065 result
1066 AudioInOut::SetFooterStyle(Osp::Ui::Controls::FooterStyle style, bool showBack, Osp::Ui::IActionEventListener* pListener)
1067 {
1068         result r = E_SUCCESS;
1069         Footer* pFooter = GetFooter();
1070
1071         TRY_CATCH(pFooter, r = GetLastResult(), "GetFooter() failed:%s", GetErrorMessage(GetLastResult()));
1072
1073         pFooter->SetStyle(style);
1074
1075         if (showBack)
1076         {
1077                 pFooter->SetBackButton();
1078         }
1079
1080         if (pListener != null)
1081         {
1082                 pFooter->AddActionEventListener(*pListener);
1083         }
1084
1085 CATCH:
1086         return r;
1087 }
1088
1089
1090 result
1091 AudioInOut::AddFooterItem(const Osp::Base::String& text, int actionId)
1092 {
1093         result r = E_SUCCESS;
1094         FooterItem item;
1095         Footer* pFooter = GetFooter();
1096         int index;
1097
1098         TRY_CATCH(pFooter, r = E_SYSTEM, "GetFooter() failed:%s", GetErrorMessage(GetLastResult()));
1099
1100         item.Construct(actionId);
1101         item.SetText(text);
1102
1103         index = pFooter->GetItemCount();
1104
1105         AppLog("%d is as %s", index, text.GetPointer());
1106         __footerActionId[index] = actionId;
1107
1108         pFooter->AddItem(item);
1109
1110 CATCH:
1111         return r;
1112 }
1113
1114 result
1115 AudioInOut::RemoveFooterItem(int actionId)
1116 {
1117         result r = E_SUCCESS;
1118         FooterItem item;
1119         Footer* pFooter = GetFooter();
1120
1121         TRY_CATCH(pFooter, r = E_SYSTEM, "GetFooter() failed:%s", GetErrorMessage(GetLastResult()));
1122
1123         for (unsigned int i = 0; i < SIZEOF(__footerActionId); i++)
1124         {
1125                 if (__footerActionId[i] == actionId)
1126                 {
1127                         pFooter->RemoveItemAt(i);
1128                         break;
1129                 }
1130         }
1131
1132 CATCH:
1133         return r;
1134 }
1135
1136 result
1137 AudioInOut::EnableFooterItem(int actionId, bool enable)
1138 {
1139         result r = E_SUCCESS;
1140         Footer* pFooter = GetFooter();
1141         TRY_CATCH(pFooter, r = E_SYSTEM, "GetFooter() failed:%s", GetErrorMessage(GetLastResult()));
1142
1143         for (unsigned int i = 0; i < SIZEOF(__footerActionId); i++)
1144         {
1145                 if (__footerActionId[i] == actionId)
1146                 {
1147                         pFooter->SetItemEnabled(i, enable);
1148                         pFooter->Draw();
1149                         break;
1150                 }
1151         }
1152
1153 CATCH:
1154         return r;
1155 }
1156
1157 void
1158 AudioInOut::OnFormBackRequested(Osp::Ui::Controls::Form& source)
1159 {
1160         Finalize();
1161         Deactivate();
1162 }
1163
1164 void
1165 AudioInOut::SetSampleRateText(int sampleRate)
1166 {
1167         String text;
1168         text.Format(32, L": %d", sampleRate);
1169         text = __sampleRateText + text;
1170         __pLabelSampleRate->SetText(text);
1171         __pLabelSampleRate->Draw();
1172 }