Browse Source

more experimentation

master
hex 3 years ago
parent
commit
1f5be031c1
2 changed files with 215 additions and 2 deletions
  1. 5
    0
      CMakeLists.txt
  2. 210
    2
      src/main.c

+ 5
- 0
CMakeLists.txt View File

@@ -0,0 +1,5 @@
cmake_minimum_required (VERSION 2.6)
project (hmp)
set(CMAKE_BUILD_TYPE Debug)
add_executable(hmp src/main.c)
target_link_libraries(hmp ao m avcodec avformat avutil swresample microhttpd)

+ 210
- 2
src/main.c View File

@@ -1,5 +1,213 @@

#include <stdio.h>
#include <string.h>
#include <ao/ao.h>
#include <math.h>

#include <libavutil/opt.h>
#include <libavcodec/avcodec.h>
#include <libavformat/avformat.h>
#include <libswresample/swresample.h>

#define BUF_SIZE 4096

#include <sys/types.h>
#include <sys/select.h>
#include <sys/socket.h>
#include <microhttpd.h>

#define PORT 8888

int decode_audio_file(const char* path, char** data, int* size) {
//initialize things
av_register_all();

//get format
AVFormatContext* format = avformat_alloc_context();
if (avformat_open_input(&format, path, NULL, NULL)) {
fprintf(stderr, "Could not open file '%s'\n", path);
return -1;
}

if (avformat_find_stream_info(format, NULL) < 0) {
fprintf(stderr, "Could not retrieve stream info from file '%s'", path);
return -1;
}

//get stream
int stream_index = -1;
for (int i=0; i<format->nb_streams; ++i) {
if(format->streams[i]->codec->codec_type == AVMEDIA_TYPE_AUDIO) {
stream_index = i;
break;
}
}

if (stream_index == -1) {
fprintf(stderr, "Could not retrieve stream from file '%s'", path);
return -1;
}

AVStream* stream = format->streams[stream_index];
//open codec
AVCodecContext* codec = stream->codec;

//initialize resampler
struct SwrContext* swr = swr_alloc();
av_opt_set_int(swr, "in_channel_count", codec->channels, 0);
av_opt_set_int(swr, "out_channel_count", 2, 0);
av_opt_set_int(swr, "in_channel_layout", codec->channel_layout, 0);
av_opt_set_int(swr, "out_channel_layout", AV_CH_LAYOUT_STEREO, 0);
av_opt_set_int(swr, "in_sample_rate", codec->sample_rate, 0);
av_opt_set_int(swr, "out_sample_rate", 44100, 0);
av_opt_set_int(swr, "in_sample_fmt", codec->sample_fmt, 0);
av_opt_set_int(swr, "out_sample_fmt", AV_SAMPLE_FMT_S16, 0);
swr_init(swr);
if (!swr_is_initialized(swr)) {
fprintf(stderr, "Resampler not properly initialized!");
return -1;
}
AVPacket packet;
av_init_packet(&packet);
AVFrame* frame = av_frame_alloc();
if (!frame) {
fprintf(stderr, "Unable to allocate frame");
return -1;
}

//iterate through frames
*data = NULL;
*size = 0;

while(av_read_frame(format, &packet) >= 0) {
int gotFrame;
printf("test");
if (avcodec_decode_audio4(codec, frame, &gotFrame, &packet) < 0) {
break;
}

printf("test2");
if (!gotFrame) {
continue;
}

//resample frames
char* buffer;
av_samples_alloc((uint8_t**) &buffer,
NULL,
2,
frame->nb_samples,
AV_SAMPLE_FMT_S16, 0);

int frame_count = swr_convert(swr,
(uint8_t**) &buffer,
frame->nb_samples,
(const uint8_t**) frame->data,
frame->nb_samples);
//append resampled frames to data
*data = (char*) realloc(*data,
(*size + frame->nb_samples) * sizeof(char) * 2);
memcpy(*data + *size, buffer, frame_count * sizeof(char) * 2);
*size += frame_count;
}
return 0;
}

// play 44.1/16 PCM data
int play_pcm_data(char* data, int size) {
ao_device *device;
ao_sample_format format;
int default_driver;
char *buffer;
int buf_size;
int sample;
float freq = 440.0;
int i;

/* -- Initialize -- */

fprintf(stderr, "libao example program\n");

ao_initialize();

/* -- Setup for default driver -- */

default_driver = ao_default_driver_id();

memset(&format, 0, sizeof(format));
format.bits = 16;
format.channels = 2;
format.rate = 44100;
format.byte_format = AO_FMT_LITTLE;

/* -- Open driver -- */
device = ao_open_live(default_driver, &format, NULL /* no options */);
if (device == NULL) {
fprintf(stderr, "Error opening device.\n");
return 1;
}

/* -- Play some stuff -- */
buf_size = format.bits/8 * format.channels * format.rate;
buffer = calloc(buf_size,
sizeof(char));

for (i = 0; i < format.rate; i++) {
sample = (int)(0.75 * 32768.0 *
sin(2 * M_PI * freq * ((float) i/format.rate)));

/* Put the same stuff in left and right channel */
buffer[4*i] = buffer[4*i+2] = sample & 0xff;
buffer[4*i+1] = buffer[4*i+3] = (sample >> 8) & 0xff;
}
ao_play(device, buffer, buf_size);

/* -- Close and shutdown -- */
ao_close(device);

ao_shutdown();
return 0;
}

int answer_to_connection (void *cls, struct MHD_Connection *connection,
const char *url,
const char *method, const char *version,
const char *upload_data,
size_t *upload_data_size, void **con_cls)
{
const char *page = "<html><body>Hello, browser!</body></html>";
struct MHD_Response *response;
int ret;

response = MHD_create_response_from_buffer (strlen (page),
(void*) page, MHD_RESPMEM_PERSISTENT);

ret = MHD_queue_response (connection, MHD_HTTP_OK, response);
MHD_destroy_response (response);

return ret;
}

int main(int argc, char **argv)
{
struct MHD_Daemon *daemon;

daemon = MHD_start_daemon (MHD_USE_SELECT_INTERNALLY, PORT, NULL, NULL,
&answer_to_connection, NULL, MHD_OPTION_END);
if (NULL == daemon) return 1;

getchar ();

int main() {
printf("Hello World!\n");
MHD_stop_daemon (daemon);
return 0;
/*
char* data;
int size;
decode_audio_file("song.webm", &data, &size);
return (0);
*/
}

Loading…
Cancel
Save