public unsafe void do_output_frames(int strideCount) { task1.strideCount = strideCount; if (!task1.UseMappedMemory) { task1.openCLCQ.EnqueueWriteBuffer(task1.clSamplesBytes, false, 0, sizeof(int) * stride * strideCount, task1.clSamplesBytesPtr); } //task.openCLCQ.EnqueueUnmapMemObject(task.clSamplesBytes, task.clSamplesBytes.HostPtr); //task.openCLCQ.EnqueueMapBuffer(task.clSamplesBytes, true, MapFlags.WRITE, 0, task.samplesBufferLen / 2); task1.EnqueueKernels(); if (task2.strideCount > 0) { task2.openCLCQ.Finish(); } int bs = stride * strideCount; samplesInBuffer -= bs; if (samplesInBuffer > 0) { AudioSamples.MemCpy( ((byte *)task2.clSamplesBytesPtr), ((byte *)task1.clSamplesBytesPtr) + bs * _pcm.BlockAlign, samplesInBuffer * _pcm.BlockAlign); } CLParityTask tmp = task1; task1 = task2; task2 = tmp; task1.strideCount = 0; }
internal void read_bytes(byte *dst, int len) { if (ptr_m + len > end_m) { throw new IndexOutOfRangeException(); } AudioSamples.MemCpy(dst, ptr_m, len); ptr_m += len; }
unsafe void restore_samples_fixed(FlacFrame frame, int ch) { FlacSubframeInfo sub = frame.subframes[ch]; AudioSamples.MemCpy(sub.samples, sub.best.residual, sub.best.order); int *data = sub.samples + sub.best.order; int *residual = sub.best.residual + sub.best.order; int data_len = frame.blocksize - sub.best.order; int s0, s1, s2; switch (sub.best.order) { case 0: AudioSamples.MemCpy(data, residual, data_len); break; case 1: s1 = data[-1]; for (int i = data_len; i > 0; i--) { s1 += *(residual++); *(data++) = s1; } //data[i] = residual[i] + data[i - 1]; break; case 2: s2 = data[-2]; s1 = data[-1]; for (int i = data_len; i > 0; i--) { s0 = *(residual++) + (s1 << 1) - s2; *(data++) = s0; s2 = s1; s1 = s0; } //data[i] = residual[i] + data[i - 1] * 2 - data[i - 2]; break; case 3: for (int i = 0; i < data_len; i++) { data[i] = residual[i] + (((data[i - 1] - data[i - 2]) << 1) + (data[i - 1] - data[i - 2])) + data[i - 3]; } break; case 4: for (int i = 0; i < data_len; i++) { data[i] = residual[i] + ((data[i - 1] + data[i - 3]) << 2) - ((data[i - 2] << 2) + (data[i - 2] << 1)) - data[i - 4]; } break; } }
unsafe void fill_frames_buffer() { if (_framesBufferLength == 0) { _framesBufferOffset = 0; } else if (_framesBufferLength < _framesBuffer.Length / 2 && _framesBufferOffset >= _framesBuffer.Length / 2) { fixed(byte *buff = _framesBuffer) AudioSamples.MemCpy(buff, buff + _framesBufferOffset, _framesBufferLength); _framesBufferOffset = 0; } while (_framesBufferLength < _framesBuffer.Length / 2) { int read = _IO.Read(_framesBuffer, _framesBufferOffset + _framesBufferLength, _framesBuffer.Length - _framesBufferOffset - _framesBufferLength); _framesBufferLength += read; if (read == 0) { break; } } }
public unsafe void Write(AudioBuffer buff) { InitTasks(); buff.Prepare(this); int pos = 0; while (pos < buff.Length) { int block = Math.Min(buff.Length - pos, stride * stridesPerTask - samplesInBuffer); fixed(byte *buf = buff.Bytes) AudioSamples.MemCpy(((byte *)task1.clSamplesBytesPtr) + samplesInBuffer * _pcm.BlockAlign, buf + pos * _pcm.BlockAlign, block * _pcm.BlockAlign); samplesInBuffer += block; pos += block; int strideCount = samplesInBuffer / stride; if (strideCount >= stridesPerTask) { do_output_frames(strideCount); } } }
unsafe void restore_samples(FlacFrame frame) { for (int ch = 0; ch < PCM.ChannelCount; ch++) { switch (frame.subframes[ch].best.type) { case SubframeType.Constant: AudioSamples.MemSet(frame.subframes[ch].samples, frame.subframes[ch].best.residual[0], frame.blocksize); break; case SubframeType.Verbatim: AudioSamples.MemCpy(frame.subframes[ch].samples, frame.subframes[ch].best.residual, frame.blocksize); break; case SubframeType.Fixed: restore_samples_fixed(frame, ch); break; case SubframeType.LPC: restore_samples_lpc(frame, ch); break; } if (frame.subframes[ch].wbits != 0) { int *s = frame.subframes[ch].samples; int x = (int)frame.subframes[ch].wbits; for (int i = frame.blocksize; i > 0; i--) { *(s++) <<= x; } } } if (frame.ch_mode != ChannelMode.NotStereo) { int *l = frame.subframes[0].samples; int *r = frame.subframes[1].samples; switch (frame.ch_mode) { case ChannelMode.LeftRight: break; case ChannelMode.MidSide: for (int i = frame.blocksize; i > 0; i--) { int mid = *l; int side = *r; mid <<= 1; mid |= (side & 1); /* i.e. if 'side' is odd... */ *(l++) = (mid + side) >> 1; *(r++) = (mid - side) >> 1; } break; case ChannelMode.LeftSide: for (int i = frame.blocksize; i > 0; i--) { int _l = *(l++), _r = *r; *(r++) = _l - _r; } break; case ChannelMode.RightSide: for (int i = frame.blocksize; i > 0; i--) { *(l++) += *(r++); } break; } } }