إعادة إنشاء صوت THX Deep Note Sound

إذا سبق لك أن زرت دار سينما ، فربما سمعت Deep Note ، علامة THX الصوتية التجارية . هذا هو أحد الأصوات الأولى التي يتم سماعها في بداية المقطورات في قاعات THX المعتمدة. لطالما أحببت تصعيده المميز ، بدءًا بمزيج غريب من الملاحظات وانتهى بخاتمة مشرقة وعظيمة ( صوت ). يا لها من فرحة للأذن!

بالأمس (ربما) كنت مهتمًا بأصل هذا الصوت بدون سبب ، وقمت ببعض البحث. لقد تأثرت بشدة بقصته التي أود مشاركتها معك. ثم نواصل - وسننشئ هذا الصوت بأنفسنا ، ونجهز المقص والغراء!

أفضل مصدر للمعلومات حول الصوت الذي يمكن أن أجده هو ، في رأيي ، تكوينه الصوتي الكهربائي الكامل ، المنشور في مدونة Music Thing الممتازة في عام 2005. هذا هو الرابط للمنشور

بعض الحقائق عن الصوت:

  • تم إنشاؤه من قبل الدكتور جيمس أندي مورر في عام 1982.
  • في أحد الأيام في التاريخ ، ضاعت 4000 مرة في اليوم ، كل 20 ثانية تقريبًا! اقتبس من الدكتور مورر:
    "أود أن أقول إن صوت THX هو العمل الأكثر شعبية لموسيقى الكمبيوتر في العالم. قد يكون ذلك صحيحًا أم لا ، ولكنه يبدو رائعًا! "
  • يتم إنشاؤه على كمبيوتر ASP (معالج إشارة الصوت) الذي يمكنه توليف الأصوات في الوقت الحقيقي.
  • قام برنامج مكون من 20000 سطر من كود C بإنشاء بيانات للتشغيل على ASP. تتألف البيانات التي تم إنشاؤها من 250.000 صف تمت معالجتها بواسطة ASP.
  • تستخدم مذبذبات الصوت نغمة التشيلو الرقمية كإشارة. يتذكر الدكتور مورر أنه كان هناك حوالي 12 توافقية في العينة. يمكن لـ ASP تشغيل 30 من هذه المذبذبات في الوقت الحقيقي (للمقارنة ، يمكن لجهاز الكمبيوتر المحمول الخاص بي الآن معالجة أكثر من 1000 من هذه دون فشل).
  • الصوت نفسه محمي بحقوق الطبع والنشر ، ولكن هنا تكمن المشكلة: يعتمد رمز الدكتور Murer على مولدات الأرقام العشوائية (العملية التوليدية) وفي كل مرة يكون الصوت مختلفًا قليلاً. لذلك ، لا أعتقد أنه من الآمن أن نقول أن العملية نفسها "يمكن أن تكون محمية بحقوق الطبع والنشر". الصوت نفسه ، نعم ، العينة المحددة محمية.
  • الصوت ظهر لأول مرة في مقطورة THX "عودة الجيداي" قبل عرضه الأول في عام 1983.
  • أصبحت الخصائص التوليدية للعملية في مرحلة ما إشكالية. بعد إصدار عودة الجيداي ، فقد سجل Deep Note الأصلي. أعاد دكتور مورر إعادة صياغة العمل للشركة ، لكنهم اشتكوا باستمرار من أنه لا يبدو الأصلي. في النهاية ، تم العثور على التسجيل الأصلي وتخزينه في مكان آمن.
  • د. طلب دري الإذن لاستخدام العينة في موسيقاه ، ولكن تم رفضه. استخدمه على أي حال وحصل على دعوى قضائية.
  • في عمل Metastaseis بواسطة Janis Xenakis (1954) ، يوجد ذروة افتتاحية مشابهة جدًا (كما هو الحال في الأعمال الأخرى لمختلف الملحنين). لكنه يبدأ بنبرة واحدة وينتهي بمجموعة نغمية شبه معدلة بدلاً من أن تكون متناسقة تمامًا ، كما هو الحال في Deep Note. يمكن سماع التسجيل الصوتي من طلب البراءة هنا .

