# How Export Configuration Options Like Sample Rate and Channels Are Applied in Muse

> Learn how Muse applies export configuration options like sample rate and channels. Discover how AudioSampleMetadata and AudioExportPipeline manage WAV headers and MP3 encoding.

- Repository: [Ko Shin/muse](https://github.com/kkoshin/muse)
- Tags: internals
- Published: 2026-03-05

---

**Export configuration options like sample rate and channels are captured from the Export Config Sheet UI, stored in `AudioSampleMetadata`, and applied by `AudioExportPipeline` to configure both WAV headers and MP3 encoding parameters.**

When exporting audio in the Muse app, users select specific export configuration options like sample rate and channels through the Export Config Sheet. These settings propagate from the Kotlin Multiplatform UI layer down to platform-specific audio encoders to ensure the final output matches user expectations exactly according to the kkoshin/muse source code.

## How Export Configuration Options Flow Through the Pipeline

### Capturing Settings in ExportConfigSheet

In [`muse/src/commonMain/kotlin/io/github/kkoshin/muse/feature/editor/ExportConfigSheet.kt`](https://github.com/kkoshin/muse/blob/main/muse/src/commonMain/kotlin/io/github/kkoshin/muse/feature/editor/ExportConfigSheet.kt), the composable UI gathers user selections into an `ExportConfigSheetArgs` data class. This object encapsulates the chosen **sample rate** (e.g., 44100 Hz, 48000 Hz) and **channel count** (1 for mono, 2 for stereo), passing them from the sheet to the ViewModel layer.

### Propagating Metadata via ExportViewModel

The `ExportViewModel` receives these arguments and constructs an `AudioSampleMetadata` instance. This data class (defined in [`AudioSampleMetadata.kt`](https://github.com/kkoshin/muse/blob/main/AudioSampleMetadata.kt)) serves as the single source of truth for the export pipeline:

```kotlin
val sampleRateInHz: Int   // e.g., 44100, 48000
val channelCount: Int     // 1 = mono, 2 = stereo

```

The ViewModel initializes `AudioExportPipeline` with this metadata, ensuring all downstream components receive consistent configuration parameters regardless of the target output format.

## Applying Export Configuration Options to Audio Outputs

### Writing WAV Headers with WaveHeaderWriter

For WAV exports, `WaveHeaderWriter` constructs the RIFF header using the metadata values. Platform-specific implementations in [`muse/src/iosMain/kotlin/io/github/kkoshin/muse/audio/WaveHeaderWriter.ios.kt`](https://github.com/kkoshin/muse/blob/main/muse/src/iosMain/kotlin/io/github/kkoshin/muse/audio/WaveHeaderWriter.ios.kt) and [`muse/src/androidMain/kotlin/io/github/kkoshin/muse/audio/WaveHeaderWriter.android.kt`](https://github.com/kkoshin/muse/blob/main/muse/src/androidMain/kotlin/io/github/kkoshin/muse/audio/WaveHeaderWriter.android.kt) write the sample rate to bytes 24-27 and channel count to byte 22:

```kotlin
val sampleRate = audioMetadata.sampleRateInHz.toLong()
val channels = audioMetadata.channelCount

// Sample rate (little-endian)
header[24] = (sampleRate and 0xFF).toByte()
header[25] = ((sampleRate shr 8) and 0xFF).toByte()
header[26] = ((sampleRate shr 16) and 0xFF).toByte()
header[27] = ((sampleRate shr 24) and 0xFF).toByte()

// Channel count
header[22] = channels.toByte()

```

### Configuring MP3 Encoding with Mp3Encoder

When exporting to MP3, `Mp3Encoder` (located in [`muse/src/iosMain/kotlin/io/github/kkoshin/muse/audio/Mp3Encoder.ios.kt`](https://github.com/kkoshin/muse/blob/main/muse/src/iosMain/kotlin/io/github/kkoshin/muse/audio/Mp3Encoder.ios.kt) and the corresponding Android path) forwards these parameters to the native LAME library:

```kotlin
// Configure LAME encoder with export settings
lame_set_in_samplerate(lame, wavParser.sampleRate)
lame_set_num_channels(lame, wavParser.channelCount)

```

The encoder reads these values from the `WavParser` instance, which itself derives them from the `AudioSampleMetadata` passed through the pipeline.

## Pipeline Processing and Validation

During export, `AudioExportPipeline` uses `AudioSampleMetadata` to compute byte offsets and durations for any intermediate processing steps (such as silence trimming or padding). This ensures that transformations respect the configured sample rate and maintain audio synchronization throughout the export process.

## Summary

- **ExportConfigSheet** captures user selections as `ExportConfigSheetArgs` and passes them to the ViewModel.
- **ExportViewModel** transforms UI arguments into `AudioSampleMetadata` for type-safe propagation through the export pipeline.
- **WaveHeaderWriter** embeds sample rate and channel data into specific byte offsets of the WAV RIFF header.
- **Mp3Encoder** applies the same configuration to the LAME encoder via `lame_set_in_samplerate` and `lame_set_num_channels`.
- **AudioExportPipeline** maintains these settings throughout processing to ensure the final output matches the selected export configuration options.

## Frequently Asked Questions

### Where are export configuration options stored in the Muse codebase?

They are stored in the `AudioSampleMetadata` data class, which is instantiated by `ExportViewModel` based on the `ExportConfigSheetArgs` received from the UI. This object travels through `AudioExportPipeline` to reach platform-specific writers and encoders.

### How does Muse apply sample rate settings to WAV files?

`WaveHeaderWriter` writes the sample rate to bytes 24-27 of the WAV header in little-endian format, using the `sampleRateInHz` value from `AudioSampleMetadata`. Separate implementations exist for iOS and Android in [`WaveHeaderWriter.ios.kt`](https://github.com/kkoshin/muse/blob/main/WaveHeaderWriter.ios.kt) and [`WaveHeaderWriter.android.kt`](https://github.com/kkoshin/muse/blob/main/WaveHeaderWriter.android.kt).

### What controls channel configuration during MP3 export?

The `Mp3Encoder` configures the native LAME library using `lame_set_num_channels`, passing the `channelCount` from the parsed WAV source. This ensures the MP3 output maintains the user's selected mono or stereo configuration.

### How do platform-specific implementations share export configuration?

Both iOS and Android implementations of `WaveHeaderWriter` and `Mp3Encoder` consume the same common `AudioSampleMetadata` class, ensuring consistent application of export configuration options like sample rate and channels across platforms while allowing platform-specific native code for file I/O and encoding.