start sketching

This commit is contained in:
Green Sky 2024-04-24 22:29:08 +02:00
parent 2d4729a877
commit d52a1a44f8
No known key found for this signature in database
5 changed files with 138 additions and 0 deletions

View File

@ -74,6 +74,11 @@ add_executable(tomato
./chat_gui4.hpp ./chat_gui4.hpp
./chat_gui4.cpp ./chat_gui4.cpp
./content/content.hpp
./content/stream_reader.hpp
./content/stream_reader_sdl_audio.hpp
./content/stream_reader_sdl_audio.cpp
) )
target_compile_features(tomato PUBLIC cxx_std_17) target_compile_features(tomato PUBLIC cxx_std_17)

48
src/content/content.hpp Normal file
View File

@ -0,0 +1,48 @@
#pragma once
#include <entt/entity/registry.hpp>
#include <entt/entity/handle.hpp>
#include <entt/container/dense_set.hpp>
#include <solanaceae/contact/contact_model3.hpp>
#include <solanaceae/message3/registry_message_model.hpp>
#include <solanaceae/file/file2.hpp>
enum class Content1 : uint32_t {};
using ContentRegistry = entt::basic_registry<Content1>;
using ContentHandle = entt::basic_handle<ContentRegistry>;
namespace Content::Components {
// or something
struct TagFile {};
struct TagAudioStream {};
struct TagVideoStream {};
// the associated messages, if any
// useful if you want to update progress on the message
struct Messages {
std::vector<Message3Handle> messages;
};
// ?
struct SuspectedParticipants {
entt::dense_set<Contact3> participants;
};
struct ReadHeadHint {
// points to the first byte we want
// this is just a hint, that can be set from outside
// to guide the sequential "piece picker" strategy
// the strategy *should* set this to the first byte we dont yet have
uint64_t offset_into_file {0u};
};
} // Content::Components
// TODO: i have no idea
struct RawFile2ReadFromContentFactoryI {
virtual std::shared_ptr<File2I> open(ContentHandle h) = 0;
};

View File

@ -0,0 +1,15 @@
#pragma once
#include <solanaceae/util/span.hpp>
// most media that can be counted as "stream" comes in packets/frames/messages
// so this class provides an interface for ideal async fetching of frames
struct RawFrameStreamReaderI {
// return the number of ready frames in cache
// returns -1 if unknown
virtual int64_t have(void) = 0;
// get next frame, empty if none
virtual ByteSpan getNext(void) = 0;
};

View File

@ -0,0 +1,39 @@
#include "./stream_reader_sdl_audio.hpp"
SDLAudioFrameStreamReader::SDLAudioFrameStreamReader(int32_t buffer_size) : _buffer_size(buffer_size), _stream{nullptr, &SDL_DestroyAudioStream} {
_buffer.resize(_buffer_size);
const SDL_AudioSpec spec = { SDL_AUDIO_S16, 1, 48000 };
_stream = {
SDL_OpenAudioDeviceStream(SDL_AUDIO_DEVICE_DEFAULT_CAPTURE, &spec, nullptr, nullptr),
&SDL_DestroyAudioStream
};
}
Span<int16_t> SDLAudioFrameStreamReader::getNextAudioFrame(void) {
const int32_t needed_bytes = (_buffer.size() - _remaining_size) * sizeof(int16_t);
const auto read_bytes = SDL_GetAudioStreamData(_stream.get(), _buffer.data()+_remaining_size, needed_bytes);
if (read_bytes < 0) {
// error
return {};
}
if (read_bytes < needed_bytes) {
// HACK: we are just assuming here that sdl never gives us half a sample!
_remaining_size += read_bytes / sizeof(int16_t);
return {};
}
_remaining_size = 0;
return Span<int16_t>{_buffer};
}
int64_t SDLAudioFrameStreamReader::have(void) {
return -1;
}
ByteSpan SDLAudioFrameStreamReader::getNext(void) {
auto next_frame_span = getNextAudioFrame();
return ByteSpan{reinterpret_cast<const uint8_t*>(next_frame_span.ptr), next_frame_span.size};
}

View File

@ -0,0 +1,31 @@
#pragma once
#include "./stream_reader.hpp"
#include <SDL3/SDL.h>
#include <cstdint>
#include <cstdio>
#include <memory>
struct SDLAudioFrameStreamReader : public RawFrameStreamReaderI {
// count samples per buffer
const int32_t _buffer_size {1024};
std::vector<int16_t> _buffer;
size_t _remaining_size {0}; // data still in buffer, that was remaining from last call and not enough to fill a full frame
// meh, empty default
std::unique_ptr<SDL_AudioStream, decltype(&SDL_DestroyAudioStream)> _stream;
// buffer_size in number of samples
SDLAudioFrameStreamReader(int32_t buffer_size = 1024);
// data owned by StreamReader, overwritten by next call to getNext*()
Span<int16_t> getNextAudioFrame(void);
public: // interface
int64_t have(void) override;
ByteSpan getNext(void) override;
};