تأكد من الاستماع إلى الصوت ، لأنه عندما نقوم بإعادة إنشاء Deep Note ، سنشير إلى هذا التسجيل بالذات.

فيما يلي بعض الحقائق التقنية / النظرية قبل الشروع في التوليف السليم:

  • ملاحظتي: عند الدخول الأصلي من الموقع الإلكتروني لمكتب براءات الاختراع ، تكون النغمة الرئيسية بين D و Eb ، وفي الإصدارات الأحدث تكون القيمة الأساسية بين E و F. سنستخدم الثابت الأصلي D / Eb. عادة ما تكون الخيارات الجديدة أقصر ، إن لم تكن مخطئة. من الواضح أنني أفضل الخيار الذي تم إيداعه لدى مكتب براءات الاختراع.
  • وفقًا للدكتور مورر (وأكدته أذني أيضًا) ، يبدأ الجزء بمذبذبات مضبوطة على ترددات عشوائية بين 200 هرتز و 400 هرتز. لكن المذبذبات ليست مجرد طنين - يتم تعديل تردداتها بشكل عشوائي ، وتستخدم مرشحات تنعيم لتنعيم التحولات العشوائية للنغمات. يستمر هذا حتى بداية التصعيد.
  • داخل الهلال وفي نهاية جزء الصوت ، لا تزال العشوائية تعدل ترددات المذبذبات ، لذلك لا يوجد أي منها مستقر في أي وقت. لكن نطاق المسح العشوائي ضيق للغاية لدرجة أنه يضيف ببساطة صوتًا طبيعيًا / كوراليًا.
  • يتذكر د. مورير أنه كان هناك حوالي 12 توافقية مميزة في طيف صوت التشيلو الرقمي.
  • على حد علمي ، لم يتم نشر قيم المولد (التي تم استخدامها للحصول على حقوق النشر) كتابةً. يقول الدكتور مورر إنه يستطيع تسجيلها إذا حصلنا على إذن من THX. ولكن أعتقد أنه ليس من الضروري إعادة الصوت.
  • الصوت في النهاية (تقنيًا ليس وترًا) - في أذني ، مجرد إضافة ثماني نغمات أساسية. لذا ، عند إعادة البناء ، نبدأ بمذبذبات مضبوطة عشوائيًا (بين 200 و 400 هرتز) ، ونقوم بعملية مسح معقدة أو أكثر أو أقل من خلال تطبيق أوكتاف على الملعب بين انخفاض D / Eb.

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

//30 ,    ( { var numVoices = 30; //generating initial random fundamentals: var fundamentals = {rrand(200.0, 400.0)}!numVoices; Mix ({|numTone| var freq = fundamentals[numTone]; Pan2.ar ( Saw.ar(freq), rrand(-0.5, 0.5), //stereo placement of voices numVoices.reciprocal //scale the amplitude of each voice ) }!numVoices); }.play; ) 

لقد اخترت 30 مذبذبًا لتوليد الصوت ، وفقًا لقدرات كمبيوتر ASP ، كما قال الدكتور مورير. لقد قمت بإنشاء مجموعة من 30 ترددًا عشوائيًا بين 200 و 400 هرتز ، ووزعتها بشكل عشوائي على مجال الاستريو باستخدام Pan2.ar مع الوسيطة rrand (-0.5 ، 0.5) ، الترددات المخصصة لمذبذبات سن المنشار (30 نسخة). هكذا تبدو .

إذا درست المعلومات من دكتور مورر و / أو استمعت بعناية للجزء الأصلي ، يمكنك سماع أن ترددات المذبذب تتحول بشكل عشوائي لأعلى ولأسفل. أود أن أضيف هذا التأثير للحصول على صوت أكثر عضوية. مقياس التردد لوغاريتمي ، لذلك في الترددات المنخفضة يجب أن يكون هناك نطاقات تذبذب أضيق من تلك الموجودة في النطاقات الأعلى. يمكن القيام بذلك عن طريق فرز تردداتنا التي تم إنشاؤها عشوائيًا باستخدام LFNoise2 (التي تولد قيمًا عشوائية مقسمة بشكل رباعي) من وسيطات مول بالترتيب داخل ماكرو Mix الخاص بنا. وأضفت أيضًا مرشح تمرير منخفض للمذبذبات بتردد قطع يبلغ خمسة أضعاف تردد المذبذب ومتوسط ​​1 / q:

 //    , ,    ( { var numVoices = 30; //sorting to get high freqs at top var fundamentals = ({rrand(200.0, 400.0)}!numVoices).sort; Mix ({|numTone| //fundamentals are sorted, so higher frequencies drift more. var freq = fundamentals[numTone] + LFNoise2.kr(0.5, 3 * (numTone + 1)); Pan2.ar ( BLowPass.ar(Saw.ar(freq), freq * 5, 0.5), rrand(-0.5, 0.5), numVoices.reciprocal ) }!numVoices); }.play; ) 

إليك كيف تبدو العينة بأحدث التعديلات.

تبدو هذه بالفعل نقطة بداية جيدة ، لذلك دعونا نبدأ في تنفيذ عملية مسح ، وقحة جدًا في البداية. لتنفيذ عملية مسح ، تحتاج أولاً إلى تحديد الترددات النهائية لكل مذبذب. إنها ليست بسيطة للغاية ، ولكنها ليست صعبة للغاية. يجب أن تكون النغمة الرئيسية بين انخفاض D و Eb ، لذا فإن متوسط ​​التردد لهذه النغمة سيكون 14.5 (0 هو C ، يحسب لونيًا ، بدون أول أوكتاف). لذا بالنسبة لـ 30 مذبذبًا ، نترجم الترددات العشوائية بين 200 و 400 هرتز إلى قيمة 14.5 والأوكتافات المقابلة. بالإذن ، اخترت أول 6 أوكتافات. لذا ، فإن المجموعة النهائية للترددات هي كما يلي:

 (numVoices.collect({|nv| (nv/(numVoices/6)).round * 12; }) + 14.5).midicps; 

سنستخدم عملية المسح من 0 إلى 1. يتم ضرب الترددات العشوائية بالقيمة (1 − ) ، ويتم ضرب الترددات المستهدفة في عملية المسح نفسها. لذلك ، عندما يكون المسح هو 0 (البداية) ، فسيكون التردد عشوائيًا. عندما تكون عملية المسح 0.5 ، يتبين (( + ) / 2) ، وعندما تكون 1 ، فسيكون التردد هو القيمة النهائية. هنا هو الرمز المعدل:

 //   (),    ( { var numVoices = 30; var fundamentals = ({rrand(200.0, 400.0)}!numVoices).sort; var finalPitches = (numVoices.collect({|nv| (nv/(numVoices/6)).round * 12; }) + 14.5).midicps; var sweepEnv = EnvGen.kr(Env([0, 1], [13])); Mix ({|numTone| var initRandomFreq = fundamentals[numTone] + LFNoise2.kr(0.5, 3 * (numTone + 1)); var destinationFreq = finalPitches[numTone]; var freq = ((1 - sweepEnv) * initRandomFreq) + (sweepEnv * destinationFreq); Pan2.ar ( BLowPass.ar(Saw.ar(freq), freq * 5, 0.5), rrand(-0.5, 0.5), numVoices.reciprocal //scale the amplitude of each voice ) }!numVoices); }.play; ) 

الصوت هنا .

كما قلت ، هذا مسح تقريبي للغاية. يزيد خطيا من 0 إلى 1 ، وهو ما لا يتفق مع التكوين الأصلي. ربما لاحظت أيضًا أن آخر أوكتاف يبدو فظيعًا لأنه يتم ضبطه على أوكتاف مثالية ويندمج مع بعضها مثل النغمات الأساسية والإيقاعات. سنقوم بإصلاح ذلك عن طريق إضافة تأرجح عشوائي في المرحلة النهائية - تمامًا كما تم في البداية ، وسيبدو أكثر عضوية.

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

 sweepEnv = EnvGen.kr(Env([0, 0.1, 1], [5, 8], [2, 5])); 

هنا ، يستغرق الانتقال من 0 إلى 0.1 5 ثوانٍ ، والانتقال من 0.1 إلى 1 يستغرق 8 ثوانٍ. يتم تعيين انحناءات هذه الأجزاء على 2 و 5. في وقت لاحق نستمع إلى ما حدث ، ولكن أولاً نحتاج إلى إصلاح الفواصل الزمنية مرة أخرى. كما كان من قبل ، نضيف تذبذبات عشوائية باستخدام LFNoise2 ، يتناسب نطاقها مع التردد النهائي للمذبذب. هذا سيجعل الحلقة النهائية أكثر عضوية. هنا هو الرمز المعدل:

 //     ( { var numVoices = 30; var fundamentals = ({rrand(200.0, 400.0)}!numVoices).sort; var finalPitches = (numVoices.collect({|nv| (nv/(numVoices/6)).round * 12; }) + 14.5).midicps; var sweepEnv = EnvGen.kr(Env([0, 0.1, 1], [5, 8], [2, 5])); Mix ({|numTone| var initRandomFreq = fundamentals[numTone] + LFNoise2.kr(0.5, 3 * (numTone + 1)); var destinationFreq = finalPitches[numTone] + LFNoise2.kr(0.1, (numTone / 4)); var freq = ((1 - sweepEnv) * initRandomFreq) + (sweepEnv * destinationFreq); Pan2.ar ( BLowPass.ar(Saw.ar(freq), freq * 8, 0.5), rrand(-0.5, 0.5), numVoices.reciprocal ) }!numVoices); }.play; ) 

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

أنا حقا لا أحب نمط المسح هذا. تحتاج إلى تمديد البداية وتسريع الانتهاء. أو الانتظار ... هل من الضروري حقًا تنفيذ نفس الدائرة لجميع المذبذبات؟ على الاطلاق لا! يجب أن يكون لكل مذبذب دائرته الخاصة بقيم مختلفة قليلاً من الوقت والانحناء - أنا متأكد من أنه سيكون أكثر إثارة للاهتمام. لا تزال النغمات عالية التردد لمجموعة منشار المنشار العشوائي مزعجة بعض الشيء ، لذلك نضيف إلى النتيجة الإجمالية مرشح تمرير منخفض ، يتم التحكم في قطعه بواسطة قيمة "خارجية" عالمية لا علاقة لها بدوائر المذبذب. هنا هو الرمز المعدل:

 // .      ( { var numVoices = 30; var fundamentals = ({rrand(200.0, 400.0)}!numVoices).sort; var finalPitches = (numVoices.collect({|nv| (nv/(numVoices/6)).round * 12; }) + 14.5).midicps; var outerEnv = EnvGen.kr(Env([0, 0.1, 1], [8, 4], [2, 4])); var snd = Mix ({|numTone| var initRandomFreq = fundamentals[numTone] + LFNoise2.kr(0.5, 3 * (numTone + 1)); var destinationFreq = finalPitches[numTone] + LFNoise2.kr(0.1, (numTone / 4)); var sweepEnv = EnvGen.kr( Env([0, rrand(0.1, 0.2), 1], [rrand(5.0, 6), rrand(8.0, 9)], [rrand(2.0, 3.0), rrand(4.0, 5.0)])); var freq = ((1 - sweepEnv) * initRandomFreq) + (sweepEnv * destinationFreq); Pan2.ar ( BLowPass.ar(Saw.ar(freq), freq * 8, 0.5), rrand(-0.5, 0.5), numVoices.reciprocal ) }!numVoices); BLowPass.ar(snd, 2000 + (outerEnv * 18000), 0.5); }.play; ) 

تغيير صغير جعل الفحص أكثر إثارة للاهتمام. يساعد مرشح التمرير المنخفض 2000 هرتز على ترويض الكتلة الأولية. هكذا تبدو .

بقي شيء آخر سيجعل العملية أكثر إثارة للاهتمام. تذكر ، قمنا بفرز مذبذبات عشوائية في البداية؟ حسنًا ، يمكننا الآن فرزها بترتيب عكسي والتأكد من أن المذبذبات بترددات عشوائية أعلى تنتهي في الأصوات المنخفضة بعد الهبوط والعكس صحيح. سيؤدي هذا إلى إضافة المزيد من "الحركة" إلى التصعيد ويتسق مع كيفية هيكلة الجزء الأصلي. لست متأكدًا من أن دكتور مورر قام ببرمجتها بهذه الطريقة ، ولكن هناك هذه العملية في السجل ، ويبدو الأمر رائعًا ، سواء كان منتجًا عشوائيًا لعملية مولدة أو خيارًا خاصًا. (أوه ، هل قلت ذلك؟ إذا كانت العملية توفر مثل هذا الخيار ، فهذا هو الخيار ... أم لا؟). وبالتالي ، سنقوم بتغيير ترتيب الفرز وهيكل الشفرة بحيث تنخفض أسنان المنشار ذات الترددات العالية إلى أصوات منخفضة في النهاية ، والعكس صحيح.

شيء آخر: تحتاج إلى صوت أعلى. الآن كل الأصوات لها نفس السعة. أريد أن تبدو الأصوات المنخفضة أعلى وأكثر تلاشيًا بما يتناسب مع الزيادة في التردد. لذلك ، نقوم بتعديل حجة mul لـ Pan2 وفقًا لذلك. أعد ضبط ترددات القطع لمرشحات التمرير المنخفض للمذبذبات الفردية. وسوف أقوم بإضافة مخطط قياس السعة الذي سيتم تفعيله بسلاسة ويختفي في النهاية ، ويتحرر من الخداع. بعض الإعدادات العددية هنا وهناك - وإليك الرمز النهائي:

 // init sort,   ,   ,    ( { var numVoices = 30; var fundamentals = ({rrand(200.0, 400.0)}!numVoices).sort.reverse; var finalPitches = (numVoices.collect({|nv| (nv/(numVoices/6)).round * 12; }) + 14.5).midicps; var outerEnv = EnvGen.kr(Env([0, 0.1, 1], [8, 4], [2, 4])); var ampEnvelope = EnvGen.kr(Env([0, 1, 1, 0], [3, 21, 3], [2, 0, -4]), doneAction: 2); var snd = Mix ({|numTone| var initRandomFreq = fundamentals[numTone] + LFNoise2.kr(0.5, 6 * (numVoices - (numTone + 1))); var destinationFreq = finalPitches[numTone] + LFNoise2.kr(0.1, (numTone / 3)); var sweepEnv = EnvGen.kr( Env([0, rrand(0.1, 0.2), 1], [rrand(5.5, 6), rrand(8.5, 9)], [rrand(2.0, 3.0), rrand(4.0, 5.0)])); var freq = ((1 - sweepEnv) * initRandomFreq) + (sweepEnv * destinationFreq); Pan2.ar ( BLowPass.ar(Saw.ar(freq), freq * 6, 0.6), rrand(-0.5, 0.5), (1 - (1/(numTone + 1))) * 1.5 ) / numVoices }!numVoices); Limiter.ar(BLowPass.ar(snd, 2000 + (outerEnv * 18000), 0.5, (2 + outerEnv) * ampEnvelope)); }.play; ) 

وهنا التسجيل النهائي للعمل .

يمكنك المقارنة مع الأصل .

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



نعم ، وهنا شيء آخر قمت به من أجل المتعة. تذكر ، لقد أخبرتك أن الأمر استغرق 20000 سطر من كود C لإنشاء النسخة الأصلية. أنا متأكد تمامًا أن الدكتور مورر كان عليه أن يكتب كل شيء يدويًا ، لذلك هذا الرقم ليس مفاجئًا. لكن كما تعلمون ، بسبب شعبية تويتر ، نحن نحاول ضغط كل شيء في 140 حرفًا من التعليمات البرمجية. من أجل المتعة ، حاولت إعادة إنتاج العناصر الأساسية للتكوين في 140 حرفًا من الرمز. أعتقد أن العينة لا تزال تبدو رائعة ، إليك الرمز (هنا بالنغمة الرئيسية F / E):

 play{Mix({|k|k=k+1/2;2/k*Mix({|i|i=i+1;Blip.ar(i*XLine.kr(rand(2e2,4e2),87+LFNoise2.kr(2)*k,15),2,1/(i/a=XLine.kr(0.3,1,9))/9)}!9)}!40)!2*a} 

وها هو الصوت الذي يولده هذا الإصدار.

في مستند واحد - كل التعليمات البرمجية من هذه الصفحة لتجاربك.

تصاعدي جيد ، أصدقاء!

Source: https://habr.com/ru/post/ar426949/


All Articles