audio_quality中的工厂方法 源码学习

135 篇文章 5 订阅

audiosignal工厂

#ifndef CTSAUDIO_AUDIOSIGNALFACTORY_H
#define CTSAUDIO_AUDIOSIGNALFACTORY_H
#include <utils/StrongPointer.h>
#include "AudioHardware.h"
#include "Buffer.h"
/**
 * factory for creating various audio signals
 */
class AudioSignalFactory {
public:
    static android::sp<Buffer> generateSineWave(AudioHardware::BytesPerSample BPS,
            int maxPositive, AudioHardware::SamplingRate samplingRate, int signalFreq, int samples,
            bool stereo = true);
    static android::sp<Buffer> generateWhiteNoise(AudioHardware::BytesPerSample BPS,
            int maxPositive, int samples, bool stereo = true);
    static android::sp<Buffer> generateZeroSound(AudioHardware::BytesPerSample BPS,
            int samples, bool stereo = true);
};
#endif

抽象类的工厂方法GenericFactory

#include <getopt.h>
#include <stdio.h>
#include <utils/String8.h>
#include <UniquePtr.h>
#include "GenericFactory.h"
#include "Log.h"
#include "Report.h"
#include "Settings.h"
#include "task/TaskGeneric.h"
#include "task/ModelBuilder.h"
// For flushing report and log before exiting
class CleanupStatics {//注释1
public:
    CleanupStatics() {
    }
    ~CleanupStatics() {
        Log::Finalize();
        Report::Finalize();
        // create zip file after log and report files are closed.
        android::String8 reportDirPath =
                Settings::Instance()->getSetting(Settings::EREPORT_FILE).getPathDir();
        android::String8 zipFilename = reportDirPath.getPathLeaf();
        android::String8 command = android::String8::format("cd %s;zip -r ../%s.zip *",
                reportDirPath.string(), zipFilename.string());
        fprintf(stderr, "\n\nexecuting %s\n", command.string());
        if (system(command.string()) == -1) {
            fprintf(stderr, "cannot create zip file with command %s\n", command.string());
        }
        Settings::Finalize();
    }
};
void usage(char* bin)
{
    fprintf(stderr, "%s [-l log_level][-s serial] test_xml\n", bin);
}
int main(int argc, char *argv[])
{
    if (argc < 2) {
        fprintf(stderr, "%s [-l log_level][-s serial] test_xml\n", argv[0]);
        return 1;
    }
    int logLevel = Log::ELogW;
    char* serial = NULL;
    int opt;
    while ((opt = getopt(argc, argv, "l:s:")) != -1) {
        switch (opt) {
        case 'l':
            logLevel = atoi(optarg);
            break;
        case 's':
            serial = optarg;
            break;
        default:
            usage(argv[0]);
            return 1;
        }
    }
    if (optind >= argc) {
        usage(argv[0]);
        return 1;
    }
    android::String8 xmlFile(argv[optind]);
    android::String8 dirName;
    if (!FileUtil::prepare(dirName)) {
        fprintf(stderr, "cannot prepare report dir");
        return 1;
    }
    UniquePtr<CleanupStatics> staticStuffs(new CleanupStatics());
    if (Settings::Instance() == NULL) {
        fprintf(stderr, "caanot create Settings");
        return 1;
    }
    if (serial != NULL) {
        android::String8 strSerial(serial);
        Settings::Instance()->addSetting(Settings::EADB, strSerial);
    }
    if (Log::Instance(dirName.string()) == NULL) {
        fprintf(stderr, "cannot create Log");
        return 1;
    }
    Log::Instance()->setLogLevel((Log::LogLevel)logLevel);
    // Log can be used from here
    if (Report::Instance(dirName.string()) == NULL) {
        LOGE("cannot create log");
        return 1;
    }
    GenericFactory factory;
    ClientInterface* client = factory.createClientInterface();//注释2
    if (client == NULL) {
        fprintf(stderr, "cannot create ClientInterface");
        return 1;
    }
    if (!client->init(Settings::Instance()->getSetting(Settings::EADB))) {
        fprintf(stderr, "cannot init ClientInterface");
        return 1;
    }
    android::String8 deviceInfo;
    if (!client->getAudio()->getDeviceInfo(deviceInfo)) {//注释3
        fprintf(stderr, "cannot get device info");
        return 1;
    }
    delete client; // release so that it can be used in tests
    Settings::Instance()->addSetting(Settings::EDEVICE_INFO, deviceInfo);
    ModelBuilder modelBuilder;
    UniquePtr<TaskGeneric> topTask(modelBuilder.parseTestDescriptionXml(xmlFile));
    if (topTask.get() == NULL) {
        LOGE("Parsing of %x failed", xmlFile.string());
        return 1;
    }
    Settings::Instance()->addSetting(Settings::ETEST_XML, xmlFile);
    topTask->run();
    return 0;
}

注释1:

CleanupStatics用于程序退出时flush报告和日志

注释2:ClientInterface

#ifndef CTSAUDIO_CLIENTINTERFACE_H
#define CTSAUDIO_CLIENTINTERFACE_H
#include <utils/String8.h>
#include <utils/StrongPointer.h>
#include "audio/RemoteAudio.h"
#include "ClientSocket.h"
class ClientInterface {
public:
    virtual ~ClientInterface() {};
    /**
     * launch client and perform initial connection
     * @param param parameter for connection. It will be device serial number or zero length string
     */
    virtual bool init(const android::String8& param) = 0;
    virtual ClientSocket& getSocket()  = 0;
    virtual android::sp<RemoteAudio>& getAudio() = 0;
};
#endif

测试程序

#include <utils/String8.h>
#include <gtest/gtest.h>
#include <audio/AudioSignalFactory.h>
#include <ClientInterface.h>
#include <ClientImpl.h>
#include <GenericFactory.h>
#include <audio/RemoteAudio.h>
class ClientInterfaceTest : public testing::Test {
protected:
    ClientInterface* mClient;
protected:
    virtual void SetUp() {
        GenericFactory factory;
        mClient = factory.createClientInterface();
        ASSERT_TRUE(mClient != NULL);
        android::String8 dummyParam;
        ASSERT_TRUE(mClient->init(dummyParam));
    }
    virtual void TearDown() {
        delete mClient;
        mClient = NULL;
    }
};
TEST_F(ClientInterfaceTest, InitTest) {
    // all done in SetUp
}
TEST_F(ClientInterfaceTest, getDeviceInfoTest) {
    ClientImpl* client = reinterpret_cast<ClientImpl*>(mClient);
    android::sp<RemoteAudio>& audio(client->getAudio());
    android::String8 info;
    ASSERT_TRUE(audio->getDeviceInfo(info));
    LOGD("device info %s", info.string());
}
TEST_F(ClientInterfaceTest, PlayTest) {
    ClientImpl* client = reinterpret_cast<ClientImpl*>(mClient);
    android::sp<RemoteAudio>& audio(client->getAudio());
    const int maxPositive = 10000;
    const int signalFreq = AudioHardware::ESampleRate_44100/100;
    const int samples = 8192*2;
    android::sp<Buffer> buffer = AudioSignalFactory::generateSineWave(AudioHardware::E2BPS,
            maxPositive, AudioHardware::ESampleRate_44100, signalFreq, samples);
    int id;
    android::String8 name("1");
    ASSERT_TRUE(audio->downloadData(name, buffer, id));
    ASSERT_TRUE(audio->startPlayback(true, AudioHardware::ESampleRate_44100,
            AudioHardware::EModeVoice, 100, id, 1));
    ASSERT_TRUE(audio->waitForPlaybackCompletion());
    ASSERT_TRUE(id == audio->getDataId(name));
    android::String8 name2("2");
    ASSERT_TRUE(audio->getDataId(name2) < 0);
}
TEST_F(ClientInterfaceTest, RecordTest) {
    ClientImpl* client = reinterpret_cast<ClientImpl*>(mClient);
    android::sp<RemoteAudio>& audio(client->getAudio());
    const int maxPositive = 10000;
    const int signalFreq = AudioHardware::ESampleRate_44100 / 100;
    const int samples = 44100 * 4;
    android::sp<Buffer> buffer(new Buffer(samples * 2, samples * 2, false));
    ASSERT_TRUE(audio->startRecording(false, AudioHardware::ESampleRate_44100,
            AudioHardware::EModeVoice, 100, buffer));
    ASSERT_TRUE(audio->waitForRecordingCompletion());
    ASSERT_TRUE(buffer->amountHandled() == (samples * 2));
}

生成ClientInterface使用到的工厂方法GenericFactory

#ifndef CTSAUDIO_GENERIC_FACTORY_H
#define CTSAUDIO_GENERIC_FACTORY_H
#include "task/TaskGeneric.h"
#include "ClientInterface.h"
/**
 * Factory methods for all abstract classes
 */
class GenericFactory {
public:
    virtual ClientInterface* createClientInterface();
    virtual TaskGeneric* createTask(TaskGeneric::TaskType type);
};
#endif


注释3:

根据RemoteAudio的指针获取设备信息

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值