-
-
Save adaptivedev/9ea5ad4c75ca55d1098d to your computer and use it in GitHub Desktop.
Why won't my Tweak.xm write anything to file upon phonecall (it does print when I start my test app1)? Do I need to killall mediaserverd ? Anyhow, I've tried that, before killall SpringBoard, uicache, etc, but I can't get the Tweak to do anything upon phone call.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
include theos/makefiles/common.mk | |
TWEAK_NAME = recordtweak | |
recordtweak_FILES = Tweak.xm | |
recordtweak_FRAMEWORKS = CoreAudio UIKit CoreTelephony AudioToolbox | |
recordtweak_PRIVATE_FRAMEWORKS = CoreAudio UIKit CoreTelephony | |
#recordtweak_LIBRARIES = AudioUnitProcess | |
include $(THEOS_MAKE_PATH)/tweak.mk | |
after-install:: | |
install.exec "killall -9 SpringBoard" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Filter = { | |
Executables = ("mediaserverd"); | |
Bundles = ( "com.mytest.app1" ); | |
Mode = "Any"; | |
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
These output files are created when I run app1, but not when I start a phone call. | |
The other output files that should be created by the Tweak.xm (in the other 2 functions), are never created. | |
-rw-r--r-- 1 mobile wheel 0 May 7 12:37 recordtweak-ctnc.txt | |
-rw-r--r-- 1 mobile wheel 0 May 7 12:37 recordtweak.txt |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#import <AudioToolbox/AudioToolbox.h> | |
#import <libkern/OSAtomic.h> | |
#include "substrate.h" | |
//CoreTelephony.framework | |
extern "C" CFStringRef const kCTCallStatusChangeNotification; | |
extern "C" CFStringRef const kCTCallStatus; | |
extern "C" id CTTelephonyCenterGetDefault(); | |
extern "C" void CTTelephonyCenterAddObserver(id ct, void* observer, CFNotificationCallback callBack, CFStringRef name, void *object, CFNotificationSuspensionBehavior sb); | |
extern "C" int CTGetCurrentCallCount(); | |
enum | |
{ | |
kCTCallStatusActive = 1, | |
kCTCallStatusHeld = 2, | |
kCTCallStatusOutgoing = 3, | |
kCTCallStatusIncoming = 4, | |
kCTCallStatusHanged = 5 | |
}; | |
NSString* kMicFilePath = @"/var/mobile/Media/DCIM/mic.caf"; | |
NSString* kSpeakerFilePath = @"/var/mobile/Media/DCIM/speaker.caf"; | |
NSString* kResultFilePath = @"/var/mobile/Media/DCIM/result.m4a"; | |
OSSpinLock phoneCallIsActiveLock = 0; | |
OSSpinLock speakerLock = 0; | |
OSSpinLock micLock = 0; | |
ExtAudioFileRef micFile = NULL; | |
ExtAudioFileRef speakerFile = NULL; | |
BOOL phoneCallIsActive = NO; | |
void Convert() | |
{ | |
// WRITE TO FILE | |
FILE *f = fopen("/tmp/recordtweak-convert.txt", "w"); | |
if (f == NULL) | |
{ | |
printf("Error opening file!\n"); | |
exit(1); | |
} | |
/* print some text */ | |
const char *text = "Convert"; | |
fprintf(f, "Some text: %s\n", text); | |
//File URLs | |
CFURLRef micUrl = CFURLCreateWithFileSystemPath(NULL, (CFStringRef)kMicFilePath, kCFURLPOSIXPathStyle, false); | |
CFURLRef speakerUrl = CFURLCreateWithFileSystemPath(NULL, (CFStringRef)kSpeakerFilePath, kCFURLPOSIXPathStyle, false); | |
CFURLRef mixUrl = CFURLCreateWithFileSystemPath(NULL, (CFStringRef)kResultFilePath, kCFURLPOSIXPathStyle, false); | |
ExtAudioFileRef micFile = NULL; | |
ExtAudioFileRef speakerFile = NULL; | |
ExtAudioFileRef mixFile = NULL; | |
//Opening input files (speaker and mic) | |
ExtAudioFileOpenURL(micUrl, &micFile); | |
ExtAudioFileOpenURL(speakerUrl, &speakerFile); | |
//Reading input file audio format (mono LPCM) | |
AudioStreamBasicDescription inputFormat, outputFormat; | |
UInt32 descSize = sizeof(inputFormat); | |
ExtAudioFileGetProperty(micFile, kExtAudioFileProperty_FileDataFormat, &descSize, &inputFormat); | |
int sampleSize = inputFormat.mBytesPerFrame; | |
//Filling input stream format for output file (stereo LPCM) | |
FillOutASBDForLPCM(inputFormat, inputFormat.mSampleRate, 2, inputFormat.mBitsPerChannel, inputFormat.mBitsPerChannel, true, false, false); | |
//Filling output file audio format (AAC) | |
memset(&outputFormat, 0, sizeof(outputFormat)); | |
outputFormat.mFormatID = kAudioFormatMPEG4AAC; | |
outputFormat.mSampleRate = 8000; | |
outputFormat.mFormatFlags = kMPEG4Object_AAC_Main; | |
outputFormat.mChannelsPerFrame = 2; | |
//Opening output file | |
ExtAudioFileCreateWithURL(mixUrl, kAudioFileM4AType, &outputFormat, NULL, kAudioFileFlags_EraseFile, &mixFile); | |
ExtAudioFileSetProperty(mixFile, kExtAudioFileProperty_ClientDataFormat, sizeof(inputFormat), &inputFormat); | |
//Freeing URLs | |
CFRelease(micUrl); | |
CFRelease(speakerUrl); | |
CFRelease(mixUrl); | |
//Setting up audio buffers | |
int bufferSizeInSamples = 64 * 1024; | |
AudioBufferList micBuffer; | |
micBuffer.mNumberBuffers = 1; | |
micBuffer.mBuffers[0].mNumberChannels = 1; | |
micBuffer.mBuffers[0].mDataByteSize = sampleSize * bufferSizeInSamples; | |
micBuffer.mBuffers[0].mData = malloc(micBuffer.mBuffers[0].mDataByteSize); | |
AudioBufferList speakerBuffer; | |
speakerBuffer.mNumberBuffers = 1; | |
speakerBuffer.mBuffers[0].mNumberChannels = 1; | |
speakerBuffer.mBuffers[0].mDataByteSize = sampleSize * bufferSizeInSamples; | |
speakerBuffer.mBuffers[0].mData = malloc(speakerBuffer.mBuffers[0].mDataByteSize); | |
AudioBufferList mixBuffer; | |
mixBuffer.mNumberBuffers = 1; | |
mixBuffer.mBuffers[0].mNumberChannels = 2; | |
mixBuffer.mBuffers[0].mDataByteSize = sampleSize * bufferSizeInSamples * 2; | |
mixBuffer.mBuffers[0].mData = malloc(mixBuffer.mBuffers[0].mDataByteSize); | |
//Converting | |
while (true) | |
{ | |
//Reading data from input files | |
UInt32 framesToRead = bufferSizeInSamples; | |
ExtAudioFileRead(micFile, &framesToRead, &micBuffer); | |
ExtAudioFileRead(speakerFile, &framesToRead, &speakerBuffer); | |
if (framesToRead == 0) | |
{ | |
break; | |
} | |
//Building interleaved stereo buffer - left channel is mic, right - speaker | |
for (int i = 0; i < framesToRead; i++) | |
{ | |
memcpy((char*)mixBuffer.mBuffers[0].mData + i * sampleSize * 2, (char*)micBuffer.mBuffers[0].mData + i * sampleSize, sampleSize); | |
memcpy((char*)mixBuffer.mBuffers[0].mData + i * sampleSize * 2 + sampleSize, (char*)speakerBuffer.mBuffers[0].mData + i * sampleSize, sampleSize); | |
} | |
//Writing to output file - LPCM will be converted to AAC | |
ExtAudioFileWrite(mixFile, framesToRead, &mixBuffer); | |
} | |
//Closing files | |
ExtAudioFileDispose(micFile); | |
ExtAudioFileDispose(speakerFile); | |
ExtAudioFileDispose(mixFile); | |
//Freeing audio buffers | |
free(micBuffer.mBuffers[0].mData); | |
free(speakerBuffer.mBuffers[0].mData); | |
free(mixBuffer.mBuffers[0].mData); | |
} | |
void Cleanup() | |
{ | |
[[NSFileManager defaultManager] removeItemAtPath:kMicFilePath error:NULL]; | |
[[NSFileManager defaultManager] removeItemAtPath:kSpeakerFilePath error:NULL]; | |
} | |
void CoreTelephonyNotificationCallback(CFNotificationCenterRef center, void *observer, CFStringRef name, const void *object, CFDictionaryRef userInfo) | |
{ | |
// WRITE TO FILE | |
FILE *f = fopen("/tmp/recordtweak-ctnc.txt", "w"); | |
if (f == NULL) | |
{ | |
printf("Error opening file!\n"); | |
exit(1); | |
} | |
/* print some text */ | |
const char *text = "CoreTelephonyNotificationCallback"; | |
fprintf(f, "Some text: %s\n", text); | |
NSDictionary* data = (NSDictionary*)userInfo; | |
if ([(NSString*)name isEqualToString:(NSString*)kCTCallStatusChangeNotification]) | |
{ | |
int currentCallStatus = [data[(NSString*)kCTCallStatus] integerValue]; | |
if (currentCallStatus == kCTCallStatusOutgoing || currentCallStatus == kCTCallStatusActive) | |
{ | |
OSSpinLockLock(&phoneCallIsActiveLock); | |
phoneCallIsActive = YES; | |
OSSpinLockUnlock(&phoneCallIsActiveLock); | |
} | |
else if (currentCallStatus == kCTCallStatusHanged) | |
{ | |
if (CTGetCurrentCallCount() > 0) | |
{ | |
return; | |
} | |
OSSpinLockLock(&phoneCallIsActiveLock); | |
phoneCallIsActive = NO; | |
OSSpinLockUnlock(&phoneCallIsActiveLock); | |
//Closing mic file | |
OSSpinLockLock(&micLock); | |
if (micFile != NULL) | |
{ | |
ExtAudioFileDispose(micFile); | |
} | |
micFile = NULL; | |
OSSpinLockUnlock(&micLock); | |
//Closing speaker file | |
OSSpinLockLock(&speakerLock); | |
if (speakerFile != NULL) | |
{ | |
ExtAudioFileDispose(speakerFile); | |
} | |
speakerFile = NULL; | |
OSSpinLockUnlock(&speakerLock); | |
Convert(); | |
Cleanup(); | |
} | |
} | |
} | |
OSStatus(*AudioUnitProcess_orig)(AudioUnit unit, AudioUnitRenderActionFlags *ioActionFlags, const AudioTimeStamp *inTimeStamp, UInt32 inNumberFrames, AudioBufferList *ioData); | |
OSStatus AudioUnitProcess_hook(AudioUnit unit, AudioUnitRenderActionFlags *ioActionFlags, const AudioTimeStamp *inTimeStamp, UInt32 inNumberFrames, AudioBufferList *ioData) | |
{ | |
// WRITE TO FILE | |
FILE *f = fopen("/tmp/recordtweak-OSStatus.txt", "w"); | |
if (f == NULL) | |
{ | |
printf("Error opening file!\n"); | |
exit(1); | |
} | |
/* print some text */ | |
const char *text = "inTimeStamp"; | |
fprintf(f, "Some text: %s\n", text); | |
OSSpinLockLock(&phoneCallIsActiveLock); | |
if (phoneCallIsActive == NO) | |
{ | |
OSSpinLockUnlock(&phoneCallIsActiveLock); | |
return AudioUnitProcess_orig(unit, ioActionFlags, inTimeStamp, inNumberFrames, ioData); | |
} | |
OSSpinLockUnlock(&phoneCallIsActiveLock); | |
ExtAudioFileRef* currentFile = NULL; | |
OSSpinLock* currentLock = NULL; | |
AudioComponentDescription unitDescription = {0}; | |
AudioComponentGetDescription(AudioComponentInstanceGetComponent(unit), &unitDescription); | |
//'agcc', 'mbdp' - iPhone 4S, iPhone 5 | |
//'agc2', 'vrq2' - iPhone 5C, iPhone 5S | |
if (unitDescription.componentSubType == 'agcc' || unitDescription.componentSubType == 'agc2') | |
{ | |
currentFile = &micFile; | |
currentLock = &micLock; | |
} | |
else if (unitDescription.componentSubType == 'mbdp' || unitDescription.componentSubType == 'vrq2') | |
{ | |
currentFile = &speakerFile; | |
currentLock = &speakerLock; | |
} | |
if (currentFile != NULL) | |
{ | |
OSSpinLockLock(currentLock); | |
//Opening file | |
if (*currentFile == NULL) | |
{ | |
//Obtaining input audio format | |
AudioStreamBasicDescription desc; | |
UInt32 descSize = sizeof(desc); | |
AudioUnitGetProperty(unit, kAudioUnitProperty_StreamFormat, kAudioUnitScope_Input, 0, &desc, &descSize); | |
//Opening audio file | |
CFURLRef url = CFURLCreateWithFileSystemPath(NULL, (CFStringRef)((currentFile == &micFile) ? kMicFilePath : kSpeakerFilePath), kCFURLPOSIXPathStyle, false); | |
ExtAudioFileRef audioFile = NULL; | |
OSStatus result = ExtAudioFileCreateWithURL(url, kAudioFileCAFType, &desc, NULL, kAudioFileFlags_EraseFile, &audioFile); | |
if (result != 0) | |
{ | |
*currentFile = NULL; | |
} | |
else | |
{ | |
*currentFile = audioFile; | |
//Writing audio format | |
ExtAudioFileSetProperty(*currentFile, kExtAudioFileProperty_ClientDataFormat, sizeof(desc), &desc); | |
} | |
CFRelease(url); | |
} | |
else | |
{ | |
//Writing audio buffer | |
ExtAudioFileWrite(*currentFile, inNumberFrames, ioData); | |
} | |
OSSpinLockUnlock(currentLock); | |
} | |
return AudioUnitProcess_orig(unit, ioActionFlags, inTimeStamp, inNumberFrames, ioData); | |
} | |
__attribute__((constructor)) | |
static void initialize() | |
{ | |
NSLog(@"%s", "initialize THIS! HEY THERE THIS IS GB AND I WANT YOU TO KNOW THAT MY MONKEY TOLD ME TO DO IT. ALSO F U APPLE AND WEAR TUXEDOS FOR NO REASON.. YET AGAIN I SAY, I SAY"); | |
// WRITE TO FILE | |
FILE *f = fopen("/tmp/recordtweak.txt", "w"); | |
if (f == NULL) | |
{ | |
printf("Error opening file!\n"); | |
exit(1); | |
} | |
/* print some text */ | |
const char *text = "initialize"; | |
fprintf(f, "Some text: %s\n", text); | |
CTTelephonyCenterAddObserver(CTTelephonyCenterGetDefault(), NULL, CoreTelephonyNotificationCallback, NULL, NULL, CFNotificationSuspensionBehaviorHold); | |
MSHookFunction(AudioUnitProcess, AudioUnitProcess_hook, &AudioUnitProcess_orig); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment