Computer >> บทช่วยสอนคอมพิวเตอร์ >  >> การเขียนโปรแกรม >> JavaScript

ฟังก์ชัน DataView.setInt16() ใน JavaScript

DataView.setInt16() คืออะไร

เมธอด DataView.prototype.setInt16() ใช้สำหรับ เขียนค่าจำนวนเต็มมีเครื่องหมาย 16-bit (signed 16-bit integer) ลงในตำแหน่งที่กำหนดใน DataView ค่าที่เขียนได้จะอยู่ในช่วง -32,768 ถึง 32,767 (-2^15 ถึง 2^15-1)

ไวยากรณ์ (Syntax)

dataView.setInt16(byteOffset, value [, littleEndian])
  • byteOffset - ตำแหน่งเริ่มต้นในหน่วยไบต์ (0-indexed)
  • value - ค่าที่จะเขียน (-32768 ถึง 32767)
  • littleEndian (optional) - true = little-endian, false = big-endian (default: false)

คืนค่า: undefined

ตัวอย่างการใช้งาน

ตัวอย่างที่ 1: การเขียนและอ่านค่าพื้นฐาน

const buffer = new ArrayBuffer(4);
const view = new DataView(buffer);

view.setInt16(0, 3225);
console.log(view.getInt16(0)); // 3225

ตัวอย่างที่ 2: ค่าลบและ Two's Complement

const buffer = new ArrayBuffer(4);
const view = new DataView(buffer);

view.setInt16(0, -1);      // 0xFFFF
view.setInt16(2, -32768);  // 0x8000 (min)
view.setInt16(2, 32767);   // 0x7FFF (max)

console.log(view.getInt16(0)); // -1
console.log(view.getInt16(2)); // 32767

ตัวอย่างที่ 3: การแปลงค่า Float

const buffer = new ArrayBuffer(4);
const view = new DataView(buffer);

view.setInt16(0, 564.22); // truncate -> 564
console.log(view.getInt16(0)); // 564

ตัวอย่างที่ 4: Endianness Handling

const buffer = new ArrayBuffer(4);
const view = new DataView(buffer);
const value = 0x1234; // 4660

view.setInt16(0, value, false); // big-endian
view.setInt16(2, value, true);  // little-endian

console.log(view.getInt16(0, false).toString(16)); // 1234
console.log(view.getInt16(2, true).toString(16));  // 1234

ตัวอย่างที่ 5: Audio Sample Packing (16-bit PCM)

function floatToInt16PCM(samples) {
  // samples: Float32Array [-1.0, 1.0]
  const buffer = new ArrayBuffer(samples.length * 2);
  const view = new DataView(buffer);
  
  for (let i = 0; i < samples.length; i++) {
    // clamp และ scale ไปยัง int16 range
    const clamped = Math.max(-1, Math.min(1, samples[i]));
    const intValue = Math.round(clamped * 32767);
    view.setInt16(i * 2, intValue, true); // little-endian for WAV
  }
  return buffer;
}

function int16PCMToFloat(buffer) {
  const view = new DataView(buffer);
  const samples = new Float32Array(buffer.byteLength / 2);
  
  for (let i = 0; i < samples.length; i++) {
    samples[i] = view.getInt16(i * 2, true) / 32767;
  }
  return samples;
}

// ทดสอบ
const testSamples = new Float32Array([0, 0.5, -0.5, 1.0, -1.0]);
const packed = floatToInt16PCM(testSamples);
const unpacked = int16PCMToFloat(packed);
console.log(Array.from(unpacked)); // [0, 0.5, -0.5, 1, -1]

ตัวอย่างที่ 6: อ่านค่าที่ยังไม่ได้ตั้งค่า

const buffer = new ArrayBuffer(4);
const view = new DataView(buffer);
console.log(view.getInt16(0)); // 0

Two's Complement สำหรับ 16-bit

DecimalHexUnsigned
327670x7FFF32767
00x00000
-10xFFFF65535
-327680x800032768

กรณีการใช้งานทั่วไป

  • Audio processing: 16-bit PCM (CD quality, WAV files) - ใช้ little-endian
  • Sensor data: Accelerometer, gyroscope, magnetometer (signed values)
  • Network protocols: Signed short fields
  • Image processing: Signed pixel differences, DCT coefficients
  • Game development: Relative coordinates, velocity vectors
  • Scientific data: Compact signed measurements

กรณีพิเศษและข้อผิดพลาด

  • โยน RangeError หาก byteOffset ติดลบ หรือ byteOffset + 2 > byteLength
  • ค่า value จะถูกแปลงด้วย ToInt16 (modulo 65536 แล้ว interpret เป็น signed)
  • Endianness ต้องตรงกับที่อ่าน (getInt16) - สำคัญมากสำหรับ audio/file formats