Skip to content
This repository has been archived by the owner on Jan 16, 2024. It is now read-only.

Cycle test within a test function(TEST_F) #32

Closed
boyce-xx opened this issue Jun 21, 2017 · 8 comments
Closed

Cycle test within a test function(TEST_F) #32

boyce-xx opened this issue Jun 21, 2017 · 8 comments

Comments

@boyce-xx
Copy link

boyce-xx commented Jun 21, 2017

Hi, I'm trying to do a cycle test within(TEST_F), in other words, I would like it to run SetUp() one time, and I can send my audio data cycle by cycle to AVS, do you have some advises?

I have a question about this: What is the life-cycle of it If I want to do cycle test?
this is my understand: initial -> connect -> startRecognizing -> stopCapture -> play response audio --> disconnect --> connect -> startRecognizing -> stopCapture -> play response audio --> disconnect --> connect -> .........
Is it correct?

code snippet like below:

int MAX = 150;
int testCycleIndex = 0;
while(testCycleIndex < MAX){
// Signal to the AIP to start recognizing.
ASSERT_TRUE(m_tapToTalkButton->startRecognizing(m_AudioInputProcessor, m_TapToTalkAudioProvider));

// Check that AIP is now in RECOGNIZING state.
//ASSERT_TRUE(m_StateObserver->checkState(AudioInputProcessor::State::RECOGNIZING, AUDIO_FILE_TIMEOUT_DURATION));

// temp
sysLocalTime("Decode File data.......");
std::string file="recognize_joke_test.wav";
std::cout << "file: " << file << std::endl;
const int RIFF_HEADER_SIZE = 44;
std::ifstream inputFile(file.c_str(), std::ifstream::binary);
if (!inputFile.good()) {
std::cout << "Couldn't open audio file!" << std::endl;
return ;
}
inputFile.seekg(0, std::ios::end);
int fileLengthInBytes = inputFile.tellg();
if (fileLengthInBytes <= RIFF_HEADER_SIZE) {
std::cout << "File should be larger than 44 bytes, which is the size of the RIFF header" << std::endl;
return ;
}

inputFile.seekg(RIFF_HEADER_SIZE, std::ios::beg);
std::cout << "\t\tfile lenght In bytes: " << fileLengthInBytes << std::endl;
int numSamples = (fileLengthInBytes - RIFF_HEADER_SIZE) / 2;
std::cout << "\t\tnumSamples: " << numSamples << std::endl;
std::vector<int16_t> retVal(8192, 0);
//inputFile.read((char *)&retVal[0], numSamples * 2);
//m_AudioBufferWriter->write(retVal.data(), retVal.size());

int index = 0;
while(!inputFile.eof())
{
index ++;
inputFile.read((char *)&retVal[0], 8192);
m_AudioBufferWriter->write(retVal.data(), inputFile.gcount());
printf("start recording size: %d, %d\n", retVal.size(), inputFile.gcount());
retVal.clear();
std::cout << "index= " << index << std::endl;
}
inputFile.close();

// The test channel client has been notified the alarm channel has been backgrounded.
//ASSERT_EQ(m_testClient->waitForFocusChange(AUDIO_FILE_TIMEOUT_DURATION), FocusState::BACKGROUND);

// Check that AIP is in BUSY state.
//ASSERT_TRUE(m_StateObserver->checkState(AudioInputProcessor::State::BUSY, AUDIO_FILE_TIMEOUT_DURATION));

// Check that AIP is in an IDLE state.
//ASSERT_TRUE(m_StateObserver->checkState(AudioInputProcessor::State::IDLE, AUDIO_FILE_TIMEOUT_DURATION));

// Check that the test context provider was asked to provide context for the event.
//ASSERT_TRUE(m_stateProvider->checkStateRequested());

// The test channel client has been notified the alarm channel has been foregrounded.
//ASSERT_EQ(m_testClient->waitForFocusChange(AUDIO_FILE_TIMEOUT_DURATION), FocusState::FOREGROUND);

// Check that a recognize event was sent.
//ASSERT_TRUE(checkSentEventName(m_avsConnectionManager, NAME_RECOGNIZE));

// decode result
// ***** omitted ***** here to play response audio.

std::thread t1(&AlexaAudioTest::reConnect, this);
testCycleIndex ++;
t1.join();
}

@charleschen84
Copy link

  1. call setUp()
  2. send audio data to the shared data buffer in a loop
  3. waketrigger wil call startRecognizing when a hotword detected. AVS will send stopCapture Directive to AIP and send play response audio to Speecher/MediaPlayer.

Here are some of my code:

`m_detector = kwd::KittAiKeyWordDetector::create(
m_AudioBuffer,
m_compatibleAudioFormat,
{m_WakeWordTrigger},
std::unordered_set<std::shared_ptr>(),
inputPath + RESOURCE_FILE,
{config},
2.0,
false);
assert(nullptr != m_detector);

  m_mediaPlayer = MediaPlayer::create();
  assert(nullptr != m_mediaPlayer);

  // Create and register the SpeechSynthesizer.
  m_speechSynthesizer = SpeechSynthesizer::create(m_mediaPlayer,
                                                  m_avsConnectionManager,
                                                  m_focusManager,
                                                  m_contextManager,
                                                  m_attachmentManager,
                                                  m_exceptionEncounteredSender);

  m_speechSynthesizerObserver = std::make_shared<TestSpeechSynthesizerObserver>();
  m_speechSynthesizer->addObserver(m_speechSynthesizerObserver);`

`void AlexaClient::StartService(void)
{
PortAudioWrapper pa_wrapper(COMPATIBLE_SAMPLE_RATE,
COMPATIBLE_NUM_CHANNELS,
COMPATIBLE_SAMPLE_SIZE_IN_BITS);

  std::vector<int16_t> audioData;
  while(1) {
      pa_wrapper.Read(&audioData);
      if(!audioData.empty()) {
          m_AudioBufferWriter->write(audioData.data(), audioData.size());
      }
  }

}`

@alexa alexa deleted a comment from boyce-xx Jun 22, 2017
@kencecka
Copy link
Contributor

Hi Boyce,

There shouldn't be any problem with running multiple cycles, and your lifecycle flow sounds correct. Are you having specific problems implementing the cycle test?

Ken

@boyce-xx
Copy link
Author

Hi @kencecka

From what we have tried based on the flow above, we need to disconnect/connect AVS again to keep the inquiry process normal, but it costs 3s~4s to reconnect with AVS, we expect to inquire AVS more than once without disconnecting and connecting with AVS again and again.

The flow what we expected is: initial -> connect -> startRecognizing -> stopCapture -> play response audio --> startRecognizing -> stopCapture -> play response audio --> startRecognizing -> .........

But if we skip the disconnect/connect step, we can inquire AVS for 2 times normally, then we got the following errors when trying a 3rd time:

SharedDataStream::createReader failed: all readers are already in use.
InProcessAttachmentReader:ConstructorFailed:reason=could not create an SDS reader
InProcessAttachmentReader:createFailed:reason=object not fully created
executeRecognize failed: Failed to create attachment reader.
/home/king/Project/DB20_Linux/AVS/alexa-client-sdk_v0.4.1_desktop/alexa-client-sdk/Integration/test/AlexaAudioLongRunTest.cpp:692: Failure
Value of: m_tapToTalkButton->startRecognizing(m_AudioInputProcessor, m_TapToTalkAudioProvider)
Actual: false
Expected: true
MessageRouter:connectionStatusChanged:reason=ACL_CLIENT_REQUEST,newStatus=DISCONNECTED
DirectiveSequencer:shutdown
executeOnFocusChanged: Lost focus.

[ FAILED ] AlexaAudioTest.avsFunctionTest (19913 ms)
[----------] 1 test from AlexaAudioTest (19913 ms total)

[----------] Global test environment tear-down
[==========] 1 test from 1 test case ran. (19913 ms total)
[ PASSED ] 0 tests.
[ FAILED ] 1 test, listed below:
[ FAILED ] AlexaAudioTest.avsFunctionTest

