Switch to unified view

a/sc2src/sc2mpd.cpp b/sc2src/sc2mpd.cpp
...
...
38
#include "workqueue.h"
38
#include "workqueue.h"
39
#include "rcvqueue.h"
39
#include "rcvqueue.h"
40
#include "log.h"
40
#include "log.h"
41
#include "conftree.h"
41
#include "conftree.h"
42
#include "chrono.h"
42
#include "chrono.h"
43
44
#ifdef WITH_WAVSC2
45
#include "openaudio.h"
46
#include "audioreader.h"
47
#endif
43
48
44
#include <vector>
49
#include <vector>
45
#include <stdio.h>
50
#include <stdio.h>
46
#include <iostream>
51
#include <iostream>
47
52
...
...
354
    Brhz metatext(aMsg.Metatext());
359
    Brhz metatext(aMsg.Metatext());
355
    LOGDEB("OhmRcvDrv::Process:meta: METATEXT SEQUENCE " <<  aMsg.Sequence() <<
360
    LOGDEB("OhmRcvDrv::Process:meta: METATEXT SEQUENCE " <<  aMsg.Sequence() <<
356
           " METATEXT " << metatext.CString() << endl);
361
           " METATEXT " << metatext.CString() << endl);
357
}
362
}
358
363
364
#ifdef WITH_WAVSC2
365
static int playWav(const string& wavfile, AudioEater *eater,
366
                   AudioEater::Context *ctxt)
