[haiku-commits] haiku: hrev50076 - headers/private/media src/kits/media src/apps/soundrecorder

  • From: b.vitruvio@xxxxxxxxx
  • To: haiku-commits@xxxxxxxxxxxxx
  • Date: Tue, 9 Feb 2016 13:44:11 +0100 (CET)

hrev50076 adds 2 changesets to branch 'master'
old head: 801b3e3bf487edd9de0c68bdf44f749370849e38
new head: 7b83e044e7b0115b8e2a6e483efb3720b6d4fc4c
overview: 
http://cgit.haiku-os.org/haiku/log/?qt=range&q=7b83e044e7b0+%5E801b3e3bf487

----------------------------------------------------------------------------

2a2e352a4a58: BMediaRecorder: Rework to allow external connections
  
  * This required to review various parts of the code, and
  isn't probably still perfect. The main problem was an attributes
  hell where redondance created a lot of problems, all this data
  is now controlled mostly by the node.
  * Header indentation changes needed too.

7b83e044e7b0: SoundRecorder: Fix connection and disconnection from Cortex
  
  * SoundRecorder can now be connected and disconnected safely,
  due to some unknown reason, probably format negotiation problems,
  ATM we need a system mixer between.
  * The normal behavior is unchanged, when the record button is pressed
  it will record from the preferred audio interface and disconnect on
  stop. But when the connection is made manually it will stay connected
  until the user explictly disconnect it.
  * To make it work, instantiate a system mixer, connect the output to
  SoundRecorder, instantiate a node like the ToneProducer, and connect
  it's output to the mixer input. Press the record button and check
  the Mixer has started from the Cortex transport, if not, start it.

                                [ Dario Casalinuovo <b.vitruvio@xxxxxxxxx> ]

----------------------------------------------------------------------------

6 files changed, 147 insertions(+), 120 deletions(-)
headers/private/media/MediaRecorder.h     |  15 ++--
headers/private/media/MediaRecorderNode.h | 103 +++++++++++++-------------
src/apps/soundrecorder/RecorderWindow.cpp |  32 ++++----
src/apps/soundrecorder/RecorderWindow.h   |   1 +
src/kits/media/MediaRecorder.cpp          |  86 ++++++++++-----------
src/kits/media/MediaRecorderNode.cpp      |  30 ++++++--

############################################################################

Commit:      2a2e352a4a58214b162ed9dac27d898f1dc910ef
URL:         http://cgit.haiku-os.org/haiku/commit/?id=2a2e352a4a58
Author:      Dario Casalinuovo <b.vitruvio@xxxxxxxxx>
Date:        Tue Feb  9 12:33:09 2016 UTC

BMediaRecorder: Rework to allow external connections

* This required to review various parts of the code, and
isn't probably still perfect. The main problem was an attributes
hell where redondance created a lot of problems, all this data
is now controlled mostly by the node.
* Header indentation changes needed too.

----------------------------------------------------------------------------

diff --git a/headers/private/media/MediaRecorder.h 
b/headers/private/media/MediaRecorder.h
index 417be03..eeb64f0 100644
--- a/headers/private/media/MediaRecorder.h
+++ b/headers/private/media/MediaRecorder.h
@@ -46,6 +46,7 @@ public:
 
                        void                            SetAcceptedFormat(
                                                                        const 
media_format& format);
+                       const media_format&     AcceptedFormat() const;
 
        virtual status_t                        Start(bool force = false);
        virtual status_t                        Stop(bool force = false);
@@ -66,13 +67,18 @@ public:
 
                        const media_format&     Format() const;
 
-                       const media_output&     MediaOutput() const;
-                       const media_input&      MediaInput() const;
-
 protected:
