Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
64 changes: 64 additions & 0 deletions .github/workflows/checks.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
name: Build & Static Checks

on:
push:
branches: [ main, develop ]
pull_request:
branches: [ main, develop ]
workflow_dispatch:

jobs:
analyze:
runs-on: ubuntu-22.04

steps:
- uses: actions/checkout@v4
with:
submodules: 'recursive'

- name: Set up Buildx
uses: docker/setup-buildx-action@v3

- name: Build SDK image (cached)
uses: docker/build-push-action@v6
with:
context: .
file: Dockerfile.ci
tags: freeswitch-sdk:ci
load: true
cache-from: type=gha
cache-to: type=gha,mode=max

- name: Run analysis inside container
uses: addnab/docker-run-action@v3
with:
image: freeswitch-sdk:ci
options: -v ${{ github.workspace }}:/work
run: |
set -eux
cd /work
cmake -S . -B build \
-DCMAKE_BUILD_TYPE=Release \
-DCMAKE_EXPORT_COMPILE_COMMANDS=ON \
-DCMAKE_C_COMPILER=clang \
-DCMAKE_CXX_COMPILER=clang++ \
-DCMAKE_C_COMPILER_LAUNCHER=ccache \
-DCMAKE_CXX_COMPILER_LAUNCHER=ccache

scan-build --status-bugs cmake --build build -j"$(nproc)"

clang-tidy -p build $(git ls-files '*.c' '*.cc' '*.cpp' '*.cxx') \
FILES="$(git ls-files '*.c' '*.cc' '*.cpp' '*.cxx')"
if [ -n "$FILES" ]; then
clang-tidy -p build $FILES \
--warnings-as-errors='clang-analyzer-*,bugprone-*,performance-*'
else
echo "No source files found for clang-tidy analysis."
fi


cppcheck --enable=warning,style,performance,portability --std=c++17 --force \
--project=build/compile_commands.json \
--suppress=missingIncludeSystem \
-i build . 2> cppcheck.log || true
cat cppcheck.log
81 changes: 81 additions & 0 deletions Dockerfile.ci
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
# syntax=docker/dockerfile:1.7

############################
# Stage 1: Build dependencies + FreeSWITCH
############################
FROM debian:12 AS builder

ENV DEBIAN_FRONTEND=noninteractive


RUN apt-get update && apt-get install -y --no-install-recommends \
ca-certificates git curl wget \
build-essential cmake automake autoconf libtool libtool-bin libltdl-dev pkg-config \
libssl-dev zlib1g-dev libdb-dev unixodbc-dev libncurses5-dev libexpat1-dev \
libgdbm-dev bison erlang-dev libtpl-dev libtiff5-dev uuid-dev \
libpcre3-dev libpcre2-dev libedit-dev libsqlite3-dev libcurl4-openssl-dev nasm \
libogg-dev libspeex-dev libspeexdsp-dev libldns-dev python3-dev \
libavformat-dev libswscale-dev libswresample-dev \
liblua5.2-dev libopus-dev libpq-dev \
libsndfile1-dev libflac-dev libvorbis-dev \
&& rm -rf /var/lib/apt/lists/*


WORKDIR /src

RUN git clone https://github.com/signalwire/libks && \
git clone https://github.com/freeswitch/sofia-sip && \
git clone https://github.com/freeswitch/spandsp && \
git clone https://github.com/signalwire/signalwire-c && \
git clone https://github.com/signalwire/freeswitch

# libks
WORKDIR /src/libks
RUN cmake . -DCMAKE_INSTALL_PREFIX=/usr -DWITH_LIBBACKTRACE=1 && \
make -j"$(nproc)" && make install

# sofia-sip
WORKDIR /src/sofia-sip
RUN ./bootstrap.sh && \
./configure --with-pic --with-glib=no --without-doxygen --disable-stun --prefix=/usr && \
make -j"$(nproc)" && make install

# spandsp
WORKDIR /src/spandsp
RUN ./bootstrap.sh && \
./configure --with-pic --prefix=/usr && \
make -j"$(nproc)" && make install

# signalwire-c
WORKDIR /src/signalwire-c
RUN PKG_CONFIG_PATH=/usr/lib/pkgconfig cmake . -DCMAKE_INSTALL_PREFIX=/usr && \
make -j"$(nproc)" && make install

# FreeSWITCH SDK
WORKDIR /src/freeswitch
RUN ./bootstrap.sh -j && \
./configure --prefix=/usr && \
make -j"$(nproc)" && make install

############################
# Stage 2: Slim SDK image (no FreeSWITCH runtime)
############################
FROM debian:12

ENV DEBIAN_FRONTEND=noninteractive

RUN apt-get update && apt-get install -y --no-install-recommends \
build-essential \
clang clang-tidy clang-tools \
cppcheck cmake pkg-config ccache \
libssl-dev zlib1g-dev \
libspeexdsp-dev libspandsp-dev \
git curl wget \
&& rm -rf /var/lib/apt/lists/*

# Copy only SDK bits
COPY --from=builder /usr/include/freeswitch/ /usr/include/freeswitch/
COPY --from=builder /usr/lib/pkgconfig/freeswitch.pc /usr/lib/pkgconfig/
COPY --from=builder /usr/lib/libfreeswitch.so* /usr/lib/

WORKDIR /work
10 changes: 7 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,9 +1,13 @@
# mod_openai_audio_stream

A fork of [mod_audio_stream](https://github.com/amigniter/mod_audio_stream) specifically designed for streaming audio to OpenAI's realtime API and playing the responses back to the user via FreeSWITCH and WebSocket.
**mod_openai_audio_stream** is a FreeSWITCH module that streams L16 audio from a channel to an OpenAI realtime websocket endpoint. The stream is adherent to OpenAI's Realtime API specification and allows for real-time audio playback directly in the channel.
![Build & Static Code Checks](https://github.com/VoiSmart/mod_openai_audio_stream/actions/workflows/checks.yml/badge.svg)

**mod_openai_audio_stream** is a FreeSWITCH module that streams L16 audio from a channel to an OpenAI Realtime WebSocket endpoint. The stream follows OpenAI's Realtime API specification and enables real-time audio playback directly in the channel.

It is a fork of [mod_audio_stream](https://github.com/amigniter/mod_audio_stream), specifically adapted for streaming audio to OpenAI's Realtime API and playing the responses back to the user via FreeSWITCH and WebSocket.

The goal of **mod_openai_audio_stream** is to provide a simple, lightweight, yet effective module for streaming audio and receiving responses directly from OpenAI’s Realtime WebSocket into the call through FreeSWITCH. It uses [ixwebsocket](https://machinezone.github.io/IXWebSocket/), a C++ WebSocket library compiled as a static library.

The purpose of **mod_openai_audio_stream** was to make a simple, less dependent but yet effective module to stream audio and receive responses directly from OpenAI realtime websocket into the call via switch. It uses [ixwebsocket](https://machinezone.github.io/IXWebSocket/), c++ library for websocket protocol which is compiled as a static library.

## Notes

Expand Down