You are aware (no?) that this code was abandon in 2005 and replaced by
sqMacUnixInterfaceSound.c & sqUnixSoundMacOSX.c
The typedefs are wrong for 64bit work, but I've replace the logic in Squeak V5 anyway.
sqInt sound_RecordSamplesIntoAtLength(sqInt buf, sqInt startSliceIndex, sqInt bufferSizeInBytes) { if (input) { if (Buffer_avail(input->buffer) >= (512 * DeviceFrameSize)) { sqInt start= startSliceIndex * SqueakFrameSize / 2; UInt32 count= min(input->cvtBufSize, bufferSizeInBytes - start); if (kAudioHardwareNoError == AudioConverterFillBuffer(input->converter, bufferDataProc, input, &count, (char *)buf + start)) return count / (SqueakFrameSize / 2) / input->channels; } return 0; } success(false); return 0; }
sqInt snd_RecordSamplesIntoAtLength(usqInt *buf, sqInt startSliceIndex, sqInt bufferSizeInBytes) { return sound_RecordSamplesIntoAtLength(buf, startSliceIndex, bufferSizeInBytes); }
Version 5 of Squeak macintosh VM uses
- (sqInt) snd_RecordSamplesIntoAtLength: (char*) arrayIndex startSliceIndex: (usqInt) startSliceIndex bufferSizeInBytes: (usqInt) bufferSizeInBytes { usqInt count; if (!self.inputAudioQueue) return interpreterProxy->primitiveFail(); if (startSliceIndex > bufferSizeInBytes) return interpreterProxy->primitiveFail();
usqInt start= startSliceIndex * SqueakFrameSize / 2; soundAtom *atom = [self.soundInQueue returnOldest]; if (atom == nil) return 0; if (bufferSizeInBytes-start >= atom.byteCount && atom.startOffset == 0) { atom = [self.soundInQueue returnAndRemoveOldest]; memcpy(arrayIndex+start,atom.data,atom.byteCount); count= MIN(atom.byteCount, bufferSizeInBytes - start); [atom release]; return count / (SqueakFrameSize / 2) / self.inputChannels; } else { count= MIN(atom.byteCount-atom.startOffset, bufferSizeInBytes - start); memcpy(arrayIndex+start,atom.data+atom.startOffset,count); atom.startOffset = atom.startOffset + (count); if (atom.startOffset == atom.byteCount) { atom = [self.soundInQueue returnAndRemoveOldest]; //ignore now it's empty [atom release]; } return count / (SqueakFrameSize / 2) / self.inputChannels; } }
On 2010-03-29, at 12:05 PM, Eliot Miranda wrote:
Now in the Mac code there is no code to subtract (startWordIndex - 1) * 2 from bufSizeInBytes, and so without my fix there could be a buffer overrun:
int snd_RecordSamplesIntoAtLength(int buf, int startSliceIndex, int bufferSizeInBytes) { /* if data is available, copy as many sample slices as possible into the given buffer starting at the given slice index. do not write past the end of the buffer, which is buf + bufferSizeInBytes. return the number of slices (not bytes) copied. a slice is one 16-bit sample in mono or two 16-bit samples in stereo. */ int bytesPerSlice = (recordBuffer1.brokenOSXWasMono) ? 2 : ((recordBuffer1.stereo) ? 4 : 2); char *nextBuf = (char *) buf + (startSliceIndex * bytesPerSlice); char *bufEnd = (char *) buf + bufferSizeInBytes; char *src, *srcEnd; RecordBuffer recBuf = nil; int bytesCopied;
-- =========================================================================== John M. McIntosh johnmci@smalltalkconsulting.com Twitter: squeaker68882 Corporate Smalltalk Consulting Ltd. http://www.smalltalkconsulting.com ===========================================================================