+                       // Get the producer node source
+                       const media_source&     MediaSource() const;
+                       // This is the our own input
+                       const media_input&      MediaInput() const;
 
        virtual void                            BufferReceived(void* buffer, 
size_t size,
                                                                        const 
media_header& header);
+
+                       status_t                        
SetUpConnection(media_input ourInput,
+                                                                       
media_source outputSource);
+
 private:
 
                        status_t                        _Connect(const 
media_node& mediaNode,
@@ -98,10 +104,9 @@ private:
                        NotifyFunc                      fNotifyHook;
 
                        media_node                      fOutputNode;
-                       media_output            fOutput;
+                       media_source            fOutputSource;
 
                        BMediaRecorderNode*     fNode;
-                       media_input                     fInput;
 
                        void*                           fBufferCookie;
                        uint32                          fPadding[32];
diff --git a/headers/private/media/MediaRecorderNode.h 
b/headers/private/media/MediaRecorderNode.h
index 8a4f2fe..746e5ac 100644
--- a/headers/private/media/MediaRecorderNode.h
+++ b/headers/private/media/MediaRecorderNode.h
@@ -20,44 +20,45 @@ class BMediaRecorder;
 class BMediaRecorderNode : public BMediaEventLooper,
        public BBufferConsumer {
 public:
-                                                       
BMediaRecorderNode(const char* name,
-                                                               BMediaRecorder* 
recorder,
-                                                               media_type type
-                                                                       = 
B_MEDIA_UNKNOWN_TYPE);
+                                                               
BMediaRecorderNode(const char* name,
+                                                                       
BMediaRecorder* recorder,
+                                                                       
media_type type
+                                                                               
= B_MEDIA_UNKNOWN_TYPE);
 
                        //      TODO these are not thread safe; we should fix 
that...
-                       void                    SetAcceptedFormat(const 
media_format& format);
+                       void                            SetAcceptedFormat(const 
media_format& format);
+                       const media_format&     AcceptedFormat() const;
 
-                       status_t                GetInput(media_input* outInput);
+                       void                            GetInput(media_input* 
input);
 
-                       void                    SetDataEnabled(bool enabled);
+                       void                            SetDataEnabled(bool 
enabled);
 
 protected:
 
-       virtual BMediaAddOn*    AddOn(int32* id) const;
+       virtual BMediaAddOn*            AddOn(int32* id) const;
 
-       virtual void                    NodeRegistered();
+       virtual void                            NodeRegistered();
 
-       virtual void                    SetRunMode(run_mode mode);
+       virtual void                            SetRunMode(run_mode mode);
 
-       virtual void                    HandleEvent(const media_timed_event* 
event,
-                                                               bigtime_t 
lateness,
-                                                               bool 
realTimeEvent);
+       virtual void                            HandleEvent(const 
media_timed_event* event,
+                                                                       
bigtime_t lateness,
+                                                                       bool 
realTimeEvent);
 
-       virtual void                    Start(bigtime_t performanceTime);
+       virtual void                            Start(bigtime_t 
performanceTime);
 
-       virtual void                    Stop(bigtime_t performanceTime,
-                                                               bool immediate);
+       virtual void                            Stop(bigtime_t performanceTime,
+                                                                       bool 
immediate);
 
-       virtual void                    Seek(bigtime_t mediaTime,
-                                                               bigtime_t 
performanceTime);
+       virtual void                            Seek(bigtime_t mediaTime,
+                                                                       
bigtime_t performanceTime);
 
-       virtual void                    TimeWarp(bigtime_t realTime,
-                                                               bigtime_t 
performanceTime);
+       virtual void                            TimeWarp(bigtime_t realTime,
+                                                                       
bigtime_t performanceTime);
 
-       virtual status_t                HandleMessage(int32 message,
-                                                               const void* 
data,
-                                                               size_t size);
+       virtual status_t                        HandleMessage(int32 message,
+                                                                       const 
void* data,
+                                                                       size_t 
size);
 
                        // Someone, probably the producer, is asking you about
                        // this format. Give your honest opinion, possibly
@@ -65,46 +66,46 @@ protected:
                        //      the format, since he's synchronously waiting 
for your
                        // reply.
 
-       virtual status_t                AcceptFormat(const media_destination& 
dest,
-                                                               media_format* 
format);
+       virtual status_t                        AcceptFormat(const 
media_destination& dest,
+                                                                       
media_format* format);
 
-       virtual status_t                GetNextInput(int32* cookie,
-                                                               media_input* 
outInput);
+       virtual status_t                        GetNextInput(int32* cookie,
+                                                                       
media_input* outInput);
 
-       virtual void                    DisposeInputCookie(int32 cookie);
+       virtual void                            DisposeInputCookie(int32 
cookie);
 
-       virtual void                    BufferReceived(BBuffer* buffer);
+       virtual void                            BufferReceived(BBuffer* buffer);
 
-       virtual void                    ProducerDataStatus(
-                                                               const 
media_destination& destination,
-                                                               int32 status,
-                                                               bigtime_t 
performanceTime);
+       virtual void                            ProducerDataStatus(
+                                                                       const 
media_destination& destination,
+                                                                       int32 
status,
+                                                                       
bigtime_t performanceTime);
 
-       virtual status_t                GetLatencyFor(const media_destination& 
destination,
-                                                               bigtime_t* 
outLatency,
-                                                               media_node_id* 
outTimesource);
+       virtual status_t                        GetLatencyFor(const 
media_destination& destination,
+                                                                       
bigtime_t* outLatency,
+                                                                       
media_node_id* outTimesource);
 
-       virtual status_t                Connected(const media_source& producer,
-                                                               const 
media_destination& where,
-                                                               const 
media_format& format,
-                                                               media_input* 
outInput);
+       virtual status_t                        Connected(const media_source& 
producer,
+                                                                       const 
media_destination& where,
+                                                                       const 
media_format& format,
+                                                                       
media_input* outInput);
 
-       virtual void                    Disconnected(const media_source& 
producer,
-                                                               const 
media_destination& where);
+       virtual void                            Disconnected(const 
media_source& producer,
+                                                                       const 
media_destination& where);
 
-       virtual status_t                FormatChanged(const media_source& 
producer,
-                                                               const 
media_destination& consumer,
-                                                               int32 tag,
-                                                               const 
media_format& format);
+       virtual status_t                        FormatChanged(const 
media_source& producer,
+                                                                       const 
media_destination& consumer,
+                                                                       int32 
tag,
+                                                                       const 
media_format& format);
 
 protected:
 
-       virtual                                 ~BMediaRecorderNode();
+       virtual                                         ~BMediaRecorderNode();
 
-                       BMediaRecorder* fRecorder;
-                       media_format    fOKFormat;
-                       media_input             fInput;
-                       BString                 fName;
+                       BMediaRecorder*         fRecorder;
+                       media_format            fOKFormat;
+                       media_input                     fInput;
+                       BString                         fName;
 };
 
 }