367
{
368
    audioqueue.start(1, eater->worker, ctxt);
369
370
    AudioReader *audio = openAudio(wavfile, "", true);
371
372
    if (!audio || !audio->open() || audio->bytesPerSample() == 0 ||
373
        audio->numChannels() == 0) {
374
        cerr << "Audio file open failed" << endl;
375
        return 1;
376
    }
377
    LOGDEB("sample rate:        " << audio->sampleRate() << endl);
378
    LOGDEB("sample size:        " << audio->bytesPerSample() << endl);
379
    LOGDEB("channels:           " << audio->numChannels() << endl);
380
381
    size_t packetBytes = 441 * 16 *2;
382
    while (true) {
383
        const unsigned char *ibuf = audio->data(packetBytes);
384
        if (ibuf == 0) {
385
            return 1;
386
        }
387
        // We allocate a bit more space to avoir reallocations in the resampler
388
        unsigned int allocbytes = packetBytes + 100;
389
        char *buf = (char *)malloc(allocbytes);
390
        if (buf == 0) {
391
            LOGERR("playWav: can't allocate " << allocbytes << " bytes\n");
392
            return 1;
393
        }
394
395
        // Songcast data is always msb-first.  Convert to desired order:
396
        // depends on what downstream wants, and just as well we do it
397
        // here because we copy the buf anyway.
398
        bool needswap = false;
399
        switch (eater->input_border) {
400
        case AudioEater::BO_MSB:
401
            break;
402
        case AudioEater::BO_LSB:
403
            needswap = true;
404
            break;
405
        case AudioEater::BO_HOST:
406
#ifdef WORDS_BIGENDIAN
407
            needswap = false;
408
#else
409
            needswap = true;
410
#endif
411
            break;
412
        }
413
414
        int bitDepth = 8 * audio->bytesPerSample();
415
        if (needswap) {
416
            copyswap((unsigned char *)buf, ibuf, packetBytes, bitDepth);
417
        } else {
418
            memcpy(buf, ibuf, packetBytes);
419
        }
420
421
        // The constructor wants the number of frames as input (frame
422
        // being all samples at given timepoint, typically 2 for
423
        // stereo)
424
        int frames = packetBytes /
425
            (audio->bytesPerSample() * audio->numChannels());
426
        AudioMessage *ap = new
427
            AudioMessage(bitDepth, audio->numChannels(), frames,
428
                         audio->sampleRate(), buf, allocbytes);
429
430
        // There is nothing special we can do if put fails: no way to
431
        // return status. Should we just exit ?
432
        if (!audioqueue.put(ap, false)) {
433
            LOGERR("sc2mpd: queue dead: exiting\n");
434
            return 1;
435
        }
436
    }
437
    return 0;
438
}
439
#endif
440
359
int CDECL main(int aArgc, char* aArgv[])
441
int CDECL main(int aArgc, char* aArgv[])
360
{
442
{
361
    string logfilename;
443
    string logfilename;
362
    int loglevel(Logger::LLINF);
444
    int loglevel(Logger::LLINF);
363
445
...
...
384
    OptionBool optionDevice("-d", "--direct-alsa", 
466
    OptionBool optionDevice("-d", "--direct-alsa", 
385
                            "[stream] Use alsa directly instead of producing "
467
                            "[stream] Use alsa directly instead of producing "
386
                            "http stream");
468
                            "http stream");
387
    parser.AddOption(&optionDevice);
469
    parser.AddOption(&optionDevice);
388
470
471
#ifdef WITH_WAVSC2
472
    OptionString optionWav("-w", "--wav", Brn(""), 
473
                           "Test audio with wav file instead of sender");
474
    parser.AddOption(&optionWav);
475
#endif
476
389
    if (!parser.Parse(aArgc, aArgv)) {
477
    if (!parser.Parse(aArgc, aArgv)) {
390
        return (1);
478
        return (1);
391
    }
479
    }
392
393
    InitialisationParams* initParams = InitialisationParams::Create();
394
395
    Library* lib = new Library(initParams);
396
397
    std::vector<NetworkAdapter*>* subnetList = lib->CreateSubnetList();
398
    TIpAddress subnet = (*subnetList)[optionAdapter.Value()]->Subnet();
399
    TIpAddress adapter = (*subnetList)[optionAdapter.Value()]->Address();
400
    Library::DestroySubnetList(subnetList);
401
402
403
    TUint ttl = optionTtl.Value();
404
    Brhz uri(optionUri.Value());
405
480
406
    string uconfigfile = (const char *)optionConfig.Value().Ptr();
481
    string uconfigfile = (const char *)optionConfig.Value().Ptr();
407
482
408
    bool cfspecified = true;
483
    bool cfspecified = true;
409
    if (uconfigfile.empty()) {
484
    if (uconfigfile.empty()) {
...
...
425
        cerr << "Can't initialize log" << endl;
500
        cerr << "Can't initialize log" << endl;
426
        return 1;
501
        return 1;
427
    }
502
    }
428
    Logger::getTheLog("")->setLogLevel(Logger::LogLevel(loglevel));
503
    Logger::getTheLog("")->setLogLevel(Logger::LogLevel(loglevel));
429
504
505
    AudioEater::Context *ctxt = new AudioEater::Context(&audioqueue);
506
    ctxt->config = &config;
507
508
#ifdef WITH_WAVSC2
509
    string wavname(Brhz(optionWav.Value()).CString());
510
    if (!wavname.empty()) {
511
        string value;
512
        if (!config.get("sccvttype", value) || 
513
            value.compare("NONE")) {
514
            cerr << "Wav input play test. NEEDS sccvttype == NONE\n";
515
            return 1;
516
        }
517
        return playWav(wavname, &alsaAudioEater, ctxt);
518
    }
519
#endif
520
521
    InitialisationParams* initParams = InitialisationParams::Create();
522
523
    Library* lib = new Library(initParams);
524
525
    std::vector<NetworkAdapter*>* subnetList = lib->CreateSubnetList();
526
    TIpAddress subnet = (*subnetList)[optionAdapter.Value()]->Subnet();
527
    TIpAddress adapter = (*subnetList)[optionAdapter.Value()]->Address();
528
    Library::DestroySubnetList(subnetList);
529
530
    TUint ttl = optionTtl.Value();
531
    Brhz uri(optionUri.Value());
532
430
    LOGINF("scmpdcli: using subnet " << (subnet & 0xff) << "." << 
533
    LOGINF("scmpdcli: using subnet " << (subnet & 0xff) << "." << 
431
           ((subnet >> 8) & 0xff) << "." << ((subnet >> 16) & 0xff) << "." <<
534
           ((subnet >> 8) & 0xff) << "." << ((subnet >> 16) & 0xff) << "." <<
432
           ((subnet >> 24) & 0xff) << endl);
535
           ((subnet >> 24) & 0xff) << endl);
433
434
    AudioEater::Context *ctxt = new AudioEater::Context(&audioqueue);
435
    ctxt->config = &config;
436
536
437
    OhmReceiverDriver* driver = 
537
    OhmReceiverDriver* driver = 
438
        new OhmReceiverDriver(optionDevice.Value() ? 
538
        new OhmReceiverDriver(optionDevice.Value() ? 
439
                              &alsaAudioEater : &httpAudioEater, ctxt);
539
                              &alsaAudioEater : &httpAudioEater, ctxt);
440
540