Samples - REST

These samples of code can be used to begin using our API quickly.

All clients are generated automatically using openapi generator. Check the openapi specification

Installation

Install dependencies : add in your gradle file

dependencies {
    ...
    implementation "ai.cochl:sense-api:v0.0.1"
}

For file upload, you will need an audio file. You can download one here

wget https://docs.cochl.ai/audio/siren.wav

For microphone upload, the sample of code assumes that audio stream is being taken from android microphone

This sample of code is working with node. The library is also compatible with browser.

Install dependencies

npm install @cochl/sense-api

For file upload, you will need an audio file. You can download one here

wget https://docs.cochl.ai/audio/siren.wav

For microphone upload, you will need to install one more dependency

npm install naudiodon

Install coch-sense-api

pip install cochl-sense-api

For file upload, you will need an audio file. You can download one here

wget https://docs.cochl.ai/audio/siren.wav

For microphone upload, you will need to install one more dependency

pip install pyaudio

Upload File

package ai.cochlear.example;

import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.Arrays;
import java.util.Base64;

import ai.cochl.client.ApiClient;
import ai.cochl.client.Configuration;
import ai.cochl.client.auth.ApiKeyAuth;
import ai.cochl.sense.api.AudioSessionApi;
import ai.cochl.sense.model.*;

public class Example {
    public static void main(String[] args) {
        try {
            inference();
        } catch (ai.cochl.client.ApiException e) {
            System.out.println(e.getResponseBody());
        } catch (Exception e) {
            System.out.println(e.toString());
        }
    }

    static void inference() throws ai.cochl.client.ApiException, java.io.IOException {
        String path = "siren.wav";
        String contentType = "audio/wav";
        String key = "YOUR_API_KEY";

        byte[] file = Files.readAllBytes(Paths.get(path));

        ApiClient cli = Configuration.getDefaultApiClient();
        ApiKeyAuth API_Key = (ApiKeyAuth) cli.getAuthentication("API_Key");
        API_Key.setApiKey(key);

        AudioSessionApi api = new AudioSessionApi(cli);

        CreateSession create = new CreateSession();
        create.setContentType(contentType);
        create.setType(AudioType.FILE);
        create.setTotalSize(file.length);
        SessionRefs session =  api.createSession(create);

        //upload
        int chunkSize = 1024 * 1024;
        for (int sequence = 0; sequence * chunkSize < file.length; sequence++) {
            System.out.println("uploading");
            byte[] slice = Arrays.copyOfRange(file, sequence * chunkSize, (sequence + 1) * chunkSize);
            
            AudioChunk chunk = new AudioChunk();
            chunk.setData(Base64.getEncoder().encodeToString(slice));
            api.uploadChunk(session.getSessionId(), sequence, chunk);
        }

        //Get result
        String token = null;
        while (true){
            SessionStatus result = api.readStatus(session.getSessionId(), null, null, token);
            token = result.getInference().getPage().getNextToken();
            if (token == null) {
                break;
            }
            for (SenseEvent event : result.getInference().getResults()) {
                System.out.println(event.toString());
            }
        }
    }
}

const { AudioSessionApi, AudioType, Configuration } = require("@cochl/sense-api")
const { readFileSync } = require("fs")

const apikey = "YOUR_API_KEY"
const filePath = "siren.wav"

const contentType = "audio/" + filePath.split(".").pop()
const file = readFileSync(filePath)

const conf = new Configuration({
    apiKey: apikey,
})
const session = new AudioSessionApi(conf)

async function init(){
    const created = await session.createSession({
        content_type: contentType,
        type: AudioType.File,
        total_size: file.length,
    })
    return created.data.session_id
}

async function upload(id) {
    const size = 1024  * 1024
    for(var sequence = 0; sequence * size < file.length; sequence++) {
        console.log("uploading")
        const chunk = file.slice(sequence * size, (sequence + 1) * size)
        await session.uploadChunk(id, sequence, {
            data: chunk.toString("base64")
        })
    }
}

async function results(id) {
    var nextToken
    do {
        const result = await session.readStatus(id, undefined, undefined, nextToken)
        nextToken = result.data.inference.page?.next_token
        result.data.inference.results?.forEach(result => {
            console.log(JSON.stringify(result))
        })
    } while (nextToken != undefined)
}


