Skip to content

Instantly share code, notes, and snippets.

@njh
Created November 11, 2012 18:48
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save njh/4055841 to your computer and use it in GitHub Desktop.
Save njh/4055841 to your computer and use it in GitHub Desktop.
TwoLame concurrency test tool
// TwoLame concurrency test tool
//
// Convert an input file to raw using:
// sox music.wav -r 44100 -b 16 -e signed-integer -t raw music.raw
//
// Run a single-threaded test to get expected MD5SUM:
// twolame -r music.raw - | md5sum -b
//
// Compile using:
// cc -o tct twolame-concurrency-test.c -I/usr/local/include -ltwolame -lcrypto -pthread -Wall
//
// Then multi-threaded test run:
// ./tct music.raw
//
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <pthread.h>
#include <twolame.h>
#include <openssl/md5.h>
// Threading settings
#define NUMBER_THREADS (20)
// Audio settings
#define NUMBER_CHANNELS (2)
#define INPUT_BUFFER_SIZE (1152)
#define OUTPUT_BUFFER_SIZE (1024)
void print_md5_sum(unsigned char* md) {
int i;
for(i=0; i <MD5_DIGEST_LENGTH; i++) {
printf("%02x",md[i]);
}
printf("\n");
}
void* encode_file(void* arg)
{
twolame_options *opts = twolame_init();
short int input_buffer[INPUT_BUFFER_SIZE];
unsigned char output_buffer[OUTPUT_BUFFER_SIZE];
unsigned char md5_result[MD5_DIGEST_LENGTH];
const char* filename = (const char*)arg;
FILE* input = NULL;
MD5_CTX md5;
// Configure encoder
twolame_set_in_samplerate(opts, 44100);
twolame_set_num_channels(opts, NUMBER_CHANNELS);
twolame_set_bitrate(opts, 192);
twolame_set_psymodel(opts, 3);
MD5_Init(&md5);
if (twolame_init_params(opts)) {
printf("Failed to initialise encoder.\n");
return NULL;
}
input = fopen(filename, "rb");
if (!input) {
perror("Failed to open file:");
return NULL;
}
while(!feof(input)) {
size_t samples_read = fread(input_buffer, sizeof(short), INPUT_BUFFER_SIZE, input);
int encoded_bytes = 0;
// Encode a frame
samples_read /= NUMBER_CHANNELS;
encoded_bytes = twolame_encode_buffer_interleaved(opts, input_buffer, samples_read, output_buffer, OUTPUT_BUFFER_SIZE);
// Update the MD5
if (encoded_bytes) {
MD5_Update(&md5, output_buffer, encoded_bytes);
}
}
fclose(input);
twolame_close(&opts);
// Display the MD5
MD5_Final(md5_result, &md5);
print_md5_sum(md5_result);
pthread_exit(NULL);
return NULL;
}
int main( int argc, char** argv )
{
const char* inputfile = NULL;
pthread_t threads[NUMBER_THREADS];
int result;
int n;
if (argc < 2) {
printf("Usage: tct <filename.raw>\n");
exit(-1);
} else {
inputfile = argv[1];
printf("Input file: %s\n", inputfile);
}
// Start multiple encoding threads
for(n=0; n<NUMBER_THREADS; n++) {
// Delay for a random amount (0 - 1 second)
int rand = (((float)random() / RAND_MAX) * 1000000);
usleep(rand);
// Start the encoder thread
printf("Starting thread %d\n", n);
result = pthread_create(&threads[n], NULL, encode_file, (void*)inputfile);
if (result) {
perror("Failed to start thread\n");
}
}
// Wait for threads to complete
for(n=0; n<NUMBER_THREADS; n++) {
if (threads[n]) {
result = pthread_join(threads[n], NULL);
if (result) {
perror("pthread_join() failed");
} else {
printf("Thread %d completed.\n", n);
}
}
}
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment