Semi working version
This commit is contained in:
parent
333ab8f82d
commit
a80bd0c480
3
.gitignore
vendored
3
.gitignore
vendored
@ -1,2 +1,5 @@
|
||||
/build/sdlamp2
|
||||
/build/sdlamp2.dSYM
|
||||
*.mp3
|
||||
*.m4a
|
||||
|
||||
|
||||
10
build.sh
10
build.sh
@ -1,11 +1,15 @@
|
||||
#!/bin/sh
|
||||
|
||||
pushd build
|
||||
pushd build 2>&1 >/dev/null
|
||||
|
||||
gcc -Wall -O0 -ggdb3 \
|
||||
gcc -Wall -Wno-unused -O0 -ggdb3 \
|
||||
-o sdlamp2 \
|
||||
`sdl2-config --cflags --libs` \
|
||||
`pkgconf --cflags --libs libavformat` \
|
||||
`pkgconf --cflags --libs libavcodec` \
|
||||
`pkgconf --cflags --libs libavutil` \
|
||||
`pkgconf --cflags --libs libswresample` \
|
||||
-lSDL2_image \
|
||||
../src/sdlamp2.c
|
||||
|
||||
popd
|
||||
popd 2>&1 >/dev/null
|
||||
|
||||
133
src/sdlamp2.c
133
src/sdlamp2.c
@ -1,25 +1,29 @@
|
||||
#include <libavcodec/avcodec.h>
|
||||
#include <libavformat/avformat.h>
|
||||
#include <libavutil/avutil.h>
|
||||
|
||||
#include "SDL.h"
|
||||
#include "SDL_image.h"
|
||||
|
||||
static SDL_Window *window = NULL;
|
||||
static SDL_Renderer *renderer = NULL;
|
||||
static SDL_Window* window = NULL;
|
||||
static SDL_Renderer* renderer = NULL;
|
||||
|
||||
static SDL_AudioDeviceID audio_device = 0;
|
||||
static Uint8 *wavbuf = NULL;
|
||||
static Uint8* wavbuf = NULL;
|
||||
static Uint32 wavlen = 0;
|
||||
static SDL_AudioSpec wavspec;
|
||||
static SDL_AudioStream *stream = NULL;
|
||||
static SDL_AudioStream* stream = NULL;
|
||||
// static SDL_bool paused = SDL_TRUE;
|
||||
static SDL_bool paused = SDL_FALSE;
|
||||
|
||||
static void panic_and_abort(const char *title, const char *text) {
|
||||
static void panic_and_abort(const char* title, const char* text) {
|
||||
fprintf(stderr, "PANIC: %s ... %s\n", title, text);
|
||||
SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_ERROR, title, text, window);
|
||||
SDL_Quit();
|
||||
exit(1);
|
||||
}
|
||||
|
||||
static SDL_bool load_audio_file(const char *fname) {
|
||||
static SDL_bool load_audio_file(const char* fname) {
|
||||
SDL_FreeAudioStream(stream);
|
||||
stream = NULL;
|
||||
SDL_FreeWAV(wavbuf);
|
||||
@ -27,24 +31,21 @@ static SDL_bool load_audio_file(const char *fname) {
|
||||
wavlen = 0;
|
||||
|
||||
if (SDL_LoadWAV(fname, &wavspec, &wavbuf, &wavlen) == NULL) {
|
||||
SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_ERROR, "Couldn't load wav file!",
|
||||
SDL_GetError(), window);
|
||||
SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_ERROR, "Couldn't load wav file!", SDL_GetError(),
|
||||
window);
|
||||
return SDL_FALSE;
|
||||
}
|
||||
|
||||
stream = SDL_NewAudioStream(wavspec.format, wavspec.channels, wavspec.freq,
|
||||
AUDIO_F32, 2, 48000);
|
||||
stream = SDL_NewAudioStream(wavspec.format, wavspec.channels, wavspec.freq, AUDIO_F32, 2, 48000);
|
||||
if (!stream) {
|
||||
SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_ERROR,
|
||||
"Couldn't create audio stream!", SDL_GetError(),
|
||||
SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_ERROR, "Couldn't create audio stream!", SDL_GetError(),
|
||||
window);
|
||||
SDL_FreeWAV(wavbuf);
|
||||
wavbuf = NULL;
|
||||
wavlen = 0;
|
||||
}
|
||||
|
||||
if (SDL_AudioStreamPut(stream, wavbuf, wavlen) ==
|
||||
-1) { // FIXME(m): graceful handling.
|
||||
if (SDL_AudioStreamPut(stream, wavbuf, wavlen) == -1) { // FIXME(m): graceful handling.
|
||||
panic_and_abort("Audio stream put failed!", SDL_GetError());
|
||||
}
|
||||
SDL_AudioStreamFlush(stream); // FIXME(m): error handling.
|
||||
@ -53,7 +54,76 @@ static SDL_bool load_audio_file(const char *fname) {
|
||||
return SDL_TRUE;
|
||||
}
|
||||
|
||||
int main(int argc, char **argv) {
|
||||
static SDL_bool decode_audio() {
|
||||
printf("libavutil version: %s\n", av_version_info());
|
||||
|
||||
// Trying to open and decode AAC / ALAC (.m4a file) with ffmpeg libraries
|
||||
AVFormatContext* pFormatContext = avformat_alloc_context();
|
||||
if (avformat_open_input(&pFormatContext, "./build/music.m4a", NULL, NULL) != 0) {
|
||||
printf("ERROR: could not open the file!\n");
|
||||
return SDL_FALSE;
|
||||
}
|
||||
printf("Format: %s\n", pFormatContext->iformat->long_name);
|
||||
|
||||
avformat_find_stream_info(pFormatContext, NULL);
|
||||
if (pFormatContext->nb_streams < 1) {
|
||||
printf("ERROR: no valid streams found in file!\n");
|
||||
return SDL_FALSE;
|
||||
}
|
||||
|
||||
AVCodecParameters* pLocalCodecParameters = pFormatContext->streams[0]->codecpar;
|
||||
if (pLocalCodecParameters->codec_type != AVMEDIA_TYPE_AUDIO) {
|
||||
printf("ERROR: no audio stream found in file!\n");
|
||||
return SDL_FALSE;
|
||||
}
|
||||
|
||||
printf("Audio stream: %d channels, sample rate %d\n",
|
||||
pLocalCodecParameters->ch_layout.nb_channels, pLocalCodecParameters->sample_rate);
|
||||
|
||||
const AVCodec* pLocalCodec = avcodec_find_decoder(pLocalCodecParameters->codec_id);
|
||||
printf("Codec: %s ID %d bit_rate %lld\n", pLocalCodec->long_name, pLocalCodec->id,
|
||||
pLocalCodecParameters->bit_rate);
|
||||
|
||||
AVCodecContext* pCodecContext = avcodec_alloc_context3(pLocalCodec);
|
||||
avcodec_parameters_to_context(pCodecContext, pLocalCodecParameters);
|
||||
avcodec_open2(pCodecContext, pLocalCodec, NULL);
|
||||
|
||||
AVPacket* pPacket = av_packet_alloc();
|
||||
AVFrame* pFrame = av_frame_alloc();
|
||||
|
||||
SDL_FreeAudioStream(stream);
|
||||
stream = NULL;
|
||||
wavlen = 0;
|
||||
|
||||
stream = SDL_NewAudioStream(AUDIO_F32, pLocalCodecParameters->ch_layout.nb_channels,
|
||||
pLocalCodecParameters->sample_rate, AUDIO_F32, 2, 48000);
|
||||
if (!stream) {
|
||||
SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_ERROR, "Couldn't create audio stream!", SDL_GetError(),
|
||||
window);
|
||||
}
|
||||
|
||||
while (av_read_frame(pFormatContext, pPacket) >= 0) {
|
||||
if (!avcodec_send_packet(pCodecContext, pPacket)) {
|
||||
avcodec_receive_frame(pCodecContext, pFrame);
|
||||
if (pFrame->linesize[0] > 0) {
|
||||
if (SDL_AudioStreamPut(stream, pFrame->data[0], pFrame->linesize[0]) ==
|
||||
-1) { // FIXME(m): graceful handling.
|
||||
panic_and_abort("Audio stream put failed!", SDL_GetError());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// printf("Frame %c (%lld) pts %lld dts %lld\n", av_get_picture_type_char(pFrame->pict_type),
|
||||
// pCodecContext->frame_num, pFrame->pts, pFrame->pkt_dts);
|
||||
}
|
||||
|
||||
SDL_AudioStreamFlush(stream); // FIXME(m): error handling.
|
||||
SDL_PauseAudioDevice(audio_device, paused);
|
||||
|
||||
return SDL_TRUE;
|
||||
}
|
||||
|
||||
int main(int argc, char** argv) {
|
||||
SDL_AudioSpec desired;
|
||||
SDL_bool running = SDL_TRUE;
|
||||
const SDL_Rect rewind_rect = {10, 10, 100, 100};
|
||||
@ -71,8 +141,8 @@ int main(int argc, char **argv) {
|
||||
panic_and_abort("SDL_Init failed!", SDL_GetError());
|
||||
}
|
||||
|
||||
window = SDL_CreateWindow("SDLamp2", SDL_WINDOWPOS_UNDEFINED,
|
||||
SDL_WINDOWPOS_UNDEFINED, 640, 480, 0);
|
||||
window =
|
||||
SDL_CreateWindow("SDLamp2", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, 640, 480, 0);
|
||||
if (!window) {
|
||||
panic_and_abort("SDL_CreateWindow failed!", SDL_GetError());
|
||||
}
|
||||
@ -94,15 +164,15 @@ int main(int argc, char **argv) {
|
||||
panic_and_abort("Could not open audio device!", SDL_GetError());
|
||||
}
|
||||
|
||||
load_audio_file("music.wav");
|
||||
// load_audio_file("music.wav");
|
||||
decode_audio();
|
||||
|
||||
SDL_Surface *controls_surface = IMG_Load("controls.png");
|
||||
SDL_Surface* controls_surface = IMG_Load("controls.png");
|
||||
if (controls_surface == NULL) {
|
||||
panic_and_abort("Could not load controls asset!", SDL_GetError());
|
||||
}
|
||||
|
||||
SDL_Texture *controls_texture =
|
||||
SDL_CreateTextureFromSurface(renderer, controls_surface);
|
||||
SDL_Texture* controls_texture = SDL_CreateTextureFromSurface(renderer, controls_surface);
|
||||
SDL_FreeSurface(controls_surface);
|
||||
if (controls_texture == NULL) {
|
||||
panic_and_abort("Could not load controls asset!", SDL_GetError());
|
||||
@ -119,16 +189,15 @@ int main(int argc, char **argv) {
|
||||
|
||||
case SDL_MOUSEBUTTONDOWN: {
|
||||
const SDL_Point pt = {e.button.x, e.button.y};
|
||||
if (SDL_PointInRect(&pt, &rewind_rect)) { // Pressed the "rewind" button
|
||||
if (SDL_PointInRect(&pt,
|
||||
&rewind_rect)) { // Pressed the "rewind" button
|
||||
SDL_ClearQueuedAudio(audio_device);
|
||||
SDL_AudioStreamClear(stream);
|
||||
if (SDL_AudioStreamPut(stream, wavbuf, wavlen) ==
|
||||
-1) { // FIXME(m): graceful handling.
|
||||
if (SDL_AudioStreamPut(stream, wavbuf, wavlen) == -1) { // FIXME(m): graceful handling.
|
||||
panic_and_abort("Audio stream put failed!", SDL_GetError());
|
||||
}
|
||||
SDL_AudioStreamFlush(stream); // FIXME(m): error handling.
|
||||
} else if (SDL_PointInRect(
|
||||
&pt,
|
||||
} else if (SDL_PointInRect(&pt,
|
||||
&play_pause_rect)) { // Pressed the "pause" button
|
||||
paused = paused ? SDL_FALSE : SDL_TRUE;
|
||||
SDL_PauseAudioDevice(audio_device, paused);
|
||||
@ -160,18 +229,14 @@ int main(int argc, char **argv) {
|
||||
SDL_RenderFillRect(renderer, &play_pause_rect);
|
||||
SDL_RenderFillRect(renderer, &fast_forward_rect);
|
||||
|
||||
SDL_RenderCopy(renderer, controls_texture, &rewind_symbol_rect,
|
||||
&rewind_rect);
|
||||
SDL_RenderCopy(renderer, controls_texture, &rewind_symbol_rect, &rewind_rect);
|
||||
SDL_RenderCopy(renderer, controls_texture, &stop_symbol_rect, &stop_rect);
|
||||
if (paused) {
|
||||
SDL_RenderCopy(renderer, controls_texture, &play_symbol_rect,
|
||||
&play_pause_rect);
|
||||
SDL_RenderCopy(renderer, controls_texture, &play_symbol_rect, &play_pause_rect);
|
||||
} else {
|
||||
SDL_RenderCopy(renderer, controls_texture, &pause_symbol_rect,
|
||||
&play_pause_rect);
|
||||
SDL_RenderCopy(renderer, controls_texture, &pause_symbol_rect, &play_pause_rect);
|
||||
}
|
||||
SDL_RenderCopy(renderer, controls_texture, &fast_forward_symbol_rect,
|
||||
&fast_forward_rect);
|
||||
SDL_RenderCopy(renderer, controls_texture, &fast_forward_symbol_rect, &fast_forward_rect);
|
||||
|
||||
SDL_RenderPresent(renderer);
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user