<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
</head>
<body bgcolor="#ffffff" text="#000000">
Hi,<br>
<br>
Attached a patch that places the AudioSources/Sinks in the
Networkplayer, thus separating them from the actual backend - which
have it's own details, but the loops are all the same.<br>
<br>
It passes all tests (unit, functional, back2back) and networks play.<br>
 <br>
However, I am not happy with two things:<br>
- the timing: the copy is done in SetNetworkBackLink<br>
- it's a copy, so it does not reflect changes in the network<br>
<br>
So, second try was with GetAudioSources/Sinks (which gives an up to
date copy). It works, but now it is called a lot in loops in the player
- which I don't think it was meant for. However, this was the case in
the PA backend, so it might be fine.<br>
<br>
The question that I have more or less is 'who should own who', I mean
the network has a pointer to a player and the player has a pointer to
the network. This feels a bit circular.<br>
<br>
Code example:<br>
<br>
<tt><small>    void testAnalysisSynthesisInaNetwork()<br>
    {<br>
        //CLAM::ErrAssertionFailed::breakpointInCLAMAssertEnabled =
true;<br>
        CLAM::Network net;<br>
        CLAM::MonoOfflineNetworkPlayer * player =  new
CLAM::MonoOfflineNetworkPlayer;<br>
<br>
        <b>net.SetPlayer( player );</b> // network owns the player
memory (and sets backlink!)<br>
<br>
        net.AddProcessing( "Source", new CLAM::AudioSource );<br>
        net.AddProcessing( "Sink", new CLAM::AudioSink );<br>
        net.AddProcessing( "Analysis", new CLAM::SMSAnalysisCore );<br>
        net.AddProcessing( "Synthesis", new CLAM::SMSSynthesis );<br>
<br>
        net.ConnectPorts("Source.1", "Analysis.Input Audio");<br>
        net.ConnectPorts("Analysis.Sinusoidal Peaks",
"Synthesis.InputSinPeaks");<br>
        net.ConnectPorts("Analysis.Residual Spectrum",
"Synthesis.InputResSpectrum");<br>
        net.ConnectPorts("Synthesis.OutputAudio", "Sink.1");<br>
        net.ConfigureProcessing("Analysis",
helperAnalysisConfigInstance() );<br>
        net.ConfigureProcessing("Synthesis",
helperSynthesisConfigInstance() );<br>
<br>
        std::string inputFile = GetTestDataDirectory("Elvis.wav");<br>
        std::string baseOutputFile =
GetTestDataDirectory("SMSTests/out_sms_net_stream");<br>
        player->AddInputFile(inputFile);<br>
        player->AddOutputFile(baseOutputFile+"_result.wav");<br>
        net.Start();<br>
        net.Stop();<br>
</small></tt><br>
Why does not the player start things:<br>
<br>
<tt><small>        player->AddInputFile(inputFile);<br>
        player->AddOutputFile(baseOutputFile+"_result.wav");<br>
        </small></tt><tt><small>player-></small></tt><tt><small>Start();<br>
        </small></tt><tt><small>player-></small></tt><tt><small>Stop();<br>
</small></tt><br>
Then the code then becomes<br>
<br>
<tt><small>        CLAM::Network net;<br>
        net.AddProcessing( "Source", new CLAM::AudioSource );<br>
        net.AddProcessing( "Sink", new CLAM::AudioSink );<br>
        net.AddProcessing( "Analysis", new CLAM::SMSAnalysisCore );<br>
        net.AddProcessing( "Synthesis", new CLAM::SMSSynthesis );<br>
        net.ConnectPorts("Source.1", "Analysis.Input Audio");<br>
        net.ConnectPorts("Analysis.Sinusoidal Peaks",
"Synthesis.InputSinPeaks");<br>
        net.ConnectPorts("Analysis.Residual Spectrum",
"Synthesis.InputResSpectrum");<br>
        net.ConnectPorts("Synthesis.OutputAudio", "Sink.1");<br>
        net.ConfigureProcessing("Analysis",
helperAnalysisConfigInstance() );<br>
        net.ConfigureProcessing("Synthesis",
helperSynthesisConfigInstance() );<br>
</small></tt><br>
<tt><small>        std::string inputFile =
GetTestDataDirectory("Elvis.wav");<br>
        std::string baseOutputFile =
GetTestDataDirectory("SMSTests/out_sms_net_stream");<br>
<br>
</small></tt><tt><small>        CLAM::MonoOfflineNetworkPlayer
player(net); // on the stack and by reference</small></tt><br>
<tt><small>        player->AddInputFile(inputFile);<br>
        player->AddOutputFile(baseOutputFile+"_result.wav");<br>
</small></tt><tt><small>        </small></tt><tt><small>player-></small></tt><tt><small>Start();<br>
        </small></tt><tt><small>player-></small></tt><tt><small>Stop();<br>
</small></tt><br>
And the player could set references to sources/sinks in its constructor
(not shown). But I probably am missing something here.<br>
<br>
The second question is 'how to update jack to reflect changes in the
network dynamically'. <br>
<br>
This can be solved either way: the network changes so it calls the
player:<br>
- if the player owns the net then the net would call into the player
on_change (I would use boost::function (to decouple) but a backlink
would work the same)<br>
- if the net owns the player then it calls registerports on the player
(but you need the networkbacklink in the player)<br>
<br>
What would be preferable?<br>
<br>
Dirk<br>
<br>
<br>
</body>
</html>