107910542SSiarzhuk Zharski /*
207910542SSiarzhuk Zharski * SiS 7018, Trident 4D Wave DX/NX, Acer Lab M5451 Sound Driver.
307910542SSiarzhuk Zharski * Copyright (c) 2002, 2008-2011 S.Zharski <imker@gmx.li>
407910542SSiarzhuk Zharski * Distributed under the terms of the MIT license.
507910542SSiarzhuk Zharski *
607910542SSiarzhuk Zharski * Copyright for ali5451 support:
707910542SSiarzhuk Zharski * (c) 2009, Krzysztof Ćwiertnia (krzysiek.bmkx_gmail_com).
807910542SSiarzhuk Zharski */
907910542SSiarzhuk Zharski
1007910542SSiarzhuk Zharski
1107910542SSiarzhuk Zharski #include "Stream.h"
1207910542SSiarzhuk Zharski
13*a188dae8SSiarzhuk Zharski #include <memory.h>
14*a188dae8SSiarzhuk Zharski
1507910542SSiarzhuk Zharski #include "Device.h"
1607910542SSiarzhuk Zharski #include "Registers.h"
1707910542SSiarzhuk Zharski #include "Settings.h"
1807910542SSiarzhuk Zharski
1907910542SSiarzhuk Zharski
Stream(Device * device,bool isInput)2007910542SSiarzhuk Zharski Stream::Stream(Device *device, bool isInput)
2107910542SSiarzhuk Zharski :
2207910542SSiarzhuk Zharski fDevice(device),
2307910542SSiarzhuk Zharski fStatus(B_NO_INIT),
2407910542SSiarzhuk Zharski fIsInput(isInput),
2507910542SSiarzhuk Zharski fIsActive(false),
2607910542SSiarzhuk Zharski fHWChannel(isInput ? 0 : 1),
2707910542SSiarzhuk Zharski fBuffersArea(-1),
2807910542SSiarzhuk Zharski fBuffersAreaSize(0),
2907910542SSiarzhuk Zharski fBufferSamplesCount(0),
3007910542SSiarzhuk Zharski fBuffersAddress(0),
3107910542SSiarzhuk Zharski fBuffersPhysAddress(0),
3207910542SSiarzhuk Zharski fRealTime(0),
3307910542SSiarzhuk Zharski fFramesCount(0),
3407910542SSiarzhuk Zharski fBufferCycle(fIsInput ? 1 :0)
3507910542SSiarzhuk Zharski {
3607910542SSiarzhuk Zharski fFormat.format = B_FMT_16BIT;
3707910542SSiarzhuk Zharski fFormat.rate = B_SR_48000;
3807910542SSiarzhuk Zharski fFormat.cvsr = _DecodeRate(fFormat.rate);
39*a188dae8SSiarzhuk Zharski memset(fFormat._reserved_, 0, sizeof(fFormat._reserved_));
4007910542SSiarzhuk Zharski }
4107910542SSiarzhuk Zharski
4207910542SSiarzhuk Zharski
~Stream()4307910542SSiarzhuk Zharski Stream::~Stream()
4407910542SSiarzhuk Zharski {
4507910542SSiarzhuk Zharski Free();
4607910542SSiarzhuk Zharski }
4707910542SSiarzhuk Zharski
4807910542SSiarzhuk Zharski
4907910542SSiarzhuk Zharski uint32
_HWId()5007910542SSiarzhuk Zharski Stream::_HWId()
5107910542SSiarzhuk Zharski {
5207910542SSiarzhuk Zharski return fDevice->HardwareId();
5307910542SSiarzhuk Zharski }
5407910542SSiarzhuk Zharski
5507910542SSiarzhuk Zharski
5607910542SSiarzhuk Zharski status_t
Init()5707910542SSiarzhuk Zharski Stream::Init()
5807910542SSiarzhuk Zharski {
5907910542SSiarzhuk Zharski if (fStatus == B_OK)
6007910542SSiarzhuk Zharski Free();
6107910542SSiarzhuk Zharski
6207910542SSiarzhuk Zharski fHWChannel = fIsInput ? 0 : 1;
6307910542SSiarzhuk Zharski
6407910542SSiarzhuk Zharski if (_HWId() == SiS7018)
6507910542SSiarzhuk Zharski fHWChannel += 0x20; // bank B optimized for PCM
6607910542SSiarzhuk Zharski else if (_HWId() == ALi5451 && fIsInput)
6707910542SSiarzhuk Zharski fHWChannel = 31;
6807910542SSiarzhuk Zharski
6907910542SSiarzhuk Zharski // assume maximal possible buffers size
7007910542SSiarzhuk Zharski fBuffersAreaSize = 1024; // samples
7107910542SSiarzhuk Zharski fBuffersAreaSize *= 2 * 2 * 2; // stereo + 16-bit samples + 2 buffers
7207910542SSiarzhuk Zharski fBuffersAreaSize = (fBuffersAreaSize + (B_PAGE_SIZE - 1)) &~ (B_PAGE_SIZE - 1);
7307910542SSiarzhuk Zharski fBuffersArea = create_area(
7407910542SSiarzhuk Zharski (fIsInput) ? DRIVER_NAME "_record_area" : DRIVER_NAME "_playback_area",
7507910542SSiarzhuk Zharski &fBuffersAddress, B_ANY_KERNEL_ADDRESS, fBuffersAreaSize,
7607910542SSiarzhuk Zharski B_32_BIT_CONTIGUOUS, B_READ_AREA | B_WRITE_AREA);
7707910542SSiarzhuk Zharski if (fBuffersArea < 0) {
7807910542SSiarzhuk Zharski ERROR("Error of creating %#lx-bytes size buffer area:%#010x\n",
7907910542SSiarzhuk Zharski fBuffersAreaSize, fBuffersArea);
8007910542SSiarzhuk Zharski fStatus = fBuffersArea;
8107910542SSiarzhuk Zharski return fStatus;
8207910542SSiarzhuk Zharski }
8307910542SSiarzhuk Zharski
8407910542SSiarzhuk Zharski physical_entry PhysEntry;
8507910542SSiarzhuk Zharski get_memory_map(fBuffersAddress, fBuffersAreaSize, &PhysEntry, 1);
8607910542SSiarzhuk Zharski
8707910542SSiarzhuk Zharski fBuffersPhysAddress = PhysEntry.address;
8807910542SSiarzhuk Zharski
8907910542SSiarzhuk Zharski TRACE("Created area id %d with size: %#x at address %#x[phys:%#lx]\n",
9007910542SSiarzhuk Zharski fBuffersArea, fBuffersAreaSize, fBuffersAddress, fBuffersPhysAddress);
9107910542SSiarzhuk Zharski
9207910542SSiarzhuk Zharski // back to samples - half of buffer for 16-bit stereo data
9307910542SSiarzhuk Zharski fBufferSamplesCount = fBuffersAreaSize / (2 * 2 * 2);
9407910542SSiarzhuk Zharski
9507910542SSiarzhuk Zharski fStatus = B_OK;
9607910542SSiarzhuk Zharski return fStatus;
9707910542SSiarzhuk Zharski }
9807910542SSiarzhuk Zharski
9907910542SSiarzhuk Zharski
10007910542SSiarzhuk Zharski void
Free()10107910542SSiarzhuk Zharski Stream::Free()
10207910542SSiarzhuk Zharski {
10307910542SSiarzhuk Zharski delete_area(fBuffersArea);
10407910542SSiarzhuk Zharski fStatus = B_NO_INIT;
10507910542SSiarzhuk Zharski }
10607910542SSiarzhuk Zharski
10707910542SSiarzhuk Zharski
10807910542SSiarzhuk Zharski uint32
_DecodeRate(uint32 rate)10907910542SSiarzhuk Zharski Stream::_DecodeRate(uint32 rate)
11007910542SSiarzhuk Zharski {
11107910542SSiarzhuk Zharski switch(rate) {
11207910542SSiarzhuk Zharski case B_SR_8000: return 8000;
11307910542SSiarzhuk Zharski case B_SR_11025: return 11025;
11407910542SSiarzhuk Zharski case B_SR_12000: return 12000;
11507910542SSiarzhuk Zharski case B_SR_16000: return 16000;
11607910542SSiarzhuk Zharski case B_SR_22050: return 22050;
11707910542SSiarzhuk Zharski case B_SR_24000: return 24000;
11807910542SSiarzhuk Zharski case B_SR_32000: return 32000;
11907910542SSiarzhuk Zharski case B_SR_44100: return 44100;
12007910542SSiarzhuk Zharski case B_SR_48000: return 48000;
12107910542SSiarzhuk Zharski }
12207910542SSiarzhuk Zharski
12307910542SSiarzhuk Zharski ERROR("Rate:%x is not supported. Fall to default 48000\n", rate);
12407910542SSiarzhuk Zharski return 48000;
12507910542SSiarzhuk Zharski }
12607910542SSiarzhuk Zharski
12707910542SSiarzhuk Zharski
12807910542SSiarzhuk Zharski void
GetFormat(multi_format_info * Format)12907910542SSiarzhuk Zharski Stream::GetFormat(multi_format_info *Format)
13007910542SSiarzhuk Zharski {
13107910542SSiarzhuk Zharski if (fIsInput) {
13207910542SSiarzhuk Zharski Format->input_latency = 0;
13307910542SSiarzhuk Zharski Format->input = fFormat;
13407910542SSiarzhuk Zharski } else {
13507910542SSiarzhuk Zharski Format->output_latency = 0;
13607910542SSiarzhuk Zharski Format->output = fFormat;
13707910542SSiarzhuk Zharski }
13807910542SSiarzhuk Zharski }
13907910542SSiarzhuk Zharski
14007910542SSiarzhuk Zharski
14107910542SSiarzhuk Zharski status_t
SetFormat(_multi_format & format,uint32 formats,uint32 rates)14207910542SSiarzhuk Zharski Stream::SetFormat(_multi_format& format, uint32 formats, uint32 rates)
14307910542SSiarzhuk Zharski {
14407910542SSiarzhuk Zharski if (fFormat.rate == format.rate && fFormat.format == format.format)
14507910542SSiarzhuk Zharski return B_OK;
14607910542SSiarzhuk Zharski
14707910542SSiarzhuk Zharski if ((format.rate & rates) == 0 || (format.format & formats) == 0) {
14807910542SSiarzhuk Zharski ERROR("Unsupported data format:%x or rate:%x. Ignore.\n",
14907910542SSiarzhuk Zharski format.format, format.rate);
15007910542SSiarzhuk Zharski return B_ERROR;
15107910542SSiarzhuk Zharski }
15207910542SSiarzhuk Zharski
15307910542SSiarzhuk Zharski fFormat = format;
15407910542SSiarzhuk Zharski fFormat.cvsr = _DecodeRate(fFormat.rate);
15507910542SSiarzhuk Zharski
15607910542SSiarzhuk Zharski fBufferSamplesCount = fBuffersAreaSize / (2 * 2);
15707910542SSiarzhuk Zharski switch (fFormat.format) {
15807910542SSiarzhuk Zharski default:
15907910542SSiarzhuk Zharski ERROR("Unsupported data format:%x. 16 bit assumed.\n", fFormat.format);
16007910542SSiarzhuk Zharski case B_FMT_16BIT:
16107910542SSiarzhuk Zharski fBufferSamplesCount /= 2;
16207910542SSiarzhuk Zharski break;
16307910542SSiarzhuk Zharski case B_FMT_8BIT_S:
16407910542SSiarzhuk Zharski case B_FMT_8BIT_U:
16507910542SSiarzhuk Zharski break;
16607910542SSiarzhuk Zharski }
16707910542SSiarzhuk Zharski
16807910542SSiarzhuk Zharski TRACE("Format:%#x;Rate:%#x;cvsr:%.2f\n",
16907910542SSiarzhuk Zharski fFormat.format, fFormat.rate, fFormat.cvsr);
17007910542SSiarzhuk Zharski
17107910542SSiarzhuk Zharski // stop the stream - it will be rewaked during next exchnage buffers call
17207910542SSiarzhuk Zharski Stop();
17307910542SSiarzhuk Zharski
17407910542SSiarzhuk Zharski return B_OK;
17507910542SSiarzhuk Zharski }
17607910542SSiarzhuk Zharski
17707910542SSiarzhuk Zharski
17807910542SSiarzhuk Zharski void
GetBuffers(uint32 & Flags,int32 & BuffersCount,int32 & ChannelsCount,uint32 & BufferSize,buffer_desc ** Buffers)17907910542SSiarzhuk Zharski Stream::GetBuffers(uint32& Flags, int32& BuffersCount, int32& ChannelsCount,
18007910542SSiarzhuk Zharski uint32& BufferSize, buffer_desc** Buffers)
18107910542SSiarzhuk Zharski {
18207910542SSiarzhuk Zharski Flags |= fIsInput ? B_MULTI_BUFFER_RECORD : B_MULTI_BUFFER_PLAYBACK;
18307910542SSiarzhuk Zharski BuffersCount = 2;
18407910542SSiarzhuk Zharski ChannelsCount = 2;
18507910542SSiarzhuk Zharski BufferSize = fBufferSamplesCount;
18607910542SSiarzhuk Zharski
18707910542SSiarzhuk Zharski uint32 stride = 4;
18807910542SSiarzhuk Zharski if (fFormat.format == B_FMT_8BIT_S || fFormat.format == B_FMT_8BIT_U) {
18907910542SSiarzhuk Zharski stride = 2;
19007910542SSiarzhuk Zharski }
19107910542SSiarzhuk Zharski // [b][c] init buffers
19207910542SSiarzhuk Zharski Buffers[0][0].base
19307910542SSiarzhuk Zharski = Buffers[1][0].base
19407910542SSiarzhuk Zharski = Buffers[0][1].base
19507910542SSiarzhuk Zharski = Buffers[1][1].base = (char*)fBuffersAddress;
19607910542SSiarzhuk Zharski
19707910542SSiarzhuk Zharski Buffers[0][0].stride
19807910542SSiarzhuk Zharski = Buffers[1][0].stride
19907910542SSiarzhuk Zharski = Buffers[0][1].stride
20007910542SSiarzhuk Zharski = Buffers[1][1].stride = stride;
20107910542SSiarzhuk Zharski
20207910542SSiarzhuk Zharski // shift pair of second part of buffers
20307910542SSiarzhuk Zharski Buffers[1][0].base += BufferSize * stride;
20407910542SSiarzhuk Zharski Buffers[1][1].base += BufferSize * stride;
20507910542SSiarzhuk Zharski
20607910542SSiarzhuk Zharski // shift right channel buffers
20707910542SSiarzhuk Zharski Buffers[0][1].base += stride / 2;
20807910542SSiarzhuk Zharski Buffers[1][1].base += stride / 2;
20907910542SSiarzhuk Zharski
21007910542SSiarzhuk Zharski TRACE("%s buffers:\n", fIsInput ? "input" : "output");
21107910542SSiarzhuk Zharski TRACE("1: %#010x %#010x\n", Buffers[0][0].base, Buffers[0][1].base);
21207910542SSiarzhuk Zharski TRACE("2: %#010x %#010x\n", Buffers[1][0].base, Buffers[1][1].base);
21307910542SSiarzhuk Zharski }
21407910542SSiarzhuk Zharski
21507910542SSiarzhuk Zharski
21607910542SSiarzhuk Zharski status_t
Start()21707910542SSiarzhuk Zharski Stream::Start()
21807910542SSiarzhuk Zharski {
219a4f18248SSiarzhuk Zharski if (!fIsInput)
220a4f18248SSiarzhuk Zharski fDevice->Mixer().SetOutputRate(fFormat.cvsr);
221a4f18248SSiarzhuk Zharski
22207910542SSiarzhuk Zharski uint32 CSO = 0;
22307910542SSiarzhuk Zharski uint32 LBA = uint32(fBuffersPhysAddress) & 0x3fffffff;
22407910542SSiarzhuk Zharski uint32 ESO = ((fBufferSamplesCount * 2) - 1) & 0xffff;
22507910542SSiarzhuk Zharski uint32 Delta = fIsInput ? ((48000 << 12) / uint32(fFormat.cvsr)) & 0xffff
22607910542SSiarzhuk Zharski : ((uint32(fFormat.cvsr) << 12) / 48000) & 0xffff;
22707910542SSiarzhuk Zharski uint32 DeltaESO = (ESO << 16) | Delta;
22807910542SSiarzhuk Zharski uint32 FMControlEtc = fIsInput ? 0 : (0x03 << 14);
22907910542SSiarzhuk Zharski uint32 ControlEtc = 1 << 14 | 1 << 12; // stereo data + loop enabled
23007910542SSiarzhuk Zharski
23107910542SSiarzhuk Zharski switch (fFormat.format) {
23207910542SSiarzhuk Zharski case B_FMT_16BIT:
23307910542SSiarzhuk Zharski ControlEtc |= (1 << 15); // 16 bit
23407910542SSiarzhuk Zharski case B_FMT_8BIT_S:
23507910542SSiarzhuk Zharski ControlEtc |= (1 << 13); // signed
23607910542SSiarzhuk Zharski break;
23707910542SSiarzhuk Zharski }
23807910542SSiarzhuk Zharski
23907910542SSiarzhuk Zharski switch (_HWId()) {
24007910542SSiarzhuk Zharski case TridentDX:
24107910542SSiarzhuk Zharski FMControlEtc |= (0x7f << 7) < 0x7f;
24207910542SSiarzhuk Zharski break;
24307910542SSiarzhuk Zharski case TridentNX:
24407910542SSiarzhuk Zharski CSO = Delta << 24;
24507910542SSiarzhuk Zharski DeltaESO = ((Delta << 16) & 0xff000000) | (ESO & 0x00ffffff);
24607910542SSiarzhuk Zharski FMControlEtc |= (0x7f << 7) < 0x7f;
24707910542SSiarzhuk Zharski break;
24807910542SSiarzhuk Zharski case SiS7018:
24907910542SSiarzhuk Zharski FMControlEtc = fIsInput ? (0x8a80 << 16) : FMControlEtc;
25007910542SSiarzhuk Zharski break;
25107910542SSiarzhuk Zharski }
25207910542SSiarzhuk Zharski
25307910542SSiarzhuk Zharski cpu_status cst = fDevice->Lock();
25407910542SSiarzhuk Zharski
25507910542SSiarzhuk Zharski // select used channel
25607910542SSiarzhuk Zharski uint32 ChIntReg = fDevice->ReadPCI32(RegChIndex) & ~0x3f;
25707910542SSiarzhuk Zharski ChIntReg |= (fHWChannel & 0x3f);
25807910542SSiarzhuk Zharski fDevice->WritePCI32(RegChIndex, ChIntReg);
25907910542SSiarzhuk Zharski
26007910542SSiarzhuk Zharski fDevice->WritePCI32(RegCSOAlphaFMS, CSO);
26107910542SSiarzhuk Zharski fDevice->WritePCI32(RegLBA_PPTR, LBA);
26207910542SSiarzhuk Zharski fDevice->WritePCI32(RegDeltaESO, DeltaESO);
26307910542SSiarzhuk Zharski fDevice->WritePCI32(RegRVolCVolFMC, FMControlEtc);
26407910542SSiarzhuk Zharski fDevice->WritePCI32(RegGVSelVolCtrl, ControlEtc);
26507910542SSiarzhuk Zharski fDevice->WritePCI32(RegEBuf1, 0);
26607910542SSiarzhuk Zharski fDevice->WritePCI32(RegEBuf2, 0);
26707910542SSiarzhuk Zharski
26807910542SSiarzhuk Zharski if (fIsInput) {
26907910542SSiarzhuk Zharski uint32 reg = 0;
27007910542SSiarzhuk Zharski switch (_HWId()) {
27107910542SSiarzhuk Zharski case ALi5451:
27207910542SSiarzhuk Zharski reg = fDevice->ReadPCI32(RegALiDigiMixer);
27307910542SSiarzhuk Zharski fDevice->WritePCI32(RegALiDigiMixer, reg | (1 << _HWVoice()));
27407910542SSiarzhuk Zharski break;
27507910542SSiarzhuk Zharski case TridentDX:
27607910542SSiarzhuk Zharski reg = fDevice->ReadPCI8(RegCodecStatus);
27707910542SSiarzhuk Zharski fDevice->WritePCI8(RegCodecStatus,
27807910542SSiarzhuk Zharski reg | CodecStatusADCON | CodecStatusSBCtrl);
27907910542SSiarzhuk Zharski // enable and set record channel
28007910542SSiarzhuk Zharski fDevice->WritePCI8(RegRecChannel, 0x80 | _HWVoice());
28107910542SSiarzhuk Zharski break;
28207910542SSiarzhuk Zharski case TridentNX:
28307910542SSiarzhuk Zharski reg = fDevice->ReadPCI16(RegMiscINT);
28407910542SSiarzhuk Zharski fDevice->WritePCI8(RegMiscINT, reg | 0x1000);
28507910542SSiarzhuk Zharski // enable and set record channel
28607910542SSiarzhuk Zharski fDevice->WritePCI8(RegRecChannel, 0x80 | _HWVoice());
28707910542SSiarzhuk Zharski break;
28807910542SSiarzhuk Zharski }
28907910542SSiarzhuk Zharski }
29007910542SSiarzhuk Zharski
29107910542SSiarzhuk Zharski // enable INT for current channel
29207910542SSiarzhuk Zharski uint32 ChIntMask = fDevice->ReadPCI32(_UseBankB() ? RegEnaINTB : RegEnaINTA);
29307910542SSiarzhuk Zharski ChIntMask |= 1 << _HWVoice();
29407910542SSiarzhuk Zharski fDevice->WritePCI32(_UseBankB() ? RegAddrINTB : RegAddrINTA, 1 << _HWVoice());
29507910542SSiarzhuk Zharski fDevice->WritePCI32(_UseBankB() ? RegEnaINTB : RegEnaINTA, ChIntMask);
29607910542SSiarzhuk Zharski
29707910542SSiarzhuk Zharski // start current channel
29807910542SSiarzhuk Zharski fDevice->WritePCI32(_UseBankB() ? RegStartB : RegStartA, 1 << _HWVoice());
299a4f18248SSiarzhuk Zharski fIsActive = true;
30007910542SSiarzhuk Zharski
30107910542SSiarzhuk Zharski fDevice->Unlock(cst);
30207910542SSiarzhuk Zharski
30307910542SSiarzhuk Zharski TRACE("%s:CSO:%#x;LBA:%#x;ESO:%#x;Delta:%#x;FM:%#x:Ctrl:%#x;CIR:%#x\n",
30407910542SSiarzhuk Zharski fIsInput ? "Rec" : "Play", CSO, LBA, ESO, Delta, FMControlEtc,
30507910542SSiarzhuk Zharski ControlEtc, ChIntReg);
30607910542SSiarzhuk Zharski
30707910542SSiarzhuk Zharski return B_OK;
30807910542SSiarzhuk Zharski }
30907910542SSiarzhuk Zharski
31007910542SSiarzhuk Zharski
31107910542SSiarzhuk Zharski status_t
Stop()31207910542SSiarzhuk Zharski Stream::Stop()
31307910542SSiarzhuk Zharski {
314a4f18248SSiarzhuk Zharski if (!fIsActive)
315a4f18248SSiarzhuk Zharski return B_OK;
316a4f18248SSiarzhuk Zharski
31707910542SSiarzhuk Zharski cpu_status cst = fDevice->Lock();
31807910542SSiarzhuk Zharski
31907910542SSiarzhuk Zharski // stop current channel
32007910542SSiarzhuk Zharski fDevice->WritePCI32(_UseBankB() ? RegStopB : RegStopA, 1 << _HWVoice());
321a4f18248SSiarzhuk Zharski fIsActive = false;
32207910542SSiarzhuk Zharski
32307910542SSiarzhuk Zharski if (_HWId() == ALi5451 && fIsInput) {
32407910542SSiarzhuk Zharski uint32 reg = fDevice->ReadPCI32(RegALiDigiMixer);
32507910542SSiarzhuk Zharski fDevice->WritePCI32(RegALiDigiMixer, reg & ~(1 << _HWVoice()));
32607910542SSiarzhuk Zharski }
32707910542SSiarzhuk Zharski
32807910542SSiarzhuk Zharski fDevice->Unlock(cst);
32907910542SSiarzhuk Zharski
33007910542SSiarzhuk Zharski TRACE("%s:OK\n", fIsInput ? "Rec" : "Play");
33107910542SSiarzhuk Zharski
33207910542SSiarzhuk Zharski fBufferCycle = fIsInput ? 1 : 0;
33307910542SSiarzhuk Zharski
33407910542SSiarzhuk Zharski return B_OK;
33507910542SSiarzhuk Zharski }
33607910542SSiarzhuk Zharski
33707910542SSiarzhuk Zharski
33807910542SSiarzhuk Zharski bool
InterruptHandler()33907910542SSiarzhuk Zharski Stream::InterruptHandler()
34007910542SSiarzhuk Zharski {
34107910542SSiarzhuk Zharski uint32 SignaledMask = fDevice->ReadPCI32(
34207910542SSiarzhuk Zharski _UseBankB() ? RegAddrINTB : RegAddrINTA);
34307910542SSiarzhuk Zharski uint32 ChannelMask = 1 << _HWVoice();
34407910542SSiarzhuk Zharski if ((SignaledMask & ChannelMask) == 0) {
34507910542SSiarzhuk Zharski return false;
34607910542SSiarzhuk Zharski }
34707910542SSiarzhuk Zharski
34807910542SSiarzhuk Zharski // first clear signalled channel bit
34907910542SSiarzhuk Zharski fDevice->WritePCI32(_UseBankB() ? RegAddrINTB : RegAddrINTA, ChannelMask);
35007910542SSiarzhuk Zharski
35107910542SSiarzhuk Zharski fRealTime = system_time();
35207910542SSiarzhuk Zharski fFramesCount += fBufferSamplesCount;
35307910542SSiarzhuk Zharski fBufferCycle = (fBufferCycle + 1) % 2;
35407910542SSiarzhuk Zharski
35507910542SSiarzhuk Zharski fDevice->SignalReadyBuffers();
35607910542SSiarzhuk Zharski
35707910542SSiarzhuk Zharski return true;
35807910542SSiarzhuk Zharski }
35907910542SSiarzhuk Zharski
36007910542SSiarzhuk Zharski
36107910542SSiarzhuk Zharski void
ExchangeBuffers(bigtime_t & RealTime,bigtime_t & FramesCount,int32 & BufferCycle)36207910542SSiarzhuk Zharski Stream::ExchangeBuffers(bigtime_t& RealTime,
36307910542SSiarzhuk Zharski bigtime_t& FramesCount, int32& BufferCycle)
36407910542SSiarzhuk Zharski {
36507910542SSiarzhuk Zharski RealTime = fRealTime;
36607910542SSiarzhuk Zharski FramesCount = fFramesCount;
36707910542SSiarzhuk Zharski BufferCycle = fBufferCycle;
36807910542SSiarzhuk Zharski }
36907910542SSiarzhuk Zharski
370