blob: b8c5c375d542dbecaaf81f86bfb7d3654b7dc83d [file] [log] [blame]
// Copyright 2018 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include <lib/async-loop/cpp/loop.h>
#include <lib/async/cpp/task.h>
#include "garnet/bin/media/signal_generator/signal_generator.h"
#include "lib/app/cpp/startup_context.h"
#include "lib/fxl/command_line.h"
#include "lib/fxl/strings/string_number_conversions.h"
namespace {
constexpr char kNumChannelsSwitch[] = "chans";
constexpr char kNumChannelsDefault[] = "2";
constexpr char kFrameRateSwitch[] = "rate";
constexpr char kFrameRateDefaultHz[] = "48000";
constexpr char kInt16FormatSwitch[] = "int";
constexpr char kSineWaveSwitch[] = "sine";
constexpr char kSquareWaveSwitch[] = "square";
constexpr char kSawtoothWaveSwitch[] = "saw";
constexpr char kWhiteNoiseSwitch[] = "noise";
constexpr char kFrequencyDefaultHz[] = "400";
constexpr char kAmplitudeSwitch[] = "amp";
constexpr char kAmplitudeDefaultScale[] = "0.5";
constexpr char kDurationSwitch[] = "dur";
constexpr char kDurationDefaultSecs[] = "2";
constexpr char kMSecPerPayloadSwitch[] = "ms";
constexpr char kMSecPerPayloadDefault[] = "10";
constexpr char kSaveToFileSwitch[] = "wav";
constexpr char kSaveToFileDefaultName[] = "/tmp/signal_generator.wav";
constexpr char kRendererGainSwitch[] = "rgain";
constexpr char kRendererGainDefaultDb[] = "0.0";
constexpr char kSystemGainSwitch[] = "sgain";
constexpr char kSystemGainDefaultDb[] = "-12.0";
constexpr char kPlayToLastSwitch[] = "last";
constexpr char kPlayToAllSwitch[] = "all";
constexpr char kHelpSwitch[] = "help";
} // namespace
void usage(const char* prog_name) {
printf("\nUsage: %s [--option] [...]\n", prog_name);
printf("Generate and play an audio signal to the preferred renderer.\n");
printf("\nAdditional optional settings include:\n");
printf("\t--%s=<NUM_CHANS>\tSpecify number of output channels (default %s)\n",
kNumChannelsSwitch, kNumChannelsDefault);
printf("\t--%s=<FRAME_RATE>\tSet output frame rate in Hertz (default %s)\n",
kFrameRateSwitch, kFrameRateDefaultHz);
printf("\t--%s, --i\t\tEmit signal as 16-bit integer (default float32)\n",
kInt16FormatSwitch);
printf(
"\n\t--%s[=<FREQ>] \tPlay sine of given frequency, in Hz (default %s)\n",
kSineWaveSwitch, kFrequencyDefaultHz);
printf("\t--%s[=<FREQ>] \tPlay square wave (default %s Hz)\n",
kSquareWaveSwitch, kFrequencyDefaultHz);
printf("\t--%s[=<FREQ>] \tPlay rising sawtooth wave (default %s Hz)\n",
kSawtoothWaveSwitch, kFrequencyDefaultHz);
printf("\t--%s \t\tPlay pseudo-random 'white' noise\n", kWhiteNoiseSwitch);
printf("\t\t\t\tIn the absence of --%s, --%s or --%s, a sine is played\n",
kSquareWaveSwitch, kSawtoothWaveSwitch, kWhiteNoiseSwitch);
printf(
"\n\t--%s=<AMPL>\t\tSet signal amplitude (full-scale=1.0, default %s)\n",
kAmplitudeSwitch, kAmplitudeDefaultScale);
printf("\n\t--%s=<DURATION>\tSet playback length, in seconds (default %s)\n",
kDurationSwitch, kDurationDefaultSecs);
printf(
"\t--%s=<MSEC>\t\tSet data buffer size, in milliseconds (default %s)\n",
kMSecPerPayloadSwitch, kMSecPerPayloadDefault);
printf("\n\t--%s[=<FILEPATH>]\tAlso save signal to .wav file (default %s)\n",
kSaveToFileSwitch, kSaveToFileDefaultName);
printf("\t\t\t\tNote: .wav file contents are unaffected by gain settings\n");
printf(
"\n\t--%s=<GAIN>\t\tSet Renderer gain to [%.1f, %.1f] dB (default %s)\n",
kRendererGainSwitch, fuchsia::media::kMutedGain, fuchsia::media::kMaxGain,
kRendererGainDefaultDb);
printf("\t--%s=<GAIN>\t\tSet System gain to [%.1f, 0.0] dB (default %s)\n",
kSystemGainSwitch, fuchsia::media::kMutedGain, kSystemGainDefaultDb);
printf("\t\t\t\tNote: changes to System gain persist after playback.\n");
printf("\n\t--%s\t\t\tSet 'Play to Most-Recently-Plugged' policy\n",
kPlayToLastSwitch);
printf("\t--%s\t\t\tSet 'Play to All' policy\n", kPlayToAllSwitch);
printf("\t\t\t\tNote: changes to audio policy persist after playback.\n");
printf("\n\t--%s, --?\t\tShow this message\n\n", kHelpSwitch);
}
int main(int argc, const char** argv) {
const auto command_line = fxl::CommandLineFromArgcArgv(argc, argv);
if (command_line.HasOption("?") || command_line.HasOption(kHelpSwitch)) {
usage(argv[0]);
return 0;
}
async::Loop loop(&kAsyncLoopConfigMakeDefault);
auto startup_context = fuchsia::sys::StartupContext::CreateFromStartupInfo();
media::tools::MediaApp media_app(
[&loop]() { async::PostTask(loop.async(), [&loop]() { loop.Quit(); }); });
std::string num_channels_str = command_line.GetOptionValueWithDefault(
kNumChannelsSwitch, kNumChannelsDefault);
media_app.set_num_channels(fxl::StringToNumber<uint32_t>(num_channels_str));
std::string frame_rate_str = command_line.GetOptionValueWithDefault(
kFrameRateSwitch, kFrameRateDefaultHz);
media_app.set_frame_rate(fxl::StringToNumber<uint32_t>(frame_rate_str));
if (command_line.HasOption("i") ||
command_line.HasOption(kInt16FormatSwitch)) {
media_app.set_int16_format(true);
}
if (command_line.HasOption(kWhiteNoiseSwitch)) {
media_app.set_output_type(media::tools::kOutputTypeNoise);
} else {
std::string frequency_str;
if (command_line.HasOption(kSquareWaveSwitch)) {
media_app.set_output_type(media::tools::kOutputTypeSquare);
command_line.GetOptionValue(kSquareWaveSwitch, &frequency_str);
} else if (command_line.HasOption(kSawtoothWaveSwitch)) {
media_app.set_output_type(media::tools::kOutputTypeSawtooth);
command_line.GetOptionValue(kSawtoothWaveSwitch, &frequency_str);
} else {
media_app.set_output_type(media::tools::kOutputTypeSine);
command_line.GetOptionValue(kSineWaveSwitch, &frequency_str);
}
if (frequency_str == "") {
frequency_str = kFrequencyDefaultHz;
}
media_app.set_frequency(fxl::StringToNumber<uint32_t>(frequency_str));
}
std::string amplitude_str = command_line.GetOptionValueWithDefault(
kAmplitudeSwitch, kAmplitudeDefaultScale);
media_app.set_amplitude(std::stof(amplitude_str));
std::string duration_str = command_line.GetOptionValueWithDefault(
kDurationSwitch, kDurationDefaultSecs);
media_app.set_duration(fxl::StringToNumber<uint32_t>(duration_str));
std::string msec_per_payload_str = command_line.GetOptionValueWithDefault(
kMSecPerPayloadSwitch, kMSecPerPayloadDefault);
media_app.set_msec_per_payload(
fxl::StringToNumber<uint32_t>(msec_per_payload_str));
std::string renderer_gain_str = command_line.GetOptionValueWithDefault(
kRendererGainSwitch, kRendererGainDefaultDb);
media_app.set_renderer_gain(std::stof(renderer_gain_str));
if (command_line.HasOption(kSystemGainSwitch)) {
media_app.set_will_set_system_gain(
command_line.HasOption(kSystemGainSwitch));
std::string system_gain_str = command_line.GetOptionValueWithDefault(
kSystemGainSwitch, kSystemGainDefaultDb);
media_app.set_system_gain(std::stof(system_gain_str));
}
if (command_line.HasOption(kPlayToLastSwitch)) {
if (command_line.HasOption(kPlayToAllSwitch)) {
usage(argv[0]);
return 0;
}
media_app.set_will_set_audio_policy(true);
media_app.set_audio_policy(
fuchsia::media::AudioOutputRoutingPolicy::kLastPluggedOutput);
}
if (command_line.HasOption(kPlayToAllSwitch)) {
media_app.set_will_set_audio_policy(true);
media_app.set_audio_policy(
fuchsia::media::AudioOutputRoutingPolicy::kAllPluggedOutputs);
}
if (command_line.HasOption(kSaveToFileSwitch)) {
media_app.set_save_to_file(command_line.HasOption(kSaveToFileSwitch));
media_app.set_save_file_name(command_line.GetOptionValueWithDefault(
kSaveToFileSwitch, kSaveToFileDefaultName));
}
media_app.Run(startup_context.get());
// We've set everything going. Wait for our message loop to return.
loop.Run();
return 0;
}