static StereoFrame16 GenerateCurrentFrame() { SharedMemory& read = ReadRegion(); SharedMemory& write = WriteRegion(); std::array<QuadFrame32, 3> intermediate_mixes = {}; // Generate intermediate mixes for (size_t i = 0; i < num_sources; i++) { write.source_statuses.status[i] = sources[i].Tick(read.source_configurations.config[i], read.adpcm_coefficients.coeff[i]); for (size_t mix = 0; mix < 3; mix++) { sources[i].MixInto(intermediate_mixes[mix], mix); } } // Generate final mix write.dsp_status = mixers.Tick(read.dsp_configuration, read.intermediate_mix_samples, write.intermediate_mix_samples, intermediate_mixes); StereoFrame16 output_frame = mixers.GetOutput(); // Write current output frame to the shared memory region for (size_t samplei = 0; samplei < output_frame.size(); samplei++) { for (size_t channeli = 0; channeli < output_frame[0].size(); channeli++) { write.final_samples.pcm16[samplei][channeli] = s16_le(output_frame[samplei][channeli]); } } return output_frame; }
nub_size_t MachVMMemory::Write(task_t task, nub_addr_t address, const void *data, nub_size_t data_count) { MachVMRegion vmRegion(task); nub_size_t total_bytes_written = 0; nub_addr_t curr_addr = address; const uint8_t *curr_data = (const uint8_t*)data; while (total_bytes_written < data_count) { if (vmRegion.GetRegionForAddress(curr_addr)) { mach_vm_size_t curr_data_count = data_count - total_bytes_written; mach_vm_size_t region_bytes_left = vmRegion.BytesRemaining(curr_addr); if (region_bytes_left == 0) { break; } if (curr_data_count > region_bytes_left) curr_data_count = region_bytes_left; if (vmRegion.SetProtections(curr_addr, curr_data_count, VM_PROT_READ | VM_PROT_WRITE)) { nub_size_t bytes_written = WriteRegion(task, curr_addr, curr_data, curr_data_count); if (bytes_written <= 0) { // Error should have already be posted by WriteRegion... break; } else { total_bytes_written += bytes_written; curr_addr += bytes_written; curr_data += bytes_written; } } else { DNBLogThreadedIf(LOG_MEMORY_PROTECTIONS, "Failed to set read/write protections on region for address: [0x%8.8llx-0x%8.8llx)", (uint64_t)curr_addr, (uint64_t)(curr_addr + curr_data_count)); break; } } else { DNBLogThreadedIf(LOG_MEMORY_PROTECTIONS, "Failed to get region for address: 0x%8.8llx", (uint64_t)address); break; } } return total_bytes_written; }