(buf []float32)
| 458 | } |
| 459 | |
| 460 | func (p *playerImpl) readBufferAndAdd(buf []float32) int { |
| 461 | p.m.Lock() |
| 462 | defer p.m.Unlock() |
| 463 | |
| 464 | if p.state != playerPlay { |
| 465 | return 0 |
| 466 | } |
| 467 | |
| 468 | format := p.mux.format |
| 469 | bitDepthInBytes := format.ByteLength() |
| 470 | n := len(p.buf) / bitDepthInBytes |
| 471 | if n > len(buf) { |
| 472 | n = len(buf) |
| 473 | } |
| 474 | |
| 475 | prevVolume := float32(p.prevVolume) |
| 476 | volume := float32(p.volume) |
| 477 | |
| 478 | channelCount := p.mux.channelCount |
| 479 | rateDenom := float32(n / channelCount) |
| 480 | |
| 481 | src := p.buf[:n*bitDepthInBytes] |
| 482 | |
| 483 | for i := 0; i < n; i++ { |
| 484 | var v float32 |
| 485 | switch format { |
| 486 | case FormatFloat32LE: |
| 487 | v = math.Float32frombits(uint32(src[4*i]) | uint32(src[4*i+1])<<8 | uint32(src[4*i+2])<<16 | uint32(src[4*i+3])<<24) |
| 488 | case FormatUnsignedInt8: |
| 489 | v8 := src[i] |
| 490 | v = float32(v8-(1<<7)) / (1 << 7) |
| 491 | case FormatSignedInt16LE: |
| 492 | v16 := int16(src[2*i]) | (int16(src[2*i+1]) << 8) |
| 493 | v = float32(v16) / (1 << 15) |
| 494 | default: |
| 495 | panic(fmt.Sprintf("mux: unexpected format: %d", format)) |
| 496 | } |
| 497 | if volume == prevVolume { |
| 498 | buf[i] += v * volume |
| 499 | } else { |
| 500 | rate := float32(i/channelCount) / rateDenom |
| 501 | if rate > 1 { |
| 502 | rate = 1 |
| 503 | } |
| 504 | buf[i] += v * (volume*rate + prevVolume*(1-rate)) |
| 505 | } |
| 506 | } |
| 507 | |
| 508 | p.prevVolume = p.volume |
| 509 | |
| 510 | copy(p.buf, p.buf[n*bitDepthInBytes:]) |
| 511 | p.buf = p.buf[:len(p.buf)-n*bitDepthInBytes] |
| 512 | |
| 513 | if p.eof && len(p.buf) == 0 { |
| 514 | p.returnBufferToPool() |
| 515 | p.state = playerPaused |
| 516 | } |
| 517 |
no test coverage detected