Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
73dc0c1
update docs
Tiramisioux Jan 16, 2026
1724245
Update mkdocs.yml to include FPS correction section
Tiramisioux Jan 16, 2026
eb0839b
Enhance fps correction documentation for clarity
Tiramisioux Jan 16, 2026
17bfbee
Add drive erase and format feature to README
Tiramisioux Jan 16, 2026
62d628e
Modify installation steps for CinePi-RAW
Tiramisioux Jan 17, 2026
0f4a88f
Simplify .asoundrc setup instructions
Tiramisioux Jan 17, 2026
1f8352a
Correct alias section header and add new aliases
Tiramisioux Jan 17, 2026
a42fd25
added sensor correction factor 0.9990 for imx283 25fps 2.7k
Tiramisioux Jan 30, 2026
254f7ab
fixed typo in README.md
Tiramisioux Jan 30, 2026
5a09c4b
Stop CLI input loop on EOF
Tiramisioux Feb 6, 2026
2dd5ad9
Merge pull request #81 from Tiramisioux/codex/fix-cli_commands-spammi…
Tiramisioux Feb 6, 2026
c8a176e
Update preview zoom highlight colors
Tiramisioux Feb 6, 2026
64b8c6c
Merge pull request #82 from Tiramisioux/codex/add-zoom-functionality-…
Tiramisioux Feb 6, 2026
c99eda0
Limit autostart journal spam
Tiramisioux Feb 6, 2026
2f38ced
Merge pull request #83 from Tiramisioux/codex/fix-alsaloop-message-sp…
Tiramisioux Feb 6, 2026
c0ab5ef
Add WAV indicator in audio status boxes
Tiramisioux Feb 6, 2026
4a0efb3
Merge pull request #84 from Tiramisioux/codex/add-wav-confirmation-me…
Tiramisioux Feb 6, 2026
72fcf26
Gate WAV indicator until recording completes
Tiramisioux Feb 6, 2026
0b0cb33
Merge branch 'main' into codex/add-wav-confirmation-mechanism-in-gui-…
Tiramisioux Feb 6, 2026
0a6ab6c
Merge pull request #85 from Tiramisioux/codex/add-wav-confirmation-me…
Tiramisioux Feb 6, 2026
618491b
Reduce repeated latest recording logs
Tiramisioux Feb 6, 2026
581bc58
Merge branch 'main' into codex/add-wav-confirmation-mechanism-in-gui-…
Tiramisioux Feb 6, 2026
277f5f3
Merge pull request #86 from Tiramisioux/codex/add-wav-confirmation-me…
Tiramisioux Feb 6, 2026
ce61838
updated docs
Tiramisioux Feb 16, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 10 additions & 13 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,24 +5,21 @@ Cinemate provides a minimal starting point that you can extend with your own con