async function main() {
    const id = await init()
    await Promise.all([
        upload(id),
        results(id)
    ])
}

main().catch(err => {
    console.log(err)
})

import base64
import json
import os

import cochl_sense_api as sense
import cochl_sense_api.api.audio_session_api as sense_api
from cochl_sense_api.model.audio_chunk import AudioChunk
from cochl_sense_api.model.audio_type import AudioType
from cochl_sense_api.model.create_session import CreateSession

apikey = "YOUR_API_KEY"
filename="siren.wav"

configuration = sense.Configuration()
configuration.api_key['API_Key'] = apikey

client = sense.ApiClient(configuration)
api = sense_api.AudioSessionApi(client)

f = open(filename, "rb")
size = os.stat(filename).st_size

#create a new audio session
session = api.create_session(CreateSession(
    content_type="audio/" + os.path.splitext(filename)[1][1:],
    type=AudioType("file"),
    total_size=size,
))


#upload file per 1Mib chunks
seq = session.chunk_sequence
while True:
    chunk = f.read(2**20)
    if not chunk:
        break
    encoded = base64.b64encode(chunk).decode("utf-8")

    print("uploading")
    uploaded = api.upload_chunk(session_id=session.session_id, chunk_sequence=seq, audio_chunk=AudioChunk(encoded))
    seq = uploaded.chunk_sequence


#read inference result
next_token=""
while True:
    resp = api.read_status(session_id=session.session_id, next_token=next_token)
    for result in resp.inference.results:
        print(json.dumps(result.to_dict()))

    if "next_token" in resp.inference.page:
        next_token = resp.inference.page.next_token
    else:
        break

Upload Microphone

package ai.cochlear.example;

import android.media.AudioFormat;
import android.media.AudioRecord;
import android.media.MediaRecorder;
import android.util.Base64;

import java.nio.ByteBuffer;
import java.nio.ByteOrder;

import ai.cochl.client.ApiClient;
import ai.cochl.client.ApiException;
import ai.cochl.client.Configuration;
import ai.cochl.client.auth.ApiKeyAuth;
import ai.cochl.sense.api.AudioSessionApi;
import ai.cochl.sense.model.*;

class Uploader implements Runnable {
    private  AudioSessionApi api;
    private String id;

    Uploader(AudioSessionApi api, String id) {
        this.api = api;
        this.id = id;
    }

    @Override
    public void run() {
        int channel = AudioFormat.CHANNEL_IN_MONO;
        int format = AudioFormat.ENCODING_PCM_FLOAT;
        int bitsSample = 4;
        int rate = 22050;

        AudioRecord recorder = new AudioRecord(MediaRecorder.AudioSource.DEFAULT,
                rate,
                channel,
                format,
                AudioRecord.getMinBufferSize(rate, channel, format)
        );
        recorder.startRecording();

        //record for 10 seconds
        float[] samples = new float[rate/2];
        byte[] bytes = new byte[rate * bitsSample/2];
        int sequence = 0;
        int totalRecorded = 0;
        while (totalRecorded < 10 * rate * bitsSample) {
            recorder.read(samples, 0, samples.length, AudioRecord.READ_BLOCKING);

            AudioChunk chunk = new AudioChunk();
            ByteBuffer.wrap(bytes).order(ByteOrder.LITTLE_ENDIAN).asFloatBuffer().put(samples);
            chunk.setData(Base64.encodeToString(bytes, Base64.DEFAULT));

            totalRecorded += bytes.length;
            try {
                api.uploadChunk(id, sequence, chunk);
            } catch (ApiException e) {
                System.out.println(e.getResponseBody());
                break;
            }
            sequence++;
        }

        try {
            api.deleteSession(id);
        } catch (ApiException e) {
            System.out.println(e.getResponseBody());
        }
    }
}

public class Inference implements  Runnable {
    @Override
    public void run() {
        try {
            inference();
        } catch (ApiException e) {
            System.out.println(e.getResponseBody());
        }
    }

