--- a/sc2src/sc2mpd.cpp
+++ b/sc2src/sc2mpd.cpp
@@ -46,6 +46,7 @@
#include "conftree.h"
#include "chrono.h"
#include "watcher.h"
+#include "songcastreceiver.h"
#ifdef WITH_WAVSC2
#include "openaudio.h"
@@ -113,192 +114,30 @@
}
}
-using namespace OpenHome;
-using namespace OpenHome::Net;
-using namespace OpenHome::TestFramework;
-using namespace OpenHome::Av;
-
-class OhmReceiverDriver : public IOhmReceiverDriver, public IOhmMsgProcessor {
-public:
- OhmReceiverDriver(AudioEater* eater, AudioEater::Context *ctxt);
-
- virtual TBool IsConnected();
-private:
- // IOhmReceiverDriver
- virtual void Add(OhmMsg& aMsg);
- virtual void Timestamp(OhmMsg& aMsg);
- virtual void Started();
- virtual void Connected();
- virtual void Playing();
- virtual void Disconnected();
- virtual void Stopped();
-
- // IOhmMsgProcessor
- virtual void Process(OhmMsgAudio& aMsg);
- virtual void Process(OhmMsgTrack& aMsg);
- virtual void Process(OhmMsgMetatext& aMsg);
-
-private:
- // Debug, stats, etc while we get to understand the Songcast streams
- class Observer {
- public:
- TBool iReset;
- TUint iCount;
- TUint iFrame;
- int dumpfd;
- Chrono chron;
- Observer() : iReset(true), iCount(0), iFrame(0), dumpfd(-1) {
-#if 0
- dumpfd =
- open("/y/av/tmp/sc2dump", O_WRONLY|O_CREAT|O_TRUNC, 0666);
- if (dumpfd < 0) {
- LOGERR("OhmReceiverDriver::Open dump file failed\n");
- }
-#endif
- }
-
- void reset() {
- iReset = true;
- }
-
- void process(OhmMsgAudio& aMsg);
- };
- Observer m_obs;
- AudioEater *m_eater;
- TBool iConnected;
-};
-
-OhmReceiverDriver::OhmReceiverDriver(AudioEater *eater,
- AudioEater::Context *ctxt)
- : m_eater(eater), iConnected(false)
-{
- audioqueue.start(1, m_eater->worker, ctxt);
-}
-
-void OhmReceiverDriver::Add(OhmMsg& aMsg)
-{
- aMsg.Process(*this);
- aMsg.RemoveRef();
-}
-
-void OhmReceiverDriver::Timestamp(OhmMsg& /*aMsg*/)
-{
-}
-
-void OhmReceiverDriver::Started()
-{
- LOGDEB("=== STARTED ====\n");
-}
-
-void OhmReceiverDriver::Connected()
-{
- m_obs.reset();
- printf("CONNECTED\n");
- fflush(stdout);
- LOGDEB("=== CONNECTED ====\n");
- iConnected = true;
-}
-
-void OhmReceiverDriver::Playing()
-{
- LOGDEB("=== PLAYING ====\n");
- iConnected = true;
- if (m_eater->playing)
- m_eater->playing();
-}
-
-void OhmReceiverDriver::Disconnected()
-{
- LOGDEB("=== DISCONNECTED ====\n");
- iConnected = false;
-}
-
-void OhmReceiverDriver::Stopped()
-{
- LOGDEB("=== STOPPED ====\n");
- if (m_eater->stopped)
- m_eater->stopped();
-}
-
-TBool OhmReceiverDriver::IsConnected()
-{
- return iConnected;
-}
-
-// Debug and stats only, not needed for main function
-void OhmReceiverDriver::Observer::process(OhmMsgAudio& aMsg)
-{
- if (++iCount == 400 || aMsg.Halt()) {
- LOGDEB("OhmRcvDrv::Process:audio: samplerate " << aMsg.SampleRate() <<
- " bitdepth " << aMsg.BitDepth() << " channels " <<
- aMsg.Channels() << " samples " << aMsg.Samples() <<
- " Halted ? " << aMsg.Halt() << endl);
-
-#if 0
- static unsigned long long last_timestamp;
- unsigned long long timestamp = aMsg.MediaTimestamp();
- if (last_timestamp) {
- long long intervalus =
- ((timestamp - last_timestamp) * 1000000) / (256*48000);
- long long atsus =
- ((timestamp) * 1000000) / (256*48000);
-
- // Not too sure what this did. amicros not in chrono.cpp any more
- long long absus = chron.amicros() - 1430477861905884LL;
- LOGDEB("Computed-uS: " << intervalus <<
- " Elapsed-uS: " << chron.urestart() <<
- " Timestamp-uS: " << atsus <<
- " Abs-uS: " << absus <<
- " Diff-mS " << (absus - atsus) / 1000 <<
- endl);
- }
- last_timestamp = timestamp;
-#endif
-
- if (!aMsg.Halt()) {
- unsigned int bytes =
- aMsg.Samples() * (aMsg.BitDepth() / 8) * aMsg.Channels();
-
- if (bytes != aMsg.Audio().Bytes()) {
- LOGERR("OhmRcvDrv::Process:audio: computed bytes " << bytes <<
- " != buffer's " << aMsg.Audio().Bytes() << endl);
- bytes = aMsg.Audio().Bytes();
- }
- const unsigned char *icp =
- (const unsigned char *)aMsg.Audio().Ptr();
- bool silence = true;
- for (unsigned int i = 0; i < bytes; i++) {
- if (icp[i]) {
- silence = false;
- break;
- }
- }
- if (silence) {
- LOGDEB("OhmRcvDrv::Process:audio: silence buffer" << endl);
- }
- if (dumpfd >= 0) {
- if (write(dumpfd, icp, bytes) != int(bytes)) {
- ;
- }
- }
- }
-
- iCount = 0;
- }
-
- if (iReset) {
- iFrame = aMsg.Frame();
- iReset = false;
- } else {
- if (aMsg.Frame() != iFrame + 1) {
- LOGINF("Missed frames between " << iFrame << " and " <<
- aMsg.Frame() << endl);
- }
- iFrame = aMsg.Frame();
- }
-}
-
-void copyswap(unsigned char *dest, const unsigned char *src,
+bool needswap(AudioEater::BOrder order)
+{
+ // Songcast data is always msb-first. Convert to desired order:
+ // depends on what downstream wants, and just as well we do it
+ // here because we copy the buf anyway.
+ bool needswap = false;
+ switch (order) {
+ case AudioEater::BO_MSB:
+ break;
+ case AudioEater::BO_LSB:
+ needswap = true;
+ break;
+ case AudioEater::BO_HOST:
+#ifdef WORDS_BIGENDIAN
+ needswap = false;
+#else
+ needswap = true;
+#endif
+ break;
+ }
+ return needswap;
+}
+
+void copyswap(unsigned char *dest, const unsigned char *src,
unsigned int bytes, unsigned int bits)
{
unsigned char *ocp = dest;
@@ -324,91 +163,10 @@
}
}
-void OhmReceiverDriver::Process(OhmMsgAudio& aMsg)
-{
- unsigned int bytes = 0;
- unsigned int allocbytes = 0;
- char *buf = NULL;
- bool needswap = false;
-
- if (aMsg.Audio().Bytes() == 0) {
- if (aMsg.Halt()) {
- LOGDEB("OhmReceiverDriver::Process: empty message with halt flag "
- "set\n");
- goto put_audio_message;
- } else {
- LOGDEB("OhmReceiverDriver::Process: ignoring empty message\n");
- return;
- }
- }
-
- m_obs.process(aMsg);
- if (aMsg.Halt()) {
- LOGDEB("OhmReceiverDriver::Process: halt flag set in message\n");
- }
-
- bytes = aMsg.Audio().Bytes();
- // We allocate a bit more space to avoir reallocations in the resampler
- allocbytes = bytes + 100;
- buf = (char *)malloc(allocbytes);
- if (buf == 0) {
- LOGERR("OhmReceiverDriver::Process: can't allocate " <<
- bytes << " bytes\n");
- return;
- }
-
- // Songcast data is always msb-first. Convert to desired order:
- // depends on what downstream wants, and just as well we do it
- // here because we copy the buf anyway.
- switch (m_eater->input_border) {
- case AudioEater::BO_MSB:
- break;
- case AudioEater::BO_LSB:
- needswap = true;
- break;
- case AudioEater::BO_HOST:
-#ifdef WORDS_BIGENDIAN
- needswap = false;
-#else
- needswap = true;
-#endif
- break;
- }
-
- if (needswap) {
- copyswap((unsigned char *)buf, aMsg.Audio().Ptr(), bytes, aMsg.BitDepth());
- } else {
- memcpy(buf, aMsg.Audio().Ptr(), bytes);
- }
-
-put_audio_message:
- AudioMessage *ap = new
- AudioMessage(aMsg.BitDepth(), aMsg.Channels(), aMsg.Samples(),
- aMsg.SampleRate(), aMsg.Halt(), buf, allocbytes);
-
- // There is nothing special we can do if put fails: no way to
- // return status. Should we just exit ?
- if (!audioqueue.put(ap, false)) {
- LOGERR("sc2mpd: queue dead: exiting\n");
- exit(1);
- }
-}
-
-void OhmReceiverDriver::Process(OhmMsgTrack& aMsg)
-{
- Brhz uri(aMsg.Uri());
- Brhz metadata(aMsg.Metadata());
- LOGDEB("OhmRcvDrv::Process:trk: TRACK SEQ " << aMsg.Sequence() <<
- " URI " << uri.CString() <<
- " METADATA " << metadata.CString() << endl);
-}
-
-void OhmReceiverDriver::Process(OhmMsgMetatext& aMsg)
-{
- Brhz metatext(aMsg.Metatext());
- LOGDEB("OhmRcvDrv::Process:meta: METATEXT SEQUENCE " << aMsg.Sequence() <<
- " METATEXT " << metatext.CString() << endl);
-}
+using namespace OpenHome;
+using namespace OpenHome::Net;
+using namespace OpenHome::TestFramework;
+using namespace OpenHome::Av;
#ifdef WITH_WAVSC2
static int playWav(const string& wavfile, AudioEater *eater,
@@ -489,7 +247,7 @@
#define SOCK_PATH "/tmp/sc2mpd.sock"
#define BUF_SIZE 16
-void HandleUserCmd(OhmReceiver* receiver, OhmReceiverDriver* driver,
+void HandleUserCmd(OhmReceiver* receiver, SongcastReceiver* driver,
AudioEater* audio, const Brx& aUri)
{
struct sockaddr_un server_addr, client_addr;
@@ -680,7 +438,7 @@
AudioEater* eater = optionDevice.Value() ?
&alsaAudioEater : &httpAudioEater;
- OhmReceiverDriver* driver = new OhmReceiverDriver(eater, ctxt);
+ SongcastReceiver* driver = new SongcastReceiver(eater, ctxt);
OhmReceiver* receiver = new OhmReceiver(lib->Env(), adapter, ttl, *driver);
@@ -724,7 +482,7 @@
}
delete(receiver);
-
+ delete driver;
delete lib;
if (optionInteract.Value())