diff --git a/src/apps/soundrecorder/FileUtils.cpp b/src/apps/soundrecorder/FileUtils.cpp index 3912046dda..1d9af2498c 100644 --- a/src/apps/soundrecorder/FileUtils.cpp +++ b/src/apps/soundrecorder/FileUtils.cpp @@ -7,14 +7,22 @@ / Copyright 1998-1999, Be Incorporated, All Rights Reserved / *******************************************************************************/ - - -#include -#include -#include "array_delete.h" #include "FileUtils.h" -status_t CopyFileData(BFile& dst, BFile& src) +#include +#include +#include + +#include + +#include "AutoDeleter.h" + + +using std::nothrow; + + +status_t +CopyFileData(BFile& dst, BFile& src) { struct stat src_stat; status_t err = src.GetStat(&src_stat); @@ -24,12 +32,13 @@ status_t CopyFileData(BFile& dst, BFile& src) } size_t bufSize = src_stat.st_blksize; - if (! bufSize) { + if (bufSize == 0) bufSize = 32768; - } - char* buf = new char[bufSize]; - array_delete bufDelete(buf); + char* buf = new (nothrow) char[bufSize]; + if (buf == NULL) + return B_NO_MEMORY; + ArrayDeleter _(buf); printf("copy data, bufSize = %ld\n", bufSize); // copy data @@ -38,14 +47,18 @@ status_t CopyFileData(BFile& dst, BFile& src) if (bytes > 0) { ssize_t result = dst.Write(buf, bytes); if (result != bytes) { - printf("result = %#010lx, bytes = %#010lx\n", (uint32) result, - (uint32) bytes); - return B_ERROR; + fprintf(stderr, "Failed to write %ld bytes: %s\n", bytes, + strerror((status_t)result)); + if (result < 0) + return (status_t)result; + else + return B_IO_ERROR; } } else { if (bytes < 0) { - printf(" bytes = %#010lx\n", (uint32) bytes); - return bytes; + fprintf(stderr, "Failed to read file: %s\n", strerror( + (status_t)bytes)); + return (status_t)bytes; } else { // EOF break; @@ -64,25 +77,49 @@ status_t CopyFileData(BFile& dst, BFile& src) } -status_t CopyAttributes(BNode& dst, BNode& src) +status_t +CopyAttributes(BNode& dst, BNode& src) { // copy attributes src.RewindAttrs(); - char name[B_ATTR_NAME_LENGTH]; - while (src.GetNextAttrName(name) == B_OK) { + char attrName[B_ATTR_NAME_LENGTH]; + while (src.GetNextAttrName(attrName) == B_OK) { attr_info info; - if (src.GetAttrInfo(name, &info) == B_OK) { - size_t bufSize = info.size; - char* buf = new char[bufSize]; - array_delete bufDelete = buf; - - // copy one attribute - ssize_t bytes = src.ReadAttr(name, info.type, 0, buf, bufSize); - if (bytes > 0) { - dst.WriteAttr(name, info.type, 0, buf, bufSize); - } else { - return bytes; + if (src.GetAttrInfo(attrName, &info) != B_OK) { + fprintf(stderr, "Failed to read info for attribute '%s'\n", + attrName); + continue; + } + // copy one attribute in chunks of 4096 bytes + size_t size = 4096; + uint8 buffer[size]; + off_t offset = 0; + ssize_t read = src.ReadAttr(attrName, info.type, offset, buffer, + min_c(size, info.size)); + if (read < 0) { + fprintf(stderr, "Error reading attribute '%s'\n", attrName); + return (status_t)read; + } + // NOTE: Attributes of size 0 are perfectly valid! + while (read >= 0) { + ssize_t written = dst.WriteAttr(attrName, info.type, offset, buffer, + read); + if (written != read) { + fprintf(stderr, "Error writing attribute '%s'\n", attrName); + if (written < 0) + return (status_t)written; + else + return B_IO_ERROR; } + offset += read; + read = src.ReadAttr(attrName, info.type, offset, buffer, + min_c(size, info.size - offset)); + if (read < 0) { + fprintf(stderr, "Error reading attribute '%s'\n", attrName); + return (status_t)read; + } + if (read == 0) + break; } } @@ -90,7 +127,8 @@ status_t CopyAttributes(BNode& dst, BNode& src) } -status_t CopyFile(BFile& dst, BFile& src) +status_t +CopyFile(BFile& dst, BFile& src) { status_t err = CopyFileData(dst, src); if (err != B_OK) diff --git a/src/apps/soundrecorder/Jamfile b/src/apps/soundrecorder/Jamfile index 7575178d38..d70dcde256 100644 --- a/src/apps/soundrecorder/Jamfile +++ b/src/apps/soundrecorder/Jamfile @@ -2,6 +2,8 @@ SubDir HAIKU_TOP src apps soundrecorder ; SetSubDirSupportedPlatformsBeOSCompatible ; +UsePrivateHeaders shared ; + Application SoundRecorder : DrawButton.cpp DrawingTidbits.cpp diff --git a/src/apps/soundrecorder/RecorderWindow.cpp b/src/apps/soundrecorder/RecorderWindow.cpp index e7248c4fb7..3235d53b23 100644 --- a/src/apps/soundrecorder/RecorderWindow.cpp +++ b/src/apps/soundrecorder/RecorderWindow.cpp @@ -43,7 +43,6 @@ #include "RecorderWindow.h" #include "SoundConsumer.h" #include "SoundListView.h" -#include "array_delete.h" #include "FileUtils.h" #if ! NDEBUG diff --git a/src/apps/soundrecorder/SoundConsumer.cpp b/src/apps/soundrecorder/SoundConsumer.cpp index 3377b84f37..d01acef26f 100644 --- a/src/apps/soundrecorder/SoundConsumer.cpp +++ b/src/apps/soundrecorder/SoundConsumer.cpp @@ -7,7 +7,9 @@ / Copyright 1998-1999, Be Incorporated, All Rights Reserved / *******************************************************************************/ +#include "SoundConsumer.h" +#include #include #include @@ -15,9 +17,11 @@ #include #include +#include "AutoDeleter.h" #include "SoundPrivate.h" -#include "SoundConsumer.h" -#include "array_delete.h" + + +using std::nothrow; // If we don't mind the format changing to another format while @@ -55,7 +59,8 @@ SoundConsumer::SoundConsumer( BMediaNode(name ? name : "SoundConsumer"), BBufferConsumer(B_MEDIA_RAW_AUDIO) { - NODE(stderr, "SoundConsumer::SoundConsumer(%p, %p, %p, %p)\n", name, recordFunc, notifyFunc, cookie); + NODE(stderr, "SoundConsumer::SoundConsumer(%p, %p, %p, %p)\n", name, + recordFunc, notifyFunc, cookie); if (!name) name = "SoundConsumer"; @@ -105,10 +110,8 @@ SoundConsumer::~SoundConsumer() status_t -SoundConsumer::SetHooks( - SoundProcessFunc recordFunc, - SoundNotifyFunc notifyFunc, - void * cookie) +SoundConsumer::SetHooks(SoundProcessFunc recordFunc, SoundNotifyFunc notifyFunc, + void* cookie) { // SetHooks needs to be synchronized with the service thread, else we may // call the wrong hook function with the wrong cookie, which would be bad. @@ -134,31 +137,27 @@ SoundConsumer::SetHooks( } // Clean up. delete_port(cmd.reply); - } - else { - // Within the service thread, it's OK to just go ahead and do the change. + } else { + // Within the service thread, it's OK to just go ahead and do the + // change. DoHookChange(&cmd); } return err; } - -//////////////////////////////////////////////////////////////////////////////// -// -// BMediaNode-derived methods -// -//////////////////////////////////////////////////////////////////////////////// +// #pragma mark -BMediaNode-derived methods -port_id SoundConsumer::ControlPort() const +port_id +SoundConsumer::ControlPort() const { return m_port; } -BMediaAddOn* SoundConsumer::AddOn( - int32 * internal_id) const +BMediaAddOn* +SoundConsumer::AddOn(int32 * internal_id) const { // This object is instantiated inside an application. // Therefore, it has no add-on. @@ -167,8 +166,8 @@ BMediaAddOn* SoundConsumer::AddOn( } -void SoundConsumer::Start( - bigtime_t performance_time) +void +SoundConsumer::Start(bigtime_t performance_time) { // Since we are a consumer and just blindly accept buffers that are // thrown at us, we don't need to do anything special in Start()/Stop(). @@ -180,18 +179,15 @@ void SoundConsumer::Start( m_delta = performance_time - m_tmSeekTo; m_seeking = false; } - if (m_notifyHook) { + if (m_notifyHook) (*m_notifyHook)(m_cookie, B_WILL_START, performance_time); - } - else { + else Notify(B_WILL_START, performance_time); - } } -void SoundConsumer::Stop( - bigtime_t performance_time, - bool immediate) +void +SoundConsumer::Stop(bigtime_t performance_time, bool immediate) { // Since we are a consumer and just blindly accept buffers that are // thrown at us, we don't need to do anything special in Start()/Stop(). @@ -201,18 +197,15 @@ void SoundConsumer::Stop( // it's a Node over which we have complete control, we can live with // treating buffers received before the start time or after the stop // time as any other buffer. - if (m_notifyHook) { + if (m_notifyHook) (*m_notifyHook)(m_cookie, B_WILL_STOP, performance_time, immediate); - } - else { + else Notify(B_WILL_STOP, performance_time, immediate); - } } -void SoundConsumer::Seek( - bigtime_t media_time, - bigtime_t performance_time) +void +SoundConsumer::Seek(bigtime_t media_time, bigtime_t performance_time) { // Seek() on a consumer just serves to offset the time stamp // of received buffers passed to our Record hook function. @@ -220,20 +213,19 @@ void SoundConsumer::Seek( // to disk or otherwise store them. You may also want to // synchronize this node's media time with an upstream // producer's media time to make this offset meaningful. - if (m_notifyHook) { + if (m_notifyHook) (*m_notifyHook)(m_cookie, B_WILL_SEEK, performance_time, media_time); - } - else { + else Notify(B_WILL_SEEK, performance_time, media_time); - } + m_tpSeekAt = performance_time; m_tmSeekTo = media_time; m_seeking = true; } -void SoundConsumer::SetRunMode( - run_mode mode) +void +SoundConsumer::SetRunMode(run_mode mode) { if (mode == BMediaNode::B_OFFLINE) { // BMediaNode::B_OFFLINE means we don't need to run in @@ -241,8 +233,7 @@ void SoundConsumer::SetRunMode( // thread. int32 new_prio = suggest_thread_priority(B_OFFLINE_PROCESSING); set_thread_priority(m_thread, new_prio); - } - else { + } else { // We're running in real time, so we'd better have // a big enough thread priority to handle it! // Here's where those magic scheduler values @@ -264,40 +255,39 @@ void SoundConsumer::SetRunMode( // * The amount of time we spend processing is // our ProcessingLatency(). bigtime_t period = 10000; - if (buffer_duration(m_input.format.u.raw_audio) > 0) { + if (buffer_duration(m_input.format.u.raw_audio) > 0) period = buffer_duration(m_input.format.u.raw_audio); - } + // assuming we're running for 500 us or less per buffer int32 new_prio = suggest_thread_priority(B_AUDIO_RECORDING, - period, period/2, ProcessingLatency()); + period, period / 2, ProcessingLatency()); set_thread_priority(m_thread, new_prio); } } -void SoundConsumer::TimeWarp( - bigtime_t at_real_time, - bigtime_t to_performance_time) +void +SoundConsumer::TimeWarp(bigtime_t at_real_time, bigtime_t to_performance_time) { // Since buffers will come pre-time-stamped, we only need to look // at them, so we can ignore the time warp as a consumer. if (m_notifyHook) { - (*m_notifyHook)(m_cookie, B_WILL_TIMEWARP, at_real_time, to_performance_time); - } - else { + (*m_notifyHook)(m_cookie, B_WILL_TIMEWARP, at_real_time, + to_performance_time); + } else Notify(B_WILL_TIMEWARP, at_real_time, to_performance_time); - } } -void SoundConsumer::Preroll() +void +SoundConsumer::Preroll() { // There is nothing for us to do in Preroll() } -void SoundConsumer::SetTimeSource( - BTimeSource * /* time_source */) +void +SoundConsumer::SetTimeSource(BTimeSource* /* time_source */) { // We don't need to do anything special to take note of the // fact that the time source changed, because we get our timing @@ -305,17 +295,14 @@ void SoundConsumer::SetTimeSource( } -status_t SoundConsumer::HandleMessage( - int32 message, - const void * data, - size_t size) +status_t +SoundConsumer::HandleMessage(int32 message, const void* data, size_t size) { // Check with each of our superclasses to see if they // understand the message. If none of them do, call // BMediaNode::HandleBadMessage(). - if ((BBufferConsumer::HandleMessage(message, data, size) < 0) - && (BMediaNode::HandleMessage(message, data, size) < 0)) - { + if (BBufferConsumer::HandleMessage(message, data, size) < 0 + && BMediaNode::HandleMessage(message, data, size) < 0) { HandleBadMessage(message, data, size); return B_ERROR; } @@ -323,33 +310,23 @@ status_t SoundConsumer::HandleMessage( } +// #pragma mark - BBufferConsumer-derived methods - -//////////////////////////////////////////////////////////////////////////////// -// -// BBufferConsumer-derived methods -// -//////////////////////////////////////////////////////////////////////////////// - - - -status_t SoundConsumer::AcceptFormat( - const media_destination & dest, - media_format * format) +status_t +SoundConsumer::AcceptFormat(const media_destination& dest, media_format* format) { // We only accept formats aimed at our single input. - if (dest != m_input.destination) { + if (dest != m_input.destination) return B_MEDIA_BAD_DESTINATION; - } - // If no format is specified, we say we want raw audio. + if (format->type <= 0) { + // If no format is specified, we say we want raw audio. format->type = B_MEDIA_RAW_AUDIO; format->u.raw_audio = media_raw_audio_format::wildcard; - } - // If a non-raw-audio format is specified, we tell the world what - // we want, and that the specified format was unacceptable to us. - else if (format->type != B_MEDIA_RAW_AUDIO) { + } else if (format->type != B_MEDIA_RAW_AUDIO) { + // If a non-raw-audio format is specified, we tell the world what + // we want, and that the specified format was unacceptable to us. format->type = B_MEDIA_RAW_AUDIO; format->u.raw_audio = media_raw_audio_format::wildcard; return B_MEDIA_BAD_FORMAT; @@ -368,14 +345,13 @@ status_t SoundConsumer::AcceptFormat( } -status_t SoundConsumer::GetNextInput( - int32 * cookie, - media_input * out_input) +status_t +SoundConsumer::GetNextInput(int32* cookie, media_input* out_input) { NODE(stderr, "SoundConsumer: GetNextInput()\n"); // The "next" is kind of misleading, since it's also used for // getting the first (and only) input. - if (!*cookie) { + if (*cookie == 0) { if (m_input.source == media_source::null) { // If there's no current connection, make sure we return a // reasonable format telling the world we accept any raw audio. @@ -394,16 +370,16 @@ status_t SoundConsumer::GetNextInput( } -void SoundConsumer::DisposeInputCookie( - int32 /* cookie */) +void +SoundConsumer::DisposeInputCookie(int32 /* cookie */) { // We didn't allocate any memory or set any state in GetNextInput() // so this function is a no-op. } -void SoundConsumer::BufferReceived( - BBuffer * buffer) +void +SoundConsumer::BufferReceived(BBuffer* buffer) { NODE(stderr, "SoundConsumer::BufferReceived()\n"); // Whee, a buffer! Update the seek info, if necessary. @@ -413,10 +389,12 @@ void SoundConsumer::BufferReceived( } // If there is a record hook, let the interested party have at it! if (m_recordHook) { - (*m_recordHook)(m_cookie, buffer->Header()->start_time-m_delta, buffer->Data(), buffer->Header()->size_used, m_input.format.u.raw_audio); - } - else { - Record(buffer->Header()->start_time-m_delta, buffer->Data(), buffer->Header()->size_used, m_input.format.u.raw_audio); + (*m_recordHook)(m_cookie, buffer->Header()->start_time-m_delta, + buffer->Data(), buffer->Header()->size_used, + m_input.format.u.raw_audio); + } else { + Record(buffer->Header()->start_time-m_delta, buffer->Data(), + buffer->Header()->size_used, m_input.format.u.raw_audio); } // Buffers should ALWAYS be recycled, else whomever is producing them // will starve. @@ -424,33 +402,31 @@ void SoundConsumer::BufferReceived( } -void SoundConsumer::ProducerDataStatus( - const media_destination & for_whom, - int32 status, - bigtime_t at_media_time) +void +SoundConsumer::ProducerDataStatus(const media_destination& for_whom, + int32 status, bigtime_t at_media_time) { - if (for_whom == m_input.destination) { - // Tell whomever is interested that the upstream producer will or won't - // send more data in the immediate future. - if (m_notifyHook) { - (*m_notifyHook)(m_cookie, B_PRODUCER_DATA_STATUS, status, at_media_time); - } - else { - Notify(B_PRODUCER_DATA_STATUS, status, at_media_time); - } - } + if (for_whom != m_input.destination) + return; + + // Tell whomever is interested that the upstream producer will or won't + // send more data in the immediate future. + if (m_notifyHook) { + (*m_notifyHook)(m_cookie, B_PRODUCER_DATA_STATUS, status, + at_media_time); + } else + Notify(B_PRODUCER_DATA_STATUS, status, at_media_time); } -status_t SoundConsumer::GetLatencyFor( - const media_destination & for_whom, - bigtime_t * out_latency, - media_node_id * out_timesource) +status_t +SoundConsumer::GetLatencyFor(const media_destination& for_whom, + bigtime_t* out_latency, media_node_id* out_timesource) { // We only accept requests for the one-and-only input of our Node. - if (for_whom != m_input.destination) { + if (for_whom != m_input.destination) return B_MEDIA_BAD_DESTINATION; - } + // Tell the world about our latency information (overridable by user). *out_latency = TotalLatency(); *out_timesource = TimeSource()->Node().node; @@ -458,32 +434,30 @@ status_t SoundConsumer::GetLatencyFor( } -status_t SoundConsumer::Connected( - const media_source & producer, - const media_destination & where, - const media_format & with_format, - media_input * out_input) +status_t +SoundConsumer::Connected(const media_source& producer, + const media_destination& where, const media_format& with_format, + media_input* out_input) { NODE(stderr, "SoundConsumer::Connected()\n"); // Only accept connection requests when we're not already connected. - if (m_input.source != media_source::null) { + if (m_input.source != media_source::null) return B_MEDIA_BAD_DESTINATION; - } + // Only accept connection requests on the one-and-only available input. - if (where != m_input.destination) { + if (where != m_input.destination) return B_MEDIA_BAD_DESTINATION; - } + // Other than that, we accept pretty much anything. The format has been // pre-cleared through AcceptFormat(), and we accept any format anyway. m_input.source = producer; m_input.format = with_format; // Tell whomever is interested that there's now a connection. - if (m_notifyHook) { + if (m_notifyHook) (*m_notifyHook)(m_cookie, B_CONNECTED, m_input.name); - } - else { + else Notify(B_CONNECTED, m_input.name); - } + // This is the most important line -- return our connection information // to the world so it can use it! *out_input = m_input; @@ -491,75 +465,69 @@ status_t SoundConsumer::Connected( } -void SoundConsumer::Disconnected( - const media_source & producer, - const media_destination & where) +void +SoundConsumer::Disconnected(const media_source& producer, + const media_destination& where) { // We can't disconnect something which isn't us. - if (where != m_input.destination) { + if (where != m_input.destination) return; - } // We can't disconnect from someone who isn't connected to us. - if (producer != m_input.source) { + if (producer != m_input.source) return; - } // Tell the interested party that it's time to leave. - if (m_notifyHook) { + if (m_notifyHook) (*m_notifyHook)(m_cookie, B_DISCONNECTED); - } - else { + else Notify(B_DISCONNECTED); - } // Mark ourselves as not-connected. m_input.source = media_source::null; } -status_t SoundConsumer::FormatChanged( - const media_source & producer, - const media_destination & consumer, - int32 from_change_count, - const media_format & format) +status_t +SoundConsumer::FormatChanged(const media_source& producer, + const media_destination& consumer, int32 from_change_count, + const media_format& format) { NODE(stderr, "SoundConsumer::Connected()\n"); // The up-stream guy feels like changing the format. If we can accept // arbitrary format changes, we just say "OK". If, however, we're recording // to a file, that's not such a good idea; we only accept format changes // that are compatible with the format we're already using. You set this - // behaviour at compile time by defining ACCEPT_ANY_FORMAT_CHANGE to 1 or 0. + // behaviour at compile time by defining ACCEPT_ANY_FORMAT_CHANGE to 1 or + // 0. status_t err = B_OK; #if ACCEPT_ANY_FORMAT_CHANGE media_format fmt(format); err = AcceptFormat(m_input.destination, &fmt); #else if (m_input.source != media_source::null) { - err = format_is_compatible(format, m_input.format) ? B_OK : B_MEDIA_BAD_FORMAT; + err = format_is_compatible(format, m_input.format) ? B_OK + : B_MEDIA_BAD_FORMAT; } #endif if (err >= B_OK) { m_input.format = format; if (m_notifyHook) { - (*m_notifyHook)(m_cookie, B_FORMAT_CHANGED, &m_input.format.u.raw_audio); - } - else { + (*m_notifyHook)(m_cookie, B_FORMAT_CHANGED, + &m_input.format.u.raw_audio); + } else Notify(B_FORMAT_CHANGED, &m_input.format.u.raw_audio); - } } return err; } void -SoundConsumer::DoHookChange( - void * msg) +SoundConsumer::DoHookChange(void* msg) { // Tell the old guy we're changing the hooks ... - if (m_notifyHook) { + if (m_notifyHook) (*m_notifyHook)(m_cookie, B_HOOKS_CHANGED); - } - else { + else Notify(B_HOOKS_CHANGED); - } + // ... and then do it. set_hooks_q * ptr = (set_hooks_q *)msg; m_recordHook = ptr->process; @@ -569,10 +537,10 @@ SoundConsumer::DoHookChange( status_t -SoundConsumer::ThreadEntry( - void * obj) +SoundConsumer::ThreadEntry(void* cookie) { - ((SoundConsumer *)obj)->ServiceThread(); + SoundConsumer* consumer = (SoundConsumer*)cookie; + consumer->ServiceThread(); return 0; } @@ -587,9 +555,11 @@ SoundConsumer::ServiceThread() // A media kit message will never be bigger than B_MEDIA_MESSAGE_SIZE. // Avoid wasing stack space by dynamically allocating at start. - char * msg = new char[B_MEDIA_MESSAGE_SIZE]; + char* msg = new (nothrow) char[B_MEDIA_MESSAGE_SIZE]; + if (msg == NULL) + return; // Make sure we clean up this data when we exit the function. - array_delete msg_delete(msg); + ArrayDeleter _(msg); int bad = 0; while (true) { // Call read_port_etc() with a timeout derived from a virtual function, @@ -598,57 +568,50 @@ SoundConsumer::ServiceThread() int32 code = 0; status_t err = read_port_etc(m_port, &code, msg, B_MEDIA_MESSAGE_SIZE, B_TIMEOUT, timeout); - MESSAGE(stderr, "SoundConsumer::ServiceThread() port %ld message %#010lx\n", m_port, code); - // If we received a message, err will be the size of the message (including 0). - if (err >= 0) { + MESSAGE(stderr, "SoundConsumer::ServiceThread() port %ld message " + "%#010lx\n", m_port, code); + // If we received a message, err will be the size of the message + // (including 0). + if (err >= B_OK) { // Real messages reset the timeout time. m_trTimeout = 0; bad = 0; - // Check for our private stop message. if (code == MSG_QUIT_NOW) { - if (m_notifyHook) { + // Check for our private stop message. + if (m_notifyHook) (*m_notifyHook)(m_cookie, B_NODE_DIES, 0); - } - else { + else Notify(B_NODE_DIES, 0); - } break; - } + } else if (code == MSG_CHANGE_HOOKS) { // Else check for our private change-hooks message. - else if (code == MSG_CHANGE_HOOKS) { DoHookChange(msg); // Write acknowledge to waiting thread. write_port(((set_hooks_q *)msg)->reply, 0, 0, 0); - } - // Else it has to be a regular media kit message; go ahead and - // dispatch it. - else { + } else { + // Else it has to be a regular media kit message; + // go ahead and dispatch it. HandleMessage(code, msg, err); } - } - // Timing out means that there was no buffer. Tell the interested party. - else if (err == B_TIMED_OUT) { - if (m_notifyHook) { + } else if (err == B_TIMED_OUT) { + // Timing out means that there was no buffer. Tell the interested + // party. + if (m_notifyHook) (*m_notifyHook)(m_cookie, B_OP_TIMED_OUT, timeout); - } - else { + else Notify(B_OP_TIMED_OUT, timeout); - } - } - // Other errors are bad. - else { + } else { + // Other errors are bad. FPRINTF(stderr, "SoundConsumer: error %#010lx\n", err); bad++; // If we receive three bad reads with no good messages inbetween, - // things are probably not going to improve (like the port disappeared - // or something) so we call it a day. + // things are probably not going to improve (like the port + // disappeared or something) so we call it a day. if (bad > 3) { - if (m_notifyHook) { + if (m_notifyHook) (*m_notifyHook)(m_cookie, B_NODE_DIES, bad, err, code, msg); - } - else { + else Notify(B_NODE_DIES, bad, err, code, msg); - } break; } } @@ -664,8 +627,9 @@ SoundConsumer::Timeout() // we've picked is to exponentially back off from one second and upwards. // While it's true that 44 back-offs will run us out of precision in a // bigtime_t, the time to actually reach 44 consecutive back-offs is longer - // than the expected market longevity of just about any piece of real estate. - // Is that the sound of an impending year-fifteen-million software problem? :-) + // than the expected market longevity of just about any piece of real + // estate. Is that the sound of an impending year-fifteen-million software + // problem? :-) m_trTimeout = (m_trTimeout < 1000000) ? 1000000 : m_trTimeout*2; return m_trTimeout; } @@ -689,12 +653,13 @@ SoundConsumer::TotalLatency() return ProcessingLatency(); } + +// #pragma mark - + + void -SoundConsumer::Record( - bigtime_t /* time */, - const void * /* data */, - size_t /* size */, - const media_raw_audio_format & /* format */) +SoundConsumer::Record(bigtime_t /*time*/, const void* /*data*/, + size_t /*size*/, const media_raw_audio_format& /*format*/) { // If there is no record hook installed, we instead call this function // for received buffers. @@ -702,10 +667,8 @@ SoundConsumer::Record( void -SoundConsumer::Notify( - int32 /* cause */, - ...) +SoundConsumer::Notify(int32 /*cause*/, ...) { - // If there is no notification hook installed, we instead call this function - // for giving notification of various events. + // If there is no notification hook installed, we instead call this + // function for giving notification of various events. } diff --git a/src/apps/soundrecorder/SoundConsumer.h b/src/apps/soundrecorder/SoundConsumer.h index d8fc3ca1f1..28dcaaeacd 100644 --- a/src/apps/soundrecorder/SoundConsumer.h +++ b/src/apps/soundrecorder/SoundConsumer.h @@ -7,13 +7,8 @@ / Copyright 1998, Be Incorporated, All Rights Reserved / *******************************************************************************/ - - -#if !defined( _SoundConsumer_h ) -#define _SoundConsumer_h - -#include -#include "SoundUtils.h" +#ifndef SOUND_CONSUMER_H +#define SOUND_CONSUMER_H // To use this Consumer: // 1. Create Record and Notify hooks, or subclass SoundConsumer @@ -33,141 +28,120 @@ // your Record function will see. // 6: When you're done, disconnect the Consumer, then delete it. -class SoundConsumer : - public BBufferConsumer -{ -public: - SoundConsumer( - const char * name, - SoundProcessFunc recordFunc = NULL, - SoundNotifyFunc notifyFunc = NULL, - void * cookie = NULL); - ~SoundConsumer(); +#include +#include "SoundUtils.h" - // This function is OK to call from any thread. - status_t SetHooks( - SoundProcessFunc recordFunc = NULL, - SoundNotifyFunc notifyFunc = NULL, - void * cookie = NULL); - // The MediaNode interface +class SoundConsumer : public BBufferConsumer { public: -virtual port_id ControlPort() const; -virtual BMediaAddOn* AddOn( - int32 * internal_id) const; /* Who instantiated you -- or NULL for app class */ + SoundConsumer(const char* name, + SoundProcessFunc recordFunc = NULL, + SoundNotifyFunc notifyFunc = NULL, + void* cookie = NULL); + virtual ~SoundConsumer(); + + //This function is OK to call from any thread. + status_t SetHooks(SoundProcessFunc recordFunc = NULL, + SoundNotifyFunc notifyFunc = NULL, + void* cookie = NULL); + + // The MediaNode interface +public: + virtual port_id ControlPort() const; + virtual BMediaAddOn* AddOn(int32* internalID) const; + // Who instantiated you -- or NULL for app class protected: + virtual void Start(bigtime_t performanceTime); + virtual void Stop(bigtime_t performanceTime, bool immediate); + virtual void Seek(bigtime_t mediaTime, + bigtime_t performanceTime); + virtual void SetRunMode(run_mode mode); + virtual void TimeWarp(bigtime_t atRealTime, + bigtime_t to_performanceTime); + virtual void Preroll(); + virtual void SetTimeSource(BTimeSource* timeSource); + virtual status_t HandleMessage(int32 message, const void* data, + size_t size); -virtual void Start( - bigtime_t performance_time); -virtual void Stop( - bigtime_t performance_time, - bool immediate); -virtual void Seek( - bigtime_t media_time, - bigtime_t performance_time); -virtual void SetRunMode( - run_mode mode); -virtual void TimeWarp( - bigtime_t at_real_time, - bigtime_t to_performance_time); -virtual void Preroll(); -virtual void SetTimeSource( - BTimeSource * time_source); -virtual status_t HandleMessage( - int32 message, - const void * data, - size_t size); - - // The BufferConsumer interface -virtual status_t AcceptFormat( - const media_destination & dest, - media_format * format); -virtual status_t GetNextInput( /* cookie starts at 0 */ - int32 * cookie, - media_input * out_input); -virtual void DisposeInputCookie( - int32 cookie); -virtual void BufferReceived( - BBuffer * buffer); -virtual void ProducerDataStatus( - const media_destination & for_whom, - int32 status, - bigtime_t at_media_time); -virtual status_t GetLatencyFor( - const media_destination & for_whom, - bigtime_t * out_latency, - media_node_id * out_timesource); -virtual status_t Connected( - const media_source & producer, - const media_destination & where, - const media_format & with_format, - media_input * out_input); -virtual void Disconnected( - const media_source & producer, - const media_destination & where); -virtual status_t FormatChanged( - const media_source & producer, - const media_destination & consumer, - int32 from_change_count, - const media_format & format); + // The BufferConsumer interface + virtual status_t AcceptFormat(const media_destination& dest, + media_format* format); + virtual status_t GetNextInput(int32* cookie, + media_input* _input); + virtual void DisposeInputCookie(int32 cookie); + virtual void BufferReceived(BBuffer* buffer); + virtual void ProducerDataStatus( + const media_destination& forWhom, + int32 status, bigtime_t atMediaTime); + virtual status_t GetLatencyFor(const media_destination& forWhom, + bigtime_t* _latency, + media_node_id* _timesource); + virtual status_t Connected(const media_source& producer, + const media_destination& where, + const media_format& format, + media_input* _input); + virtual void Disconnected(const media_source& producer, + const media_destination& where); + virtual status_t FormatChanged(const media_source& producer, + const media_destination& consumer, + int32 fromChangeCount, + const media_format& format); protected: - // Functions called when no hooks are installed. - // OK to override instead of installing hooks. -virtual void Record( - bigtime_t time, - const void * data, - size_t size, - const media_raw_audio_format & format); -virtual void Notify( - int32 cause, - ...); + // Functions called when no hooks are installed. + // OK to override instead of installing hooks. + virtual void Record(bigtime_t time, const void* data, + size_t size, + const media_raw_audio_format& format); + virtual void Notify(int32 cause, ...); private: - SoundProcessFunc m_recordHook; - SoundNotifyFunc m_notifyHook; - void * m_cookie; - media_input m_input; - thread_id m_thread; - port_id m_port; + SoundProcessFunc m_recordHook; + SoundNotifyFunc m_notifyHook; + void* m_cookie; + media_input m_input; + thread_id m_thread; + port_id m_port; - // The times we need to deal with - // My notation for times: tr = real time, - // tp = performance time, tm = media time. - bigtime_t m_trTimeout; // how long to wait on the input port - bigtime_t m_tpSeekAt; // when we Seek - bigtime_t m_tmSeekTo; // target time for Seek + // The times we need to deal with + // My notation for times: tr = real time, + // tp = performance time, tm = media time. + bigtime_t m_trTimeout; + // how long to wait on the input port + bigtime_t m_tpSeekAt; + // when we Seek + bigtime_t m_tmSeekTo; + // target time for Seek - // The transformation from media to peformance time. - // d = p - m, so m + d = p. - // Media time is generally governed by the Seek - // function. In our node, we simply use media time as - // the time that we report to the record hook function. - // If we were a producer node, we might use media time - // to track where we were in playing a certain piece - // of media. But we aren't. - bigtime_t m_delta; + // The transformation from media to peformance time. + // d = p - m, so m + d = p. + // Media time is generally governed by the Seek + // function. In our node, we simply use media time as + // the time that we report to the record hook function. + // If we were a producer node, we might use media time + // to track where we were in playing a certain piece + // of media. But we aren't. + bigtime_t m_delta; - // State variables - bool m_seeking; // a Seek is pending + // State variables + bool m_seeking; + // a Seek is pending - // Functions to calculate timing values. OK to override. - // ProcessingLatency is the time it takes to process a buffer; - // TotalLatency is returned to producer; Timeout is passed - // to call to read_port_etc() in service thread loop. -virtual bigtime_t Timeout(); -virtual bigtime_t ProcessingLatency(); -virtual bigtime_t TotalLatency(); - // The actual thread doing the work -static status_t ThreadEntry( - void * obj); - void ServiceThread(); - void DoHookChange( - void * msg); + // Functions to calculate timing values. OK to override. + // ProcessingLatency is the time it takes to process a buffer; + // TotalLatency is returned to producer; Timeout is passed + // to call to read_port_etc() in service thread loop. + virtual bigtime_t Timeout(); + virtual bigtime_t ProcessingLatency(); + virtual bigtime_t TotalLatency(); + // The actual thread doing the work + static status_t ThreadEntry(void* cookie); + void ServiceThread(); + void DoHookChange(void* message); }; -#endif /* _SoundConsumer_h */ +#endif // SOUND_CONSUMER_H diff --git a/src/apps/soundrecorder/array_delete.h b/src/apps/soundrecorder/array_delete.h deleted file mode 100644 index 9568203399..0000000000 --- a/src/apps/soundrecorder/array_delete.h +++ /dev/null @@ -1,30 +0,0 @@ -/******************************************************************************* -/ -/ File: array_delete.h -/ -/ Description: Template for deleting a new[] array of something. -/ -/ Copyright 1998-1999, Be Incorporated, All Rights Reserved -/ -*******************************************************************************/ - - -#if !defined( _array_delete_h ) -#define _array_delete_h - -// Oooh! It's a template! -template class array_delete { - C * & m_ptr; -public: - // auto_ptr<> uses delete, not delete[], so we have to write our own. - // I like hanging on to a reference, because if we manually delete the - // array and set the pointer to NULL (or otherwise change the pointer) - // it will still work. Others like the more elaborate implementation - // of auto_ptr<>. Your Mileage May Vary. - array_delete(C * & ptr) : m_ptr(ptr) {} - ~array_delete() { delete[] m_ptr; } -}; - - -#endif /* array_delete_h */ -