diff --git a/src/kits/media/MediaRecorder.cpp b/src/kits/media/MediaRecorder.cpp
index d2d6be4..5738e93 100644
--- a/src/kits/media/MediaRecorder.cpp
+++ b/src/kits/media/MediaRecorder.cpp
@@ -72,6 +72,15 @@ BMediaRecorder::SetAcceptedFormat(const media_format& format)
 }
 
 
+const media_format&
+BMediaRecorder::AcceptedFormat() const
+{
+       CALLED();
+
+       return fNode->AcceptedFormat();
+}
+
+
 status_t
 BMediaRecorder::SetHooks(ProcessFunc recordFunc, NotifyFunc notifyFunc,
        void* cookie)
@@ -216,10 +225,13 @@ BMediaRecorder::Disconnect()
        if (err != B_OK)
                return err;
 
+       media_input ourInput;
+       fNode->GetInput(&ourInput);
+
        // do the disconnect
        err = BMediaRoster::CurrentRoster()->Disconnect(
-               fOutputNode.node, fOutput.source,
-                       fNode->Node().node, fInput.destination);
+               fOutputNode.node, fOutputSource,
+                       fNode->Node().node, ourInput.destination);
 
        if (fReleaseOutputNode) {
                BMediaRoster::Roster()->ReleaseNode(fOutputNode);
@@ -312,12 +324,12 @@ BMediaRecorder::IsConnected() const
 }
 
 
-const media_output&
-BMediaRecorder::MediaOutput() const
+const media_source&
+BMediaRecorder::MediaSource() const
 {
        CALLED();
 
-       return fOutput;
+       return fOutputSource;
 }
 
 
@@ -326,7 +338,9 @@ BMediaRecorder::MediaInput() const
 {
        CALLED();
 
-       return fInput;
+       media_input* input = NULL;
+       fNode->GetInput(input);
+       return *input;
 }
 
 
@@ -335,7 +349,25 @@ BMediaRecorder::Format() const
 {
        CALLED();
 
-       return fOutput.format;
+       return fNode->AcceptedFormat();
+}
+
+
+status_t
+BMediaRecorder::SetUpConnection(media_input ourInput, media_source 
outputSource)
+{
+       fOutputSource = outputSource;
+
+       // Perform the connection
+       media_node timeSource;
+       if ((fOutputNode.kind & B_TIME_SOURCE) != 0)
+               timeSource = fOutputNode;
+       else
+               BMediaRoster::Roster()->GetTimeSource(&timeSource);
+
+       // Set time source
+       return BMediaRoster::Roster()->SetTimeSourceFor(fNode->Node().node,
+               timeSource.node);
 }
 
 
