Skip to content

Commit fa3c0e7

Browse files
committed
treat all audio inputs with >2 channels as stereo
1 parent 0734c29 commit fa3c0e7

File tree

4 files changed

+30
-6
lines changed

4 files changed

+30
-6
lines changed

CONTRIBUTING.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@ You can run cap in "local mode", which means that no auth is required for the de
5050

5151
1. Clone the repository
5252
2. Install dependencies with `pnpm install`
53+
3. Setup native dependencies with `pnpm cap-setup`
5354
3. Clone .env.example and rename it to .env
5455
4. Make sure you have `NEXT_PUBLIC_ENVIRONMENT=development`, `NEXT_PUBLIC_URL=http://localhost:3000` and `NEXT_PUBLIC_LOCAL_MODE=true`. These should be the only .env vars that you require to get the desktop app up and running.
5556
5. At the root of the directory, run the app with `pnpm dev`

crates/media/src/data.rs

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -144,8 +144,7 @@ impl AudioInfo {
144144
fn channel_layout_raw(channels: u16) -> Option<ChannelLayout> {
145145
Some(match channels {
146146
1 => ChannelLayout::MONO,
147-
2 => ChannelLayout::STEREO,
148-
_ => return None,
147+
_ => ChannelLayout::STEREO,
149148
})
150149
}
151150

@@ -173,7 +172,6 @@ impl AudioInfo {
173172
let interleaved_chunk_size = sample_size * self.channels;
174173
let samples = data.len() / interleaved_chunk_size;
175174

176-
dbg!(samples);
177175
let mut frame = FFAudio::new(self.sample_format, samples, self.channel_layout());
178176
frame.set_pts(Some(timestamp));
179177
frame.set_rate(self.sample_rate);

crates/media/src/feeds/audio_input.rs

Lines changed: 27 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,8 @@ pub type AudioInputSamplesReceiver = Receiver<AudioInputSamples>;
4242

4343
pub type AudioInputDeviceMap = IndexMap<String, (Device, SupportedStreamConfig)>;
4444

45+
pub const MAX_AUDIO_CHANNELS: u16 = 2;
46+
4547
#[derive(Clone)]
4648
pub struct AudioInputFeed {
4749
control_tx: Sender<AudioInputControl>,
@@ -72,10 +74,11 @@ impl AudioInputFeed {
7274
MediaError::DeviceUnreachable(selected_input.to_string())
7375
})?;
7476

75-
let audio_info = AudioInfo::from_stream_config(&config).map_err(|e| {
77+
let mut audio_info = AudioInfo::from_stream_config(&config).map_err(|e| {
7678
error!("Failed to create audio info from stream config: {}", e);
7779
e
7880
})?;
81+
audio_info.channels = audio_info.channels.clamp(1, MAX_AUDIO_CHANNELS as usize);
7982

8083
debug!("Created audio info: {:?}", audio_info);
8184
let (control_tx, control_rx) = flume::bounded(1);
@@ -173,6 +176,10 @@ impl AudioInputFeed {
173176
dbg!(&config);
174177

175178
self.audio_info = AudioInfo::from_stream_config(&config)?;
179+
self.audio_info.channels = self
180+
.audio_info
181+
.channels
182+
.clamp(1, MAX_AUDIO_CHANNELS as usize);
176183

177184
Ok(())
178185
}
@@ -299,8 +306,26 @@ fn start_capturing(
299306
}
300307

301308
match rx.recv() {
302-
Ok(data) => {
309+
Ok(mut data) => {
303310
let mut to_remove = vec![];
311+
312+
if config.channels() > MAX_AUDIO_CHANNELS {
313+
let mut new_data = Vec::with_capacity(
314+
MAX_AUDIO_CHANNELS as usize
315+
* (data.data.len() / config.channels() as usize),
316+
);
317+
318+
let sample_size = data.format.sample_size();
319+
320+
for sample in data.data.chunks(sample_size * config.channels() as usize) {
321+
new_data.extend_from_slice(
322+
&sample[0..sample_size * MAX_AUDIO_CHANNELS as usize],
323+
);
324+
}
325+
326+
data.data = new_data;
327+
}
328+
304329
for (i, sender) in senders.iter().enumerate() {
305330
if let Err(TrySendError::Disconnected(_)) = sender.try_send(data.clone()) {
306331
warn!("Audio sender {} disconnected, will be removed", i);

scripts/symbolicate-macos-crash.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
// populates an unsymbolicated crash report's 'crashed' section with symbols
2+
// reference: https://developer.apple.com/documentation/xcode/adding-identifiable-symbol-names-to-a-crash-report#Symbolicate-the-crash-report-with-the-command-line
23

34
import * as fs from "node:fs/promises";
45
import * as path from "node:path";
56
import { fileURLToPath } from "node:url";
67
import { exec as execCb } from "node:child_process";
7-
import { env } from "node:process";
88
import { promisify } from "node:util";
99

1010
const exec = promisify(execCb);

0 commit comments

Comments
 (0)