Пример #1
0
def hearing_test_audio(example_num):
    """
    Retrieve audio for hearing test

    Parameters
    ----------
    example_num : str
        The index of the example audio (1 or 2)

    Return
    ------
    flask.Response
    """
    if example_num == '0':
        # calibration
        if app.config['TEST_TYPE'] == 'segmentation':
            file_path = 'hearing_test_audio/seg_hearing.wav'
        else:
            file_path = 'hearing_test_audio/1000Hz.wav'
    else:
        hearing_test_audio_index = int(
            utilities.decrypt_data(session['hearing_test_audio_index%s' %
                                           example_num]))
        num_tones = hearing_test_audio_index / configuration.HEARING_TEST_AUDIO_FILES_PER_TONES
        file_num = hearing_test_audio_index % configuration.HEARING_TEST_AUDIO_FILES_PER_TONES
        logger.info('hearing_test %s - %d %d' %
                    (example_num, num_tones, file_num))
        file_path = 'hearing_test_audio/tones%d_%d.wav' % (num_tones, file_num)
    with open(file_path, 'rb') as f:
        response = make_response(f.read())
        response.headers['Content-Type'] = 'audio/wav'
        response.headers['Accept-Ranges'] = 'bytes'
    return response
Пример #2
0
def audio(audio_file_key):
    """
    Return audio from audio file URL in `audio_file_key`

    Parameters
    ----------
    audio_file_key: str
        The encrypted key that contains a dictionary that included an item keyed by 'path' which is the location of the
        audio file

    Returns
    -------
    flask.Response
    """
    if app.config['ENCRYPT_AUDIO_STIMULI_URLS']:
        try:
            audio_file_dict = utilities.decrypt_data(str(audio_file_key))

            # can also assert that this file is for this specific participant and condition
            assert (audio_file_dict['p_id'] == session['participant_id'])
            assert (audio_file_dict['g_id'] in session['condition_group_ids'])
            filename = audio_file_dict['URL']
        except (ValueError, TypeError):
            filename = audio_file_key + '.wav'
    else:
        filename = audio_file_key + '.wav'

    return send_file_partial(
        safe_join(safe_join(app.root_path, app.config['AUDIO_FILE_DIRECTORY']),
                  filename))
Пример #3
0
def hearing_test_audio(example_num):
    """
    Retrieve audio for hearing test

    Parameters
    ----------
    example_num : str
        The index of the example audio (1 or 2)

    Return
    ------
    flask.Response
    """
    if example_num == '0':
        # calibration
        if app.config['TEST_TYPE'] == 'segmentation':
            file_path = 'hearing_test_audio/seg_hearing.wav'
        else:
            file_path = 'hearing_test_audio/1000Hz.wav'
    else:
        hearing_test_audio_index = int(utilities.decrypt_data(session['hearing_test_audio_index%s' % example_num]))
        num_tones = hearing_test_audio_index / configuration.HEARING_TEST_AUDIO_FILES_PER_TONES
        file_num = hearing_test_audio_index % configuration.HEARING_TEST_AUDIO_FILES_PER_TONES
        logger.info('hearing_test %s - %d %d' % (example_num, num_tones, file_num))
        file_path = 'hearing_test_audio/tones%d_%d.wav' % (num_tones, file_num)
    with open(file_path, 'rb') as f:
        response = make_response(f.read())
        response.headers['Content-Type'] = 'audio/wav'
        response.headers['Accept-Ranges'] = 'bytes'
    return response
Пример #4
0
def audio(audio_file_key):
    """
    Return audio from audio file URL in `audio_file_key`

    Parameters
    ----------
    audio_file_key: str
        The encrypted key that contains a dictionary that included an item keyed by 'path' which is the location of the
        audio file

    Returns
    -------
    flask.Response
    """
    if app.config['AUDIO_CODEC'] == 'wav':
        file_format = '.wav'
    elif app.config['AUDIO_CODEC'] == 'mp3':
        file_format = '.mp3'

    if app.config['ENCRYPT_AUDIO_STIMULI_URLS']:
        try:
            audio_file_dict = utilities.decrypt_data(str(audio_file_key))

            # can also assert that this file is for this specific participant and condition
            assert (audio_file_dict['p_id'] == session['participant_id'])
            assert (audio_file_dict['g_id'] in session['condition_group_ids'])
            filename = audio_file_dict['URL']
        except (ValueError, TypeError):
            filename = audio_file_key + file_format
    else:
        filename = audio_file_key + file_format

    if app.config['EXTERNAL_FILE_HOST']:
        # return send_file_partial(app.config['AUDIO_FILE_DIRECTORY']+filename)
        return send_file_partial_hack(safe_join(app.config['AUDIO_FILE_DIRECTORY'], filename))

    else:
        return send_file_partial(safe_join(safe_join(app.root_path, app.config['AUDIO_FILE_DIRECTORY']), filename))
Пример #5
0
def hearing_test():
    """
    Determines if the user is eligible to take the hearing test (i.e. has not exceeded `MAX_HEARING_TEST_ATTEMPTS`, and
    then renders the hearing test, which consists of the assessor counting the tones in two audio files.

    If caqe.settings.HEARING_TEST_REJECTION_ENABLED is set to False, then pass them through after they had their 2
    attempts.

    Returns
    -------
    flask.Response
    """
    participant = get_current_participant(session)

    if request.method == 'GET':
        if participant.hearing_test_attempts >= app.config[
                'MAX_HEARING_TEST_ATTEMPTS']:
            logger.info('Max hearing test attempts reached - %r' % participant)
            return render_template(
                'sorry.html',
                message='Sorry. You have exceed the number of allowed attempts. '
                'Please try again tomorrow.')

        while True:
            hearing_test_audio_index1 = random.randint(
                configuration.MIN_HEARING_TEST_AUDIO_INDEX,
                configuration.MAX_HEARING_TEST_AUDIO_INDEX)
            hearing_test_audio_index2 = random.randint(
                configuration.MIN_HEARING_TEST_AUDIO_INDEX,
                configuration.MAX_HEARING_TEST_AUDIO_INDEX)
            if hearing_test_audio_index1 != hearing_test_audio_index2:
                # encrypt the data so that someone can't figure out the pattern on the client side
                logger.info('Hearing test indices %d and %d assigned to %r' %
                            (hearing_test_audio_index1,
                             hearing_test_audio_index2, participant))
                session['hearing_test_audio_index1'] = utilities.encrypt_data(
                    hearing_test_audio_index1)
                session['hearing_test_audio_index2'] = utilities.encrypt_data(
                    hearing_test_audio_index2)
                break

        return render_template('hearing_screening.html')
    elif request.method == 'POST':
        try:
            hearing_test_audio_index1 = session['hearing_test_audio_index1']
            hearing_test_audio_index2 = session['hearing_test_audio_index2']
        except KeyError as e:
            hearing_test_audio_index1 = None
            hearing_test_audio_index2 = None
            logger.error("Invalid state - %r" % e)

        if (int(request.form['audiofile1_tones']) ==
                int(int(utilities.decrypt_data(hearing_test_audio_index1)) /
                    configuration.HEARING_TEST_AUDIO_FILES_PER_TONES)) \
            and (int(request.form['audiofile2_tones']) ==
                 int(int(utilities.decrypt_data(hearing_test_audio_index2)) /
                     configuration.HEARING_TEST_AUDIO_FILES_PER_TONES)):
            logger.info('Hearing test passed - %r' % participant)
            participant.set_passed_hearing_test(True)
            db.session.commit()
            return pre_evaluation_tasks()
        else:
            logger.info('Hearing test failed - %r' % participant)
            participant.set_passed_hearing_test(False)
            db.session.commit()

            if participant.hearing_test_attempts < app.config[
                    'MAX_HEARING_TEST_ATTEMPTS']:
                flash(
                    'You answered incorrectly. If you are unable to pass this test, it is likely that your output '
                    'device (e.g. your headphones) is not producing the full range of frequencies required for this '
                    'task. Try using better headphones.', 'danger')
            else:
                if not app.config['HEARING_TEST_REJECTION_ENABLED']:
                    # They attempted, but they failed, but pass them through since rejection is not enabled
                    logger.info(
                        'Hearing test rejection enabled. Passing failed participant to evaluation.'
                    )
                    return pre_evaluation_tasks()
            return redirect(
                url_for('hearing_test',
                        _method='GET',
                        _external=True,
                        _scheme=app.config['PREFERRED_URL_SCHEME']))
Пример #6
0
def _decode_url(encrypted_url):
    # remove /audio/
    encrypted_data = encrypted_url[7:]
    # remove .wav
    encrypted_data = encrypted_data[:-4]
    return utilities.decrypt_data(str(encrypted_data))
Пример #7
0
def hearing_test():
    """
    Determines if the user is eligible to take the hearing test (i.e. has not exceeded `MAX_HEARING_TEST_ATTEMPTS`, and
    then renders the hearing test, which consists of the assessor counting the tones in two audio files.

    If caqe.settings.HEARING_TEST_REJECTION_ENABLED is set to False, then pass them through after they had their 2
    attempts.

    Returns
    -------
    flask.Response
    """
    participant = get_current_participant(session)

    if request.method == 'GET':
        if participant.hearing_test_attempts >= app.config['MAX_HEARING_TEST_ATTEMPTS']:
            logger.info('Max hearing test attempts reached - %r' % participant)
            return render_template('sorry.html', message='Sorry. You have exceed the number of allowed attempts. '
                                                         'Please try again tomorrow.')

        while True:
            hearing_test_audio_index1 = random.randint(configuration.MIN_HEARING_TEST_AUDIO_INDEX,
                                                       configuration.MAX_HEARING_TEST_AUDIO_INDEX)
            hearing_test_audio_index2 = random.randint(configuration.MIN_HEARING_TEST_AUDIO_INDEX,
                                                       configuration.MAX_HEARING_TEST_AUDIO_INDEX)
            if hearing_test_audio_index1 != hearing_test_audio_index2:
                # encrypt the data so that someone can't figure out the pattern on the client side
                logger.info('Hearing test indices %d and %d assigned to %r' %
                            (hearing_test_audio_index1, hearing_test_audio_index2, participant))
                session['hearing_test_audio_index1'] = utilities.encrypt_data(hearing_test_audio_index1)
                session['hearing_test_audio_index2'] = utilities.encrypt_data(hearing_test_audio_index2)
                break

        return render_template('hearing_screening.html')
    elif request.method == 'POST':
        try:
            hearing_test_audio_index1 = session['hearing_test_audio_index1']
            hearing_test_audio_index2 = session['hearing_test_audio_index2']
        except KeyError as e:
            hearing_test_audio_index1 = None
            hearing_test_audio_index2 = None
            logger.error("Invalid state - %r" % e)

        if (int(request.form['audiofile1_tones']) ==
                (int(utilities.decrypt_data(hearing_test_audio_index1)) /
                     configuration.HEARING_TEST_AUDIO_FILES_PER_TONES)) \
                and (int(request.form['audiofile2_tones']) ==
                         (int(utilities.decrypt_data(hearing_test_audio_index2)) /
                              configuration.HEARING_TEST_AUDIO_FILES_PER_TONES)):
            logger.info('Hearing test passed - %r' % participant)
            participant.set_passed_hearing_test(True)
            db.session.commit()
            return pre_evaluation_tasks()
        else:
            logger.info('Hearing test failed - %r' % participant)
            participant.set_passed_hearing_test(False)
            db.session.commit()

            if participant.hearing_test_attempts < app.config['MAX_HEARING_TEST_ATTEMPTS']:
                flash('You answered incorrectly. If you are unable to pass this test, it is likely that your output '
                      'device (e.g. your headphones) is not producing the full range of frequencies required for this '
                      'task. Try using better headphones.', 'danger')
            else:
                if not app.config['HEARING_TEST_REJECTION_ENABLED']:
                    # They attempted, but they failed, but pass them through since rejection is not enabled
                    logger.info('Hearing test rejection enabled. Passing failed participant to evaluation.')
                    return pre_evaluation_tasks()
            return redirect(url_for('hearing_test', _method='GET', _external=True, _scheme=app.config['PREFERRED_URL_SCHEME']))
Пример #8
0
def _decode_url(encrypted_url):
    # remove /audio/
    encrypted_data = encrypted_url[7:]
    # remove .wav
    encrypted_data = encrypted_data[:-4]
    return utilities.decrypt_data(str(encrypted_data))