@@ -381,45 +413,15 @@ BMediaRecorder::_Connect(const media_node& node,
        if (ourOutput.source == media_source::null)
                return B_MEDIA_BAD_SOURCE;
 
+       fOutputSource = ourOutput.source;
+
        // find our Node's free input
        media_input ourInput;
-       err = fNode->GetInput(&ourInput);
-       if (err != B_OK)
-               return err;
-
-       media_node timeSource;
-       if ((node.kind & B_TIME_SOURCE) != 0)
-               timeSource = node;
-       else
-               BMediaRoster::Roster()->GetTimeSource(&timeSource);
-
-       // set time source
-       err = BMediaRoster::Roster()->SetTimeSourceFor(fNode->Node().node,
-               timeSource.node);
-
-       if (err != B_OK)
-               return err;
+       fNode->GetInput(&ourInput);
 
-       // start the recorder node (it's always running)
-       err = BMediaRoster::CurrentRoster()->StartNode(fOutputNode,
-               fNode->TimeSource()->Now());
-
-       if (err != B_OK)
-               return err;
-
-       // perform the connection
-       fOutput = ourOutput;
-       fInput = ourInput;
-
-       err = BMediaRoster::CurrentRoster()->Connect(fOutput.source,
-               fInput.destination, &ourFormat, &fOutput, &fInput,
+       return BMediaRoster::CurrentRoster()->Connect(fOutputSource,
+               ourInput.destination, &ourFormat, &ourOutput, &ourInput,
                BMediaRoster::B_CONNECT_MUTED);
-
-       if (err != B_OK)
-               return err;
-
-       fConnected = true;
-       return B_OK;
 }
 
 
diff --git a/src/kits/media/MediaRecorderNode.cpp 
b/src/kits/media/MediaRecorderNode.cpp
index bb6d5be..87ef527 100644
--- a/src/kits/media/MediaRecorderNode.cpp
+++ b/src/kits/media/MediaRecorderNode.cpp
@@ -10,6 +10,8 @@
 
 #include <Buffer.h>
 #include <scheduler.h>
+#include <MediaRoster.h>
+#include <MediaRosterEx.h>
 #include <TimedEventQueue.h>
 #include <TimeSource.h>
 
@@ -27,6 +29,7 @@ BMediaRecorderNode::BMediaRecorderNode(const char* name,
 {
        CALLED();
 
+       fInput.node = Node();
        fInput.destination.id = 1;
        fInput.destination.port = ControlPort();
 
@@ -105,15 +108,22 @@ BMediaRecorderNode::SetAcceptedFormat(const media_format& 
format)
 }
 
 
-status_t
+const media_format&
+BMediaRecorderNode::AcceptedFormat() const
+{
+       CALLED();
+
+       return fOKFormat;
+}
+
+
+void
 BMediaRecorderNode::GetInput(media_input* outInput)
 {
        CALLED();
 
        fInput.node = Node();
        *outInput = fInput;
-
-       return B_OK;
 }
 
 
@@ -287,8 +297,16 @@ BMediaRecorderNode::Connected(const media_source &producer,
        fInput.format = withFormat;
        *outInput = fInput;
 
+       // This is a workaround needed for us to get the node
+       // so that our owner class can do it's operations.
+       media_node node;
+       BMediaRosterEx* roster = MediaRosterEx(BMediaRoster::CurrentRoster());
+       roster->GetNodeFor(roster->NodeIDFor(producer.port), &node);
+       fRecorder->fOutputNode = node;
+       fRecorder->fReleaseOutputNode = true;
+
+       fRecorder->SetUpConnection(fInput, producer);
        fRecorder->fConnected = true;
-       fRecorder->fInput = fInput;
 
        return B_OK;
 }
@@ -301,10 +319,8 @@ BMediaRecorderNode::Disconnected(const media_source& 
producer,
        CALLED();
 
        fInput.source = media_source::null;
-
        fRecorder->fConnected = false;
-
-       fRecorder->fInput.format = fOKFormat;
+       fInput.format = fOKFormat;
 }
 
 

############################################################################

Revision:    hrev50076
Commit:      7b83e044e7b0115b8e2a6e483efb3720b6d4fc4c
URL:         http://cgit.haiku-os.org/haiku/commit/?id=7b83e044e7b0
Author:      Dario Casalinuovo <b.vitruvio@xxxxxxxxx>
Date:        Tue Feb  9 12:23:14 2016 UTC

SoundRecorder: Fix connection and disconnection from Cortex

* SoundRecorder can now be connected and disconnected safely,
due to some unknown reason, probably format negotiation problems,
ATM we need a system mixer between.
* The normal behavior is unchanged, when the record button is pressed
it will record from the preferred audio interface and disconnect on
stop. But when the connection is made manually it will stay connected
until the user explictly disconnect it.
* To make it work, instantiate a system mixer, connect the output to
SoundRecorder, instantiate a node like the ToneProducer, and connect
it's output to the mixer input. Press the record button and check
the Mixer has started from the Cortex transport, if not, start it.

----------------------------------------------------------------------------

diff --git a/src/apps/soundrecorder/RecorderWindow.cpp 
b/src/apps/soundrecorder/RecorderWindow.cpp
index aebfc7f..06bcdc6 100644
--- a/src/apps/soundrecorder/RecorderWindow.cpp
+++ b/src/apps/soundrecorder/RecorderWindow.cpp
@@ -125,6 +125,7 @@ RecorderWindow::RecorderWindow()
        fInputField = NULL;
        fRecorder = NULL;
        fRecording = false;
+       fExternalConnection = false;
        fTempCount = -1;
        fButtonState = btnPaused;
 
@@ -693,7 +694,7 @@ RecorderWindow::Record(BMessage * message)
 
        fRecFile.Seek(sizeof(struct wave_struct), SEEK_SET);
 
-       //      Hook up input
+       // Hook up input
        err = MakeRecordConnection(fAudioInputNode);
        if (err < B_OK) {
                ErrorAlert(B_TRANSLATE("Cannot connect to the selected sound 
input"),
@@ -702,7 +703,6 @@ RecorderWindow::Record(BMessage * message)
                fRecEntry.Unset();
                return;
        }
-
        fRecorder->Start();
 }
 
@@ -892,15 +892,14 @@ RecorderWindow::MakeRecordConnection(const media_node & 
input)
                        return B_BUSY;
                }
 
+               // Get a format, any format.
+               fRecordFormat.u.raw_audio = audioOutput.format.u.raw_audio;
+               fExternalConnection = false;
        } else {
-               CONNECT((stderr, "RecorderWindow::MakeRecordConnection():"
-                       " audio input node already connected\n"));
-
-               return B_BUSY;
+               fRecordFormat.u.raw_audio = 
fRecorder->AcceptedFormat().u.raw_audio;
+               fExternalConnection = true;
        }
 
-       //      Get a format, any format.
-       fRecordFormat.u.raw_audio = audioOutput.format.u.raw_audio;
        fRecordFormat.type = B_MEDIA_RAW_AUDIO;
 
        //      Tell the consumer where we want data to go.
@@ -932,12 +931,6 @@ RecorderWindow::MakeRecordConnection(const media_node & 
input)
 status_t
 RecorderWindow::BreakRecordConnection()
 {
-       status_t err = B_OK;
-
-       err = fRecorder->Stop(true);
-       if (err < B_OK)
-               return err;
-
        return fRecorder->Disconnect();
 }
 
@@ -949,7 +942,16 @@ RecorderWindow::StopRecording()
                return B_OK;
        fRecording = false;
 
-       BreakRecordConnection();
+       status_t err = B_OK;
+       err = fRecorder->Stop(true);
+       if (err < B_OK)
+               return err;
+
+       // We maintain the connection active
+       // if the user connected us from Cortex.
+       if (!fExternalConnection) {
+               BreakRecordConnection();
+       }
 
        fRecorder->SetHooks(NULL, NULL, NULL);
 
diff --git a/src/apps/soundrecorder/RecorderWindow.h 
b/src/apps/soundrecorder/RecorderWindow.h
index d0c405e..9cf0893 100644
--- a/src/apps/soundrecorder/RecorderWindow.h
+++ b/src/apps/soundrecorder/RecorderWindow.h
@@ -96,6 +96,7 @@ private:
                BMediaRecorder * fRecorder;
                BSoundPlayer * fPlayer;
                bool fRecording;
+               bool fExternalConnection;
                SoundListView * fSoundList;
                BDirectory fTempDir;
                int fTempCount;


Other related posts:

  • » [haiku-commits] haiku: hrev50076 - headers/private/media src/kits/media src/apps/soundrecorder - b . vitruvio