سؤال

أحرز بعض التقدم على أخذ صوت مضغوط (MP3) وحفظه كما PCM. بالإضافة إلى ذلك، أردت تقسيم الملف الأصلي إلى قطع ثانيتين لفترة طويلة، داخل نفس العملية. يبدو أنني ناجح، لكنني مرتبك قليلا عن السبب.

كما قرأت كتل من الصوت واكتب الملفات خارجا، أتحقق من معرفة ما إذا كنت على وشك كتابة قطعة من شأنها أن تجعل ملفي يتجاوز الحد الثاني الثاني. إذا كان الأمر كذلك، أكتب ما يكفي للوصول إلى ثانيتين، ثم أغلق الملف، ثم افتح ملف جديد واكتب الباقي في الملف الجديد، ثم قراءة المزيد من البيانات. شيء من هذا القبيل:

framesInTimedSegment += numFrames;
if ((framesInTimedSegment  > (2.0 * sampleRate)) && (j < 5)) {
    UInt32 newNumFrames = numFrames;
    numFrames = framesInTimedSegment - (2.0 * sampleRate);
    newNumFrames -= numFrames;
// Question A
    UInt32 segmentOffset = newNumFrames * numChannels * 2;
    error = ExtAudioFileWrite(segmentFile, newNumFrames, &fillBufList);
// Question B
       // handle this error!  We might have an interruption
    if (segmentFile) ExtAudioFileDispose(segmentFile);
    XThrowIfError(ExtAudioFileCreateWithURL(urlArray[++j], kAudioFileCAFType, &dstFormat, NULL, kAudioFileFlags_EraseFile, &breakoutFile), "ExtAudioFileCreateWithURL failed! - segmentFile");
    size = sizeof(clientFormat);
    XThrowIfError(ExtAudioFileSetProperty(segmentFile, kExtAudioFileProperty_ClientDataFormat, size, &clientFormat), "couldn't set destination client format"); 
    fillBufList.mBuffers[0].mData = srcBuffer + segmentOffset;
    fillBufList.mBuffers[0].mDataByteSize = numFrames * fillBufList.mBuffers[0].mNumberChannels * 2;
    framesInTimedSegment = numFrames;
}
error = ExtAudioFileWrite(segmentFile, numFrames, &fillBufList);

فيما يلي أسئلتي (حاولت تسمية الخط المعني):

ج: هل هناك طريقة أفضل للعثور على الإزاحة في المخزن المؤقت الخاص بي، لذلك أنا لا أخطئ الكود الصعب بعض القيمة هناك؟ على سبيل المثال، هل هناك طريقة مباركة للحصول على إزاحة البيانات من رقم الإطار؟

ب: إذا كان التنبأ ExtAudioFile يقوم بالتحويل من مضغوط إلى إلغاء ضغطه، فإن البيانات التي أكتبها لم يتم إلغاء ضغطها بعد (أليس كذلك؟)، لذلك لا يجب أن تقلق بشأن اللعب بأرقام الإطار والإزاحات عندما أتعامل معها البيانات المضغوطة؟ يجب علي بدلا من ذلك تحويل الملف أولا، إما إلى ملف PCM أو في الذاكرة، ثم قم بتقسيم هذا PCM؟

شكرا!

-Mahboud.

ملاحظة.

يتم تعريف ClientFormat على النحو التالي:

        clientFormat = dstFormat;

و dstformat:

        dstFormat.mFormatID = outputFormat;
        dstFormat.mChannelsPerFrame = srcFormat.NumberChannels();
        dstFormat.mBitsPerChannel = 16;
        dstFormat.mBytesPerPacket = dstFormat.mBytesPerFrame = 2 * dstFormat.mChannelsPerFrame;
        dstFormat.mFramesPerPacket = 1;
        dstFormat.mFormatFlags = kLinearPCMFormatFlagIsPacked | kLinearPCMFormatFlagIsSignedInteger; // little-endian
هل كانت مفيدة؟

المحلول

من الصعب الإجابة بشكل صحيح دون رؤية رمز أكثر قليلا. ولكن، على افتراض ClientFormat هو تنسيق PCM Interleaved:

ب) extaudiofilewrite لا يؤدي التحويل من مضغوط إلى إلغاء ضغط الضغط، ExtAudioFileread - اعتمادا على تنسيق العميل الذي قمت بتعيينه. على افتراض ملف مصدر MP3 و "قياسي" 16 بت يتم ذلك تحت غطاء محرك السيارة باستخدام APIs AudioFile و Audioconverter.

أ) هذا من الصعب بعض الشيء الإجابة دون رؤية كيف يتم تعريف srcbuffer (أفترض مجموعة من int16_t). إذا كنت تعمل مع بيانات PCM، فما الذي تبذله يبدو جيدا. يمكنك أيضا استخدام NewnumFrames * clientformat.mbytesperframe * clientformat.mchannelperframe، ولكن على افتراض بيانات PCM 16 بت، mbytesperframe == mbytesperpacket == 2. إذا كنت تعمل مع بيانات غير CBR، فستحتاج إلى القلق بنفسك مع أوصاف الحزمة، ولكن لا يبدو أن هذا هو الحال.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top