The project combines a Python UI with a custom fork of [cinepi-raw](https://github.com/Tiramisioux/cinepi-raw/tree/rpicam-apps_1.7_custom_encoder).

## New features in version 3.1

- fast uncompressed dng encoder, supporting both IMX 585 color and mono sensors (normal SSD's working well for HD @ 25 fps)
- redesigned HDMI ui
- sound recording activated
- dual sensor support
- punch in digital zoom of preview
- i2c oled module and enum enhanced Redis key handling by [tevey](https://github.com/tevey)
- selection of physical camera port cam0 or cam1
- choose specific HDMI output port, 0 or 1
- adapted to libcamera 0.5/rpicam-apps 1.7
## New features in version 3.2

- improved mounting mechanics for NVME and SSD drives with less drop frames
- erase and format drives via Cinemate CLI (ext4/NTFS)
- storage preroll to "warm up" the recording media, improving writing stability
- improved audio sync with correction of effective fps (different resolutions/frame rates due to sensor VBLANK), available for fine tuning in `src/module/sensor_correction_factors.py`
- option to record a fixed number of frames or seconds for user calibration of fps correction factors (run Cinemate manually for this calibration as feedback is supplied in the terminal)
- improved recognition of attached microphones

## Compatible sensors

- IMX477 (official Raspberry Pi HQ camera)
- IMX294 (official Raspberry Pi GS camera)
- IMX585 ([Starlight Eye](https://www.tindie.com/products/will123321/starlighteye/) by Will Whang)
- IMX296 (official Raspberry Pi GS camera)
- IMX283 ([OneInchEye](https://www.tindie.com/products/will123321/oneincheye-v20/) by Will Whang)
- IMX585 ([Starlight Eye](https://www.tindie.com/products/will123321/starlighteye/) by Will Whang)

## Preinstalled hardware

Expand Down
2 changes: 1 addition & 1 deletion docs/acknowledgments.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# Acknowledgements

The [**Cinemate**](https://github.com/Tiramisioux/cinemate) stack is built on top of several open-source projects. Special thanks to all authors!
The [**Cinemate**](https://github.com/Tiramisioux/cinemate) stack is built on of several open-source projects. Special thanks to all authors!

- [**CinePi-raw**](https://github.com/cinepi/cinepi-raw) – Csaba Nagy
- [**IMX585 and IMX283 drivers**](https://github.com/will127534) – Will Whang
Expand Down
86 changes: 40 additions & 46 deletions docs/audio-recording.md
Original file line number Diff line number Diff line change
@@ -1,60 +1,54 @@
# Audio recording (experimental)

Cinemate records audio alongside the image sequence. Support is currently limited to a few USB microphones with hard coded configurations:
Cinemate records audio alongside the image sequence. Audio is written as `.wav` files into the same folder as the `.dng` frames. The implementation is still experimental and audio/video synchronization needs further investigation.

## Supported microphones
- **RØDE VideoMic NTG** – recorded in stereo at 24‑bit/48 kHz.
- **USB PnP microphones** – recorded in mono at 16‑bit/48 kHz.

Other class‑compliant USB microphones are now detected automatically by probing the ALSA hardware devices reported by `arecord -l`. Cinemate will fall back to using the matching USB device (via `plughw:<card>,<device>`) if the `mic_24bit` or `mic_16bit` aliases are not available.

Audio is written as `.wav` files into the same folder as the `.dng` frames. The implementation is still experimental and audio/video synchronization needs further investigation.

### .asoundrc Setup

For `dsnoop` support, create a `~/.asoundrc` in home directory:

```bash
nano ~/.asoundrc
```
## .asoundrc Setup

Paste this into the file:
For `dsnoop` support, create a `~/etc/asound.conf`:

```bash

pcm.dsnoop_24bit {
type dsnoop
ipc_key 2048
slave {
pcm "hw:Device,0"
channels 2
rate 48000
format S24_3LE
period_size 1024
buffer_size 4096
}
}

pcm.dsnoop_16bit {
type dsnoop
ipc_key 2049
slave {
pcm "hw:Device,0"
channels 1
rate 48000
format S16_LE
period_size 1024
buffer_size 4096
}
}

pcm.mic_24bit {
type plug
slave.pcm "dsnoop_24bit"
}

pcm.mic_16bit {
type plug
slave.pcm "dsnoop_16bit"
}
sudo tee /etc/asound.conf >/dev/null <<'EOF'
# --- Hardware handle (use stable card name; change "NTG" if your card shows a different name in `arecord -l`)
pcm.mic_hw {
type hw
card "NTG"
device 0
}

# --- One shared dsnoop backend pinned to the mic's native mode (RØDE NTG: S24_3LE @ 48k, stereo)
pcm.mic_dsnoop {
type dsnoop
ipc_key 5978
ipc_perm 0666
ipc_key_add_uid false
slave {
pcm "hw:CARD=NTG,DEV=0"
format S24_3LE
rate 48000
channels 2
}
bindings.0 0
bindings.1 1
}

# --- Front-ends: let plug adapt whatever the app asks for (stereo 24-bit or mono 16-bit)
pcm.mic_24bit {
type plug
slave.pcm "mic_dsnoop"
}

pcm.mic_16bit {
type plug
slave.pcm "mic_dsnoop"
}
EOF

```

Expand Down
2 changes: 1 addition & 1 deletion docs/backing-up-sd-card.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# Backing up the SD card

## To create a compressed image using PiShrink
## Create a compressed image using PiShrink

```shell hl_lines="2 3"
sudo bash -Eeuo pipefail -c '
Expand Down
2 changes: 1 addition & 1 deletion docs/cinepi-multi.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# How Cinemate launches cinepi-raw

`cinemate/src/module/cinepi_multi.py` starts one `cinepi-raw` process per connected camera. It takes camera information `cinemate/src/module/sensor_detect.py` and user settings from `cinemate/src/module/settings.json` to build the command and command-line flags passed to `cinepi-raw`.
The file `cinemate/src/module/cinepi_multi.py` starts one `cinepi-raw` process per connected camera. It takes camera information `cinemate/src/module/sensor_detect.py` and user settings from `cinemate/src/module/settings.json` to build the command and command-line flags passed to `cinepi-raw`.


## Detecting Cameras
Expand Down
16 changes: 13 additions & 3 deletions docs/cli-commands.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,19 @@ reads simple text commands from SSH or the serial port and calls the
corresponding controller methods.

!!! note ""

Note if you have Cinemate already running, for example by running the preinstalled image file, you first need to stop the autostarted instance in order and manually start Cinemate in order to use the Cinemate CLI:

cd cinemate # change directory to cinemate folder
make stop # stop the autostarted instance
cinemate # start cinemate manually

!!! note ""

Commands without an explicit argument will toggle the current state when possible (e.g. `set fps lock` flips the lock; `set fps lock 1` forces it on).

!!! note ""

All of the commands below can be easily mapped to GPIO buttons rotary encoders and other input devices. See [this section](settings-json.md) for how to configure the settings file.


Expand Down Expand Up @@ -67,10 +77,10 @@ If recording is not already running, the CLI starts it automatically before armi

Two new commands simplify preparing removable media directly from the Cinemate CLI:

- `erase` empties the mounted RAW volume without touching the filesystem structure so you can clear cards quickly between takes.【F:src/module/ssd_monitor.py†L628-L648】
- `format [ext4|ntfs]` reformats the drive with the chosen filesystem (`ext4` by default), remounts it and refreshes the free-space monitor. The helper tolerates the common `ex4` typo and refuses unsupported targets so you do not accidentally create an unusable volume.【F:src/module/ssd_monitor.py†L650-L716】
- `erase` empties the mounted RAW volume without touching the filesystem structure so you can clear cards quickly between takes.
- `format [ext4|ntfs]` reformats the drive with the chosen filesystem (`ext4` by default), remounts it and refreshes the free-space monitor. The helper tolerates the common `ex4` typo and refuses unsupported targets so you do not accidentally create an unusable volume.

Both actions require the RAW drive to be mounted; otherwise the CLI reports an error and leaves the media untouched.【F:src/module/ssd_monitor.py†L632-L636】【F:src/module/ssd_monitor.py†L652-L657】
Both actions require the RAW drive to be mounted; otherwise the CLI reports an error and leaves the media untouched.

## Storage pre-roll warm-up

Expand Down
4 changes: 1 addition & 3 deletions docs/cli-user-guide.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
# Using CinePi-RAW from the terminal

Here is how you can operate **CinePi-raw** from the command line.

## Checking available options

Before running the program you can view all command‑line flags with:
Expand All @@ -14,7 +12,7 @@ This prints a long list of options supported by the application. It includes the

## Camera modes

CinePi-raw uses **Libcamera** to talk to your Raspberry Pi camera module. Each sensor supports one or more *modes*, which define the resolution and bit depth of the RAW images that the sensor can produce. A mode is written as:
CinePi-Raw uses **Libcamera** to talk to your Raspberry Pi camera module. Each sensor supports one or more *modes*, which define the resolution and bit depth of the RAW images that the sensor can produce. A mode is written as:

```
--mode 2028:1080:12:U
Expand Down
3 changes: 1 addition & 2 deletions docs/compiling-cinepi-raw.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
# Recompiling cinepi-raw
Compiling cinepi-raw

For easy later rebuilding and installation of cinepi-raw you can create the file compile-raw.sh.
For easy later rebuilding and installation of cinepi-raw you can create the file `compile-raw.sh`.

```shell
nano compile-raw.sh
Expand Down
28 changes: 28 additions & 0 deletions docs/fps-correction.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
## FPS correction factors and audio sync

Some sensors report different effective frame rates than the requested FPS. This is typically caused by sensor timing details such as vertical blanking (vblank). Vblank changes the total line time the sensor needs per frame, which in turn shifts the *true* FPS even when the target FPS stays constant. Cinemate compensates for this by applying an FPS correction factor so the captured frame timing lines up with your intended rate.

With the properly fine-tuned correction factor we can achieve pretty good sync to both onboard and external audio recording

### Why the correction factor is per sensor, mode, and FPS

Each sensor model exposes its own timing characteristics. On top of that, every sensor mode (resolution/bit depth) has different blanking and pixel-clock constraints. The requested FPS also changes how the sensor clocks out frames. Because of these combined dependencies, Cinemate stores a correction factor for every **sensor type + resolution/mode + FPS** triplet in the file `src/module/sensor_correction_factors.py`.


### Running a fixed‑frame calibration clip

To validate or tune the correction factor, you can record a clip with a fixed frame count:

```
rec f 1000
```

This records exactly 1000 frames (based on the current FPS) and stops automatically.
Cinemate knows exactly how many frames *should* have landed over the elapsed duration and when recording stops it performs an analysis and proposes an fps correction factor

### How Cinemate analyzes the results

After the recording finishes, Cinemate compares the expected frame count with the actual frames captured. When there is a mismatch, it derives a suggested correction factor and suggests it to the user. If the frame count lands on the expected number of frames (with the tolerance of +/- 1 frame), it suggests to keep the existing correction factor.

!!! note ""
See [here](cli-commands.md) how to run Cinemate manually.
3 changes: 0 additions & 3 deletions docs/getting-started.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,9 +26,6 @@ Connect the Pi and the camera sensor board, connect power an boot the Pi. Cinema
- Connect your phone/tablet to the Wi‑Fi network `CinePi` (password `11111111`).
Open a browser and go to `cinepi.local:5000` to see the interface. A clean video feed without the GUI is available at `cinepi.local:8000/stream`.

!!! note ""
Note that by default, the Cinemate Wi-Fi hotspot is disabled. To enable it, see [this section](settings-json.md).


## Recording
- Attach a high‑speed drive: an **SSD** (Samsung T7 recommended), an **NVMe drive**, or the **[CFE Hat](https://www.tindie.com/products/will123321/cfe-hat-for-raspberry-pi-5/)**. Make sure storage media is formatted as `ext4` and labeled `RAW`.
Expand Down
52 changes: 50 additions & 2 deletions docs/installation-steps.md
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ sudo apt install -y libspdlog-dev libjsoncpp-dev && cd /home/pi && git clone htt
### CinePi-RAW <img src="https://img.shields.io/badge/cinemate-fork-gren" height="12" >

```bash
git clone https://github.com/Tiramisioux/cinepi-raw.git --branch rpicam-apps_1.7_custom_encoder
git clone https://github.com/Tiramisioux/cinepi-raw.git
cd cinepi-raw
sudo rm -rf build
sudo meson setup build
Expand All @@ -84,6 +84,52 @@ PUBLISH cp_controls cg_rb
EOF
```

### .asoundrc Setup

For `dsnoop` support, create a `~/etc/asound.conf`:

```bash

sudo tee /etc/asound.conf >/dev/null <<'EOF'
# --- Hardware handle (use stable card name; change "NTG" if your card shows a different name in `arecord -l`)
pcm.mic_hw {
type hw
card "NTG"
device 0
}

# --- One shared dsnoop backend pinned to the mic's native mode (RØDE NTG: S24_3LE @ 48k, stereo)
pcm.mic_dsnoop {
type dsnoop
ipc_key 5978
ipc_perm 0666
ipc_key_add_uid false
slave {
pcm "hw:CARD=NTG,DEV=0"
format S24_3LE
rate 48000
channels 2
}
bindings.0 0
bindings.1 1
}

# --- Front-ends: let plug adapt whatever the app asks for (stereo 24-bit or mono 16-bit)
pcm.mic_24bit {
type plug
slave.pcm "mic_dsnoop"
}

pcm.mic_16bit {
type plug
slave.pcm "mic_dsnoop"
}
EOF

```

Exit nano editor using ctrl+x.

### IMX585 driver (optional)

```shell
Expand Down Expand Up @@ -399,7 +445,7 @@ zoom 0 write_speed_to_drive 0 recording_time 0

(See the settings guide for the full list.)

### Add alias
### Add aliases

```shell
nano ~/.bashrc
Expand All @@ -409,6 +455,8 @@ Add to the end of the file:

```shell
alias cinemate='python3 /home/pi/cinemate/src/main.py'
alias editboot='sudo nano /boot/firmware/config.txt'
alias editsettings='sudo nano /home/pi/cinemate/src/settings.json'
```

Exit with Ctrl+x. System will ask you to save the file. Press "y" and then enter.
Expand Down
28 changes: 14 additions & 14 deletions docs/readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,20 +10,20 @@ The project combines a Python UI with a custom fork of [cinepi-raw](https://gith
<p><em>Figure 1: Camera stack exploded view. Apps change settings by updating Redis keys. CinePi-RAW listens for those updates and captures frames accordingly while Cinemate provides the camera user interface.</em></p>
</div>

!!! tip ""
## New features in version 3.2

- improved mounting mechanics for NVME and SSD drives with less drop frames

!!! tip ""
## New features in version 3.1

- fast uncompressed dng encoder, supporting both IMX 585 color and mono sensors (normal SSD's working well for HD @ 25 fps)
- redesigned HDMI ui
- sound recording activated
- dual sensor support
- punch in digital zoom of preview
- i2c oled module and enum enhanced Redis key handling by [tevey](https://github.com/tevey)
- selection of physical camera port cam0 or cam1
- choose specific HDMI output port, 0 or 1
- adapted to libcamera 0.5/rpicam-apps 1.7
- storage preroll to "warm up" the recording media, improving writing stability

- improved audio sync with correction of effective fps (different resolutions/frame rates due to sensor VBLANK), available for fine tuning in `src/module/sensor_correction_factors.py`

- option to record a fixed number of frames or seconds for user calibration of fps correction factors (run Cinemate manually for this calibration as feedback is supplied in the terminal)

- system startup fix to have Cinemate wait for sensor to be loaded properly by the system (contribution from user Yabbo01)

- simple GUI now supports different resolutions defined by the user in `setting.json` (contribution from user 0point)

## Installation
See the [releases section](https://github.com/Tiramisioux/cinemate/releases) for preinstalled image file and [Quick Start Guide](https://tiramisioux.github.io/cinemate/getting-started/).
Expand All @@ -33,9 +33,9 @@ For manual install of the camera stack on Raspberry Pi Bookworm, see the [here](
## Compatible sensors

- IMX477 (official Raspberry Pi HQ camera)
- IMX294 (official Raspberry Pi GS camera)
- IMX585 ([Starlight Eye](https://www.tindie.com/products/will123321/starlighteye/) by Will Whang)
- IMX296 (official Raspberry Pi GS camera)
- IMX283 ([OneInchEye](https://www.tindie.com/products/will123321/oneincheye-v20/) by Will Whang)
- IMX585 ([Starlight Eye](https://www.tindie.com/products/will123321/starlighteye/) by Will Whang)

## Preinstalled hardware

Expand Down
Loading