    public void inference() throws ApiException {
        String key = "YOUR_API_KEY";

        ApiClient cli = Configuration.getDefaultApiClient();
        ApiKeyAuth API_Key = (ApiKeyAuth) cli.getAuthentication("API_Key");
        API_Key.setApiKey(key);

        AudioSessionApi api = new AudioSessionApi(cli);

        CreateSession create = new CreateSession();
        create.setContentType("audio/x-raw; rate=22050; format=s32");
        create.setType(AudioType.STREAM);
        SessionRefs session =  api.createSession(create);

        //upload data from microphone in other thread
        Uploader uploader = new Uploader(api, session.getSessionId());
        new Thread(uploader).start();

        //Get result
        String token = null;
        while (true){
            SessionStatus result = api.readStatus(session.getSessionId(), null, null, token);
            token = result.getInference().getPage().getNextToken();
            if (token == null) {
                break;
            }
            for (SenseEvent event : result.getInference().getResults()) {
                System.out.println(event.toString());
            }
        }
    }
}

const { AudioSessionApi, AudioType, Configuration } = require("@cochl/sense-api")
const { AudioIO, SampleFormat32Bit } = require("naudiodon")

const apikey = "YOUR_API_KEY"

const conf = new Configuration({
    apiKey: apikey,
})
const session = new AudioSessionApi(conf)

async function init(){
    const created = await session.createSession({
        content_type: "audio/x-raw; rate=22050; format=s32",
        type: AudioType.Stream,
    })
    return created.data.session_id
}

async function upload(id) {
    const size = 22050 * 4 / 2 
    const audioInput = AudioIO({
        inOptions: {
            deviceId: -1,
            channelCount: 1,
            sampleFormat: SampleFormat32Bit,
            sampleRate: 22050,
        },
    });

    var seq = 0
    var buffer = new Uint8Array()
    audioInput.on("data", async (chunk) => {
        buffer = Buffer.concat([buffer, chunk])
        if (buffer.length >= size) {
            const toUpload = buffer.slice(0, size)
            buffer = buffer.slice(size)
            await session.uploadChunk(id, seq++, {
                    data: Buffer.from(toUpload).toString("base64"),
            })
        }
    })

    audioInput.start()
}


async function results(id) {
    var nextToken
    do {
        const result = await session.readStatus(id, undefined, undefined, nextToken)
        nextToken = result.data.inference.page?.next_token
        result.data.inference.results?.forEach(result => {
            console.log(JSON.stringify(result))
        })
    } while (nextToken != undefined)
}


async function main() {
    const id = await init()
    await Promise.all([
        upload(id),
        results(id)
    ])
}

main().catch(err => {
    console.log(err)
})


import base64
import json
import queue
import threading

from pyaudio import PyAudio, paContinue, paFloat32
from cochl_sense_api import Configuration, ApiClient 
from cochl_sense_api.api import audio_session_api
from cochl_sense_api.model.audio_chunk import AudioChunk
from cochl_sense_api.model.audio_type import AudioType
from cochl_sense_api.model.create_session import CreateSession

configuration = Configuration()
configuration.api_key['API_Key'] = 'YOUR_API_KEY'

client = ApiClient(configuration)
api = audio_session_api.AudioSessionApi(client)
created = api.create_session(CreateSession(
    content_type="audio/x-raw; rate=22050; format=f32",
    type=AudioType("stream"),
))
id = created.session_id

class PyAudioSense:
    def __init__(self):
        self.rate = 22050
        chunk = int(self.rate / 2)
        self.buff = queue.Queue()
        self.audio_interface = PyAudio()
        self.audio_stream = self.audio_interface.open(
             format=paFloat32,
             channels=1, rate=self.rate,
             input=True, frames_per_buffer=chunk,
             stream_callback=self._fill_buffer
        )

    def _fill_buffer(self, in_data, frame_count, time_info, status_flags):
        self.buff.put(in_data)
        return None, paContinue

    def generator(self):
        while True:
            chunk = self.buff.get()
            if chunk is None:
                return
            yield chunk

    def upload(self):
        seq = 0
        for chunk in self.generator():
            encoded = base64.b64encode(chunk).decode("utf-8")
            uploaded = api.upload_chunk(session_id=id, chunk_sequence=seq, audio_chunk=AudioChunk(encoded))
            seq = uploaded.chunk_sequence

#upload audio chunk from microphone in other thread
microphone = PyAudioSense()
thread = threading.Thread(target=microphone.upload)
thread.start()

#get results
next_token=""
while True:
    resp = api.read_status(session_id=id, next_token=next_token)
    for result in resp.inference.results:
        print(json.dumps(result.to_dict()))

    if "next_token" in resp.inference.page:
        next_token = resp.inference.page.next_token
    else:
        break