2017-03-17 10 views
1

をプレイされていて最終的にオーディオデバイスに送信される前にオーディオデータを変更することができます。ALSAフックは、オーディオを変更することは、私は基本的に私のオーディオストリームに「タップ」することを必要と心の中でいくつかの個人的なプロジェクトを持って、私はこの—と途方に暮れてよ

これらの個人プロジェクトの1つの例は、ソフトウェアベースのアクティブなクロスオーバです。 6チャンネルのオーディオデバイスがある場合は、データを読み込み、LPフィルタ(左+右)、BPフィルタ、HPフィルタを適用して出力します。 6つのチャンネルのそれぞれを通って流れます。

代わりにこの—を実行するプレーヤアプリケーションを作成する方法を知っていることに注意してください。これはすべてのソース(オーディオプレーヤー、ビデオプレーヤー、YouTubeまたは他のオーディオソースがウェブブラウザなど)は、この処理の対象となる。

私はいくつかの例を見てきました(例えば、alsa-projectウェブサイトのpcm_min.c、2004年9月のJeff TranterによるLinux Journalの記事の例を再生して記録します)が、私は持っていないようです上記のような何かをするのに十分な情報。

ご意見やご指摘をお待ちしております。

+1

これは、[外部フィルタプラグイン(http://www.alsa-project.org/alsa-doc/alsa-lib/group___p_c_m___ext_plug.html)のための仕事のように聞こえます。 (例えば、 'upmix'や' vdownmix'プラグインを参照してください) –

+0

私はこの権利を理解していますか? http://www.alsa-project.org/alsa-doc/alsa-lib/pcm_external_plugins.htmlのドキュメントから: "フィルタタイプのプラグインは、入力からフィードへのPCM信号を出力に変換するプラグインです"これは私が行ったことではありません---私は出力に送信されるデータを(トーテムまたはVLCビデオプレーヤーから、YouTubeまたは一般的にWebブラウザ、ゲームなどから)傍受したい、それを変更するチャンネル数の変更など)を行い、出力デバイスに進むことができます。私は誤解していますか?外部フィルタプラグインでこれを達成できますか? –

+1

これはまさにフィルタプラグインの機能です。 「入力」と「出力」は、別々のデバイスを指すのではなく、データの流れを指します。 –

答えて

0

あなたには、いくつかのコードをあなたの手が汚れて取得したい場合は、(ポール・デイヴィスは、Linuxのオーディオの第一人者である)ポール・デービスによってsome of these articlesをチェックアウトすることができます。ライブオーディオを取得するには、再生とキャプチャの例を組み合わせる必要があります。ショットを付けてください。問題がある場合は、コード固有の問題を投稿できます。

あなたは、ライブオーディオ作業を取得したら、LP filterを実装し、そこから行くことができます。

LP、HPやBPフィルタを実装するが、私はすべてのあなたの特定のチャンネル構成のために利用可能なのかはわからないLADSPAとLV2オーディオプラグインがたくさんあります。とにかく自分自身をロールしたいように思えます。

+0

はい、デジタルフィルタの部分は私のための簡単なものです...ペンティアム2世が地球を回り、C/C++ユーザージャーナルがまだ存在していた時代に、私はこの(おそらくきれいな)C++ FIRフィルタライブラリを作成しました。 C/C++ UJの記事を公開しました。誰かが好奇心が強い場合に備えて、私自身のコピーがあります:https://mochima.com/articles/FIR/FIR.html –

+0

@ Cal-linuxああ、そうですかなりクール。フィルタにDSPライブラリを使用しますか? – tay10r

+0

私はその点に着目すると、何がうまく機能しているかを決めることができます。もう一度、DSPの経験があります。それは私にストレスを与えない部分です:-)今日のPCでは、パフォーマンスは問題ではありません(私は知っている、知っている---有名な最後の言葉?:-)) –

0

プロジェクトをLADSPAプラグインとして実装し、audacityまたはLADSPAプラグインをサポートする他のプログラムでテストし、好きなときにalsa/pulseaudio/jack再生チェーンに挿入することができます。

「LADSPAは、」オーディオ処理プラグインを作成するための簡単なインタフェースを定義single header fileあります。各プラグインには入力/出力/制御ポートとrun()機能があります。 run()関数は、実際のオーディオ処理を行うためにサンプルブロックごとに実行されます。「制御」引数を「入力」バッファに適用し、結果を「出力」バッファに書き込みます。

例LADSPAステレオアンププラグイン(単一の制御引数:「増幅率」とは、2つの入力ポート、二つの出力ポート):

///gcc -shared -o /full/path/to/plugindir/amp_example.so amp_example.c 
#include <stdlib.h> 
#include "ladspa.h" 

enum PORTS { 
    PORT_CAMP, 
    PORT_INPUT1, 
    PORT_INPUT2, 
    PORT_OUTPUT1, 
    PORT_OUTPUT2 
}; 

typedef struct { 
    LADSPA_Data *c_amp; 
    LADSPA_Data *i_audio1; 
    LADSPA_Data *i_audio2; 
    LADSPA_Data *o_audio1; 
    LADSPA_Data *o_audio2; 
} MyAmpData; 

static LADSPA_Handle myamp_instantiate(const LADSPA_Descriptor *Descriptor, unsigned long SampleRate) 
{ 
    MyAmpData *data = (MyAmpData*)malloc(sizeof(MyAmpData)); 
    data->c_amp = NULL; 
    data->i_audio1 = NULL; 
    data->i_audio2 = NULL; 
    data->o_audio1 = NULL; 
    data->o_audio2 = NULL; 
    return data; 
} 

static void myamp_connect_port(LADSPA_Handle Instance, unsigned long Port, LADSPA_Data *DataLocation) 
{ 
    MyAmpData *data = (MyAmpData*)Instance; 
    switch (Port) 
    { 
    case PORT_CAMP: data->c_amp = DataLocation; break; 
    case PORT_INPUT1: data->i_audio1 = DataLocation; break; 
    case PORT_INPUT2: data->i_audio2 = DataLocation; break; 
    case PORT_OUTPUT1: data->o_audio1 = DataLocation; break; 
    case PORT_OUTPUT2: data->o_audio2 = DataLocation; break; 
    } 
} 

static void myamp_run(LADSPA_Handle Instance, unsigned long SampleCount) 
{ 
    MyAmpData *data = (MyAmpData*)Instance; 
    double amp = *data->c_amp; 
    size_t i; 
    for (i = 0; i < SampleCount; i++) 
    { 
    data->o_audio1[i] = data->i_audio1[i]*amp; 
    data->o_audio2[i] = data->i_audio2[i]*amp; 
    } 
} 

static void myamp_cleanup(LADSPA_Handle Instance) 
{ 
    MyAmpData *data = (MyAmpData*)Instance; 
    free(data); 
} 

static LADSPA_Descriptor myampDescriptor = { 
    .UniqueID = 123, // for public release see http://ladspa.org/ladspa_sdk/unique_ids.html 
    .Label = "amp_example", 
    .Name = "My Amplify Plugin", 
    .Maker = "alsauser", 
    .Copyright = "WTFPL", 
    .PortCount = 5, 
    .PortDescriptors = (LADSPA_PortDescriptor[]){ 
    LADSPA_PORT_INPUT | LADSPA_PORT_CONTROL, 
    LADSPA_PORT_INPUT | LADSPA_PORT_AUDIO, 
    LADSPA_PORT_INPUT | LADSPA_PORT_AUDIO, 
    LADSPA_PORT_OUTPUT | LADSPA_PORT_AUDIO, 
    LADSPA_PORT_OUTPUT | LADSPA_PORT_AUDIO 
    }, 
    .PortNames = (const char * const[]){ 
    "Amplification factor", 
    "Input left", 
    "Input right", 
    "Output left", 
    "Output right" 
    }, 
    .PortRangeHints = (LADSPA_PortRangeHint[]){ 
    { /* PORT_CAMP */ 
     LADSPA_HINT_BOUNDED_BELOW | LADSPA_HINT_BOUNDED_ABOVE | LADSPA_HINT_DEFAULT_1, 
     0, /* LowerBound*/ 
     10 /* UpperBound */ 
    }, 
    {0, 0, 0}, /* PORT_INPUT1 */ 
    {0, 0, 0}, /* PORT_INPUT2 */ 
    {0, 0, 0}, /* PORT_OUTPUT1 */ 
    {0, 0, 0} /* PORT_OUTPUT2 */ 
    }, 
    .instantiate = myamp_instantiate, 
    //.activate = myamp_activate, 
    .connect_port = myamp_connect_port, 
    .run = myamp_run, 
    //.deactivate = myamp_deactivate, 
    .cleanup = myamp_cleanup 
}; 

// NULL-terminated list of plugins in this library 
const LADSPA_Descriptor *ladspa_descriptor(unsigned long Index) 
{ 
    if (Index == 0) 
    return &myampDescriptor; 
    else 
    return NULL; 
} 

(あなたが「短い」40ラインを好む場合、バージョンhttps://pastebin.com/unCnjYfDを参照されたいです)

必要なだけ多くの入出力チャンネルを追加し、myamp_run()関数でコードを実装します。他のアプリはそれを見つけることができるように、プラグインを構築し、あなたがそれを構築したディレクトリにLADSPA_PATH環境変数を設定します。

export LADSPA_PATH=/usr/lib/ladspa:/full/path/to/plugindir 

audacityやLADSPAプラグインをサポートする他のプログラムでテストし、それを。

applyplugin input.wav output.wav /full/path/to/plugindir/amp_example.so amp_example 2 

をそして、あなたは結果を好きなら、あなたのデフォルトの再生チェーンに挿入:ターミナルでそれをテストするには、「LADSPA-SDK」パッケージからapplypluginツールを使用することができます。

# ~/.asoundrc 
pcm.myamp { 
    type plug 
    slave.pcm { 
    type ladspa 
    path "/usr/lib/ladspa" # required but ignored as `filename` is set 
    slave.pcm "sysdefault" 
    playback_plugins [{ 
     filename "/full/path/to/plugindir/amp_example.so" 
     label "amp_example" 
     input.controls [ 2.0 ] # Amplification=2 
    }] 
    } 
} 
# to test it: aplay -Dmyamp input.wav 

# to point "default" pcm to it uncomment next line: 
#pcm.!default "myamp" 

もご覧ください:プレーンALSAのためにあなたのような設定(パルス/ジャックのために動作しません)を使用することができます

関連する問題