Ticket #1104: mythtv_ac3.release-19-fixes.patch
File mythtv_ac3.release-19-fixes.patch, 110.6 KB (added by , 20 years ago) |
---|
-
libs/libmythtv/NuppelVideoPlayer.h
106 106 void SetKeyframeDistance(int keyframedistance); 107 107 void SetVideoParams(int w, int h, double fps, int keydist, 108 108 float a = 1.33333, FrameScanType scan = kScan_Ignore); 109 void SetAudioParams(int bits, int channels, int samplerate); 109 void SetAudioParams(int bits, int channels, int samplerate, bool passthru); 110 void SetAudioCodec(void *ac); 110 111 void SetEffDsp(int dsprate); 111 112 void SetFileLength(int total, int frames); 112 113 void Zoom(int direction); … … 143 144 bool IsDecoderThreadAlive(void) const { return decoder_thread_alive; } 144 145 bool IsReallyNearEnd(void) const; 145 146 bool IsNearEnd(long long framesRemaining = -1) const; 147 float GetAudioStretchFactor() { return audio_stretchfactor; } 146 148 bool PlayingSlowForPrebuffer(void) const { return m_playing_slower; } 147 149 bool HasAudioIn(void) const { return !no_audio_in; } 148 150 bool HasAudioOut(void) const { return !no_audio_out; } … … 171 173 bool Play(float speed = 1.0, bool normal = true, 172 174 bool unpauseaudio = true); 173 175 bool GetPause(void) const; 176 float GetNextPlaySpeed() { return next_play_speed; } 174 177 175 178 // Seek stuff 176 179 bool FastForward(float seconds); … … 493 496 int audio_bits; 494 497 int audio_samplerate; 495 498 float audio_stretchfactor; 499 void *audio_codec; 500 bool audio_passthru; 496 501 497 502 // Picture-in-Picture 498 503 NuppelVideoPlayer *pipplayer; -
libs/libmythtv/nuppeldecoder.cpp
474 474 #endif 475 475 GetNVP()->SetAudioParams(extradata.audio_bits_per_sample, 476 476 extradata.audio_channels, 477 extradata.audio_sample_rate); 477 extradata.audio_sample_rate, 478 false /* AC3/DTS pass through */); 478 479 GetNVP()->ReinitAudio(); 479 480 foundit = 1; 480 481 } -
libs/libmythtv/NuppelVideoPlayer.cpp
124 124 audioOutput(NULL), audiodevice("/dev/dsp"), 125 125 audio_channels(2), audio_bits(-1), 126 126 audio_samplerate(44100), audio_stretchfactor(1.0f), 127 audio_codec(NULL), 127 128 // Picture-in-Picture 128 129 pipplayer(NULL), setpipplayer(NULL), needsetpipplayer(false), 129 130 // Preview window support … … 510 511 audioOutput = AudioOutput::OpenAudio(audiodevice, audio_bits, 511 512 audio_channels, audio_samplerate, 512 513 AUDIOOUTPUT_VIDEO, 513 setVolume );514 setVolume, audio_passthru); 514 515 if (!audioOutput) 515 516 errMsg = QObject::tr("Unable to create AudioOutput."); 516 517 else … … 536 537 537 538 if (audioOutput) 538 539 { 539 audioOutput->Reconfigure(audio_bits, audio_channels, audio_samplerate); 540 audioOutput->Reconfigure(audio_bits, audio_channels, 541 audio_samplerate, audio_passthru, 542 audio_codec); 540 543 errMsg = audioOutput->GetError(); 541 544 if (!errMsg.isEmpty()) 542 545 audioOutput->SetStretchFactor(audio_stretchfactor); … … 669 672 { 670 673 VERBOSE(VB_IMPORTANT, "Video sync method can't support double " 671 674 "framerate (refresh rate too low for bob deint)"); 675 //m_scan = kScan_Ignore; 676 //m_can_double = false; 672 677 FallbackDeint(); 673 678 } 674 679 } … … 1532 1537 warpfactor_avg = (warpfactor + (warpfactor_avg * (WARPAVLEN - 1))) / 1533 1538 WARPAVLEN; 1534 1539 1535 //cerr << "Divergence: " << divergence << " Rate: " << rate 1536 //<< " Warpfactor: " << warpfactor << " warpfactor_avg: " 1537 //<< warpfactor_avg << endl; 1540 #if 1 1541 VERBOSE(VB_PLAYBACK|VB_TIMESTAMP, QString("A/V " 1542 "Divergence: %1 " 1543 " Rate: %2" 1544 " Warpfactor: %3" 1545 " warpfactor_avg: %4") 1546 .arg(divergence) 1547 .arg(rate) 1548 .arg(warpfactor) 1549 .arg(warpfactor_avg) 1550 ); 1551 #endif 1538 1552 return divergence; 1539 1553 } 1540 1554 … … 1615 1629 if (diverge < -MAXDIVERGE) 1616 1630 { 1617 1631 // If video is way ahead of audio, adjust for it... 1618 QString dbg = QString(" Video is %1 frames ahead of audio, ")1632 QString dbg = QString("Audio is %1 frames ahead of video, ") 1619 1633 .arg(-diverge); 1620 1634 1621 1635 // Reset A/V Sync … … 1630 1644 // decoding; display the frame, but don't wait for A/V Sync. 1631 1645 videoOutput->PrepareFrame(buffer, ps); 1632 1646 videoOutput->Show(m_scan); 1633 VERBOSE(VB_PLAYBACK , LOC + dbg + "skipping A/V wait.");1647 VERBOSE(VB_PLAYBACK|VB_TIMESTAMP, LOC + dbg + "skipping A/V wait."); 1634 1648 } 1635 1649 else 1636 1650 { 1637 1651 // If we are using software decoding, skip this frame altogether. 1638 VERBOSE(VB_PLAYBACK , LOC + dbg + "dropping frame.");1652 VERBOSE(VB_PLAYBACK|VB_TIMESTAMP, LOC + dbg + "dropping frame."); 1639 1653 } 1640 1654 } 1641 1655 else if (!using_null_videoout) … … 1644 1658 if (buffer) 1645 1659 videoOutput->PrepareFrame(buffer, ps); 1646 1660 1661 VERBOSE(VB_PLAYBACK|VB_TIMESTAMP, QString("AVSync waitforframe %1 %2").arg(avsync_adjustment).arg(m_double_framerate)); 1647 1662 videosync->WaitForFrame(avsync_adjustment); 1663 VERBOSE(VB_PLAYBACK|VB_TIMESTAMP, "AVSync show"); 1648 1664 if (!resetvideo) 1649 1665 videoOutput->Show(m_scan); 1650 1666 … … 1664 1680 1665 1681 // Display the second field 1666 1682 videosync->AdvanceTrigger(); 1667 videosync->WaitForFrame( 0);1683 videosync->WaitForFrame(avsync_adjustment); 1668 1684 if (!resetvideo) 1669 1685 videoOutput->Show(kScan_Intr2ndField); 1670 1686 } … … 1676 1692 1677 1693 if (output_jmeter && output_jmeter->RecordCycleTime()) 1678 1694 { 1679 //cerr << "avsync_delay: " << avsync_delay / 1000 1680 // << ", avsync_avg: " << avsync_avg / 1000 1681 // << ", warpfactor: " << warpfactor 1682 // << ", warpfactor_avg: " << warpfactor_avg << endl; 1695 #if 1 1696 VERBOSE(VB_PLAYBACK|VB_TIMESTAMP, QString("A/V " 1697 "avsync_delay: %1" 1698 ", avsync_avg: %2" 1699 ", warpfactor: %3" 1700 ", warpfactor_avg: %4") 1701 .arg(avsync_delay / 1000) 1702 .arg(avsync_avg / 1000) 1703 .arg(warpfactor) 1704 .arg(warpfactor_avg)); 1705 #endif 1683 1706 } 1684 1707 1685 1708 videosync->AdvanceTrigger(); … … 1690 1713 // If audio is way ahead of video, adjust for it... 1691 1714 // by cutting the frame rate in half for the length of this frame 1692 1715 1693 avsync_adjustment = frame_interval; 1716 //avsync_adjustment = frame_interval; 1717 avsync_adjustment = refreshrate; 1694 1718 lastsync = true; 1695 VERBOSE(VB_PLAYBACK , LOC +1696 QString(" Audio is %1 frames ahead of video,\n"1719 VERBOSE(VB_PLAYBACK|VB_TIMESTAMP, LOC + 1720 QString("Video is %1 frames ahead of audio,\n" 1697 1721 "\t\t\tdoubling video frame interval.").arg(diverge)); 1698 1722 } 1699 1723 1700 1724 if (audioOutput && normal_speed) 1701 1725 { 1702 1726 long long currentaudiotime = audioOutput->GetAudiotime(); 1703 #if 01704 VERBOSE(VB_PLAYBACK , QString(1727 #if 1 1728 VERBOSE(VB_PLAYBACK|VB_TIMESTAMP, QString( 1705 1729 "A/V timecodes audio %1 video %2 frameinterval %3 " 1706 1730 "avdel %4 avg %5 tcoffset %6") 1707 1731 .arg(currentaudiotime) … … 1947 1971 1948 1972 usevideotimebase = gContext->GetNumSetting("UseVideoTimebase", 0); 1949 1973 1950 if ((print_verbose_messages & VB_PLAYBACK ) != 0)1974 if ((print_verbose_messages & VB_PLAYBACK|VB_TIMESTAMP) == (VB_PLAYBACK|VB_TIMESTAMP)) 1951 1975 output_jmeter = new Jitterometer("video_output", 100); 1952 1976 else 1953 1977 output_jmeter = NULL; … … 1987 2011 { 1988 2012 VERBOSE(VB_IMPORTANT, "Video sync method can't support double " 1989 2013 "framerate (refresh rate too low for bob deint)"); 2014 //m_scan = kScan_Ignore; 2015 //m_can_double = false; 1990 2016 FallbackDeint(); 1991 2017 } 1992 2018 } … … 2696 2722 } 2697 2723 } 2698 2724 2699 void NuppelVideoPlayer::SetAudioParams(int bps, int channels, int samplerate) 2725 void NuppelVideoPlayer::SetAudioParams(int bps, int channels, 2726 int samplerate, bool passthru) 2700 2727 { 2701 2728 audio_bits = bps; 2702 2729 audio_channels = channels; 2703 2730 audio_samplerate = samplerate; 2731 audio_passthru = passthru; 2704 2732 } 2705 2733 2734 void NuppelVideoPlayer::SetAudioCodec(void* ac) 2735 { 2736 audio_codec = ac; 2737 } 2738 2706 2739 void NuppelVideoPlayer::SetEffDsp(int dsprate) 2707 2740 { 2708 2741 if (audioOutput) … … 2747 2780 tc_avcheck_framecounter++; 2748 2781 if (tc_avcheck_framecounter == 30) 2749 2782 { 2750 #define AUTO_RESYNC 12783 #define AUTO_RESYNC 0 2751 2784 #if AUTO_RESYNC 2752 2785 // something's terribly, terribly wrong. 2753 2786 if (tc_lastval[TC_AUDIO] < tc_lastval[TC_VIDEO] - 10000000 || -
libs/libmythtv/avformatdecoder.cpp
38 38 #define MAX_AC3_FRAME_SIZE 6144 39 39 40 40 /** Set to zero to allow any number of AC3 channels. */ 41 #define MAXCHANNELSELECT 1 42 #if MAXCHANNELSELECT 43 #define MAX_OUTPUT_CHANNELS compiler error 44 #else 41 45 #define MAX_OUTPUT_CHANNELS 2 46 #endif 42 47 43 48 static int dts_syncinfo(uint8_t *indata_ptr, int *flags, 44 49 int *sample_rate, int *bit_rate); … … 286 291 #ifdef CONFIG_DTS 287 292 allow_dts_passthru = gContext->GetNumSetting("DTSPassThru", false); 288 293 #endif 294 max_channels = gContext->GetNumSetting("MaxChannels", 2); 289 295 290 296 audioIn.sample_size = -32; // force SetupAudioStream to run once 291 297 } … … 406 412 framesPlayed = lastKey; 407 413 framesRead = lastKey; 408 414 415 VERBOSE(VB_PLAYBACK, QString("AvFormatDecoder::DoFastForward newframe %5 frame %1 fps %2 ts %3 disc %4 cur_dts %6 adj %7 newts %8 fsa %9") 416 .arg(desiredFrame) 417 .arg(fps) 418 .arg(ts) 419 .arg(discardFrames) 420 .arg(framesPlayed) 421 .arg(st->cur_dts) 422 .arg(adj_cur_dts) 423 .arg(newts) 424 .arg(frameseekadjust) 425 ); 426 409 427 int normalframes = desiredFrame - framesPlayed; 410 428 429 #if 0 430 if (!exactseeks) 431 normalframes = 0; 432 #endif 433 411 434 SeekReset(lastKey, normalframes, discardFrames, discardFrames); 412 435 413 436 if (discardFrames) … … 739 762 740 763 fmt->flags &= ~AVFMT_NOFILE; 741 764 765 #if 1 766 if ((m_playbackinfo) || livetv || watchingrecording) 767 { 768 const char *name = ic->av_class->item_name(ic); 769 VERBOSE(VB_GENERAL, QString("libavformat type %1").arg(name)); 770 } 771 #endif 772 742 773 av_estimate_timings(ic); 743 774 av_read_frame_flush(ic); 744 775 … … 747 778 if (-1 == ret) 748 779 return ret; 749 780 781 // make sure its at the real start due to av_find_stream_info reading 782 ret = av_seek_frame(ic, -1, 0, AVSEEK_FLAG_BACKWARD); 783 if (ret < 0) 784 av_seek_frame(ic, -1, 0, AVSEEK_FLAG_BYTE); // reposition to start of stream 785 750 786 // Select some starting audio and subtitle tracks. 751 787 // TODO do we need this? They will be called by GetFrame() anyway... 752 788 autoSelectAudioTrack(); … … 769 805 // If we don't have a position map, set up ffmpeg for seeking 770 806 if (!recordingHasPositionMap) 771 807 { 808 const char *name = ic->av_class->item_name(ic); 772 809 VERBOSE(VB_PLAYBACK, LOC + 773 "Recording has no position -- using libavformat seeking.");810 QString("Recording has no position -- using libavformat seeking. %1").arg(name)); 774 811 int64_t dur = ic->duration / (int64_t)AV_TIME_BASE; 775 812 776 813 if (dur > 0) … … 815 852 QString("Successfully opened decoder for file: " 816 853 "\"%1\". novideo(%2)").arg(filename).arg(novideo)); 817 854 855 // set initial position correctly 856 //DoFastForward(0, true); 857 818 858 // Return true if recording has position map 819 859 return recordingHasPositionMap; 820 860 } … … 1053 1093 } 1054 1094 assert(enc->codec_id); 1055 1095 1096 VERBOSE(VB_GENERAL, QString("AVFD: codec %1 has %2 channels").arg(codec_id_string(enc->codec_id)).arg(enc->channels)); 1097 #if 0 1098 if (enc->channels > 2) 1099 enc->channels = 2; 1100 #endif 1101 1102 #if 0 1056 1103 // HACK BEGIN REALLY UGLY HACK FOR DTS PASSTHRU 1057 1104 if (enc->codec_id == CODEC_ID_DTS) 1058 1105 { … … 1061 1108 // enc->bit_rate = what??; 1062 1109 } 1063 1110 // HACK END REALLY UGLY HACK FOR DTS PASSTHRU 1111 #endif 1064 1112 1065 1113 bitrate += enc->bit_rate; 1066 1114 break; … … 1185 1233 // waiting on audio. 1186 1234 if (GetNVP()->HasAudioIn() && audioStreams.empty()) 1187 1235 { 1188 GetNVP()->SetAudioParams(-1, -1, -1 );1236 GetNVP()->SetAudioParams(-1, -1, -1, false /* AC3/DTS pass-through */); 1189 1237 GetNVP()->ReinitAudio(); 1190 1238 } 1191 1239 … … 1561 1609 { 1562 1610 long long startpos = pkt->pos; 1563 1611 1564 VERBOSE(VB_PLAYBACK , LOC +1612 VERBOSE(VB_PLAYBACK|VB_TIMESTAMP, LOC + 1565 1613 QString("positionMap[ %1 ] == %2.") 1566 1614 .arg(prevgoppos / keyframedist) 1567 1615 .arg((int)startpos)); … … 2276 2324 2277 2325 AVStream *curstream = ic->streams[pkt->stream_index]; 2278 2326 2327 #if 0 2328 VERBOSE(VB_PLAYBACK|VB_TIMESTAMP, LOC + QString("timecode pts:%1 dts:%2 codec:%3") 2329 .arg(pkt->pts) 2330 .arg(pkt->dts) 2331 .arg((curstream && curstream->codec)?curstream->codec->codec_type:-1) 2332 ); 2333 #endif 2334 2279 2335 if (pkt->dts != (int64_t)AV_NOPTS_VALUE) 2280 2336 pts = (long long)(av_q2d(curstream->time_base) * pkt->dts * 1000); 2281 2337 … … 2389 2445 if (!curstream->codec->channels) 2390 2446 { 2391 2447 QMutexLocker locker(&avcodeclock); 2448 #if MAXCHANNELSELECT 2449 VERBOSE(VB_IMPORTANT, LOC + QString("Setting channels to %1").arg(audioOut.channels)); 2450 curstream->codec->cqp = max_channels; 2451 curstream->codec->channels = audioOut.channels; 2452 #else 2392 2453 curstream->codec->channels = MAX_OUTPUT_CHANNELS; 2454 #endif 2393 2455 ret = avcodec_decode_audio( 2394 2456 curstream->codec, audioSamples, 2395 2457 &data_size, ptr, len); … … 2440 2502 { 2441 2503 AVCodecContext *ctx = curstream->codec; 2442 2504 2505 #if MAXCHANNELSELECT 2443 2506 if ((ctx->channels == 0) || 2507 (ctx->channels > audioOut.channels)) 2508 ctx->channels = audioOut.channels; 2509 #else 2510 if ((ctx->channels == 0) || 2444 2511 (ctx->channels > MAX_OUTPUT_CHANNELS)) 2445 2512 ctx->channels = MAX_OUTPUT_CHANNELS; 2513 #endif 2446 2514 2447 2515 ret = avcodec_decode_audio( 2448 2516 ctx, audioSamples, &data_size, ptr, len); … … 2478 2546 (curstream->codec->channels * 2) / 2479 2547 curstream->codec->sample_rate); 2480 2548 2549 VERBOSE(VB_PLAYBACK|VB_TIMESTAMP, LOC + QString("audio timecode %1 %2 %3 %4") 2550 .arg(pkt->pts) 2551 .arg(pkt->dts) 2552 .arg(temppts).arg(lastapts)); 2481 2553 GetNVP()->AddAudioData((char *)audioSamples, data_size, 2482 2554 temppts); 2483 2555 … … 2569 2641 else 2570 2642 temppts = lastvpts; 2571 2643 2644 VERBOSE(VB_PLAYBACK|VB_TIMESTAMP, LOC + QString("video timecode %1 %2 %3 %4") 2645 .arg(pkt->pts) 2646 .arg(pkt->dts) 2647 .arg(temppts).arg(lastvpts)); 2572 2648 /* XXX: Broken. 2573 2649 if (mpa_pic.qscale_table != NULL && mpa_pic.qstride > 0 && 2574 2650 context->height == picframe->height) … … 2663 2739 2664 2740 void AvFormatDecoder::SetDisablePassThrough(bool disable) 2665 2741 { 2742 #if MAXCHANNELSELECT 2743 // can only disable never reenable as once tiemstretch is on its on for the session 2744 if (disable_passthru) 2745 return; 2746 #endif 2666 2747 if (selectedAudioStream.av_stream_index < 0) 2667 2748 { 2668 2749 disable_passthru = disable; 2669 2750 return; 2670 2751 } 2671 2752 2672 2753 if (disable != disable_passthru) 2673 2754 { 2674 2755 disable_passthru = disable; … … 2695 2776 AVCodecContext *codec_ctx = NULL; 2696 2777 AudioInfo old_in = audioIn; 2697 2778 AudioInfo old_out = audioOut; 2779 bool using_passthru = false; 2698 2780 2699 2781 if ((currentAudioTrack >= 0) && 2700 2782 (selectedAudioStream.av_stream_index <= ic->nb_streams) && … … 2702 2784 { 2703 2785 assert(curstream); 2704 2786 assert(curstream->codec); 2705 codec_ctx = curstream->codec; 2787 codec_ctx = curstream->codec; 2706 2788 bool do_ac3_passthru = (allow_ac3_passthru && !transcoding && 2707 !disable_passthru &&2708 2789 (codec_ctx->codec_id == CODEC_ID_AC3)); 2709 2790 bool do_dts_passthru = (allow_dts_passthru && !transcoding && 2710 !disable_passthru &&2711 2791 (codec_ctx->codec_id == CODEC_ID_DTS)); 2792 using_passthru = do_ac3_passthru || do_dts_passthru; 2712 2793 info = AudioInfo(codec_ctx->codec_id, 2713 2794 codec_ctx->sample_rate, codec_ctx->channels, 2714 do_ac3_passthru || do_dts_passthru);2795 using_passthru && !disable_passthru); 2715 2796 } 2716 2797 2717 2798 if (info == audioIn) 2718 2799 return false; // no change 2719 2800 2801 QString ptmsg = ""; 2802 if (using_passthru) 2803 { 2804 ptmsg = QString(" using passthru"); 2805 } 2720 2806 VERBOSE(VB_AUDIO, LOC + "Initializing audio parms from " + 2721 QString("audio track #%1").arg(currentAudioTrack+1)); 2807 QString("audio track #%1") 2808 .arg(currentAudioTrack+1) 2809 + ptmsg ); 2722 2810 2723 2811 audioOut = audioIn = info; 2812 #if MAXCHANNELSELECT 2813 if (using_passthru) 2814 #else 2724 2815 if (audioIn.do_passthru) 2816 #endif 2725 2817 { 2726 2818 // A passthru stream looks like a 48KHz 2ch (@ 16bit) to the sound card 2727 audioOut.channels = 2; 2728 audioOut.sample_rate = 48000; 2729 audioOut.sample_size = 4; 2819 AudioInfo digInfo = audioOut; 2820 if (!disable_passthru) 2821 { 2822 digInfo.channels = 2; 2823 digInfo.sample_rate = 48000; 2824 digInfo.sample_size = 4; 2825 } 2826 if (audioOut.channels > max_channels) 2827 { 2828 audioOut.channels = max_channels; 2829 audioOut.sample_size = audioOut.channels * 2; 2830 codec_ctx->channels = audioOut.channels; 2831 } 2832 #if MAXCHANNELSELECT 2833 VERBOSE(VB_AUDIO, LOC + "Audio format changed digital passthrough " + 2834 QString("%1\n\t\t\tfrom %2 ; %3\n\t\t\tto %4 ; %5") 2835 .arg(digInfo.toString()) 2836 .arg(old_in.toString()).arg(old_out.toString()) 2837 .arg(audioIn.toString()).arg(audioOut.toString())); 2838 2839 if (digInfo.sample_rate > 0) 2840 GetNVP()->SetEffDsp(digInfo.sample_rate * 100); 2841 2842 //GetNVP()->SetAudioParams(audioOut.bps(), audioOut.channels, 2843 // audioOut.sample_rate); 2844 GetNVP()->SetAudioParams(digInfo.bps(), digInfo.channels, 2845 digInfo.sample_rate, audioIn.do_passthru); 2846 // allow the audio stuff to reencode 2847 GetNVP()->SetAudioCodec(codec_ctx); 2848 GetNVP()->ReinitAudio(); 2849 return true; 2850 #endif 2730 2851 } 2852 #if MAXCHANNELSELECT 2731 2853 else 2732 2854 { 2855 if (audioOut.channels > max_channels) 2856 { 2857 audioOut.channels = max_channels; 2858 audioOut.sample_size = audioOut.channels * 2; 2859 codec_ctx->channels = audioOut.channels; 2860 } 2861 } 2862 bool audiook; 2863 #if 0 2864 do 2865 { 2866 #endif 2867 #else 2868 else 2869 { 2733 2870 if (audioOut.channels > MAX_OUTPUT_CHANNELS) 2734 2871 { 2735 2872 audioOut.channels = MAX_OUTPUT_CHANNELS; … … 2737 2874 codec_ctx->channels = MAX_OUTPUT_CHANNELS; 2738 2875 } 2739 2876 } 2877 #endif 2740 2878 2741 2879 VERBOSE(VB_AUDIO, LOC + "Audio format changed " + 2742 2880 QString("\n\t\t\tfrom %1 ; %2\n\t\t\tto %3 ; %4") … … 2747 2885 GetNVP()->SetEffDsp(audioOut.sample_rate * 100); 2748 2886 2749 2887 GetNVP()->SetAudioParams(audioOut.bps(), audioOut.channels, 2750 audioOut.sample_rate); 2751 GetNVP()->ReinitAudio(); 2888 audioOut.sample_rate, 2889 audioIn.do_passthru); 2890 // allow the audio stuff to reencode 2891 GetNVP()->SetAudioCodec(using_passthru?codec_ctx:NULL); 2892 QString errMsg = GetNVP()->ReinitAudio(); 2893 #if MAXCHANNELSELECT 2894 audiook = errMsg.isEmpty(); 2895 #if 0 2896 if (!audiook) 2897 { 2898 switch (audioOut.channels) 2899 { 2900 #if 0 2901 case 8: 2902 audioOut.channels = 6; 2903 break; 2904 #endif 2905 case 6: 2906 #if 0 2907 audioOut.channels = 5; 2908 break; 2909 case 5: 2910 audioOut.channels = 4; 2911 break; 2912 case 4: 2913 audioOut.channels = 3; 2914 break; 2915 case 3: 2916 #endif 2917 audioOut.channels = 2; 2918 break; 2919 #if 0 2920 case 2: 2921 audioOut.channels = 1; 2922 break; 2923 #endif 2924 default: 2925 // failed to reconfigure under any circumstances 2926 audiook = true; 2927 audioOut.channels = 0; 2928 break; 2929 } 2930 audioOut.sample_size = audioOut.channels * 2; 2931 codec_ctx->channels = audioOut.channels; 2932 } 2933 } while (!audiook); 2934 #endif 2935 #endif 2752 2936 2753 2937 return true; 2754 2938 } -
libs/libmythtv/avformatdecoder.h
238 238 bool allow_ac3_passthru; 239 239 bool allow_dts_passthru; 240 240 bool disable_passthru; 241 int max_channels; 241 242 242 243 AudioInfo audioIn; 243 244 AudioInfo audioOut; -
libs/libmythsoundtouch/TDStretch.cpp
96 96 97 97 pMidBuffer = NULL; 98 98 pRefMidBufferUnaligned = NULL; 99 midBufferLength = 0; 99 100 overlapLength = 0; 100 101 101 102 setParameters(44100, DEFAULT_SEQUENCE_MS, DEFAULT_SEEKWINDOW_MS, DEFAULT_OVERLAP_MS); … … 108 109 109 110 TDStretch::~TDStretch() 110 111 { 111 delete[] pMidBuffer; 112 delete[] pRefMidBufferUnaligned; 112 if (midBufferLength) 113 { 114 delete[] pMidBuffer; 115 delete[] pRefMidBufferUnaligned; 116 midBufferLength = 0; 117 } 113 118 } 114 119 115 120 … … 196 201 197 202 void TDStretch::clearMidBuffer() 198 203 { 199 if (bMidBufferDirty )204 if (bMidBufferDirty && midBufferLength) 200 205 { 201 memset(pMidBuffer, 0, 2* sizeof(SAMPLETYPE) * overlapLength);206 memset(pMidBuffer, 0, channels * sizeof(SAMPLETYPE) * overlapLength); 202 207 bMidBufferDirty = FALSE; 203 208 } 204 209 } … … 239 244 // Seeks for the optimal overlap-mixing position. 240 245 uint TDStretch::seekBestOverlapPosition(const SAMPLETYPE *refPos) 241 246 { 247 #ifdef MULTICHANNEL 248 if (channels > 2) 249 { 250 // stereo sound 251 if (bQuickseek) 252 { 253 return seekBestOverlapPositionMultiQuick(refPos); 254 } 255 else 256 { 257 return seekBestOverlapPositionMulti(refPos); 258 } 259 } 260 else 261 #endif 242 262 if (channels == 2) 243 263 { 244 264 // stereo sound … … 272 292 // of 'ovlPos'. 273 293 inline void TDStretch::overlap(SAMPLETYPE *output, const SAMPLETYPE *input, uint ovlPos) const 274 294 { 295 #ifdef MULTICHANNEL 296 if (channels > 2) 297 { 298 overlapMulti(output, input + channels * ovlPos); 299 } 300 else 301 #endif 275 302 if (channels == 2) 276 303 { 277 304 // stereo sound … … 285 312 286 313 287 314 315 #ifdef MULTICHANNEL 288 316 // Seeks for the optimal overlap-mixing position. The 'stereo' version of the 289 317 // routine 290 318 // 291 319 // The best position is determined as the position where the two overlapped 292 320 // sample sequences are 'most alike', in terms of the highest cross-correlation 293 321 // value over the overlapping period 322 uint TDStretch::seekBestOverlapPositionMulti(const SAMPLETYPE *refPos) 323 { 324 uint bestOffs; 325 LONG_SAMPLETYPE bestCorr, corr; 326 uint i; 327 328 // Slopes the amplitudes of the 'midBuffer' samples 329 precalcCorrReference(); 330 331 bestCorr = INT_MIN; 332 bestOffs = 0; 333 334 // Scans for the best correlation value by testing each possible position 335 // over the permitted range. 336 for (i = 0; i < seekLength; i ++) 337 { 338 // Calculates correlation value for the mixing position corresponding 339 // to 'i' 340 corr = calcCrossCorrMulti(refPos + channels * i, pRefMidBuffer); 341 342 // Checks for the highest correlation value 343 if (corr > bestCorr) 344 { 345 bestCorr = corr; 346 bestOffs = i; 347 } 348 } 349 // clear cross correlation routine state if necessary (is so e.g. in MMX routines). 350 clearCrossCorrState(); 351 352 return bestOffs; 353 } 354 355 356 // Seeks for the optimal overlap-mixing position. The 'stereo' version of the 357 // routine 358 // 359 // The best position is determined as the position where the two overlapped 360 // sample sequences are 'most alike', in terms of the highest cross-correlation 361 // value over the overlapping period 362 uint TDStretch::seekBestOverlapPositionMultiQuick(const SAMPLETYPE *refPos) 363 { 364 uint j; 365 uint bestOffs; 366 LONG_SAMPLETYPE bestCorr, corr; 367 uint scanCount, corrOffset, tempOffset; 368 369 // Slopes the amplitude of the 'midBuffer' samples 370 precalcCorrReference(); 371 372 bestCorr = INT_MIN; 373 bestOffs = 0; 374 corrOffset = 0; 375 tempOffset = 0; 376 377 // Scans for the best correlation value using four-pass hierarchical search. 378 // 379 // The look-up table 'scans' has hierarchical position adjusting steps. 380 // In first pass the routine searhes for the highest correlation with 381 // relatively coarse steps, then rescans the neighbourhood of the highest 382 // correlation with better resolution and so on. 383 for (scanCount = 0;scanCount < 4; scanCount ++) 384 { 385 j = 0; 386 while (scanOffsets[scanCount][j]) 387 { 388 tempOffset = corrOffset + scanOffsets[scanCount][j]; 389 if (tempOffset >= seekLength) break; 390 391 // Calculates correlation value for the mixing position corresponding 392 // to 'tempOffset' 393 corr = calcCrossCorrMulti(refPos + channels * tempOffset, pRefMidBuffer); 394 395 // Checks for the highest correlation value 396 if (corr > bestCorr) 397 { 398 bestCorr = corr; 399 bestOffs = tempOffset; 400 } 401 j ++; 402 } 403 corrOffset = bestOffs; 404 } 405 // clear cross correlation routine state if necessary (is so e.g. in MMX routines). 406 clearCrossCorrState(); 407 408 return bestOffs; 409 } 410 #endif 411 412 // Seeks for the optimal overlap-mixing position. The 'stereo' version of the 413 // routine 414 // 415 // The best position is determined as the position where the two overlapped 416 // sample sequences are 'most alike', in terms of the highest cross-correlation 417 // value over the overlapping period 294 418 uint TDStretch::seekBestOverlapPositionStereo(const SAMPLETYPE *refPos) 295 419 { 296 420 uint bestOffs; … … 512 636 void TDStretch::setChannels(uint numChannels) 513 637 { 514 638 if (channels == numChannels) return; 639 #ifdef MULTICHANNEL 640 assert(numChannels >= 1 && numChannels <= MULTICHANNEL); 641 #else 515 642 assert(numChannels == 1 || numChannels == 2); 643 #endif 516 644 517 645 channels = numChannels; 518 646 inputBuffer.setChannels(channels); … … 635 763 /// Set new overlap length parameter & reallocate RefMidBuffer if necessary. 636 764 void TDStretch::acceptNewOverlapLength(uint newOverlapLength) 637 765 { 638 uint prevOvl;639 640 prevOvl = overlapLength;641 766 overlapLength = newOverlapLength; 642 767 643 if (overlapLength > prevOvl)768 if (overlapLength*channels > midBufferLength) 644 769 { 645 delete[] pMidBuffer; 646 delete[] pRefMidBufferUnaligned; 770 if (midBufferLength) 771 { 772 delete[] pMidBuffer; 773 delete[] pRefMidBufferUnaligned; 774 midBufferLength = 0; 775 } 647 776 648 pMidBuffer = new SAMPLETYPE[overlapLength * 2]; 777 midBufferLength = overlapLength * channels; 778 pMidBuffer = new SAMPLETYPE[midBufferLength]; 649 779 bMidBufferDirty = TRUE; 650 780 clearMidBuffer(); 651 781 652 pRefMidBufferUnaligned = new SAMPLETYPE[ 2 * overlapLength + 16 / sizeof(SAMPLETYPE)];782 pRefMidBufferUnaligned = new SAMPLETYPE[midBufferLength + 16 / sizeof(SAMPLETYPE)]; 653 783 // ensure that 'pRefMidBuffer' is aligned to 16 byte boundary for efficiency 654 784 pRefMidBuffer = (SAMPLETYPE *)((((ulong)pRefMidBufferUnaligned) + 15) & -16); 655 785 } … … 718 848 719 849 #ifdef INTEGER_SAMPLES 720 850 851 #ifdef MULTICHANNEL 721 852 // Slopes the amplitude of the 'midBuffer' samples so that cross correlation 722 853 // is faster to calculate 854 void TDStretch::precalcCorrReference() 855 { 856 int i,j; 857 int temp, temp2; 858 short *src = pMidBuffer; 859 short *dest = pRefMidBuffer; 860 861 for (i=0 ; i < (int)overlapLength ;i ++) 862 { 863 temp = i * (overlapLength - i); 864 865 for(j=0;j<channels;j++) 866 { 867 temp2 = (*src++ * temp) / slopingDivider; 868 *dest++ = (short)(temp2); 869 } 870 } 871 } 872 #endif 873 874 // Slopes the amplitude of the 'midBuffer' samples so that cross correlation 875 // is faster to calculate 723 876 void TDStretch::precalcCorrReferenceStereo() 724 877 { 725 878 int i, cnt2; … … 772 925 } 773 926 } 774 927 928 #ifdef MULTICHANNEL 929 // Overlaps samples in 'midBuffer' with the samples in 'input'. The 'Stereo' 930 // version of the routine. 931 void TDStretch::overlapMulti(short *output, const short *input) const 932 { 933 int i,j; 934 short temp; 935 //uint cnt2; 936 const short *ip = input; 937 short *op = output; 938 const short *md = pMidBuffer; 775 939 940 for (i = 0; i < (int)overlapLength ; i ++) 941 { 942 temp = (short)(overlapLength - i); 943 for(j=0;j<channels;j++) 944 *op++ = (*ip++ * i + *md++ * temp ) / overlapLength; 945 } 946 } 947 #endif 948 949 776 950 /// Calculates overlap period length in samples. 777 951 /// Integer version rounds overlap length to closest power of 2 778 952 /// for a divide scaling operation. … … 824 998 return corr; 825 999 } 826 1000 1001 #ifdef MULTICHANNEL 1002 long TDStretch::calcCrossCorrMulti(const short *mixingPos, const short *compare) const 1003 { 1004 long corr; 1005 uint i; 1006 1007 corr = 0; 1008 for (i = channels; i < channels * overlapLength; i++) 1009 { 1010 corr += (mixingPos[i] * compare[i]) >> overlapDividerBits; 1011 } 1012 1013 return corr; 1014 } 1015 #endif 1016 827 1017 #endif // INTEGER_SAMPLES 828 1018 829 1019 ////////////////////////////////////////////////////////////////////////////// … … 931 1121 return corr; 932 1122 } 933 1123 934 #endif // FLOAT_SAMPLES 935 No newline at end of file 1124 #endif // FLOAT_SAMPLES -
libs/libmythsoundtouch/TDStretch.h
48 48 #include "RateTransposer.h" 49 49 #include "FIFOSamplePipe.h" 50 50 51 #ifdef MULTICHANNEL 52 #define USE_MULTI_MMX 53 #endif 54 51 55 namespace soundtouch 52 56 { 53 57 … … 100 104 SAMPLETYPE *pMidBuffer; 101 105 SAMPLETYPE *pRefMidBuffer; 102 106 SAMPLETYPE *pRefMidBufferUnaligned; 107 uint midBufferLength; 103 108 uint overlapLength; 104 109 uint overlapDividerBits; 105 110 uint slopingDivider; … … 123 128 virtual void clearCrossCorrState(); 124 129 void calculateOverlapLength(uint overlapMs); 125 130 131 #ifdef MULTICHANNEL 132 virtual LONG_SAMPLETYPE calcCrossCorrMulti(const SAMPLETYPE *mixingPos, const SAMPLETYPE *compare) const; 133 #endif 126 134 virtual LONG_SAMPLETYPE calcCrossCorrStereo(const SAMPLETYPE *mixingPos, const SAMPLETYPE *compare) const; 127 135 virtual LONG_SAMPLETYPE calcCrossCorrMono(const SAMPLETYPE *mixingPos, const SAMPLETYPE *compare) const; 128 136 137 #ifdef MULTICHANNEL 138 virtual uint seekBestOverlapPositionMulti(const SAMPLETYPE *refPos); 139 virtual uint seekBestOverlapPositionMultiQuick(const SAMPLETYPE *refPos); 140 #endif 129 141 virtual uint seekBestOverlapPositionStereo(const SAMPLETYPE *refPos); 130 142 virtual uint seekBestOverlapPositionStereoQuick(const SAMPLETYPE *refPos); 131 143 virtual uint seekBestOverlapPositionMono(const SAMPLETYPE *refPos); 132 144 virtual uint seekBestOverlapPositionMonoQuick(const SAMPLETYPE *refPos); 133 145 uint seekBestOverlapPosition(const SAMPLETYPE *refPos); 134 146 147 #ifdef MULTICHANNEL 148 virtual void overlapMulti(SAMPLETYPE *output, const SAMPLETYPE *input) const; 149 #endif 135 150 virtual void overlapStereo(SAMPLETYPE *output, const SAMPLETYPE *input) const; 136 151 virtual void overlapMono(SAMPLETYPE *output, const SAMPLETYPE *input) const; 137 152 138 153 void clearMidBuffer(); 139 154 void overlap(SAMPLETYPE *output, const SAMPLETYPE *input, uint ovlPos) const; 140 155 156 #ifdef MULTICHANNEL 157 void precalcCorrReference(); 158 #endif 141 159 void precalcCorrReferenceMono(); 142 160 void precalcCorrReferenceStereo(); 143 161 … … 225 243 class TDStretchMMX : public TDStretch 226 244 { 227 245 protected: 246 #ifdef USE_MULTI_MMX 247 #ifdef MULTICHANNEL 248 long calcCrossCorrMulti(const short *mixingPos, const short *compare) const; 249 #endif 250 #endif 228 251 long calcCrossCorrStereo(const short *mixingPos, const short *compare) const; 229 252 virtual void overlapStereo(short *output, const short *input) const; 230 253 virtual void clearCrossCorrState(); … … 237 260 class TDStretch3DNow : public TDStretch 238 261 { 239 262 protected: 263 #ifdef MULTICHANNEL 264 //double calcCrossCorrMulti(const float *mixingPos, const float *compare) const; 265 #endif 240 266 double calcCrossCorrStereo(const float *mixingPos, const float *compare) const; 241 267 }; 242 268 #endif /// ALLOW_3DNOW … … 247 273 class TDStretchSSE : public TDStretch 248 274 { 249 275 protected: 276 #ifdef MULTICHANNEL 277 //double calcCrossCorrMulti(const float *mixingPos, const float *compare) const; 278 #endif 250 279 double calcCrossCorrStereo(const float *mixingPos, const float *compare) const; 251 280 }; 252 281 -
libs/libmythsoundtouch/RateTransposer.cpp
330 330 { 331 331 if (uChannels == numchannels) return; 332 332 333 #ifdef MULTICHANNEL 334 assert(numchannels >= 1 && numchannels <= MULTICHANNEL); 335 #else 333 336 assert(numchannels == 1 || numchannels == 2); 337 #endif 334 338 uChannels = numchannels; 335 339 336 340 storeBuffer.setChannels(uChannels); -
libs/libmythsoundtouch/mmx_gcc.cpp
141 141 return tmp; 142 142 } 143 143 144 #ifdef USE_MULTI_MMX 145 // Calculates cross correlation of two buffers 146 long TDStretchMMX::calcCrossCorrMulti(const short *pV1, const short *pV2) const 147 { 148 //static const unsigned long long int mm_half __attribute__ ((aligned(8))) = 0xffffffffULL; 149 static const __m64 mm_mask[4][8] __attribute__ ((aligned(8))) = { 150 { 151 // even bit 152 0xffffffffffffffffULL, 153 0xffffffffffffffffULL, 154 0xffffffffffffffffULL, 155 0xffffffffffffffffULL, 156 0, 157 0, 158 0, 159 0 160 }, 161 { 162 0xffffffffffffffffULL, 163 0xffffffffffffffffULL, 164 0xffffffffffffffffULL, 165 0x0000ffffffffffffULL, 166 0, 167 0, 168 0, 169 0 170 }, 171 { 172 0xffffffffffffffffULL, 173 0xffffffffffffffffULL, 174 0xffffffffffffffffULL, 175 0x00000000ffffffffULL, 176 0, 177 0, 178 0, 179 0 180 }, 181 { 182 0xffffffffffffffffULL, 183 0xffffffffffffffffULL, 184 0xffffffffffffffffULL, 185 0x000000000000ffffULL, 186 0, 187 0, 188 0, 189 0 190 } 191 }; 192 uint tmp; 193 uint adjustedOverlapLength = overlapLength*channels; 194 uint counter = ((adjustedOverlapLength+15)>>4)-1; // load counter to counter = overlapLength / 8 - 1 195 uint remainder = (16-adjustedOverlapLength)&0xf; // since there are 1/3 sample per 1/2 quadword 196 197 __m64 *ph = (__m64*)&mm_mask[remainder&3][remainder>>2]; 198 __m64 *pv1=(__m64*)pV1, *pv2=(__m64*)pV2; 199 GI(__m64 m0, m1, m2, m3, m4, m5, m6); // temporaries 200 uint shift = overlapDividerBits; 201 202 // prepare to the first round by loading 203 SI(m1 = pv1[0], movq_a2r(0, pv1, mm1)); // load m1 = pv1[0] 204 SI(m2 = pv1[1], movq_a2r(8, pv1, mm2)); // load m2 = pv1[1] 205 SI(m0 = _mm_setzero_si64(), pxor_r2r(mm0, mm0)); // clear m0 206 SI(m5 = _mm_cvtsi32_si64(shift),movd_v2r(shift, mm5)); // shift in 64bit reg 207 208 do { 209 // Calculate cross-correlation between the tempOffset and tmpbid_buffer. 210 // Process 4 parallel batches of 2 * stereo samples each during one 211 // round to improve CPU-level parallellization. 212 SI(m1 = _mm_madd_pi16(m1, pv2[0]),pmaddwd_a2r(0, pv2, mm1)); // multiply-add m1 = m1 * pv2[0] 213 SI(m3 = pv1[2], movq_a2r(16, pv1, mm3)); // load mm3 = pv1[2] 214 SI(m2 = _mm_madd_pi16(m2, pv2[1]),pmaddwd_a2r(8, pv2, mm2)); // multiply-add m2 = m2 * pv2[1] 215 SI(m4 = pv1[3], movq_a2r(24, pv1, mm4)); // load mm4 = pv1[3] 216 SI(m3 = _mm_madd_pi16(m3, pv2[2]),pmaddwd_a2r(16, pv2, mm3));// multiply-add m3 = m3 * pv2[2] 217 SI(m2 = _mm_add_pi32(m2, m1), paddd_r2r(mm1, mm2)); // add m2 += m1 218 SI(m4 = _mm_madd_pi16(m4, pv2[3]),pmaddwd_a2r(24, pv2, mm4));// multiply-add m4 = m4 * pv2[3] 219 SI(m1 = pv1[4], movq_a2r(32, pv1, mm1)); // mm1 = pv1[0] for next round 220 SI(m2 = _mm_srai_pi32(m2, m5), psrad_r2r(mm5, mm2)); // m2 >>= shift (mm5) 221 pv1 += 4; // increment first pointer 222 SI(m3 = _mm_add_pi32(m3, m4), paddd_r2r(mm4, mm3)); // m3 += m4 223 SI(m0 = _mm_add_pi32(m0, m2), paddd_r2r(mm2, mm0)); // m0 += m2 224 SI(m2 = pv1[1], movq_a2r(8, pv1, mm2)); // mm2 = pv1[1] for next round 225 SI(m3 = _mm_srai_pi32(m3, m5), psrad_r2r(mm5, mm3)); // m3 >>= shift (mm5) 226 pv2 += 4; // increment second pointer 227 SI(m0 = _mm_add_pi32(m0, m3), paddd_r2r(mm3, mm0)); // add m0 += m3 228 } while ((--counter)!=0); 229 230 SI(m6 = ph[0], movq_a2r(0, ph, mm6)); 231 // Finalize the last partial loop: 232 SI(m1 = _mm_madd_pi16(m1, pv2[0]), pmaddwd_a2r(0, pv2, mm1)); 233 SI(m1 = _mm_and_si64(m1, m6), pand_r2r(mm6, mm1)); 234 SI(m3 = pv1[2], movq_a2r(16, pv1, mm3)); 235 SI(m6 = ph[1], movq_a2r(8, ph, mm6)); 236 SI(m2 = _mm_madd_pi16(m2, pv2[1]), pmaddwd_a2r(8, pv2, mm2)); 237 SI(m2 = _mm_and_si64(m2, m6), pand_r2r(mm6, mm2)); 238 SI(m4 = pv1[3], movq_a2r(24, pv1, mm4)); 239 SI(m6 = ph[2], movq_a2r(16, ph, mm6)); 240 SI(m3 = _mm_madd_pi16(m3, pv2[2]), pmaddwd_a2r(16, pv2, mm3)); 241 SI(m3 = _mm_and_si64(m3, m6), pand_r2r(mm6, mm3)); 242 SI(m2 = _mm_add_pi32(m2, m1), paddd_r2r(mm1, mm2)); 243 SI(m6 = ph[3], movq_a2r(24, ph, mm6)); 244 SI(m4 = _mm_madd_pi16(m4, pv2[3]), pmaddwd_a2r(24, pv2, mm4)); 245 SI(m4 = _mm_and_si64(m4, m6), pand_r2r(mm6, mm4)); 246 SI(m2 = _mm_srai_pi32(m2, m5), psrad_r2r(mm5, mm2)); 247 SI(m3 = _mm_add_pi32(m3, m4), paddd_r2r(mm4, mm3)); 248 SI(m0 = _mm_add_pi32(m0, m2), paddd_r2r(mm2, mm0)); 249 SI(m3 = _mm_srai_pi32(m3, m5), psrad_r2r(mm5, mm3)); 250 SI(m0 = _mm_add_pi32(m0, m3), paddd_r2r(mm3, mm0)); 251 252 // copy hi-dword of mm0 to lo-dword of mm1, then sum mm0+mm1 253 // and finally return the result 254 SI(m1 = m0, movq_r2r(mm0, mm1)); 255 SI(m1 = _mm_srli_si64(m1, 32), psrld_i2r(32, mm1)); 256 SI(m0 = _mm_add_pi32(m0, m1), paddd_r2r(mm1, mm0)); 257 SI(tmp = _mm_cvtsi64_si32(m0), movd_r2m(mm0, tmp)); 258 return tmp; 259 } 260 #endif 261 144 262 void TDStretchMMX::clearCrossCorrState() 145 263 { 146 264 _mm_empty(); … … 224 342 _mm_empty(); 225 343 } 226 344 345 #if 0 346 // MMX-optimized version of the function overlapMulti 347 void TDStretchMMX::overlapMulti(short *output, const short *input) const 348 { 349 _mm_empty(); 350 uint shift = overlapDividerBits; 351 uint counter = overlapLength>>2; // counter = overlapLength / 4 352 __m64 *inPtr = (__m64*) input; // load address of inputBuffer 353 __m64 *midPtr = (__m64*) pMidBuffer; // load address of midBuffer 354 __m64 *outPtr = ((__m64*) output)-2; // load address of outputBuffer 355 GI(__m64 m0, m1, m2, m3, m4, m5, m6, m7); // temporaries 356 357 // load mixing value adder to mm5 358 uint tmp0 = 0x0002fffe; // tmp0 = 0x0002 fffe 359 SI(m5 = _mm_cvtsi32_si64(tmp0), movd_v2r(tmp0, mm5)); // mm5 = 0x0000 0000 0002 fffe 360 SI(m5 = _mm_unpacklo_pi32(m5,m5), punpckldq_r2r(mm5, mm5)); // mm5 = 0x0002 fffe 0002 fffe 361 // load sliding mixing value counter to mm6 362 SI(m6 = _mm_cvtsi32_si64(overlapLength), movd_v2r(overlapLength, mm6)); 363 SI(m6 = _mm_unpacklo_pi32(m6, m6), punpckldq_r2r(mm6, mm6)); // mm6 = 0x0000 OVL_ 0000 OVL_ 364 // load sliding mixing value counter to mm7 365 uint tmp1 = (overlapLength-1)|0x00010000; // tmp1 = 0x0001 overlapLength-1 366 SI(m7 = _mm_cvtsi32_si64(tmp1), movd_v2r(tmp1, mm7)); // mm7 = 0x0000 0000 0001 01ff 367 SI(m7 = _mm_unpacklo_pi32(m7, m7), punpckldq_r2r(mm7, mm7)); // mm7 = 0x0001 01ff 0001 01ff 368 369 do { 370 // Process two parallel batches of 2+2 stereo samples during each round 371 // to improve CPU-level parallellization. 372 // 373 // Load [midPtr] into m0 and m1 374 // Load [inPtr] into m3 375 // unpack words of m0, m1 and m3 into m0 and m1 376 // multiply-add m0*m6 and m1*m7, store results into m0 and m1 377 // divide m0 and m1 by 512 (=right-shift by overlapDividerBits) 378 // pack the result into m0 and store into [edx] 379 // 380 // Load [midPtr+8] into m2 and m3 381 // Load [inPtr+8] into m4 382 // unpack words of m2, m3 and m4 into m2 and m3 383 // multiply-add m2*m6 and m3*m7, store results into m2 and m3 384 // divide m2 and m3 by 512 (=right-shift by overlapDividerBits) 385 // pack the result into m2 and store into [edx+8] 386 SI(m0 = midPtr[0], movq_a2r(0, midPtr, mm0));// mm0 = m1l m1r m0l m0r 387 outPtr += 2; 388 SI(m3 = inPtr[0], movq_a2r(0, inPtr, mm3)); // mm3 = i1l i1r i0l i0r 389 SI(m1 = m0, movq_r2r(mm0, mm1)); // mm1 = m1l m1r m0l m0r 390 SI(m2 = midPtr[1], movq_a2r(8, midPtr, mm2));// mm2 = m3l m3r m2l m2r 391 SI(m0 = _mm_unpacklo_pi16(m0, m3),punpcklwd_r2r(mm3, mm0)); // mm0 = i0l m0l i0r m0r 392 midPtr += 2; 393 SI(m4 = inPtr[1], movq_a2r(8, inPtr, mm4)); // mm4 = i3l i3r i2l i2r 394 SI(m1 = _mm_unpackhi_pi16(m1, m3),punpckhwd_r2r(mm3, mm1)); // mm1 = i1l m1l i1r m1r 395 inPtr+=2; 396 SI(m3 = m2, movq_r2r(mm2, mm3)); // mm3 = m3l m3r m2l m2r 397 SI(m2 = _mm_unpacklo_pi16(m2, m4),punpcklwd_r2r(mm4, mm2)); // mm2 = i2l m2l i2r m2r 398 // mm0 = i0l*m63+m0l*m62 i0r*m61+m0r*m60 399 SI(m0 = _mm_madd_pi16(m0, m6), pmaddwd_r2r(mm6, mm0)); 400 SI(m3 = _mm_unpackhi_pi16(m3, m4),punpckhwd_r2r(mm4, mm3)); // mm3 = i3l m3l i3r m3r 401 SI(m4 = _mm_cvtsi32_si64(shift), movd_v2r(shift, mm4)); // mm4 = shift 402 // mm1 = i1l*m73+m1l*m72 i1r*m71+m1r*m70 403 SI(m1 = _mm_madd_pi16(m1, m7), pmaddwd_r2r(mm7, mm1)); 404 SI(m6 = _mm_add_pi16(m6, m5), paddw_r2r(mm5, mm6)); 405 SI(m7 = _mm_add_pi16(m7, m5), paddw_r2r(mm5, mm7)); 406 SI(m0 = _mm_srai_pi32(m0, m4), psrad_r2r(mm4, mm0)); // mm0 >>= shift 407 // mm2 = i2l*m63+m2l*m62 i2r*m61+m2r*m60 408 SI(m2 = _mm_madd_pi16(m2, m6), pmaddwd_r2r(mm6, mm2)); 409 SI(m1 = _mm_srai_pi32(m1, m4), psrad_r2r(mm4, mm1)); // mm1 >>= shift 410 // mm3 = i3l*m73+m3l*m72 i3r*m71+m3r*m70 411 SI(m3 = _mm_madd_pi16(m3, m7), pmaddwd_r2r(mm7, mm3)); 412 SI(m2 = _mm_srai_pi32(m2, m4), psrad_r2r(mm4, mm2)); // mm2 >>= shift 413 SI(m0 = _mm_packs_pi32(m0, m1), packssdw_r2r(mm1, mm0)); // mm0 = mm1h mm1l mm0h mm0l 414 SI(m3 = _mm_srai_pi32(m3, m4), psrad_r2r(mm4, mm3)); // mm3 >>= shift 415 SI(m6 = _mm_add_pi16(m6, m5), paddw_r2r(mm5, mm6)); 416 SI(m2 = _mm_packs_pi32(m2, m3), packssdw_r2r(mm3, mm2)); // mm2 = mm2h mm2l mm3h mm3l 417 SI(m7 = _mm_add_pi16(m7, m5), paddw_r2r(mm5, mm7)); 418 SI(outPtr[0] = m0, movq_r2a(mm0, 0, outPtr)); 419 SI(outPtr[1] = m2, movq_r2a(mm2, 8, outPtr)); 420 } while ((--counter)!=0); 421 _mm_empty(); 422 } 423 #endif 424 227 425 ////////////////////////////////////////////////////////////////////////////// 228 426 // 229 427 // implementation of MMX optimized functions of class 'FIRFilter' -
libs/libmythsoundtouch/STTypes.h
61 61 #define INTEGER_SAMPLES //< 16bit integer samples 62 62 //#define FLOAT_SAMPLES //< 32bit float samples 63 63 64 #define MULTICHANNEL 6 64 65 65 66 /// Define this to allow CPU-specific assembler optimizations. Notice that 66 67 /// having this enabled on non-x86 platforms doesn't matter; the compiler can -
libs/libmythsoundtouch/SoundTouch.cpp
140 140 // Sets the number of channels, 1 = mono, 2 = stereo 141 141 void SoundTouch::setChannels(uint numChannels) 142 142 { 143 #ifdef MULTICHANNEL 144 if (numChannels < 1 || numChannels > MULTICHANNEL) 145 #else 143 146 if (numChannels != 1 && numChannels != 2) 147 #endif 144 148 { 145 149 throw std::runtime_error("Illegal number of channels"); 146 150 } -
libs/libmyth/audiooutputjack.h
14 14 public: 15 15 AudioOutputJACK(QString audiodevice, int laudio_bits, 16 16 int laudio_channels, int laudio_samplerate, 17 AudioOutputSource source, bool set_initial_vol); 17 AudioOutputSource source, 18 bool set_initial_vol, bool laudio_passthru); 18 19 virtual ~AudioOutputJACK(); 19 20 20 21 // Volume control -
libs/libmyth/audiooutputbase.h
12 12 #include "samplerate.h" 13 13 #include "SoundTouch.h" 14 14 15 #define AUDBUFSIZE 768000 15 struct AVCodecContext; 16 class DigitalEncoder; 16 17 18 //#define AUDBUFSIZE 768000 19 //divisible by 12,10,8,6,4,2 and around 1024000 20 //#define AUDBUFSIZE 1024080 21 #define AUDBUFSIZE 1536000 22 17 23 class AudioOutputBase : public AudioOutput 18 24 { 19 25 public: 20 26 AudioOutputBase(QString audiodevice, int laudio_bits, 21 27 int laudio_channels, int laudio_samplerate, 22 AudioOutputSource source, bool set_initial_vol); 28 AudioOutputSource source, 29 bool set_initial_vol, bool laudio_passthru); 23 30 virtual ~AudioOutputBase(); 24 31 25 32 // reconfigure sound out for new params 26 33 virtual void Reconfigure(int audio_bits, 27 int audio_channels, int audio_samplerate); 34 int audio_channels, 35 int audio_samplerate, 36 bool audio_passthru, 37 void* audio_codec = NULL); 28 38 29 39 // do AddSamples calls block? 30 40 virtual void SetBlocking(bool blocking); … … 106 116 long soundcard_buffer_size; 107 117 QString audiodevice; 108 118 119 bool audio_passthru; 120 109 121 float audio_stretchfactor; 110 122 AudioOutputSource source; 123 AVCodecContext *audio_codec; 111 124 112 125 bool killaudio; 113 126 … … 115 128 bool set_initial_vol; 116 129 bool buffer_output_data_for_use; // used by AudioOutputNULL 117 130 131 int configured_audio_channels; 132 118 133 private: 119 134 QString lastError; 120 135 … … 127 142 128 143 // timestretch 129 144 soundtouch::SoundTouch * pSoundStretch; 145 DigitalEncoder * encoder; 130 146 131 147 bool blocking; // do AddSamples calls block? 132 148 … … 142 158 143 159 pthread_mutex_t avsync_lock; /* must hold avsync_lock to read or write 144 160 'audiotime' and 'audiotime_updated' */ 145 intaudiotime; // timecode of audio leaving the soundcard (same units as161 long long audiotime; // timecode of audio leaving the soundcard (same units as 146 162 // timecodes) ... 147 163 struct timeval audiotime_updated; // ... which was last updated at this time 148 164 149 165 /* Audio circular buffer */ 150 166 unsigned char audiobuffer[AUDBUFSIZE]; /* buffer */ 151 167 int raud, waud; /* read and write positions */ 152 intaudbuf_timecode; /* timecode of audio most recently placed into168 long long audbuf_timecode; /* timecode of audio most recently placed into 153 169 buffer */ 154 170 155 171 int numlowbuffer; -
libs/libmyth/audiooutputalsa.cpp
12 12 13 13 AudioOutputALSA::AudioOutputALSA(QString audiodevice, int laudio_bits, 14 14 int laudio_channels, int laudio_samplerate, 15 AudioOutputSource source, bool set_initial_vol) 16 : AudioOutputBase(audiodevice, laudio_bits, 17 laudio_channels, laudio_samplerate, source, set_initial_vol) 15 AudioOutputSource source, 16 bool set_initial_vol, bool laudio_passthru) 17 : AudioOutputBase(audiodevice, laudio_bits, 18 laudio_channels, laudio_samplerate, source, 19 set_initial_vol, laudio_passthru) 18 20 { 19 21 // our initalisation 20 22 pcm_handle = NULL; … … 22 24 mixer_handle = NULL; 23 25 24 26 // Set everything up 25 Reconfigure(laudio_bits, laudio_channels, laudio_samplerate); 27 Reconfigure(laudio_bits, laudio_channels, 28 laudio_samplerate, laudio_passthru); 26 29 } 27 30 28 31 AudioOutputALSA::~AudioOutputALSA() … … 41 44 42 45 pcm_handle = NULL; 43 46 numbadioctls = 0; 47 48 QString real_device = audiodevice; 49 if (audio_passthru) 50 real_device.append(":{ AES0 0x02 }"); 44 51 45 err = snd_pcm_open(&pcm_handle, audiodevice,52 err = snd_pcm_open(&pcm_handle, real_device, 46 53 SND_PCM_STREAM_PLAYBACK, SND_PCM_NONBLOCK); 47 54 48 55 if (err < 0) … … 75 82 } 76 83 else 77 84 { 78 fragment_size = 6144; // nicely divisible by 2,4,6,8 channels @ 16-bits 79 buffer_time = 500000; // .5 seconds 85 //fragment_size = 6144; // nicely divisible by 2,4,6,8 channels @ 16-bits 86 //fragment_size = 3072*audio_channels; // nicely divisible by 2,4,6,8 channels @ 16-bits 87 fragment_size = (audio_bits * audio_channels * audio_samplerate) / (8*30); 88 buffer_time = 100000; // .5 seconds 80 89 period_time = buffer_time / 4; // 4 interrupts per buffer 81 90 } 82 91 … … 148 157 149 158 tmpbuf = aubuf; 150 159 151 VERBOSE(VB_AUDIO , QString("WriteAudio: Preparing %1 bytes (%2 frames)")160 VERBOSE(VB_AUDIO|VB_TIMESTAMP, QString("WriteAudio: Preparing %1 bytes (%2 frames)") 152 161 .arg(size).arg(frames)); 153 162 154 163 while (frames > 0) -
libs/libmyth/audiooutputca.cpp
38 38 39 39 AudioOutputCA::AudioOutputCA(QString audiodevice, int laudio_bits, 40 40 int laudio_channels, int laudio_samplerate, 41 AudioOutputSource source, bool set_initial_vol) 42 : AudioOutputBase(audiodevice, laudio_bits, 43 laudio_channels, laudio_samplerate, 44 source, set_initial_vol) 41 AudioOutputSource source, 42 bool set_initial_vol, bool laudio_passthru) 43 : AudioOutputBase(audiodevice, laudio_bits, 44 laudio_channels, laudio_samplerate, source, 45 set_initial_vol, laudio_passthru) 45 46 { 46 47 // Create private data 47 48 coreaudio_data = new CoreAudioData(); 48 49 coreaudio_data->output_unit = NULL; 49 50 50 Reconfigure(laudio_bits, laudio_channels, laudio_samplerate); 51 Reconfigure(laudio_bits, laudio_channels, 52 laudio_samplerate, laudio_passthru); 51 53 } 52 54 53 55 AudioOutputCA::~AudioOutputCA() -
libs/libmyth/audiooutputjack.cpp
23 23 24 24 AudioOutputJACK::AudioOutputJACK(QString audiodevice, int laudio_bits, 25 25 int laudio_channels, int laudio_samplerate, 26 AudioOutputSource source, bool set_initial_vol) 27 : AudioOutputBase(audiodevice, laudio_bits, laudio_channels, 28 laudio_samplerate, source, set_initial_vol) 26 AudioOutputSource source, 27 bool set_initial_vol, bool laudio_passthru) 28 : AudioOutputBase(audiodevice, laudio_bits, 29 laudio_channels, laudio_samplerate, source, 30 set_initial_vol, laudio_passthru) 29 31 { 30 32 // Initialise the Jack output layer 31 33 JACK_Init(); … … 34 36 audioid = -1; 35 37 36 38 // Set everything up 37 Reconfigure(laudio_bits, laudio_channels, laudio_samplerate); 39 Reconfigure(laudio_bits, laudio_channels, 40 laudio_samplerate, laudio_passthru); 38 41 } 39 42 40 43 AudioOutputJACK::~AudioOutputJACK() -
libs/libmyth/audiooutputoss.h
15 15 public: 16 16 AudioOutputOSS(QString audiodevice, int laudio_bits, 17 17 int laudio_channels, int laudio_samplerate, 18 AudioOutputSource source, bool set_initial_vol); 18 AudioOutputSource source, bool set_initial_vol, 19 bool laudio_passthru); 19 20 virtual ~AudioOutputOSS(); 20 21 21 22 // Volume control -
libs/libmyth/audiooutputbase.cpp
12 12 #include <sys/time.h> 13 13 #include <unistd.h> 14 14 15 extern "C" { 16 #include "libavcodec/avcodec.h" 17 #include "libavcodec/liba52/a52.h" 18 } 15 19 20 #if QT_VERSION < 0x030200 21 #define LONGLONGCONVERT (long) 22 #else 23 #define LONGLONGCONVERT 24 #endif 25 26 #define LOC QString("DEnc: "); 27 #define MAX_AC3_FRAME_SIZE 6144 28 class DigitalEncoder 29 { 30 public: 31 DigitalEncoder(); 32 ~DigitalEncoder(); 33 void Dispose(); 34 bool DigitalEncoder::Init(CodecID codec_id, int bitrate, int samplerate, int channels); 35 size_t Encode(short * buff); 36 37 // if needed 38 char * GetFrameBuffer() 39 { 40 if (!frame_buffer && av_context) 41 { 42 frame_buffer = new char [one_frame_bytes]; 43 } 44 return frame_buffer; 45 } 46 size_t FrameSize() const { return one_frame_bytes; } 47 char * GetOutBuff() const { return outbuf; } 48 49 size_t audio_bytes_per_sample; 50 private: 51 AVCodecContext *av_context; 52 char * outbuf; 53 char * frame_buffer; 54 int outbuf_size; 55 size_t one_frame_bytes; 56 }; 57 58 DigitalEncoder::DigitalEncoder() 59 { 60 av_context = NULL; 61 outbuf = NULL; 62 outbuf_size = 0; 63 one_frame_bytes = 0; 64 frame_buffer = NULL; 65 } 66 67 DigitalEncoder::~DigitalEncoder() 68 { 69 Dispose(); 70 } 71 72 void DigitalEncoder::Dispose() 73 { 74 if (av_context) 75 { 76 avcodec_close(av_context); 77 av_free(av_context); 78 av_context = NULL; 79 } 80 if (outbuf) 81 { 82 delete [] outbuf; 83 outbuf = NULL; 84 outbuf_size = 0; 85 } 86 if (frame_buffer) 87 { 88 delete [] frame_buffer; 89 frame_buffer = NULL; 90 one_frame_bytes = 0; 91 } 92 } 93 94 //CODEC_ID_AC3 95 bool DigitalEncoder::Init(CodecID codec_id, int bitrate, int samplerate, int channels) 96 { 97 AVCodec * codec; 98 int ret; 99 100 VERBOSE(VB_AUDIO, QString("DigitalEncoder::Init codecid=%1, br=%2, sr=%3, ch=%4") 101 .arg(codec_id_string(codec_id)) 102 .arg(bitrate) 103 .arg(samplerate) 104 .arg(channels)); 105 //codec = avcodec_find_encoder(codec_id); 106 // always AC3 as there is no DTS encoder at the moment 2005/1/9 107 codec = avcodec_find_encoder(CODEC_ID_AC3); 108 if (!codec) 109 { 110 VERBOSE(VB_IMPORTANT,"Error: could not find codec"); 111 return false; 112 } 113 av_context = avcodec_alloc_context(); 114 av_context->bit_rate = bitrate; 115 av_context->sample_rate = samplerate; 116 av_context->channels = channels; 117 // open it */ 118 if ((ret = avcodec_open(av_context, codec)) < 0) 119 { 120 VERBOSE(VB_IMPORTANT,"Error: could not open codec, invalid bitrate or samplerate"); 121 Dispose(); 122 return false; 123 } 124 125 size_t bytes_per_frame = av_context->channels * sizeof(short); 126 audio_bytes_per_sample = bytes_per_frame; 127 one_frame_bytes = bytes_per_frame * av_context->frame_size; 128 129 outbuf_size = 16384; // ok for AC3 but DTS? 130 outbuf = new char [outbuf_size]; 131 VERBOSE(VB_AUDIO, QString("DigitalEncoder::Init fs=%1, bpf=%2 ofb=%3") 132 .arg(av_context->frame_size) 133 .arg(bytes_per_frame) 134 .arg(one_frame_bytes) 135 ); 136 137 return true; 138 } 139 140 static int DTS_SAMPLEFREQS[16] = 141 { 142 0, 8000, 16000, 32000, 64000, 128000, 11025, 22050, 143 44100, 88200, 176400, 12000, 24000, 48000, 96000, 192000 144 }; 145 146 static int DTS_BITRATES[30] = 147 { 148 32000, 56000, 64000, 96000, 112000, 128000, 149 192000, 224000, 256000, 320000, 384000, 448000, 150 512000, 576000, 640000, 768000, 896000, 1024000, 151 1152000, 1280000, 1344000, 1408000, 1411200, 1472000, 152 1536000, 1920000, 2048000, 3072000, 3840000, 4096000 153 }; 154 155 static int dts_decode_header(uint8_t *indata_ptr, int *rate, 156 int *nblks, int *sfreq) 157 { 158 uint id = ((indata_ptr[0] << 24) | (indata_ptr[1] << 16) | 159 (indata_ptr[2] << 8) | (indata_ptr[3])); 160 161 if (id != 0x7ffe8001) 162 return -1; 163 164 int ftype = indata_ptr[4] >> 7; 165 166 int surp = (indata_ptr[4] >> 2) & 0x1f; 167 surp = (surp + 1) % 32; 168 169 *nblks = (indata_ptr[4] & 0x01) << 6 | (indata_ptr[5] >> 2); 170 ++*nblks; 171 172 int fsize = (indata_ptr[5] & 0x03) << 12 | 173 (indata_ptr[6] << 4) | (indata_ptr[7] >> 4); 174 ++fsize; 175 176 *sfreq = (indata_ptr[8] >> 2) & 0x0f; 177 *rate = (indata_ptr[8] & 0x03) << 3 | ((indata_ptr[9] >> 5) & 0x07); 178 179 if (ftype != 1) 180 { 181 VERBOSE(VB_IMPORTANT, LOC + 182 QString("DTS: Termination frames not handled (ftype %1)") 183 .arg(ftype)); 184 return -1; 185 } 186 187 if (*sfreq != 13) 188 { 189 VERBOSE(VB_IMPORTANT, LOC + 190 QString("DTS: Only 48kHz supported (sfreq %1)").arg(*sfreq)); 191 return -1; 192 } 193 194 if ((fsize > 8192) || (fsize < 96)) 195 { 196 VERBOSE(VB_IMPORTANT, LOC + 197 QString("DTS: fsize: %1 invalid").arg(fsize)); 198 return -1; 199 } 200 201 if (*nblks != 8 && *nblks != 16 && *nblks != 32 && 202 *nblks != 64 && *nblks != 128 && ftype == 1) 203 { 204 VERBOSE(VB_IMPORTANT, LOC + 205 QString("DTS: nblks %1 not valid for normal frame") 206 .arg(*nblks)); 207 return -1; 208 } 209 210 return fsize; 211 } 212 213 static int dts_syncinfo(uint8_t *indata_ptr, int * /*flags*/, 214 int *sample_rate, int *bit_rate) 215 { 216 int nblks; 217 int rate; 218 int sfreq; 219 220 int fsize = dts_decode_header(indata_ptr, &rate, &nblks, &sfreq); 221 if (fsize >= 0) 222 { 223 if (rate >= 0 && rate <= 29) 224 *bit_rate = DTS_BITRATES[rate]; 225 else 226 *bit_rate = 0; 227 if (sfreq >= 1 && sfreq <= 15) 228 *sample_rate = DTS_SAMPLEFREQS[sfreq]; 229 else 230 *sample_rate = 0; 231 } 232 return fsize; 233 } 234 235 static int encode_frame( 236 bool dts, 237 unsigned char *data, 238 size_t &len) 239 { 240 size_t enc_len; 241 int flags, sample_rate, bit_rate; 242 243 // we don't do any length/crc validation of the AC3 frame here; presumably 244 // the receiver will have enough sense to do that. if someone has a 245 // receiver that doesn't, here would be a good place to put in a call 246 // to a52_crc16_block(samples+2, data_size-2) - but what do we do if the 247 // packet is bad? we'd need to send something that the receiver would 248 // ignore, and if so, may as well just assume that it will ignore 249 // anything with a bad CRC... 250 251 uint nr_samples = 0, block_len; 252 if (dts) 253 { 254 enc_len = dts_syncinfo(data+8, &flags, &sample_rate, &bit_rate); 255 int rate, sfreq, nblks; 256 dts_decode_header(data+8, &rate, &nblks, &sfreq); 257 nr_samples = nblks * 32; 258 block_len = nr_samples * 2 * 2; 259 } 260 else 261 { 262 enc_len = a52_syncinfo(data+8, &flags, &sample_rate, &bit_rate); 263 block_len = MAX_AC3_FRAME_SIZE; 264 } 265 266 if (enc_len == 0 || enc_len > len) 267 { 268 int l = len; 269 len = 0; 270 return l; 271 } 272 273 enc_len = min((uint)enc_len, block_len - 8); 274 275 //uint32_t x = *(uint32_t*)(data+8); 276 // in place swab 277 swab(data+8, data+8, enc_len); 278 //VERBOSE(VB_AUDIO|VB_TIMESTAMP, 279 // QString("DigitalEncoder::Encode swab test %1 %2") 280 // .arg(x,0,16).arg(*(uint32_t*)(data+8),0,16)); 281 282 // the following values come from libmpcodecs/ad_hwac3.c in mplayer. 283 // they form a valid IEC958 AC3 header. 284 data[0] = 0x72; 285 data[1] = 0xF8; 286 data[2] = 0x1F; 287 data[3] = 0x4E; 288 data[4] = 0x01; 289 if (dts) 290 { 291 switch(nr_samples) 292 { 293 case 512: 294 data[4] = 0x0B; /* DTS-1 (512-sample bursts) */ 295 break; 296 297 case 1024: 298 data[4] = 0x0C; /* DTS-2 (1024-sample bursts) */ 299 break; 300 301 case 2048: 302 data[4] = 0x0D; /* DTS-3 (2048-sample bursts) */ 303 break; 304 305 default: 306 VERBOSE(VB_IMPORTANT, LOC + 307 QString("DTS: %1-sample bursts not supported") 308 .arg(nr_samples)); 309 data[4] = 0x00; 310 break; 311 } 312 } 313 data[5] = 0x00; 314 data[6] = (enc_len << 3) & 0xFF; 315 data[7] = (enc_len >> 5) & 0xFF; 316 memset(data + 8 + enc_len, 0, block_len - 8 - enc_len); 317 len = block_len; 318 319 return enc_len; 320 } 321 322 // must have exactly 1 frames worth of data 323 size_t DigitalEncoder::Encode(short * buff) 324 { 325 int encsize = 0; 326 size_t outsize = 0; 327 328 // put data in the correct spot for encode frame 329 outsize = avcodec_encode_audio( 330 av_context, 331 ((uchar*)outbuf)+8, 332 outbuf_size-8, 333 buff); 334 size_t tmpsize = outsize; 335 336 outsize = MAX_AC3_FRAME_SIZE; 337 encsize = encode_frame( 338 //av_context->codec_id==CODEC_ID_DTS, 339 false, 340 (unsigned char*)outbuf, outsize); 341 VERBOSE(VB_AUDIO|VB_TIMESTAMP, 342 QString("DigitalEncoder::Encode len1=%1 len2=%2 finallen=%3") 343 .arg(tmpsize) 344 .arg(encsize) 345 .arg(outsize) 346 ); 347 348 return outsize; 349 } 350 #undef LOC 351 #define LOC QString("AO: ") 352 16 353 AudioOutputBase::AudioOutputBase(QString audiodevice, int, 17 354 int, int, 18 AudioOutputSource source, bool set_initial_vol) 355 AudioOutputSource source, 356 bool set_initial_vol, 357 bool /*laudio_passthru*/) 19 358 { 20 359 pthread_mutex_init(&audio_buflock, NULL); 21 360 pthread_mutex_init(&avsync_lock, NULL); … … 29 368 current_seconds = -1; 30 369 source_bitrate = -1; 31 370 audio_stretchfactor = 1.0; 371 audio_codec = NULL; 32 372 pSoundStretch = NULL; 373 encoder = NULL; 33 374 blocking = false; 34 375 this->source = source; 35 376 this->set_initial_vol = set_initial_vol; 36 377 soundcard_buffer_size = 0; 37 378 buffer_output_data_for_use = false; // used by AudioOutputNULL 379 configured_audio_channels = gContext->GetNumSetting("MaxChannels", 2); 38 380 39 40 381 src_ctx = NULL; 41 382 42 383 // You need to call the next line from your concrete class. 43 384 // Virtuals cause problems in the base class constructors 44 // Reconfigure(laudio_bits, laudio_channels, laudio_samplerate );385 // Reconfigure(laudio_bits, laudio_channels, laudio_samplerate, laudio_passthru); 45 386 } 46 387 47 388 AudioOutputBase::~AudioOutputBase() … … 78 419 VERBOSE(VB_GENERAL, QString("Using time stretch %1") 79 420 .arg(audio_stretchfactor)); 80 421 pSoundStretch = new soundtouch::SoundTouch(); 81 pSoundStretch->setSampleRate(audio_samplerate); 82 pSoundStretch->setChannels(audio_channels); 422 if (audio_codec) 423 { 424 if (!encoder) 425 { 426 VERBOSE(VB_AUDIO, LOC + QString("Creating Encoder for codec %1 origfs %2").arg(audio_codec->codec_id).arg(audio_codec->frame_size)); 427 encoder = new DigitalEncoder(); 428 if (!encoder->Init(audio_codec->codec_id, 429 audio_codec->bit_rate, 430 audio_codec->sample_rate, 431 audio_codec->channels 432 )) 433 { 434 // eeks 435 delete encoder; 436 encoder = NULL; 437 VERBOSE(VB_AUDIO, LOC + QString("Failed to Create Encoder")); 438 } 439 } 440 } 441 if (encoder) 442 { 443 pSoundStretch->setSampleRate(audio_codec->sample_rate); 444 pSoundStretch->setChannels(audio_codec->channels); 445 } 446 else 447 { 448 pSoundStretch->setSampleRate(audio_samplerate); 449 pSoundStretch->setChannels(audio_channels); 450 } 83 451 84 452 pSoundStretch->setTempo(audio_stretchfactor); 85 453 pSoundStretch->setSetting(SETTING_SEQUENCE_MS, 35); … … 102 470 } 103 471 104 472 void AudioOutputBase::Reconfigure(int laudio_bits, int laudio_channels, 105 int laudio_samplerate) 473 int laudio_samplerate, bool laudio_passthru, 474 void* laudio_codec) 106 475 { 476 int codec_id = CODEC_ID_NONE; 477 int lcodec_id = CODEC_ID_NONE; 478 int lcchannels = 0; 479 int cchannels = 0; 480 if (laudio_codec) 481 { 482 lcodec_id = ((AVCodecContext*)laudio_codec)->codec_id; 483 laudio_bits = 16; 484 laudio_channels = 2; 485 laudio_samplerate = 48000; 486 lcchannels = ((AVCodecContext*)laudio_codec)->channels; 487 } 488 if (audio_codec) 489 { 490 codec_id = audio_codec->codec_id; 491 cchannels = ((AVCodecContext*)audio_codec)->channels; 492 } 493 ClearError(); 107 494 if (laudio_bits == audio_bits && laudio_channels == audio_channels && 108 laudio_samplerate == audio_samplerate && !need_resampler) 495 laudio_samplerate == audio_samplerate && !need_resampler && 496 laudio_passthru == audio_passthru && 497 lcodec_id == codec_id && lcchannels == cchannels) 109 498 return; 110 499 111 500 KillAudio(); … … 117 506 waud = raud = 0; 118 507 audio_actually_paused = false; 119 508 509 bool redo_stretch = (pSoundStretch && audio_channels != laudio_channels); 120 510 audio_channels = laudio_channels; 121 511 audio_bits = laudio_bits; 122 512 audio_samplerate = laudio_samplerate; 513 audio_codec = (AVCodecContext*)laudio_codec; 514 audio_passthru = laudio_passthru; 123 515 if (audio_bits != 8 && audio_bits != 16) 124 516 { 125 517 pthread_mutex_unlock(&avsync_lock); … … 137 529 138 530 numlowbuffer = 0; 139 531 140 VERBOSE(VB_GENERAL, QString("Opening audio device '%1'. ")141 .arg(audiodevice) );532 VERBOSE(VB_GENERAL, QString("Opening audio device '%1'. ch %2 sr %3") 533 .arg(audiodevice).arg(audio_channels).arg(audio_samplerate)); 142 534 143 535 // Actually do the device specific open call 144 536 if (!OpenDevice()) 145 537 { 146 VERBOSE(VB_AUDIO, "Aborting reconfigure");147 538 pthread_mutex_unlock(&avsync_lock); 148 539 pthread_mutex_unlock(&audio_buflock); 540 if (GetError().isEmpty()) 541 Error("Aborting reconfigure"); 542 VERBOSE(VB_AUDIO, "Aborting reconfigure"); 149 543 return; 150 544 } 151 545 … … 167 561 current_seconds = -1; 168 562 source_bitrate = -1; 169 563 564 // NOTE: this wont do anything as above samplerate vars are set equal 170 565 // Check if we need the resampler 171 566 if (audio_samplerate != laudio_samplerate) 172 567 { … … 190 585 } 191 586 192 587 VERBOSE(VB_AUDIO, QString("Audio Stretch Factor: %1").arg(audio_stretchfactor)); 588 VERBOSE(VB_AUDIO, QString("Audio Codec Used: %1") 589 .arg(audio_codec?codec_id_string(audio_codec->codec_id):"not set")); 193 590 194 SetStretchFactorLocked(audio_stretchfactor); 195 if (pSoundStretch) 591 if (redo_stretch) 196 592 { 197 pSoundStretch->setSampleRate(audio_samplerate); 198 pSoundStretch->setChannels(audio_channels); 593 float laudio_stretchfactor = audio_stretchfactor; 594 delete pSoundStretch; 595 pSoundStretch = NULL; 596 audio_stretchfactor = 0.0; 597 SetStretchFactorLocked(laudio_stretchfactor); 199 598 } 599 else 600 { 601 SetStretchFactorLocked(audio_stretchfactor); 602 if (pSoundStretch) 603 { 604 // if its passthru then we need to reencode 605 if (audio_codec) 606 { 607 if (!encoder) 608 { 609 VERBOSE(VB_AUDIO, LOC + QString("Creating Encoder for codec %1").arg(audio_codec->codec_id)); 610 encoder = new DigitalEncoder(); 611 if (!encoder->Init(audio_codec->codec_id, 612 audio_codec->bit_rate, 613 audio_codec->sample_rate, 614 audio_codec->channels 615 )) 616 { 617 // eeks 618 delete encoder; 619 encoder = NULL; 620 VERBOSE(VB_AUDIO, LOC + QString("Failed to Create Encoder")); 621 } 622 } 623 } 624 if (encoder) 625 { 626 pSoundStretch->setSampleRate(audio_codec->sample_rate); 627 pSoundStretch->setChannels(audio_codec->channels); 628 } 629 else 630 { 631 pSoundStretch->setSampleRate(audio_samplerate); 632 pSoundStretch->setChannels(audio_channels); 633 } 634 } 635 } 200 636 201 637 // Setup visualisations, zero the visualisations buffers 202 638 prepareVisuals(); … … 242 678 pSoundStretch = NULL; 243 679 } 244 680 681 if (encoder) 682 { 683 delete encoder; 684 encoder = NULL; 685 } 686 245 687 CloseDevice(); 246 688 247 689 killAudioLock.unlock(); … … 255 697 256 698 void AudioOutputBase::Pause(bool paused) 257 699 { 700 VERBOSE(VB_AUDIO, LOC+ QString("Pause %0").arg(paused)); 258 701 pauseaudio = paused; 259 702 audio_actually_paused = false; 260 703 } … … 335 778 The reason is that computing 'audiotime' requires acquiring the audio 336 779 lock, which the video thread should not do. So, we call 'SetAudioTime()' 337 780 from the audio thread, and then call this from the video thread. */ 338 intret;781 long long ret; 339 782 struct timeval now; 340 783 341 784 if (audiotime == 0) … … 347 790 348 791 ret = (now.tv_sec - audiotime_updated.tv_sec) * 1000; 349 792 ret += (now.tv_usec - audiotime_updated.tv_usec) / 1000; 350 ret = ( int)(ret * audio_stretchfactor);793 ret = (long long)(ret * audio_stretchfactor); 351 794 795 #if 1 796 VERBOSE(VB_AUDIO|VB_TIMESTAMP, 797 QString("GetAudiotime now=%1.%2, set=%3.%4, ret=%5, audt=%6 sf=%7") 798 .arg(now.tv_sec).arg(now.tv_usec) 799 .arg(audiotime_updated.tv_sec).arg(audiotime_updated.tv_usec) 800 .arg(ret) 801 .arg(audiotime) 802 .arg(audio_stretchfactor) 803 ); 804 #endif 805 352 806 ret += audiotime; 353 807 354 808 pthread_mutex_unlock(&avsync_lock); 355 return ret;809 return (int)ret; 356 810 } 357 811 358 812 void AudioOutputBase::SetAudiotime(void) … … 389 843 // include algorithmic latencies 390 844 if (pSoundStretch) 391 845 { 846 // if encoder is active, then use its idea of audiobytes 847 //size_t abps = encoder?encoder->audio_bytes_per_sample:audio_bytes_per_sample; 848 849 // add the effect of any unused but processed samples, AC3 reencode does this 850 totalbuffer += (int)(pSoundStretch->numSamples() * audio_bytes_per_sample); 392 851 // add the effect of unprocessed samples in time stretch algo 393 852 totalbuffer += (int)((pSoundStretch->numUnprocessedSamples() * 394 853 audio_bytes_per_sample) / audio_stretchfactor); 395 854 } 396 855 397 856 audiotime = audbuf_timecode - (int)(totalbuffer * 100000.0 / 398 857 (audio_bytes_per_sample * effdspstretched)); 399 858 400 859 gettimeofday(&audiotime_updated, NULL); 860 #if 1 861 VERBOSE(VB_AUDIO|VB_TIMESTAMP, 862 QString("SetAudiotime set=%1.%2, audt=%3 atc=%4 tb=%5 sb=%6 eds=%7 abps=%8 sf=%9") 863 .arg(audiotime_updated.tv_sec).arg(audiotime_updated.tv_usec) 864 .arg(audiotime) 865 .arg(audbuf_timecode) 866 .arg(totalbuffer) 867 .arg(soundcard_buffer) 868 .arg(effdspstretched) 869 .arg(audio_bytes_per_sample) 870 .arg(audio_stretchfactor) 871 ); 872 #endif 401 873 402 874 pthread_mutex_unlock(&avsync_lock); 403 875 pthread_mutex_unlock(&audio_buflock); … … 457 929 // NOTE: This function is not threadsafe 458 930 459 931 int afree = audiofree(true); 460 int len = samples * audio_bytes_per_sample;932 int len = samples * (encoder?encoder->audio_bytes_per_sample:audio_bytes_per_sample); 461 933 462 934 // Check we have enough space to write the data 463 935 if (need_resampler && src_ctx) 464 936 len = (int)ceilf(float(len) * src_data.src_ratio); 465 937 if ((len > afree) && !blocking) 938 { 939 VERBOSE(VB_AUDIO|VB_TIMESTAMP, QString("AddSamples FAILED bytes=%1, used=%2, free=%3, timecode=%4") 940 .arg(len) 941 .arg(AUDBUFSIZE-afree).arg(afree).arg(LONGLONGCONVERT timecode)); 466 942 return false; // would overflow 943 } 467 944 468 945 // resample input if necessary 469 946 if (need_resampler && src_ctx) … … 497 974 498 975 int AudioOutputBase::WaitForFreeSpace(int samples) 499 976 { 500 int len = samples * audio_bytes_per_sample; 977 int abps = encoder?encoder->audio_bytes_per_sample:audio_bytes_per_sample; 978 int len = samples * abps; 501 979 int afree = audiofree(false); 502 980 503 981 while (len > afree) 504 982 { 505 983 if (blocking) 506 984 { 507 VERBOSE(VB_AUDIO , "Waiting for free space");985 VERBOSE(VB_AUDIO|VB_TIMESTAMP, "Waiting for free space"); 508 986 // wait for more space 509 987 pthread_cond_wait(&audio_bufsig, &audio_buflock); 510 988 afree = audiofree(false); 511 989 } 512 990 else 513 991 { 514 VERBOSE(VB_IMPORTANT, "Audio buffer overflow, audio data lost!"); 515 samples = afree / audio_bytes_per_sample; 516 len = samples * audio_bytes_per_sample; 992 VERBOSE(VB_IMPORTANT, 993 QString("Audio buffer overflow, %1 audio samples lost!") 994 .arg(samples-afree / abps)); 995 samples = afree / abps; 996 len = samples * abps; 517 997 if (src_ctx) 518 998 { 519 999 int error = src_reset(src_ctx); … … 538 1018 539 1019 int afree = audiofree(false); 540 1020 541 VERBOSE(VB_AUDIO, QString("_AddSamples bytes=%1, used=%2, free=%3, timecode=%4") 542 .arg(samples * audio_bytes_per_sample) 543 .arg(AUDBUFSIZE-afree).arg(afree).arg((long)timecode)); 1021 int abps = encoder?encoder->audio_bytes_per_sample:audio_bytes_per_sample; 1022 VERBOSE(VB_AUDIO|VB_TIMESTAMP, QString("_AddSamples samples=%1 bytes=%2, used=%3, free=%4, timecode=%5") 1023 .arg(samples) 1024 .arg(samples * abps) 1025 .arg(AUDBUFSIZE-afree).arg(afree).arg(LONGLONGCONVERT timecode)); 544 1026 545 1027 len = WaitForFreeSpace(samples); 546 1028 … … 577 1059 578 1060 if (pSoundStretch) 579 1061 { 1062 580 1063 // does not change the timecode, only the number of samples 581 1064 // back to orig pos 582 1065 org_waud = waud; 583 1066 int bdiff = AUDBUFSIZE - org_waud; 584 int nSamplesToEnd = bdiff/a udio_bytes_per_sample;1067 int nSamplesToEnd = bdiff/abps; 585 1068 if (bdiff < len) 586 1069 { 587 1070 pSoundStretch->putSamples((soundtouch::SAMPLETYPE*)(audiobuffer + 588 1071 org_waud), nSamplesToEnd); 589 1072 pSoundStretch->putSamples((soundtouch::SAMPLETYPE*)audiobuffer, 590 (len - bdiff) / a udio_bytes_per_sample);1073 (len - bdiff) / abps); 591 1074 } 592 1075 else 593 1076 { 594 1077 pSoundStretch->putSamples((soundtouch::SAMPLETYPE*)(audiobuffer + 595 org_waud), len / a udio_bytes_per_sample);1078 org_waud), len / abps); 596 1079 } 597 1080 598 int newLen = 0; 599 int nSamples; 600 len = WaitForFreeSpace(pSoundStretch->numSamples() * 601 audio_bytes_per_sample); 602 do 1081 if (encoder) 603 1082 { 604 int samplesToGet = len/audio_bytes_per_sample; 605 if (samplesToGet > nSamplesToEnd) 1083 // pull out a packet's worth and reencode it until we dont have enough 1084 // for any more packets 1085 soundtouch::SAMPLETYPE* temp_buff = 1086 (soundtouch::SAMPLETYPE*)encoder->GetFrameBuffer(); 1087 size_t frameSize = encoder->FrameSize()/abps; 1088 VERBOSE(VB_AUDIO|VB_TIMESTAMP, 1089 QString("_AddSamples Enc sfs=%1 bfs=%2 sss=%3") 1090 .arg(frameSize) 1091 .arg(encoder->FrameSize()) 1092 .arg(pSoundStretch->numSamples()) 1093 ); 1094 // process the same number of samples as it creates a full encoded buffer 1095 // just like before 1096 while (pSoundStretch->numSamples() >= frameSize) 606 1097 { 607 samplesToGet = nSamplesToEnd; 1098 int got = pSoundStretch->receiveSamples(temp_buff, frameSize); 1099 int amount = encoder->Encode(temp_buff); 1100 VERBOSE(VB_AUDIO|VB_TIMESTAMP, 1101 QString("_AddSamples Enc bytes=%1 got=%2 left=%3") 1102 .arg(amount) 1103 .arg(got) 1104 .arg(pSoundStretch->numSamples()) 1105 ); 1106 if (amount == 0) 1107 continue; 1108 //len = WaitForFreeSpace(amount); 1109 char * ob = encoder->GetOutBuff(); 1110 if (amount >= bdiff) 1111 { 1112 memcpy(audiobuffer + org_waud, ob, bdiff); 1113 ob += bdiff; 1114 amount -= bdiff; 1115 org_waud = 0; 1116 } 1117 if (amount > 0) 1118 memcpy(audiobuffer + org_waud, ob, amount); 1119 bdiff = AUDBUFSIZE - amount; 1120 org_waud += amount; 608 1121 } 609 610 nSamples = pSoundStretch->receiveSamples((soundtouch::SAMPLETYPE*) 611 (audiobuffer + org_waud), samplesToGet); 612 if (nSamples == nSamplesToEnd) 1122 } 1123 else 1124 { 1125 int newLen = 0; 1126 int nSamples; 1127 len = WaitForFreeSpace(pSoundStretch->numSamples() * 1128 audio_bytes_per_sample); 1129 do 613 1130 { 614 org_waud = 0; 615 nSamplesToEnd = AUDBUFSIZE/audio_bytes_per_sample; 616 } 617 else 618 { 619 org_waud += nSamples * audio_bytes_per_sample; 620 nSamplesToEnd -= nSamples; 621 } 1131 int samplesToGet = len/audio_bytes_per_sample; 1132 if (samplesToGet > nSamplesToEnd) 1133 { 1134 samplesToGet = nSamplesToEnd; 1135 } 622 1136 623 newLen += nSamples * audio_bytes_per_sample; 624 len -= nSamples * audio_bytes_per_sample; 625 } while (nSamples > 0); 1137 nSamples = pSoundStretch->receiveSamples((soundtouch::SAMPLETYPE*) 1138 (audiobuffer + org_waud), samplesToGet); 1139 if (nSamples == nSamplesToEnd) 1140 { 1141 org_waud = 0; 1142 nSamplesToEnd = AUDBUFSIZE/audio_bytes_per_sample; 1143 } 1144 else 1145 { 1146 org_waud += nSamples * audio_bytes_per_sample; 1147 nSamplesToEnd -= nSamples; 1148 } 1149 1150 newLen += nSamples * audio_bytes_per_sample; 1151 len -= nSamples * audio_bytes_per_sample; 1152 } while (nSamples > 0); 1153 } 626 1154 } 627 1155 628 1156 waud = org_waud; … … 692 1220 space_on_soundcard = getSpaceOnSoundcard(); 693 1221 694 1222 if (space_on_soundcard != last_space_on_soundcard) { 695 VERBOSE(VB_AUDIO , QString("%1 bytes free on soundcard")1223 VERBOSE(VB_AUDIO|VB_TIMESTAMP, QString("%1 bytes free on soundcard") 696 1224 .arg(space_on_soundcard)); 697 1225 last_space_on_soundcard = space_on_soundcard; 698 1226 } … … 705 1233 WriteAudio(zeros, fragment_size); 706 1234 } else { 707 1235 // this should never happen now -dag 708 VERBOSE(VB_AUDIO ,1236 VERBOSE(VB_AUDIO|VB_TIMESTAMP, 709 1237 QString("waiting for space on soundcard " 710 1238 "to write zeros: have %1 need %2") 711 1239 .arg(space_on_soundcard).arg(fragment_size)); … … 741 1269 if (fragment_size > audiolen(true)) 742 1270 { 743 1271 if (audiolen(true) > 0) // only log if we're sending some audio 744 VERBOSE(VB_AUDIO ,1272 VERBOSE(VB_AUDIO|VB_TIMESTAMP, 745 1273 QString("audio waiting for buffer to fill: " 746 1274 "have %1 want %2") 747 1275 .arg(audiolen(true)).arg(fragment_size)); 748 1276 749 VERBOSE(VB_AUDIO, "Broadcasting free space avail");1277 //VERBOSE(VB_AUDIO|VB_TIMESTAMP, "Broadcasting free space avail"); 750 1278 pthread_mutex_lock(&audio_buflock); 751 1279 pthread_cond_broadcast(&audio_bufsig); 752 1280 pthread_mutex_unlock(&audio_buflock); … … 760 1288 if (fragment_size > space_on_soundcard) 761 1289 { 762 1290 if (space_on_soundcard != last_space_on_soundcard) { 763 VERBOSE(VB_AUDIO ,1291 VERBOSE(VB_AUDIO|VB_TIMESTAMP, 764 1292 QString("audio waiting for space on soundcard: " 765 1293 "have %1 need %2") 766 1294 .arg(space_on_soundcard).arg(fragment_size)); … … 822 1350 823 1351 /* update raud */ 824 1352 raud = (raud + fragment_size) % AUDBUFSIZE; 825 VERBOSE(VB_AUDIO, "Broadcasting free space avail");1353 //VERBOSE(VB_AUDIO|VB_TIMESTAMP, "Broadcasting free space avail"); 826 1354 pthread_cond_broadcast(&audio_bufsig); 827 1355 828 1356 written_size = fragment_size; -
libs/libmyth/audiooutput.cpp
28 28 29 29 AudioOutput *AudioOutput::OpenAudio(QString audiodevice, int audio_bits, 30 30 int audio_channels, int audio_samplerate, 31 AudioOutputSource source, bool set_initial_vol) 31 AudioOutputSource source, 32 bool set_initial_vol, bool audio_passthru) 32 33 { 33 34 if (audiodevice.startsWith("ALSA:")) 34 35 { 35 36 #ifdef USE_ALSA 36 37 return new AudioOutputALSA(audiodevice.remove(0, 5), audio_bits, 37 audio_channels, audio_samplerate, source, set_initial_vol); 38 audio_channels, audio_samplerate, source, 39 set_initial_vol, audio_passthru); 38 40 #else 39 41 VERBOSE(VB_IMPORTANT, "Audio output device is set to an ALSA device " 40 42 "but ALSA support is not compiled in!"); … … 44 46 else if (audiodevice.startsWith("NULL")) 45 47 { 46 48 return new AudioOutputNULL(audiodevice, audio_bits, 47 audio_channels, audio_samplerate, source, set_initial_vol); 49 audio_channels, audio_samplerate, source, 50 set_initial_vol, audio_passthru); 48 51 } 49 52 else if (audiodevice.startsWith("ARTS:")) 50 53 { 51 54 #ifdef USE_ARTS 52 55 return new AudioOutputARTS(audiodevice.remove(0, 5), audio_bits, 53 audio_channels, audio_samplerate, source, set_initial_vol); 56 audio_channels, audio_samplerate, source, 57 set_initial_vol, audio_passthru); 54 58 #else 55 59 VERBOSE(VB_IMPORTANT, "Audio output device is set to an ARTS device " 56 60 "but ARTS support is not compiled in!"); … … 61 65 { 62 66 #ifdef USE_JACK 63 67 return new AudioOutputJACK(audiodevice.remove(0, 5), audio_bits, 64 audio_channels, audio_samplerate, source, set_initial_vol); 68 audio_channels, audio_samplerate, source, 69 set_initial_vol, audio_passthru); 65 70 #else 66 71 VERBOSE(VB_IMPORTANT, "Audio output device is set to a JACK device " 67 72 "but JACK support is not compiled in!"); … … 71 76 #if defined(USING_DIRECTX) 72 77 else 73 78 return new AudioOutputDX(audiodevice, audio_bits, 74 audio_channels, audio_samplerate, source, set_initial_vol); 79 audio_channels, audio_samplerate, source, 80 set_initial_vol, audio_passthru); 75 81 #elif defined(USING_OSS) 76 82 else 77 83 return new AudioOutputOSS(audiodevice, audio_bits, 78 audio_channels, audio_samplerate, source, set_initial_vol); 84 audio_channels, audio_samplerate, source, 85 set_initial_vol, audio_passthru); 79 86 #elif defined(CONFIG_DARWIN) 80 87 else 81 88 return new AudioOutputCA(audiodevice, audio_bits, 82 audio_channels, audio_samplerate, source, set_initial_vol); 89 audio_channels, audio_samplerate, source, 90 set_initial_vol, audio_passthru); 83 91 #endif 84 92 85 93 VERBOSE(VB_IMPORTANT, "No useable audio output driver found."); -
libs/libmyth/libmyth.pro
34 34 SOURCES += virtualkeyboard.cpp mythobservable.cpp 35 35 36 36 INCLUDEPATH += ../libmythsamplerate ../libmythsoundtouch ../.. 37 INCLUDEPATH += ../libavutil .. 37 38 DEPENDPATH += ../libmythsamplerate ../libmythsoundtouch 39 DEPENDPATH += ../libavutil ../libavcodec 38 40 39 41 40 42 LIBS += -L../libmythsamplerate -lmythsamplerate-$${LIBVERSION} 41 43 LIBS += -L../libmythsoundtouch -lmythsoundtouch-$${LIBVERSION} 44 LIBS += -L../libavcodec -lmythavcodec-$${LIBVERSION} 42 45 43 46 isEmpty(QMAKE_EXTENSION_SHLIB) { 44 47 QMAKE_EXTENSION_SHLIB=so -
libs/libmyth/audiooutputca.h
19 19 public: 20 20 AudioOutputCA(QString audiodevice, int laudio_bits, 21 21 int laudio_channels, int laudio_samplerate, 22 AudioOutputSource source, bool set_initial_vol); 22 AudioOutputSource source, 23 bool set_initial_vol, bool laudio_passthru); 23 24 virtual ~AudioOutputCA(); 24 25 25 26 // callback for delivering audio to output device -
libs/libmyth/audiooutputoss.cpp
27 27 28 28 AudioOutputOSS::AudioOutputOSS(QString audiodevice, int laudio_bits, 29 29 int laudio_channels, int laudio_samplerate, 30 AudioOutputSource source, bool set_initial_vol) 31 : AudioOutputBase(audiodevice, laudio_bits, 32 laudio_channels, laudio_samplerate, source, set_initial_vol) 30 AudioOutputSource source, bool set_initial_vol, 31 bool laudio_passthru) 32 : AudioOutputBase(audiodevice, laudio_bits, 33 laudio_channels, laudio_samplerate, source, 34 set_initial_vol, laudio_passthru) 33 35 { 34 36 // our initalisation 35 37 audiofd = -1; … … 37 39 numbadioctls = 0; 38 40 39 41 // Set everything up 40 Reconfigure(laudio_bits, laudio_channels, laudio_samplerate); 42 Reconfigure(laudio_bits, laudio_channels, 43 laudio_samplerate, laudio_passthru); 41 44 } 42 45 43 46 AudioOutputOSS::~AudioOutputOSS() -
libs/libmyth/audiooutputarts.cpp
9 9 10 10 AudioOutputARTS::AudioOutputARTS(QString audiodevice, int audio_bits, 11 11 int audio_channels, int audio_samplerate, 12 AudioOutputSource source, bool set_initial_vol) 13 : AudioOutputBase(audiodevice, audio_bits, audio_channels, 14 audio_samplerate, source, set_initial_vol) 12 AudioOutputSource source, 13 bool set_initial_vol, bool audio_passthru) 14 : AudioOutputBase(audiodevice, audio_bits, audio_channels, 15 audio_samplerate, source, set_initial_vol, 16 audio_passthru) 15 17 { 16 18 // our initalisation 17 19 pcm_handle = NULL; 18 20 19 21 // Set everything up 20 Reconfigure(audio_bits, audio_channels, audio_samplerate );22 Reconfigure(audio_bits, audio_channels, audio_samplerate, audio_passthru); 21 23 } 22 24 23 25 AudioOutputARTS::~AudioOutputARTS() -
libs/libmyth/audiooutputdx.cpp
97 97 98 98 AudioOutputDX::AudioOutputDX(QString audiodevice, int audio_bits, 99 99 int audio_channels, int audio_samplerate, 100 AudioOutputSource source, bool set_initial_vol) 100 AudioOutputSource source, 101 bool set_initial_vol, bool audio_passthru) 101 102 { 102 103 this->audiodevice = audiodevice; 103 104 … … 110 111 111 112 InitDirectSound(); 112 113 113 Reconfigure(audio_bits, audio_channels, audio_samplerate );114 Reconfigure(audio_bits, audio_channels, audio_samplerate, audio_passthru); 114 115 } 115 116 116 117 void AudioOutputDX::SetBlocking(bool blocking) … … 119 120 } 120 121 121 122 void AudioOutputDX::Reconfigure(int audio_bits, 122 int audio_channels, int audio_samplerate) 123 int audio_channels, 124 int audio_samplerate, 125 int audio_passthru, 126 AudioCodecMode laom 127 ) 123 128 { 124 129 if (dsbuffer) 125 130 DestroyDSBuffer(); … … 132 137 effdsp = audio_samplerate; 133 138 this->audio_bits = audio_bits; 134 139 this->audio_channels = audio_channels; 140 this->audio_passthru = audio_passthru; 135 141 } 136 142 137 143 AudioOutputDX::~AudioOutputDX() -
libs/libmyth/audiooutputnull.h
26 26 public: 27 27 AudioOutputNULL(QString audiodevice, int laudio_bits, 28 28 int laudio_channels, int laudio_samplerate, 29 AudioOutputSource source, bool set_initial_vol); 29 AudioOutputSource source, 30 bool set_initial_vol, bool laudio_passthru); 30 31 virtual ~AudioOutputNULL(); 31 32 32 33 virtual void Reset(void); -
libs/libmyth/audiooutput.h
19 19 public: 20 20 // opens one of the concrete subclasses 21 21 static AudioOutput *OpenAudio(QString audiodevice, int audio_bits, 22 int audio_channels, int audio_samplerate, 23 AudioOutputSource source, bool set_initial_vol); 22 int audio_channels, int audio_samplerate, 23 AudioOutputSource source, 24 bool set_initial_vol, bool audio_passthru); 24 25 25 26 AudioOutput() : VolumeBase(), OutputListeners() { lastError = QString::null; }; 26 27 virtual ~AudioOutput() { }; 27 28 28 29 // reconfigure sound out for new params 29 30 virtual void Reconfigure(int audio_bits, 30 int audio_channels, int audio_samplerate) = 0; 31 int audio_channels, 32 int audio_samplerate, 33 bool audio_passthru, 34 void* audio_codec = NULL 35 ) = 0; 31 36 32 37 virtual void SetStretchFactor(float factor); 33 38 … … 65 70 protected: 66 71 void Error(QString msg) 67 72 { lastError = msg; VERBOSE(VB_IMPORTANT, lastError); }; 73 void ClearError() 74 { lastError = QString::null; }; 68 75 69 76 private: 70 77 QString lastError; -
libs/libmyth/audiooutputnull.cpp
18 18 19 19 AudioOutputNULL::AudioOutputNULL(QString audiodevice, int laudio_bits, 20 20 int laudio_channels, int laudio_samplerate, 21 AudioOutputSource source, bool set_initial_vol) 21 AudioOutputSource source, bool set_initial_vol, 22 bool laudio_passthru) 22 23 : AudioOutputBase(audiodevice, laudio_bits, laudio_channels, 23 laudio_samplerate, source, set_initial_vol) 24 laudio_samplerate, source, set_initial_vol, 25 laudio_passthru) 24 26 { 25 27 locked_audio_channels = laudio_channels; 26 28 locked_audio_bits = laudio_bits; 27 29 locked_audio_samplerate = laudio_samplerate; 28 Reconfigure(laudio_bits, laudio_channels, laudio_samplerate );30 Reconfigure(laudio_bits, laudio_channels, laudio_samplerate, laudio_passthru); 29 31 current_buffer_size = 0; 30 32 } 31 33 -
libs/libmyth/audiooutputarts.h
16 16 public: 17 17 AudioOutputARTS(QString audiodevice, int audio_bits, 18 18 int audio_channels, int audio_samplerate, 19 AudioOutputSource source, bool set_initial_vol); 19 AudioOutputSource source, 20 bool set_initial_vol, bool laudio_passthru); 20 21 virtual ~AudioOutputARTS(); 21 22 22 23 // Volume control -
libs/libmyth/audiooutputdx.h
16 16 public: 17 17 AudioOutputDX(QString audiodevice, int audio_bits, 18 18 int audio_channels, int audio_samplerate, 19 AudioOutputSource source, bool set_initial_vol); 19 AudioOutputSource source, 20 bool set_initial_vol, bool laudio_passthru); 20 21 virtual ~AudioOutputDX(); 21 22 22 23 virtual void Reset(void); 23 24 virtual void Reconfigure(int audio_bits, 24 int audio_channels, int audio_samplerate); 25 int audio_channels, 26 int audio_samplerate, 27 bool audio_passthru, 28 AudioCodecMode aom = AUDIOCODECMODE_NORMAL); 25 29 virtual void SetBlocking(bool blocking); 26 30 27 31 virtual bool AddSamples(char *buffer, int samples, long long timecode); -
libs/libmyth/audiooutputalsa.h
17 17 { 18 18 public: 19 19 AudioOutputALSA(QString audiodevice, int laudio_bits, 20 int laudio_channels, int laudio_samplerate, 21 AudioOutputSource source, bool set_initial_vol); 20 int laudio_channels, int laudio_samplerate, 21 AudioOutputSource source, 22 bool set_initial_vol, bool laudio_passthru); 22 23 virtual ~AudioOutputALSA(); 23 24 24 25 // Volume control -
libs/libavcodec/a52dec.c
149 149 } 150 150 } 151 151 152 static inline int16_t convert (int32_t i) 153 { 154 if (i > 0x43c07fff) 155 return 32767; 156 else if (i < 0x43bf8000) 157 return -32768; 158 else 159 return i - 0x43c00000; 160 } 161 162 void float2s16_2 (float * _f, int16_t * s16) 163 { 164 int i; 165 int32_t * f = (int32_t *) _f; 166 167 for (i = 0; i < 256; i++) { 168 s16[2*i] = convert (f[i]); 169 s16[2*i+1] = convert (f[i+256]); 170 } 171 } 172 173 void float2s16_4 (float * _f, int16_t * s16) 174 { 175 int i; 176 int32_t * f = (int32_t *) _f; 177 178 for (i = 0; i < 256; i++) { 179 s16[4*i] = convert (f[i]); 180 s16[4*i+1] = convert (f[i+256]); 181 s16[4*i+2] = convert (f[i+512]); 182 s16[4*i+3] = convert (f[i+768]); 183 } 184 } 185 186 void float2s16_5 (float * _f, int16_t * s16) 187 { 188 int i; 189 int32_t * f = (int32_t *) _f; 190 191 for (i = 0; i < 256; i++) { 192 s16[5*i] = convert (f[i]); 193 s16[5*i+1] = convert (f[i+256]); 194 s16[5*i+2] = convert (f[i+512]); 195 s16[5*i+3] = convert (f[i+768]); 196 s16[5*i+4] = convert (f[i+1024]); 197 } 198 } 199 200 int channels_multi (int flags) 201 { 202 if (flags & A52_LFE) 203 return 6; 204 else if (flags & 1) /* center channel */ 205 return 5; 206 else if ((flags & A52_CHANNEL_MASK) == A52_2F2R) 207 return 4; 208 else 209 return 2; 210 } 211 212 void float2s16_multi (float * _f, int16_t * s16, int flags) 213 { 214 int i; 215 int32_t * f = (int32_t *) _f; 216 217 switch (flags) { 218 case A52_MONO: 219 for (i = 0; i < 256; i++) { 220 s16[5*i] = s16[5*i+1] = s16[5*i+2] = s16[5*i+3] = 0; 221 s16[5*i+4] = convert (f[i]); 222 } 223 break; 224 case A52_CHANNEL: 225 case A52_STEREO: 226 case A52_DOLBY: 227 float2s16_2 (_f, s16); 228 break; 229 case A52_3F: 230 for (i = 0; i < 256; i++) { 231 s16[5*i] = convert (f[i]); 232 s16[5*i+1] = convert (f[i+512]); 233 s16[5*i+2] = s16[5*i+3] = 0; 234 s16[5*i+4] = convert (f[i+256]); 235 } 236 break; 237 case A52_2F2R: 238 float2s16_4 (_f, s16); 239 break; 240 case A52_3F2R: 241 float2s16_5 (_f, s16); 242 break; 243 case A52_MONO | A52_LFE: 244 for (i = 0; i < 256; i++) { 245 s16[6*i] = s16[6*i+1] = s16[6*i+2] = s16[6*i+3] = 0; 246 s16[6*i+4] = convert (f[i+256]); 247 s16[6*i+5] = convert (f[i]); 248 } 249 break; 250 case A52_CHANNEL | A52_LFE: 251 case A52_STEREO | A52_LFE: 252 case A52_DOLBY | A52_LFE: 253 for (i = 0; i < 256; i++) { 254 s16[6*i] = convert (f[i+256]); 255 s16[6*i+1] = convert (f[i+512]); 256 s16[6*i+2] = s16[6*i+3] = s16[6*i+4] = 0; 257 s16[6*i+5] = convert (f[i]); 258 } 259 break; 260 case A52_3F | A52_LFE: 261 for (i = 0; i < 256; i++) { 262 s16[6*i] = convert (f[i+256]); 263 s16[6*i+1] = convert (f[i+768]); 264 s16[6*i+2] = s16[6*i+3] = 0; 265 s16[6*i+4] = convert (f[i+512]); 266 s16[6*i+5] = convert (f[i]); 267 } 268 break; 269 case A52_2F2R | A52_LFE: 270 for (i = 0; i < 256; i++) { 271 s16[6*i] = convert (f[i+256]); 272 s16[6*i+1] = convert (f[i+512]); 273 s16[6*i+2] = convert (f[i+768]); 274 s16[6*i+3] = convert (f[i+1024]); 275 s16[6*i+4] = 0; 276 s16[6*i+5] = convert (f[i]); 277 } 278 break; 279 case A52_3F2R | A52_LFE: 280 for (i = 0; i < 256; i++) { 281 s16[6*i] = convert (f[i+256]); 282 s16[6*i+1] = convert (f[i+768]); 283 s16[6*i+2] = convert (f[i+1024]); 284 s16[6*i+3] = convert (f[i+1280]); 285 s16[6*i+4] = convert (f[i+512]); 286 s16[6*i+5] = convert (f[i]); 287 } 288 break; 289 } 290 } 291 292 152 293 /**** end */ 153 294 154 295 #define HEADER_SIZE 7 … … 190 331 /* update codec info */ 191 332 avctx->sample_rate = sample_rate; 192 333 s->channels = ac3_channels[s->flags & 7]; 334 if (avctx->cqp >= 0) 335 avctx->channels = avctx->cqp; 193 336 if (s->flags & A52_LFE) 194 337 s->channels++; 195 338 if (avctx->channels == 0) … … 212 355 s->inbuf_ptr += len; 213 356 buf_size -= len; 214 357 } else { 358 int chans; 215 359 flags = s->flags; 216 360 if (avctx->channels == 1) 217 361 flags = A52_MONO; 218 else if (avctx->channels == 2) 219 flags = A52_STEREO; 362 else if (avctx->channels == 2) { 363 if (s->channels>2) 364 flags = A52_DOLBY; 365 else 366 flags = A52_STEREO; 367 } 220 368 else 221 369 flags |= A52_ADJUST_LEVEL; 222 370 level = 1; 371 chans = channels_multi(flags); 223 372 if (s->a52_frame(s->state, s->inbuf, &flags, &level, 384)) { 224 373 fail: 225 374 s->inbuf_ptr = s->inbuf; … … 229 378 for (i = 0; i < 6; i++) { 230 379 if (s->a52_block(s->state)) 231 380 goto fail; 232 float_to_int(s->samples, out_samples + i * 256 * avctx->channels, avctx->channels); 381 //float_to_int(s->samples, out_samples + i * 256 * avctx->channels, avctx->channels); 382 float2s16_multi(s->samples, out_samples + i * 256 * chans, flags); 233 383 } 234 384 s->inbuf_ptr = s->inbuf; 235 385 s->frame_size = 0; 236 *data_size = 6 * avctx->channels * 256 * sizeof(int16_t); 386 //*data_size = 6 * avctx->channels * 256 * sizeof(int16_t); 387 *data_size = 6 * chans * 256 * sizeof(int16_t); 237 388 break; 238 389 } 239 390 } -
libs/libavcodec/ac3enc.c
1362 1362 { 1363 1363 AC3EncodeContext *s = avctx->priv_data; 1364 1364 int16_t *samples = data; 1365 // expects L C R LS RS LFE 1366 // audio format is L R LS RS C LFE 1367 static int channel_index[6] = { 0, 4, 1, 2, 3, 5 }; 1368 /* 1369 * A52->Analog->AC3Enc 1370 * 1->0->0 1371 * 3->1->2 1372 * 4->2->3 1373 * 5->3->4 1374 * 2->4->1 1375 * 0->5->5 1376 */ 1365 1377 int i, j, k, v, ch; 1366 1378 int16_t input_samples[N]; 1367 1379 int32_t mdct_coef[NB_BLOCKS][AC3_MAX_CHANNELS][N/2]; … … 1382 1394 /* compute input samples */ 1383 1395 memcpy(input_samples, s->last_samples[ch], N/2 * sizeof(int16_t)); 1384 1396 sinc = s->nb_all_channels; 1385 sptr = samples + (sinc * (N/2) * i) + ch ;1397 sptr = samples + (sinc * (N/2) * i) + channel_index[ch]; 1386 1398 for(j=0;j<N/2;j++) { 1387 1399 v = *sptr; 1388 1400 input_samples[j + N/2] = v; … … 1403 1415 v = 14 - log2_tab(input_samples, N); 1404 1416 if (v < 0) 1405 1417 v = 0; 1406 exp_samples[i][ch] = v - 8;1418 exp_samples[i][ch] = v - 9; 1407 1419 lshift_tab(input_samples, N, v); 1408 1420 1409 1421 /* do the MDCT */ -
programs/mythfrontend/globalsettings.cpp
36 36 dev.setNameFilter("adsp*"); 37 37 gc->fillSelectionsFromDir(dev); 38 38 } 39 #ifdef USE_ALSA 40 gc->addSelection("ALSA:default", "ALSA:default"); 41 gc->addSelection("ALSA:analog", "ALSA:analog"); 42 gc->addSelection("ALSA:digital", "ALSA:digital"); 43 gc->addSelection("ALSA:mixed-analog", "ALSA:mixed-analog"); 44 gc->addSelection("ALSA:mixed-digital", "ALSA:mixed-digital"); 45 #endif 46 #ifdef USE_ARTS 47 gc->addSelection("ARTS:", "ARTS:"); 48 #endif 49 #ifdef USE_JACK 50 gc->addSelection("JACK:output", "JACK:output"); 51 #endif 52 gc->addSelection("NULL", "NULL"); 39 53 40 54 return gc; 41 55 } 42 56 57 static HostComboBox *MaxAudioChannels() 58 { 59 HostComboBox *gc = new HostComboBox("MaxChannels",false); 60 gc->setLabel(QObject::tr("Max Audio Channels")); 61 //gc->addSelection(QObject::tr("Mono"), "1"); 62 //gc->addSelection(QObject::tr("Stereo L+R"), "2", true); // default 63 //gc->addSelection(QObject::tr("3 Channel: L C R"), "3"); 64 //gc->addSelection(QObject::tr("4 Channel: L R LS RS"), "4"); 65 //gc->addSelection(QObject::tr("5 Channel: L C R LS RS"), "5"); 66 //gc->addSelection(QObject::tr("6 Channel: L C R LS RS LFE"), "6"); 67 gc->addSelection(QObject::tr("Stereo"), "2", true); // default 68 gc->addSelection(QObject::tr("6 Channel"), "6"); 69 gc->setHelpText( 70 QObject::tr("Set the maximum number of audio channels to be decoded. " 71 "This is for multi-channel/surround audio playback.")); 72 return gc; 73 } 74 43 75 static HostCheckBox *MythControlsVolume() 44 76 { 45 77 HostCheckBox *gc = new HostCheckBox("MythControlsVolume"); … … 2092 2124 setUseLabel(false); 2093 2125 2094 2126 addChild(AudioOutputDevice()); 2127 #if 0 2128 ConfigurationGroup *hg = new HorizontalConfigurationGroup(false, false); 2129 ConfigurationGroup* settingsLeft = new VerticalConfigurationGroup(false,false); 2130 settingsLeft->addChild(AC3PassThrough()); 2131 #ifdef CONFIG_DTS 2132 settingsLeft->addChild(DTSPassThrough()); 2133 #endif 2134 settingsLeft->addChild(AggressiveBuffer()); 2135 hg->addChild(settingsLeft); 2136 2137 ConfigurationGroup* settingsRight = new VerticalConfigurationGroup(false,false); 2138 settingsRight->addChild(MaxAudioChannels()); 2139 hg->addChild(settingsRight); 2140 2141 addChild(hg); 2142 #else 2095 2143 addChild(AC3PassThrough()); 2096 2144 #ifdef CONFIG_DTS 2097 2145 addChild(DTSPassThrough()); 2098 2146 #endif 2099 2147 addChild(AggressiveBuffer()); 2148 addChild(MaxAudioChannels()); 2149 #endif 2100 2150 2101 2151 Setting* volumeControl = MythControlsVolume(); 2102 2152 addChild(volumeControl); -
programs/mythtranscode/transcode.cpp
34 34 AudioReencodeBuffer(int audio_bits, int audio_channels) 35 35 { 36 36 Reset(); 37 Reconfigure(audio_bits, audio_channels, 0 );37 Reconfigure(audio_bits, audio_channels, 0, 0); 38 38 bufsize = 512000; 39 39 audiobuffer = new unsigned char[bufsize]; 40 40 } … … 45 45 } 46 46 47 47 // reconfigure sound out for new params 48 virtual void Reconfigure(int audio_bits, 49 int audio_channels, int audio_samplerate) 48 virtual void Reconfigure(int audio_bits, int audio_channels, 49 int audio_samplerate, bool audio_passthru, 50 void * = NULL) 50 51 { 52 ClearError(); 51 53 (void)audio_samplerate; 52 54 bits = audio_bits; 53 55 channels = audio_channels; 54 56 bytes_per_sample = bits * channels / 8; 57 if (channels>2) 58 Error("Invalid channel count"); 55 59 } 56 60 57 61 // dsprate is in 100 * samples/second