⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 osssoundcard.cc

📁 Linux下比较早的基于命令行的DVD播放器
💻 CC
字号:
//// Copyright (c) 2004 by Istv醤 V醨adi//// This file is part of dxr3Player, a DVD player written specifically // for the DXR3 (aka Hollywood+) decoder card.// This program is free software; you can redistribute it and/or modify// it under the terms of the GNU General Public License as published by// the Free Software Foundation; either version 2 of the License, or// (at your option) any later version.//// This program is distributed in the hope that it will be useful,// but WITHOUT ANY WARRANTY; without even the implied warranty of// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the// GNU General Public License for more details.//// You should have received a copy of the GNU General Public License// along with this program; if not, write to the Free Software// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA//------------------------------------------------------------------------------#include "OSSSoundcard.h"#include "util/Log.h"#include <cassert>#include <linux/soundcard.h>//------------------------------------------------------------------------------using output::OSSSoundcard;//------------------------------------------------------------------------------//------------------------------------------------------------------------------OSSSoundcard::OSSSoundcard(const char* dsp) :    Thread("output::OSSSoundcard"),    bytesWritten(0),    data(0),    dataLength(0){    fd = POSIX::open(dsp, O_RDWR, "Cannot open DSP device");    int caps;    ioctl(SNDCTL_DSP_GETCAPS, &caps, "Cannot query capabilities from the sound card!");        realTime = (caps&DSP_CAP_REALTIME)==DSP_CAP_REALTIME;    triggerable = (caps&DSP_CAP_TRIGGER)==DSP_CAP_TRIGGER;    audio_buf_info abi;    ioctl(SNDCTL_DSP_GETOSPACE, &abi, "Cannot query output buffer info from the sound card!");        bufferSize = abi.fragstotal;    bufferSize *= abi.fragsize;    Log::debug("output::OSSSoundcard::OSSSoundcard: %sreal-time capable, %striggerable, buffer size: %u\n",               realTime ? "" : "not ", triggerable ? "" : "not ", bufferSize);    if (!realTime) {        Log::debug("output::OSSSoundcard::OSSSoundcard: without real-time capability, audio and video may go out of sync!\n");    }        setup(audioMode, sampleRate, stereo);    stopPlayback();    start();}//------------------------------------------------------------------------------OSSSoundcard::~OSSSoundcard(){}//------------------------------------------------------------------------------void OSSSoundcard::startPlayback(){    assert(triggerable);    int trigger;    ioctl(SNDCTL_DSP_GETTRIGGER, &trigger, "Error querying the trigger");    trigger |= PCM_ENABLE_OUTPUT;    ioctl(SNDCTL_DSP_SETTRIGGER, &trigger, "Error setting the trigger");}//------------------------------------------------------------------------------size_t OSSSoundcard::play(const void* buf, size_t count, bool /*interruptible*/){    assert(data==0);        data = buf;    dataLength = count;    trigger();        assert(data==0);    bytesWritten += dataLength;    return dataLength;}//------------------------------------------------------------------------------unsigned long long OSSSoundcard::getNumberOfSamplesPlayed(){    assert(realTime);    count_info info;    ioctl(SNDCTL_DSP_GETOPTR, &info, "Error querying the number of samples played");    int delay;    ioctl(SNDCTL_DSP_GETODELAY, &delay, "Error querying the output delay");    assert(delay>=0);    // Due to bugs/inaccuracies in drivers, we need to do some tricks.    // This is the maximum position, the samples played cannot be    // bigger than this. ('delay' seems to be a lower bound on the real    // delay...)    unsigned long long maxPosition = bytesWritten - delay;    // The current position may be some number of full buffers    // plus the DMA pointer. The 'bytes' member of 'info' is not    // always correct, at least for ALSA OSS emulation. And it would    // overflow anyway after about 3 hours.    unsigned long long position = (bytesWritten / bufferSize) * bufferSize;    position += info.ptr;        // The position may not be bigger than the maximal one, but    // the difference may only be one or more bufferful.    while(position>maxPosition && position>=bufferSize) position -= bufferSize;    return position/getSampleSize();}//------------------------------------------------------------------------------unsigned long long OSSSoundcard::getNumberOfSamplesBuffered(){    assert(realTime);    int delay;    ioctl(SNDCTL_DSP_GETODELAY, &delay, "Error querying the output delay");    assert(delay>=0);    return delay/getSampleSize();}//------------------------------------------------------------------------------void OSSSoundcard::stopPlayback(){    ioctl(SNDCTL_DSP_RESET, 0, "Error resetting DSP device");        bytesWritten = 0;        if (triggerable) {        int trigger;        ioctl(SNDCTL_DSP_GETTRIGGER, &trigger, "Error querying the trigger");        trigger &= ~PCM_ENABLE_OUTPUT;        ioctl(SNDCTL_DSP_SETTRIGGER, &trigger, "Error setting the trigger");    }}//------------------------------------------------------------------------------void OSSSoundcard::stop(){    Thread::stop();}//------------------------------------------------------------------------------void OSSSoundcard::doSetup(audioMode_t& mode, unsigned& rate, bool& s){    int dspFormat = (mode==AM_DIGITAL_AC3) ? AFMT_AC3 : AFMT_S16_LE;    int dspSpeed = (int)rate;    int dspStereo = s ? 1 : 0;    ioctl(SNDCTL_DSP_SPEED, &dspSpeed, "Error setting audio sample rate to %d", dspSpeed);    ioctl(SNDCTL_DSP_STEREO, &dspStereo, "Error setting DSP stereo to %d", dspStereo);    ioctl(SNDCTL_DSP_SETFMT, &dspFormat, "Error setting audio format to %d", dspFormat);}//------------------------------------------------------------------------------void OSSSoundcard::perform(){    assert(data!=0);        size_t written = write(data, dataLength);    if (written!=dataLength) {        Log::debug("output::sdl::SoundThread: written=%u, dataLength=%u\n",                   written, dataLength);    }    data = 0;    dataLength = written;    }//------------------------------------------------------------------------------

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -