मैं सफलतापूर्वक रास्ता माइक Seymour प्रस्तावित में libmp3lame का इस्तेमाल किया है: मैं एक आदर्श रूपांतरण जब मैं इस bash कमांड का इस्तेमाल किया गया। अब मैं एन्कोडिंग को गति देने के लिए पॉज़िक्स थ्रेड का उपयोग करके एक ही दृष्टिकोण का उपयोग करने की कोशिश कर रहा हूं। मैं एक lame_t पॉइंटर को बढ़िया कर रहा हूं, और रूपांतरण के बिट्स कर रहे कई थ्रेड हैं, यह ध्यान रखना कि प्रत्येक थ्रेड में पीसीएम ट्रैक का एक अद्वितीय बिट है जो ट्रांसकोड करता है।
मैं एक वैश्विक lame_t संरचना का उपयोग करता हूं जिसका उपयोग प्रत्येक थ्रेड में एन्कोडिंग के लिए किया जाता है। मेरा कोड 1 थ्रेड (कोई समानांतर निष्पादन) के लिए काम नहीं करता है, यह भी काम करता है अगर मैं समानांतर मोड में थ्रेड सृजन में देरी करता हूं (जैसे कि कोई समांतर निष्पादन नहीं है, लेकिन डेटा संरचनाएं सरणी हैं)।
जब मैं समानांतर मोड में मेरी कोड चलाने के लिए, मैं इस तरह के
Internal buffer inconsistency. flushbits <> ResvSizebit reservoir error:
l3_side->main_data_begin: 5440
Resvoir size: 4088
resv drain (post) 1
resv drain (pre) 184
header and sideinfo: 288
data bits: 1085
total bits: 1374 (remainder: 6)
bitsperframe: 3336
This is a fatal error. It has several possible causes:90% LAME compiled with buggy version of gcc using advanced optimizations 9% Your system is overclocked 1% bug in LAME encoding libraryfinished encoding
Internal buffer inconsistency. flushbits <> ResvSizefinished encoding
referernce के लिए के रूप में त्रुटियों की एक बहुत कुछ मिलता है, मैं कोड है कि मैं उपयोग कर रहा हूँ, कि ठीक संकलित देते हैं।
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <math.h>
#include <iostream>
#include <string>
#include <lame/lame.h>
#include <pthread.h>
#include <thread>
#include <chrono>
using namespace std;
typedef struct Data{
lame_t lame;
FILE * wav_file;
short int * pcm_buffer;
unsigned char * mp3_buffer;
unsigned long mp3_buffer_size;
unsigned long first_sample;
unsigned long n_samples;
unsigned long items_read;
unsigned long mp3_bytes_to_write;
pthread_mutex_t *mutexForReading;
} Data;
void *encode_chunk(void *arg)
{
Data * data = (Data *) arg;
unsigned long offset = 40 + 2 * 2 * data->first_sample;
pthread_mutex_lock(data->mutexForReading);
fseek(data->wav_file, offset, SEEK_SET);
data->items_read = fread(data->pcm_buffer, 2*sizeof(short int) , data->n_samples, data->wav_file);
cout << "first sample " << data->first_sample << " n_samples "<< data->n_samples << " items read " << data->items_read << " data address " << data << " mp3 a " << static_cast<void *> (data->mp3_buffer) << endl;
pthread_mutex_unlock(data->mutexForReading);
if (data->items_read != 0)
{
data->mp3_bytes_to_write = lame_encode_buffer_interleaved(data->lame,
data->pcm_buffer,
data->items_read,
data->mp3_buffer,
data->mp3_buffer_size);
}
cout << "finished encoding " << endl;
return NULL;
}
int main(int argc, char * argv[])
{
int read,write;
FILE *wav = fopen("test.wav", "rb");
FILE *mp3 = fopen("file.mp3", "wb");
fseek(wav,0,SEEK_END);
unsigned long file_size_wav = ftell(wav);
unsigned long bytes_PCM = file_size_wav - 40;
unsigned long n_total_samples = bytes_PCM/4;
const unsigned long MAX_SAMPLE_NUMBER = pow(2,10);
const unsigned short NTHREADS = 2;
const unsigned long MAX_MP3_SIZE = int(MAX_SAMPLE_NUMBER * 1.25 + 7200) + 1;
short int pcm_buffer[NTHREADS][MAX_SAMPLE_NUMBER * 2]; // 2 channels
unsigned char mp3_buffer[NTHREADS][MAX_MP3_SIZE]; // according to libmp3lame api
lame_t lame = lame_init();
lame_set_in_samplerate(lame, 44100);
lame_set_VBR(lame, vbr_default);
// lame_set_brate(lame, 128); // only for CBR mode
// lame_set_quality(lame, 2);
// lame_set_mode(lame, JOINT_STEREO); // 1 joint stereo , 3 mono
lame_init_params(lame);
Data data_ptr[NTHREADS];
unsigned short n_main_loops = n_total_samples/MAX_SAMPLE_NUMBER/NTHREADS + 1;
cout << "total samples " << n_total_samples << endl;
cout << "Number of iterations in main loop : " << n_main_loops << endl;
unsigned long samples_remaining = n_total_samples;
unsigned long current_sample = 0;
pthread_t threadID[NTHREADS];
pthread_mutex_t mutexForReading = PTHREAD_MUTEX_INITIALIZER;
for (unsigned long i = 0 ; i < n_main_loops; i ++)
{
for (unsigned short j = 0; j < NTHREADS; j++)
{
Data data;
data.lame = lame;
data.wav_file = wav;
data.pcm_buffer = pcm_buffer[j];
data.mp3_buffer = mp3_buffer[j];
data.first_sample = current_sample;
data.n_samples = min(MAX_SAMPLE_NUMBER, n_total_samples - current_sample);
data.mutexForReading = &mutexForReading;
current_sample += data.n_samples;
samples_remaining -= data.n_samples;
data_ptr[j] = data;
if (data_ptr[j].n_samples > 0)
{
cout << "creating " << i << " " << j << " " << data_ptr[j].first_sample << " " << data_ptr[j].n_samples << endl;
pthread_create(&threadID[j],
NULL,
encode_chunk,
(void *) (&data_ptr[j]));
}
}
for (unsigned short j = 0; j < NTHREADS; j++)
{
if (data_ptr[j].n_samples > 0)
{
pthread_join(threadID[j], NULL);
}
}
for (unsigned short j = 0; j< NTHREADS; j++)
if (data_ptr[j].n_samples > 0)
{
fwrite(data_ptr[j].mp3_buffer, data_ptr[j].mp3_bytes_to_write, 1, mp3);
}
else
{
data_ptr[j].mp3_bytes_to_write = lame_encode_flush(lame, data_ptr[j].mp3_buffer, data_ptr[j].mp3_buffer_size);
}
}
lame_close(lame);
fclose(mp3);
fclose(wav);
}
शायद किसी को पता है कि समानांतर कोड में इस तरह से लंगड़ा का उपयोग नहीं किया जा सकता है। अगर यह संभव है या नहीं तो मुझे कोई संकेत नहीं मिला।
समस्या यह प्रतीत होती है कि वैश्विक lame_t संरचना को एक ही समय में कई धागे द्वारा उपयोग किया जाता है। मैंने सोचा कि यह केवल पढ़ा जाएगा, इसलिए कोई समस्या नहीं है, लेकिन मुझे गलत लगता है।
मैंने यह भी सोचा कि प्रत्येक धागे के लिए lame_t ऑब्जेक्ट बनाने के लिए एक वर्कअराउंड हो सकता है। मैंने कोशिश की, थ्रेड का उपयोग मूल WAV फ़ाइल के परस्पर अनन्य बिट्स को एन्कोड करने के लिए किया।
कोड संकलित करता है और समस्याओं के बिना चलता है, लेकिन परिणामी फ़ाइल में कोई आवाज नहीं है।
यदि कोई दिलचस्पी है, तो मैं कोड जोड़ सकता हूं। यह उपरोक्त कोड का मामूली संशोधन है जिसमें lame_t आकार NTHREADS की सरणी है।
लंगड़ा सूत्रों काफी बड़े के बावजूद , पूर्ण स्रोत सीखने की कोई आवश्यकता नहीं है। आपको केवल तंग पार्सिंग कमांड लाइम पैरामीटर और आंतरिक लंग संरचनाओं के लिए उनके मानचित्रण की आवश्यकता है। – VitalyVal