任意の音声を入力する

SkyWay Linux®︎ SDK (以下、Linux SDK ) では、v3.2.0 から任意の音声の入力が行えます。

注意 本ドキュメントはクイックスタートを実施済みの方を対象としております。

利用方法

PcmAudioSource を作成し、 skyway::media::StreamFactory::CreateAudioStream に渡すことでPCM音声を入力とした stream を生成し、Publish できます。

この機能により、実際のマイク入力の代わりに任意の音声を AudioStream として入力することができます。

この機能を利用する前に、必要なヘッダーファイルを読み込む必要があります。 ご利用にあたって、以下のincludeディレクティブを追加してください。

#include <skyway/media/audio/pcm_audio_source.hpp>

skyway::Context::Setup を行う時に設定する skyway::Context::SkyWayOptions を以下のように設定してください。

skyway::Context::SkyWayOptions options; options.audio_backend = skyway::media::AudioBackendType::kNone;

注意 PCM音声入力機能をご利用になる場合は必ず audio_backendkNone に設定してください。

入力する音声の情報を設定し、 skyway::media::audio::PcmAudioSource::Create を呼び出すことで PcmAudioSource を生成できます。

下記のコードはサンプリング48kHz、2ch(ステレオ)の音声データを入力する場合の例です。

skyway::media::audio::interface::PcmAudioSource::Options options { // 入力する音声のサンプリングレート .sample_rate = 48000, // 入力する音声のチャンネル数 .channels = 2 }; auto audio_source = skyway::media::audio::PcmAudioSource::Create(options);

skyway::media::StreamFactory::CreateAudioStreamStream を生成し、この StreamLocalRoomMemberPublish できます。

auto stream = skyway::media::StreamFactory::CreateAudioStream(audio_source);

音声の入力は 10ms ごとに PcmAudioSource::PushPcmData を呼び出すことで行います。

呼び出し時には 10ms 分の音声フレームを引数として与えてください。

auto audio_thread = std::make_unique<std::thread>([this, audio_source] { std::vector<int16_t> frame; auto next = std::chrono::steady_clock::now(); while (true) { // ユーザーが用意した音声データを `frame` に代入します frame = CreateFrame(); // このメソッドはユーザー自身で用意する必要があります。 audio_source->PushPcmData(frame.data()); // 10ms 周期で呼び出してください。 next += std::chrono::milliseconds(10); std::this_thread::sleep_until(next); } });

サンプルコード

以下は、クイックスタートで作成するアプリを元にしたサンプルコードです。

このサンプルでは、 PcmAudioSource を用いてアプリケーション側で生成した音声(48kHz,ステレオ,短形波)を10msごとに入力し、AudioStream として Publish します。

まずは、今回のサンプルで使用する定数と音声フレームを生成するメソッドを作成します。

constexpr int kSampleRate = 48000; constexpr int kChannels = 2; constexpr int kFramesPer10ms = kSampleRate / 100; constexpr int kSamplesPer10ms = kFramesPer10ms * kChannels; constexpr int kFrequencyHz = 480; constexpr int kPeriodSampleCount = kSampleRate / kFrequencyHz; constexpr int16_t kAmplitude = 5000; void CreateFrame(std::vector<int16_t>& frame, int& phase_sample) { if (frame.size() != kSamplesPer10ms) { frame.resize(kSamplesPer10ms); } for (int i = 0; i < kFramesPer10ms; ++i) { int16_t v = (phase_sample < kPeriodSampleCount / 2) ? kAmplitude : static_cast<int16_t>(-kAmplitude); phase_sample++; if (phase_sample >= kPeriodSampleCount) { phase_sample = 0; } frame[i * kChannels + 0] = v; frame[i * kChannels + 1] = v; } }

次に、 PcmAudioSource を作成後、PcmAudioSource::PushPcmDataを用いて音声の入力を行います。

skyway::media::audio::interface::PcmAudioSource::Options options { .sample_rate = kSampleRate, .channels = kChannels }; auto audio_source = skyway::media::audio::PcmAudioSource::Create(options); std::shared_ptr<skyway::core::stream::local::LocalAudioStream> stream = skyway::media::StreamFactory::CreateAudioStream(audio_source); if (audio_source) { auto audio_thread = std::make_unique<std::thread>([this, audio_source] { std::vector<int16_t> frame; int phase_sample = 0; auto next = std::chrono::steady_clock::now(); while (!is_leaving_) { CreateFrame(frame, phase_sample); // 10ms周期で音声データを入力します。 audio_source->PushPcmData(frame.data()); next += std::chrono::milliseconds(10); std::this_thread::sleep_until(next); } }); threads_.emplace_back(std::move(audio_thread)); } skyway::room::interface::LocalRoomMember::PublicationOptions publication_options {}; auto publication = room_member_->Publish(stream, publication_options);