1 FAILED TEST

For a better user experience, we want to have a seamless inquiry between cycles.
Thanks.

@kencecka
Copy link
Contributor

Hi Boyce,

You are correct in your expectation that you should not need to disconnect and reconnect. Looking at your log above, it appears that you are encountering a similar issue to the one described here. We are investigating, and will update you when we have more details. In the mean time, if you are able to provide some sample code that reproduces the issue, that may help with debugging, as we are not currently seeing this issue with our own testing.

Thanks,
Ken

@boyce-xx
Copy link
Author

Hi @kencecka

Please see this

Thanks.

@boyce-xx
Copy link
Author

Hi @kencecka ,
I have tried again based on V0.5 SDK, but get the same error, error message is:

^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ testCycleIndex: 3
2017-06-24 08:54:30.589 [ 5] I ?:?::SharedDataStream::createReader failed: all readers are already in use.
2017-06-24 08:54:30.589 [ 5] E InProcessAttachmentReader:ConstructorFailed:reason=could not create an SDS reader
2017-06-24 08:54:30.589 [ 5] E InProcessAttachmentReader:createFailed:reason=object not fully created
2017-06-24 08:54:30.589 [ 5] E AudioInputProcessor:executeRecognizeFailed:reason=Failed to create attachment reader
/home/king/Project/DB20_Linux/AVS/alexa-client-sdk_v0.5_desktop/alexa-client-sdk/Integration/test/AlexaAudioLongRun2Test.cpp:625: Failure
Value of: m_tapToTalkButton->startRecognizing(m_AudioInputProcessor, m_TapToTalkAudioProvider)
Actual: false
Expected: true
2017-06-24 08:54:30.590 [ 1] 0 MessageRouter:connectionStatusChanged:reason=ACL_CLIENT_REQUEST,newStatus=DISCONNECTED
2017-06-24 08:54:30.664 [ 1] I DirectiveSequencer:shutdown
2017-06-24 08:54:30.664 [ 8] I DirectiveRouter:cancelDirective:messageId=178cc7c1-32ba-4a38-aaa2-2196a5f4fce3,action=calling
[ FAILED ] AlexaAudioTest.avsFunctionTest (30302 ms)
[----------] 1 test from AlexaAudioTest (30302 ms total)

[----------] Global test environment tear-down
[==========] 1 test from 1 test case ran. (30302 ms total)
[ PASSED ] 0 tests.
[ FAILED ] 1 test, listed below:
[ FAILED ] AlexaAudioTest.avsFunctionTest

1 FAILED TEST

sample code like this

@kencecka
Copy link
Contributor

Hi Boyce,

I think I see where you are running in to trouble. Your sample code is a modified version of AudioInputProcessorIntegartionTest.cpp. That test tries to thoroughly verify that all aspects of the SDK interacting with AVS are working as expected. One piece of this is to verify that the correct events are being sent out to AVS.

To do this, the integration test inserts a shim (TestMessageSender) between AudioInputProcessor and AVSConnectionManager. That shim maintains a queue of MessageRequests internally, and only discards them if you call waitForNext() on the shim. The test uses this to verify every MessageRequest that passes from AudioInputProcessor to AVSConnectionManager. However, if you are using the shim and you neglect to call waitForNext(), it will simply accumulate all the MessageRequests in its queue and never discard them.

Reviewing your code, I see:

        // Check that a recognize event was sent.
        //ASSERT_TRUE(checkSentEventName(m_avsConnectionManager, NAME_RECOGNIZE));

If I uncomment the ASSERT_TRUE, I no longer see the createReader() error, and am able to run hundreds of iterations.

Note that there is no need for a shim like this in a normal use case. You can connect your AudioInputProcessor directly to your AVSConnectionManager, and this issue will go away.

Hope that helps,
Ken

@boyce-xx
Copy link
Author

boyce-xx commented Jun 27, 2017

Hi @kencecka ,
Thanks for your great support, It works now.

-- I removed the shim(TestMessageSender), and add a object of acl::AVSConnectionManager, It works for me.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants