èæ¯
ã®ã¿ãŒçšã«èªåã®ãã¥ãŒããŒãæžããšããã¢ã€ãã¢ã¯ãç§ã倧åŠã«ãã10幎ã»ã©åã®ããªãåã«æãã€ããŸããã ããã«ã¯ããã€ãã®çç±ããããŸããã
- ãŸããããã»ã©é«å質ã®ãã¥ãŒããŒããã°ã©ã ã¯ããã»ã©å€ããããŸãããäžéšã¯åã«åšæ³¢æ°ã誀ã£ãŠæ±ºå®ããããäžéšã®åŒŠã§éåžžã«äžå®å®ã«åäœããŸãã ããã«ãç§ãåºäŒã£ããã¹ãŠã®ãã¥ãŒããŒã¯ãA440ã«äºåã«èª¿æŽãããŠããŸãïŒ æåã®ãªã¯ã¿ãŒã㧠440 Hzã«èª¿æŽãããŠããå ŽåïŒã ãã ããC256ã®èšå®ããããŸãïŒ æåã®ãªã¯ã¿ãŒããŸã§ 256 Hzã«èª¿æŽãããŠããŸã ïŒã å€ãã®ãã¥ãŒããŒã¯ãã¬ããã®ãã¥ãŒãã³ã°ãèš±å¯ããŠããŸãããã5ã7ãã¬ããã§æŒå¥ããå¿ èŠãããå Žåã¯ãåããã¬ããã§æ¥œåšããã¥ãŒãã³ã°ããããšããå§ãããŸãã
- 第äºã«ãã¹ã©ã€ããŒãã¹ãã¯ãã«ãŸãã¯åšæ³¢æ°æ³¢åœ¢ã®åœ¢ã§ã®èšå®ã®èŠèŠåã¯ãç§ã®æèŠã§ã¯ãå°ãç©ççã§ãã ããŒã«ã«ãã£ãŠçæãããæ³¢ãã©ã®ããã«çŽæ¥èŠããã-ã©ãã ãããããããŸãã¯ãã®éã®æªã¿ã瀺ãããã£ãã®ã§ãã èŠèŠåãšå¿çãèŠèŠåããŸãã
- 第äžã«ãç§ã¯å€§åŠã§åŸãããDSPã®åéã§ã®ç§ã®ç¥èã人é¡ã®å©çã«é©çšãããã£ãã
äžè¬çã«ããã®ã¢ã€ãã¢ã¯é·ãéé ã«ãããŸãããããããã空ãæéãiOsããã€ã¹ãã¢ãã€ã«éçºã®çµéšããã£ãã®ã§ãä»å¹Žããå®çŸã§ããŸããã§ããã
çè«ã®ããã
ãšãŒãããã®åŒŠæ¥œåšã«å°ã粟éããŠãã人ãªã誰ã§ããå匊ãç¹å®ã®é³ã«åãããããŠãããç¹å®ã®åšæ³¢æ°ããã®é³ã«å¯Ÿå¿ããŠããããšãç¥ã£ãŠããŸãã é³ç¬Šãšåšæ³¢æ°ã®éãã¯ãåé³ç¬Šã«é³æ¥œçãªæ©èœãããããšã§ãã ãããŠããã®æ©èœã¯ãä»ã®é³ã«å¯Ÿããé³ã®çžå¯Ÿçãªäœçœ®ã«ãã£ãŠæ±ºãŸããŸããããšãã°ã Cã¡ãžã£ãŒã·ãŒã±ã³ã¹ã®ããŒãtoã¯ã ãããã¯ã®åœ¹å²ãæãããŸãã ã¡ã€ã³ã§æãå®å®ãããµãŠã³ãã ãã®é³ç¬Šãå°ãåããå Žåããã®æ©èœã倱ããŸãã æœåºãããé³ãé³ç¬Šã«å¯Ÿå¿ããããã«ã¯ãé³ç¬Šã®ééãšåšæ³¢æ°ã®æ¯çã®éã®å³å¯ãªå¯Ÿå¿é¢ä¿ã芳å¯ããå¿ èŠããããŸãã æœåºãããé³ãšé³ç¬Šã«èšèŒãããé¢æ°ã®å¯Ÿå¿ã¯ã匊ã«ãã£ãŠçæãããåšæ³¢æ°ã®ç²ŸåºŠãšå®å®æ§ã«äŸåããŸãã
匊ã«ãã£ãŠçæãããé³ã¯äœã§ããïŒ ã¢ã¡ãªã«ã®ç 究è ã§ããäœæ²å®¶ã®ãŠã©ãžããŒã«ã»ãŠãµãã§ãã¹ããŒãæåã®ã·ã³ã»ãµã€ã¶ãŒã«ææ¡ããADSRã¢ãã«ã䜿çšãããšã匊ã®é³ã¯äœããã®ãšã³ãããŒãã§å€èª¿ããã調åæ¯åã«ãªããŸãã ãã®ãšã³ãããŒãã¯ADSRãšåŒã°ããŸãã 4ã€ã®ç¹åŸŽçãªãã€ã³ãããããŸãïŒæ»æïŒ è±èªã®æ»æ ïŒãè¡°éïŒ è±èªã®æžè¡° ïŒãæç¶ïŒ è±èªã®æç¶ ïŒãæžè¡°ïŒ è±èªã®ãªãªãŒã¹ ïŒã
ãµã¹ãã€ã³ééã¯ãåšæ³¢æ°ãæãæ確ã«äŒããŸãã æ¯å¹ ã¯ã»ãšãã©å€åããã«å€åããŸãã ã®ã¿ãŒãçæ³çãªå調é³ãçæããå ŽåãADSRãšã³ãããŒããèæ ®ã«å ¥ãããšããã®ãããªæ¯åã®ã¹ãã¯ãã«ã¯çãã¹ããªããã®åœ¢ã«ãªããŸãã ãã®ã¹ããªããã®åœ¢ç¶ã¯ããšã³ãããŒãã¹ãã¯ãã«ã«å¯Ÿå¿ããŸãã
ããããå®éã®æ©åšã¯éç·åœ¢æ¯åããã»ã¹ãçæãããã®çµæãåé³ãšåŒã°ããè¿œå ã®é«èª¿æ³¢ãçŸããŸãã
ãããã®åé³ã¯ãããªãæœè¡æ§ã®ãã仲éã®æ è¡è ã§ãã ãããã¯åºæ¬é³ã«åããåšæ³¢æ°ã®æ±ºå®ã劚ããå¯èœæ§ããããŸãã ããããããã§ããéåžžãã¡ã€ã³ããŒã³ã¯è¿œå ã®æäœãªãã§æ確ã«å®çŸ©ãããŸãã
ãããã£ãŠããããã®è¡šçŸã«åºã¥ããŠãããã°ã©ã ãåäœãããã¹ãæŠèª¬ã§ããŸãã
- é³æ³¢ã®ããŒãªãšå€æãèšç®ãã
- ã¹ãã¯ãã«ã®åºæ¬é³ãèŠã€ãã
- ãããåšæ³¢æ°ãèšç®ãã
å®åšæ³¢ã«ã€ããŠ
éåžžãã°ã©ãäžã®é³ã¯æéæåŒãšããŠè¡šãããŸãã 暪軞ã®ãŒãç¹ã§ã¯ãå€ã¯èŠ³æž¬ã®æåã®ç¬éã«ããããããã1ç§ã2ç§ãªã©åŸã«èŠ³æž¬ãããå€ã«ãªããŸãã ãã®å Žåã®æž¬å®ããã»ã¹ã¯ãå·Šããå³ã«åäžã«ç§»åããæ¶ç©ºã®ãã¬ãŒã ãšããŠæ³åã§ããŸãã ãã®ãã¬ãŒã ã¯å¥ã®ååã§åŒã³åºãããšãã§ããŸãïŒèŠ³æž¬ãŠã£ã³ããŠïŒ è±èªã®èŠ³æž¬ãŠã£ã³ã㊠ïŒã芳枬ééïŒ è±èªã®èŠ³æž¬éé ïŒãæéãŠã£ã³ããŠïŒ è±èªã®æéãŠã£ã³ã㊠ïŒ-ãããã®çšèªã¯ãã¹ãŠåãããšãæå³ããŸãã
ãããã£ãŠããã¬ãŒã ã«ããã枬å®ããã»ã¹ãã©ã®ããã«è¡ãããã©ã®ç¬éããã¬ãŒã ã®æåã«è¡šç€ºãããã©ã®ç¬éãæåŸã«è¡šç€ºãããããç解ã§ããŸãã ããã«åºã¥ããŠã座æšç³»ãšãã¬ãŒã ãæ¯èŒãããšã©ããªããæ³åã§ããŸããé³æ³¢ã¯ã°ã©ãã®å³åŽã«è¡šç€ºãããå·ŠåŽã«æ¶ããããã«æããŸãã ãã®ãããªæ³¢ã¯é²è¡ãšåŒã°ããŸãïŒ
ããããé³æ³¢ã®ãã®ãããªè¡šçŸã¯æçã§ã¯ãããŸããããªããªãã æ³¢ã¯éåžžã«éãåãããšãã§ããŸãã ç§ãã¡ã®ä»äºã¯ãã©ããããããæ³¢ãæ¢ããããšã§ãã æ³¢ãæ¢ãŸãããã«ã¯ããã®é床ã0ã«çããããšãå¿ èŠã§ãã æ³¢ã«ã¯2ã€ã®é床ããããŸãããã§ãŒãºãšã°ã«ãŒãã§ãã2çš®é¡ã®å®åšæ³¢ãååŸã§ããŸãã
ã°ã«ãŒãé床ããŒãã«çããå®åšæ³¢ã¯ããã®ãšã³ãããŒããåžžã«1ã€ã®å Žæã«æ®ããšããäºå®ã«ãã£ãŠç¹åŸŽä»ããããŸãã ãããåæã«ãæ¯åã¯æ¢ãŸããŸãã-ãŒããšãã³ãã¯æšªåº§æšã«æ²¿ã£ãŠåãç¶ããŸãã æããã«ããã®ãããªæ³¢ã¯ç§ãã¡ã«ã¯é©ããŠããªãããªããªã èå³æ·±ãã®ã¯ãADSRãšã³ãããŒãã®å éšãã€ãŸãããµã¹ãã€ã³ã¢ãŒãã§æ¯åã芳枬ãããç¬éã§ãã
ãããè¡ãã«ã¯ãäœçžé床ããŒãã®å¥ã®ã¿ã€ãã®å®åšæ³¢ããããŸãã
äœçžé床ããŒãã®å ŽåãããŒããšãã³ãã¯åžžã«1ãæã«çãŸããããé«èª¿æ³¢æ¯åã®åœ¢ç¶ãç°¡åã«ç¢ºèªããŠãçæ³çãªæ£åŒŠæ³¢åœ¢ç¶ã«ã©ãã ãè¿ãããè©äŸ¡ã§ããŸãã ãã®ãããªæ³¢ãåŸãããã®ã¢ã«ãŽãªãºã ã¯æããã§ãïŒ
- ããã段éãèŠã€ãã
- 衚瀺ãããæ³¢ãäœçžããšã«ã·ããããŸã
å®è£
ãã€ã¯é²é³
å®éãAppleã¯Objective-C / Swiftããå€ãã®é«ã¬ãã«ã®ãã«ãã¡ãã£ã¢æ©èœãæäŸããŠããŸãã ããããæ¬è³ªçã«ããµãŠã³ãã®æäœã¯Audio Queue Servicesãäžå¿ã«å±éãããŸãã
Audio Queue Servicesã¯ã以åã«Sound Managerããã³OS Xã§æäŸãããŠããæ©èœãšåæ§ã®æ©èœãæäŸããŸããåæãªã©ã®è¿œå æ©èœãè¿œå ããŸãã Sound Managerã¯OS X v10.5ã§éæšå¥šã«ãªãã64ãããã¢ããªã±ãŒã·ã§ã³ã§ã¯æ©èœããŸããã Audio Queue Servicesã¯ããã¹ãŠã®æ°èŠéçºããã³æ¢åã®Macã¢ããªã®Sound Managerã®ä»£æ¿ãšããŠæšå¥šãããŸãã
ãœãŒã¹
ããããããªãé«ã¬ãã«ã®ãœãªã¥ãŒã·ã§ã³ã§ãã£ãSoundManagerãšã¯ç°ãªããAudio Queue Servicesã¯ãSwift Cã³ãŒããåçŽã«ç¹°ãè¿ãäžåšçšãªã©ãããŒã§ãã
func AudioQueueNewInput(_ inFormat: UnsafePointer<AudioStreamBasicDescription>, _ inCallbackProc: AudioQueueInputCallback, _ inUserData: UnsafeMutablePointer<Void>, _ inCallbackRunLoop: CFRunLoop!, _ inCallbackRunLoopMode: CFString!, _ inFlags: UInt32, _ outAQ: UnsafeMutablePointer<AudioQueueRef>) -> OSStatus
Swiftã«ã¯äœã¬ãã«ã®ã³ãŒãããã®å©çã¯ãªãããããªãŒãã£ãªãã£ããã£ã¯è£å©Cã³ãŒãã«ä»»ããŸããã ãããã¡ç®¡çã®ãã€ããŒã³ãŒããçç¥ããå Žåãã¬ã³ãŒãã®ã»ããã¢ããã¯ãAudioQueueNewInputé¢æ°ã䜿çšããŠAQRecorderStateæ§é äœãåæåããããšã§ãã
void AQRecorderState_init(struct AQRecorderState* aq, double sampleRate, size_t count){ aq->mDataFormat.mFormatID = kAudioFormatLinearPCM; aq->mDataFormat.mFormatFlags = kLinearPCMFormatFlagIsPacked | kLinearPCMFormatFlagIsSignedInteger; aq->mDataFormat.mSampleRate = sampleRate; aq->mDataFormat.mChannelsPerFrame = 1; aq->mDataFormat.mBitsPerChannel = 16; aq->mDataFormat.mFramesPerPacket = 1; aq->mDataFormat.mBytesPerPacket = 2;// for linear pcm aq->mDataFormat.mBytesPerFrame = 2; AudioQueueNewInput(&aq->mDataFormat, HandleInputBuffer, aq, NULL, kCFRunLoopCommonModes, 0, &aq->mQueue); DeriveBufferSize(aq->mQueue, &aq->mDataFormat, (double)count / sampleRate, // seconds &aq->bufferByteSize); for (int i = 0; i < kNumberBuffers; ++i) { AudioQueueAllocateBuffer(aq->mQueue, aq->bufferByteSize, &aq->mBuffers[i]); AudioQueueEnqueueBuffer(aq->mQueue, aq->mBuffers[i], 0, NULL); } aq->mCurrentPacket = 0; aq->mIsRunning = true; aq->buffer = Buffer_new(32768); aq->preview_buffer = Buffer_new(5000); AudioQueueStart(aq->mQueue, NULL); }
ããŒã¿ã®èšé²ã¯ãHandleInputBufferé¢æ°ãä»ããŠè¡ãããŸãã Buffer_write_intsãåŒã³åºããšãããŒã¿ãintããfloatã«å€æãããããã«åŠçããããã«ãããã¡ãŒã«ä¿åãããŸãã
static void HandleInputBuffer ( void *aqData, AudioQueueRef inAQ, AudioQueueBufferRef inBuffer, const AudioTimeStamp *inStartTime, UInt32 inNumPackets, const AudioStreamPacketDescription *inPacketDesc ) { struct AQRecorderState* pAqData = (struct AQRecorderState*)aqData; if(inNumPackets == 0 && pAqData->mDataFormat.mBytesPerPacket != 0) inNumPackets = inBuffer->mAudioDataByteSize / pAqData->mDataFormat.mBytesPerPacket; const SInt16* data = inBuffer->mAudioData; Buffer_write_ints(pAqData->buffer, data, inNumPackets); Buffer_write_ints(pAqData->preview_buffer, data, inNumPackets); if (pAqData->mIsRunning == 0) return; AudioQueueEnqueueBuffer(pAqData->mQueue, inBuffer, 0, NULL); }
ããã©ãŒãã³ã¹ã®åé¡ãšSwift
åœåãã¢ã€ãã¢ã¯Swiftèšèªã100ïŒ äœ¿çšããããšã§ããã äžè¬çã«ãç§ã¯ããããAccelerateã©ã€ãã©ãªã®å®è£ ã䜿çšãããFFTãé€ãSwiftã®ãã¹ãŠã®ã³ãŒããæžãçŽããŸããã ããããå¥åŠãªããšã«ãSwiftããŒãžã§ã³ã¯ããã»ããµæéã®95ïŒ ã®é åã§å€§ããªè² è·ãçºçãããä¿¡å·åŠçã®é 延ã«ããã¬ã³ããªã³ã°ãéåžžã«é ããªããŸããã
ãã¡ããããã®åœ¢åŒã§ã¯ãã¢ããªã±ãŒã·ã§ã³ã¯äœ¿çšã«é©ããŠããªãããããã¹ãŠã®ä¿¡å·åŠçãAccelerateã©ã€ãã©ãªãŒã«å®å šã«è»¢éããå¿ èŠããããŸããã ãããããã®åŸã§ããè² è·ã¯äŸç¶ãšããŠé«ããŸãŸã§ããã 1ã€ã®ãã¹ã®ã¿ãå¿ èŠãšããé åã䜿çšããŠããããã®æäœãCã«è»¢éããå¿ èŠããããŸããã ç·åœ¢ã©ã³ã¿ã€ã ã 説æã®ããã«ãSwiftãšCã§åãã³ãŒãã瀺ããŸãã
class Processing{ ... func getFrequency() -> Double { var peak: Double = 0 var peakFrequency: Double = 0 for i in 1..<spectrum.count/2 { var spectrumValue: Double = p->spectrum[i] var f: Double = fd * i / spectrum.count if (spectrumValue > peak) { peak = spectrum[i] peakFrequency = f } } return peakFrequency } }
double get_frequency(p* processing){ double peak = 0; double peakFrequency = 0; for(size_t i = 1; i < p.spectrumLength / 2; i ++){ double spectrumValue = p->spectrum[i]; double f = p->fd * i / p->spectrumLength; if (spectrumValue > peak) { peak = spectrum; peakFrequency = f; } } return peakFrequency; }
äžè¬ã«ã1ç§éã«20ã³ãŒã«ã®é »åºŠã®ãµã€ã¯ã«ã§ã¢ã¬ã€ãç°¡åã«ééããŠããããã€ã¹ã«ããªãã®è² è·ããããå¯èœæ§ããããŸãã
ããããããã¯Swiftã®æåã®ããŒãžã§ã³ã®åé¡ã§ããããæçµçã«ã¯ãããåäœã®æäœãå®è¡ãããã¹ãŠãSwiftããå®å šã«é€å€ããå¿ èŠããããŸããã ãã®ãããSwiftã§ã¯ãé åã®äœæãCã§èšè¿°ãããè£å©ã©ã€ãã©ãªãžã®åŒãæž¡ããããã³OpenGL ES 2ã§ã®ã³ãŒãã®ã¬ã³ããªã³ã°ãæ åœããæ åœè ã¯1人ã ãã§ããã
ããããSwiftã¯åœ¹ã«ç«ã¡ãŸãããïŒ ãã¡ãããé«ã¬ãã«ã®ã¿ã¹ã¯ã«é¢ããŠã¯ãSwiftã¯ãã®çœ°éã«å¯ŸåŠããŸãã ã³ãŒãã®èšè¿°ã¯ã¯ããã«å¿«é©ã§ãããææ°ã®æ§æã§ã¯ãã»ãã³ãã³ãäžå®ã§ãªããå€ãã®çŽæçã§äŸ¿å©ãªæ§æç³ãå¿ èŠã§ãã ãããã£ãŠãSwiftã䜿çšãããšããã€ãã®åé¡ãçºçãããšããäºå®ã«ãããããããäžè¬çã«ããã®èšèªã¯éåžžã«åªããŠããããã«èŠããŸããã
ãã€ã¯æ床ã®åé¡
ãã®ãããCã§ã³ãŒãã®äžéšãæžãæããåŸãã®ã¿ãŒããã¥ãŒãã³ã°ã§ããç¬éãè¿ã¥ããŠããããã«èŠããŸããã ãããããã®åŸãç§ã¯ãŸã£ããèããªãã£ãå¥ã®ãã©ãã«ãçºçããŸããã iPhoneã®ãã€ã¯ã¯ãã¹ãã¯ãã«ã®äœåšæ³¢éšåãã²ã©ãã«ããããŸãã ãã¡ãããã¹ããŒããã©ã³ã®ãã€ã¯ã¯çæ³ãšã¯ã»ã©é ããã®ãšæ³å®ããŸãããããã¹ãŠãã¯ããã«æªãããšãå€æããŸããã éå¡ã¯ãã§ã«200 Hzã§å§ãŸããŸããã
ã®ã¿ãŒã®ãã¥ãŒãã³ã°ã«é¢ããŠã¯ããã®ãããªåšæ³¢æ°å¿çã®åŠšå®³ã«ããã6匊ã®ãã¥ãŒãã³ã°ãäžå¯èœã«ãªããŸãã åšæ³¢æ°ã¯çŽ80 Hzã§ãã ãã®åŒ±äœåã«ãããåºæ¬é³ã¯åšæ³¢æ°160 Hzã240 Hzãªã©ã®é«èª¿æ³¢ã§æ²ã¿å§ããŸãã
ãã®åé¡ã«å¯Ÿãã2ã€ã®å¯èœãªè§£æ±ºçãããã«æŠèª¬ããŸããã
- 0.5ã®åšæ³¢æ°ã®åºæ¬åšæ³¢æ°ã§ååãçŸããå Žåãããã¯åºæ¬é³ãæ¶é³ãããŠããããšã瀺ããçµæã®åšæ³¢æ°ã調æŽããŠ1 / 2fã«ããå¿ èŠããããŸãã
- ãŠãŒã¶ãŒã匊ã®ããŒã³ãããããã«é«ãåšæ³¢æ°ãã«ããããããŒãã¹ãã£ã«ã¿ãŒã§åé³ãæå¶ããããšãã§ããŸã
æåã®ãªãã·ã§ã³ã¯ãã£ãšé¢çœããã ããªããªãã ãŠãŒã¶ãŒã®è¿œå ã®åªåã¯å¿ èŠãããŸããã§ããã ããã«ããããããã圌ã¯å®å šã«è£çŠã§ã¯ãªãã£ãã å€ãã®æªãç¶æ³ã«ã€ãªãããŸããã ããšãã°ãäž»åšæ³¢æ°ããã€ã¯ã«ãã£ãŠéåžžã«åŒ·ãã«ããããããã®æåã®é«èª¿æ³¢ã®1ã2ïŒ ã®ã¬ãã«ã«ãªãããšããããŸããã ããã«ã ã®ã¿ãŒã®ã¬ãŸããŒã¿ãŒã¯éåžžã«éç·åœ¢ãªããã€ã¹ã§ããããã2çªç®ã3çªç®ãããã«ã¯4çªç®ã®é«èª¿æ³¢ãæ¯å¹ ã§ç«¶åãå§ãããšãç¶æ³ããã°ãã°çºçããŸããã ããã«ãããããŒã³ã¯ã¡ã€ã³ã®ããŒã³ããã4åé«ããã£ããã£ããããšããäºå®ã«è³ããŸããã
ååãšããŠããããã®åé¡ã¯ããã°ã©ã ã§è§£æ±ºã§ããŸãã 倱æã®äž»ãªåå ã¯ãã®ã¿ãŒã®åé³ãéåžžã«å€§ããåãããããããã調æŽããŠã±0.1 Hzã®ç²ŸåºŠãåŸãããªãããšã§ãã ããã¯æããã«ãã¡ã€ã³ããŒã³ãããªãå®å®ããåšæ³¢æ°ã®åŒŠã«ãã£ãŠèšå®ããããšããäºå®ã«ãããã®ã§ãããéã«ãé«èª¿æ³¢ã¯äž»ã«ã®ã¿ãŒããã£ã®æ¯åã®ããã«ãµããŒãããã匊ã®é³äžã«æ°ãã«ããããããšããããŸãã
ãããã£ãŠãæåã®æ±ºå®ã¯ãããäºæž¬å¯èœã§å©äŸ¿æ§ã®äœã決å®ã®ããã«æŸæ£ãããªããã°ãªããŸããã§ããã ãã®ãããããŒãã¹ãã£ã«ã¿ãŒã®åšæ³¢æ°å¿çã¯ã»ãŒæ¬¡ã®ããã«ãªããŸãã
ã«ãããªãåšæ³¢æ°ã®å³åŽã®é害ç©ã¯åé³ãæå¶ããããããåã³åºããªãããã«ããŸãã ä¿¡å·å¯Ÿéé³æ¯ã®ãã®å šäœçãªäœäžã®ä»£äŸ¡ã¯æ¯æããããã®çµæã粟床ã¯ãããã«äœäžããŸããã蚱容ç¯å²å ã§ãã
粟床ãšããã©ãŒãã³ã¹
ããžã¿ã«ä¿¡å·åŠçã§ã¯ã芳枬ãŠã£ã³ããŠã®ãµã€ãºãéžæããã¿ã¹ã¯ãåžžã«ãããã¢ããããŸãã 倧ããªèŠ³æž¬ãŠã£ã³ããŠã䜿çšãããšãããå€ãã®æ å ±ãåéããŠãä¿¡å·ãã©ã¡ãŒã¿ãŒã®æ£ç¢ºã§å®å®ããæšå®ãè¡ãããšãã§ããŸãã äžæ¹ãããã¯ãäžåºŠã«å€æ°ã®ãµã³ãã«ãä¿åããã³åŠçããå¿ èŠããããšããäºå®ã«å ããŠãä¿¡å·åŠçã®æ¯äŸé 延ã«èµ·å ããå€ãã®åé¡ãåŒãèµ·ãããŸãã
åæ§ã«ãAccelerateã§ã¯ã32,768ãµã³ãã«ãè¶ ããªãã·ãŒã±ã³ã¹ã®ã¹ãã¯ãã«ãèšç®ã§ããŸãã ãããããã®ãããªæ°ã®ã«ãŠã³ãã¯ãã¹ãã¯ãã«å ã®åšæ³¢æ°ã°ãªããã®ã¹ããããçŽ1.35 Hzã§ããããšãæå³ããŸãã äžæ¹ã§ãããã¯ãããšãã°ã 440 Hzã®åšæ³¢æ°ãæã€æåã®ãªã¯ã¿ãŒã ãã€ãŸã éããŠããæåã®æååïŒæã现ãïŒã§ååŸãããããŒãã ãããã6çªç®ã®æååã§ã¯ããã®ãããªééãã¯èŽåœçã§ãã ããšãã°ã 倧ããªãªã¯ã¿ãŒãã®miãšã倧ããªãªã¯ã¿ãŒãã®éã«ããã®ã¯ 3 Hzã ãã§ãã ã€ãŸã 1.35 Hzã®ãšã©ãŒã¯ãããŒã³ã®ååã®ãšã©ãŒã§ãã
ããã«ããããããããã®åé¡ã®è§£æ±ºçã¯éåžžã«ç°¡åã§ãããæéåšæ³¢æ°åæã®ãã«ãã¯ãŒã瀺ããŠããŸãã ãªããªã æ°ç§ã®ä¿¡å·ãèç©ããããšã¯äžå¯èœã§ãããããããŒãªãšå€æãç¹°ãè¿ããŠåºæ¬åšæ³¢æ°ã®ã¹ãã¯ãã«ã®å€ãèç©ã§ããŸãã æ°åŠçã«ã¯ãçµæã¯åºæ¬åšæ³¢æ°ã§1.35 Hzã®ãã£ã«ã¿ãŒãåŠçããã®ãšåçã§ãã è€éãªèªã¿åãå€ã16åãããªããããçµæã®ç²ŸåºŠã16åã«ã§ããŸãã æ倧çŽ0.08 Hzã§ããããã«æ£ç¢ºãªÂ±0.1 Hzã§ãã
ã€ãŸããåºæ¬é³ã®å€ã«é¢ããæ å ±ããªãå Žåãæéæ ã5ç§ã«å¢ãããŠã±0.1 Hzã®ç²ŸåºŠãååŸãã163840ãµã³ãã«ãåŠçããå¿ èŠããããŸãã ããããä»¥æ¥ 0.743ç§ã®æéæ ã§ã¯ã1.35 Hzã®ç²ŸåºŠã§åšæ³¢æ°æšå®å€ãäœæã§ããŸããããæ£ç¢ºãªæšå®å€ãåŸãã«ã¯ã2.7 Hzã®ãµã³ããªã³ã°ã¬ãŒãã§éåžžã«çã垯åãããµã³ãã«ãèç©ããã ãã§ååã§ãã ãã®ããã«ã¯ã2.7 Hz * 5 s = 13.75ã®è€éãªèªã¿åãå€ïŒãŸãã¯äžžããŠããŒãžã³ãåã£ãŠååŸããå Žåã¯16ïŒã§ååã§ãã
é³ç¬Šãšåšæ³¢æ°ã®äžèŽ
ãã®ã¿ã¹ã¯ã¯ãSwiftã§ã¯éåžžã«ç°¡åã«è§£æ±ºã§ããŸãã ãµããŒããããŠããããŒã«ãšãããã³ã°ã«ãŒã«ã«é¢ãããã¹ãŠã®æ å ±ãå ¥åããç¹å¥ãªTunerã¯ã©ã¹ãäœæããŸããã ãããã®èšç®ã¯ãã¹ãŠã2ã€ã®åŒãbaseFrequency * powïŒ2.0ãïŒn-bïŒ/ 12.0ïŒãããã³ã12.0 * logïŒf / baseFrequencyïŒ/ logïŒ2ïŒ+ bãã«åºã¥ããŠããŸãã
ããã§ãbaseFrequencyã¯440 HzãŸãã¯256 Hzã®åºæ¬åšæ³¢æ°ã§ãããbã¯ããsubcontractãŸã§ã®æŽæ°ã®ããŒãçªå·ã§ãã
ã³ãŒãã¯éåžžã«äžåœèªã§ãïŒ
class Tuner { ... init(){ addInstrument("guitar", [ ("Standard", "e2 a2 d3 g3 b3 e4"), ("New Standard", "c2 g2 d3 a3 e4 g4"), ("Russian", "d2 g2 b2 d3 g3 b3 d4"), ("Drop D", "d2 a2 d3 g3 b3 e4"), ("Drop C", "c2 g2 c3 f3 a3 d4"), ("Drop G", "g2 d2 g3 c4 e4 a4"), ("Open D", "d2 a2 d3 f#3 a3 d4"), ("Open C", "c2 g2 c3 g3 c4 e4"), ("Open G", "g2 g3 d3 g3 b3 d4"), ("Lute", "e2 a2 d3 f#3 b3 e4"), ("Irish", "d2 a2 d3 g3 a3 d4") ]) ... } ... func noteNumber(noteString: String) -> Int { var note = noteString.lowercaseString var number = 0 var octave = 0 if note.hasPrefix("c") { number = 0; } if note.hasPrefix("c#") { number = 1; } ... if note.hasPrefix("b") { number = 11; } if note.hasSuffix("0") { octave = 0; } if note.hasSuffix("1") { octave = 1; } ... if note.hasPrefix("8") { octave = 8; } return 12 * octave + number } func noteString(num: Double) -> String { var noteOctave: Int = Int(num / 12) var noteShift: Int = Int(num % 12) var result = "" switch noteShift { case 0: result += "c" case 1: result += "c#" ... default: result += "" } return result + String(noteOctave) } func noteFrequency(noteString: String) -> Double { var n = noteNumber(noteString) var b = noteNumber(baseNote) return baseFrequency * pow(2.0, Double(n - b) / 12.0); } func frequencyNumber(f: Double) -> Double { var b = noteNumber(baseNote); return 12.0 * log(f / baseFrequency) / log(2) + Double(b); } func frequencyDistanceNumber(f0: Double, _ f1: Double) -> Double { var n0 = frequencyNumber(f0) var n1 = frequencyNumber(f1) return n1 - n0; } func targetFrequency() -> Double { return noteFrequency(string) * fretScale() } func actualFrequency() -> Double { return frequency * fretScale() } func frequencyDeviation() -> Double { return 100.0 * frequencyDistanceNumber(noteFrequency(string), frequency) } }
å®åšæ³¢ã®å¯èŠå
楜åšã®é³æ³¢ã®åœ¢ç¶ãèŠãããšãã§ããå®åšæ³¢ã«ã€ããŠã¯ããã§ã«æžããããã«ãã¢ã«ãŽãªãºã ã¯ãŸã£ããç°¡åã§ã-æ³¢é·ã¯èŠã€ãã£ãåºæ¬åšæ³¢æ°ããèšç®ãããäœçžãæšå®ããããã®åŸãèŠã€ãã£ãå€ããã·ãããè¡ãããŸã ããŒã¿ã¯è£å©ãã¬ãã¥ãŒãããã¡ããååŸãããŸãããã¡ã€ã³ãããã¡ãšã¯ç°ãªããèç©ãããŸããã ã€ãŸã ã ã¿ã³ããªã³ã°ãŠã£ã³ã㊠ãã¢ã«ãŽãªãºã ã«åŸã£ãŠåäœããŸãã
double waveLength = p->fd / f; size_t index = p->previewLength - waveLength * 2; double* src = &p->preview[index]; // double re = 0; double im = 0; for (size_t i = 0; i < waveLength*2; i++) { double t = (double)2.0 * M_PI * i / waveLength; re += src[i] * cos(t); im += src[i] * sin(t); } double phase = get_phase(re, im); // double shift = waveLength * phase / (2.0 * M_PI); // // double* shiftedSrc = &p->preview[index - (size_t)(waveLength - shift) - (size_t)waveLength];
å€èŠ³
å èµãã¬ãŒã€ãŒã«åºã¥ããŠäœæããå€èŠ³ãšããã²ãŒã·ã§ã³ã¯ããã©ãã¯ãåãæ¿ãã代ããã«ãã¹ããªã³ã°ã®åãæ¿ããçºçããŸãïŒ
ãããã«
Swift / Cã¢ããªã±ãŒã·ã§ã³ã®éçºãã¹å šäœã«ã¯çŽ2ãæããããŸããã ã¢ããªã±ãŒã·ã§ã³ã®å®è£ ã¯éåžžã«å°é£ã§ããããšãå€æããŸããã 第1ã«ãã¹ããŒããã©ã³ã®ããã©ãŒãã³ã¹ã«ã¯äŸç¶ãšããŠå€ãã®èª²é¡ãæ®ãããŠãããé«çŽèšèªã§ã®ãçŽæ¥çãªããœãªã¥ãŒã·ã§ã³ã¯ããŠãŒã¶ãŒã«ããæ¥åžžçãªäœ¿çšã«ã¯ãŸã£ããäžé©åã§ããããšãå€æããŠããŸãã 第äºã«ããµãŠã³ãåŠçã®ãããã¯ã¯ãiOã®éçºè ã®éã§éåžžã«äººæ°ããªããããæ å ±ãå°ããã€åéããå¿ èŠããããŸãã ããã¯ãããããã¢ãã€ã«ã¢ããªã±ãŒã·ã§ã³åãã«éçºããéã®UIã«é¢é£ããªããããã¯ã«é¢ãããã®ã§ãã 第äžã«ãSwiftã¯CããŒã¿ãšååã«éä¿¡ã§ããŸããããšã«ãããã®éçºæ¹æ³ã¯ã²ã©ãäžäŸ¿ã§ãããã²ã©ãåŽåãæ¶è²»ããŸãã
èšäºãéåžžã«éèŠã§ããããšãå€æãããšããäºå®ã«ãããããããå€ãã®åŸ®åŠããšåŸ®åŠãªãã¥ã¢ã³ã¹ã¯æªè§£æ±ºã®ãŸãŸã§ããã ã¢ããªã±ãŒã·ã§ã³ã®ãœãŒã¹ã³ãŒããç解ã§ããªãç¹ãæ確ã«ããã®ã«åœ¹ç«ã€ããšãé¡ã£ãŠããŸãã
github.com/kreshikhin/scituner
ãœãŒã¹ã³ãŒãã«ã¯ãMITã©ã€ã»ã³ã¹ãä»å±ããŠããŸãã ãããã£ãŠãç®çã®ã³ãŒãã»ã¯ã·ã§ã³ãŸãã¯ãããžã§ã¯ãã³ãŒãå šäœãå®å šã«äœ¿çšã§ããŸãã