sleep/wait function in velocity - velocity

Using apache velocity, I am performing a SNMP poll to a network device for Received packets. The aim is to get the Received packets per sec (PPS) but the network device only returns cumulative value.
So my plan was to run the snmp poll every sec and I can subtract the old valued from the new value to get PPS.
I could not find any sleep or wait function in apache velocity that can delay the poll by one sec.
Below is my script for reference.
#device($defensePro, 'type=defensePro', 'lazyConnect=true')
#param($output, 'type=string', 'direction=out')
#set($dp = $defensePro.readAllBeans('RsACCStatEntry'))
#result('text/text')
#foreach($x in $dp)
#if($x.id.toString().equals('RECEIVED'))
#set($id = $x.id)
#set($value = $x.value)
$date.get('H:m:s') Poll $velocityCount: $id $value
#end
#end
#end
Output
18:33:53 Poll 1: RECEIVED 18878707
Can someone please let me know if there is a sleep function in apache velocity or any other way of achieving the desired result

I'm not sure it the right way, but Velocity can call java methods
Add method (to your defensePro for example) as
public void sleep() { Thread.sleep(1000) }
And call it from template
$defensePro.sleep();
Found a very old answer in velocity mailing list
Thread.sleep should work. It pauses the current Thread for the given
amount of time

Thanks for the reply, below worked for me
#device($defensePro, 'type=defensePro', 'lazyConnect=true')
#param($output, 'type=string', 'direction=out')
#set($dp = $defensePro.readAllBeans('RsACCStatEntry'))
#macro(sleepX, $seconds)
#set($duration = $seconds * 1000)
#set($class = $class.inspect('java.lang.Thread'))
$class.type.sleep($duration)
#end
#foreach($i in [1..6])
#foreach($x in $dp)
#if($x.id.toString().equals('RECEIVED'))
#set($id = $x.id)
#set($value = $x.value)
$date.get('H:m:s') Poll $i: $id $value
#sleepX(1)
#end #end #end
Sample Output
17:4:10 Poll 1: RECEIVED 0
17:4:12 Poll 2: RECEIVED 0
17:4:13 Poll 3: RECEIVED 0
17:4:14 Poll 4: RECEIVED 0
17:4:15 Poll 5: RECEIVED 0
17:4:16 Poll 6: RECEIVED 0

Related

Ensure that clean-up code is executed even after '#Timeout'

As titled
For example, I have below test cases.
class StartupTest {
def deploymentPath = "build/milestone/deployment"
void checkConnectedProducts(){
def productConnected = XXXhelper.countConnectedProducts()
//Called another function in another class to check the number of connected products, every 1 sec
while (productConnected>2){
Thread.sleep(1000)
productConnected = XXXhelper.countConnectedProducts()
}
}
int countError(){
def error = xxx.logFinder.search("(ERROR)",TimeFrames.from(LocalDateTime.now().minusSeconds(20)).to(LocalDateTime.now().plusSeconds(20)))
return error.size()
}
#Timeout(80)
def 'Start_test'() {
setup:
//do some setup here
when: 'Test_started'
//do something here
and: 'Check_something'
//check something here
then: 'Validate_something'
checkConnectedProducts()
cleanup:
//Call the function in another class to zip the file and send out message to slack
File log = new File("$deploymentPath/logs")
def error = countError()
def zipFile = "xxx.zip"
IOHelper.createZip(log,zipFile)
File zipFile = new File(zipFile)
//Pass the zip to another class
ZipUploader.Slack(zipFile,error)
}
}
Below class is used to upload zipped file and send message to slack channel
class ZipUploader {
static uploadLocation = System.getProperty("benchmark-result-server")
static proxyHost = System.getProperty("proxy-host")
static proxyPort = System.getProperty("proxy-port")
static Slack(File file, int errorCount){
//Upload file
OkHttpClient client = new OkHttpClient()
RequestBody requestBody = new MultipartBody.Builder()
.setType(MultipartBody.FORM)
.addFormDataPart("zip", file.name,
RequestBody.create(file, MediaType.parse(com.google.common.net.MediaType.ZIP.type()))
)
.build()
Request request = new Request.Builder()
.url("$uploadLocation/!/xxxxxxxxxxxx")
.post(requestBody)
.build()
//Check the response
Response response = client.newCall(request).execute()
if (!response.isSuccessful()) throw new Exception("File cannot be uploaded" + response)
//Slack
OkHttpClient clientSlack = new OkHttpClient().newBuilder()
.proxy(new Proxy(Proxy.Type.HTTP, new InetSocketAddress(proxyHost, proxyPort)))
.build()
MediaType mediaType = MediaType.parse("application/json");
RequestBody body = RequestBody.create(mediaType, "{\n \"text\": \"Test has been finished \\t Error Log: $errorCount"\n}")
Request requestSlack = new Request.Builder()
.url("https://hooks.slack.com/services/xxxxxxx/xxxxxx/xxxxxx?Content-type=application/json")
.method("POST", body)
.addHeader("Content-Type", "application/json")
.build()
Response responseSlack = clientSlack.newCall(requestSlack).execute()
//Check the response
if (!responseSlack.isSuccessful()) throw new Exception("Failed to send message to slack " + responseSlack)
}
}
So if the test run within 80sec, the function in cleanup can be execute successfully, but I also want the function to execute even the test exceed timeout, I don't know how to achieve it.
It will just stopped the whole test in the middle if the test exceed timeout and return timeout exception, and the function under cleanup: will not be executed, including the function to upload zip and send slack notice.
#kriegaex, thanks you for your answer. For my error log, it returns as below.
[spock.lang.Timeout] Method 'Start_test' has not yet returned - interrupting. Next try in 0.50 seconds.
[spock.lang.Timeout] Method 'Start_test' has not yet returned - interrupting. Next try in 1.00 seconds.
[spock.lang.Timeout] Method 'Start_test' has not yet returned - interrupting. Next try in 2.00 seconds.
Method timed out after 70.00 seconds
Method timed out after 70.00 seconds
at app//xxx.checkConnectedProducts(StartupTest.groovy:36)
at xxx.StartupTest.Start_test(StartupTest.groovy:71)
xxx.StartupTest > Start_test STANDARD_OUT
[spock.lang.Timeout] Method 'Start_test' has not yet returned - interrupting. Next try in 0.50 seconds.
[spock.lang.Timeout] Method 'Start_test' has not yet returned - interrupting. Next try in 1.00 seconds.
[spock.lang.Timeout] Method 'Start_test' has not yet returned - interrupting. Next try in 2.00 seconds.
Gradle Test Executor 4 finished executing tests.
> Task :test
TRACE [startup log cleaner] StartupLogFactory - Flushing delayed logs as application terminates...
TRACE [startup log cleaner] StartupLogFactory - Caution: timestamps are those at the time of the flush!
DEBUG [startup log cleaner] Connector - Connecting to localhost:6450 with user admin
TRACE [startup log cleaner] StartupLogFactory - Finished flushing delayed logs.
xxx.StartupTest > Start_test FAILED
Method timed out after 70.00 seconds
at app//xxx.StartupTest.checkConnectedProducts(StartupTest.groovy:36)
at xxx.StartupTest.Start_test(StartupTest.groovy:71)
DEBUG [pool-10-thread-2] Connector - Connecting to 0.0.0.0:6450 with user <null>
1 test completed, 1 failed
It just stopped at the checkConnectedProducts(). And do not proceed IOHelper.createZip(log,zipFile) under cleanup: block.
I tried to add println("abc") under cleanup: block, indeed it can be executed after timeout, but not the zip function and upload zip class function.
Could you advice on how to make IOHelper.createZip and also Zipuploader under cleanup: block to run after timeout? In my case, they did not proceed. Thanks a lot!!!
Revised answer (2022-02-27)
I want to revise my previous statements with regard to
how I was emulating the situation and
how I was interpreting the results:
Because I had a similar use case and used my example from here as a starting point, I noticed that there is a fundamental difference between
JRE's Thread.sleep(long),
Groovy's sleep(long) and
Groovy's sleep(long, Closure).
See also this article.
I was using both Thread.sleep (in checkConnectedProducts()) and simple sleep (in the cleanup: block and the method called from there), which is why the result was the way it is shown in the log output.
Please note that Thread.sleep is interruptible, while sleep is not! Only an extended Groovy variant like sleep(4000), { e -> true } is also interruptable.
I.e., when the timeout occurs and Spock tries to interrupt the test, it successfully interrupts the Thread.sleep in checkConnectedProducts, but then immediately the two non-interruptible sleep 4000 variants are called from the cleanup: block, which means that they ignore Spock's repeated tries to interrupt them too, as you can see in the console log. If there we would also use an interruptible sleep or simply normal, interruptible Groovy or Java code, the cleanup: block or methods called from there would indeed also be interrupted by Spock quickly.
Now, assuming that you really need to make sure that the clean-up code is executed, even if the method gets interrupted by #Timeout, you simply move the clean-up code from the cleanup: block to a cleanup() method (which then gets executed for each feature method in the Spock specification). Look at this:
package de.scrum_master.stackoverflow.q60601740
import spock.lang.Issue
import spock.lang.Specification
import spock.lang.Timeout
import java.util.concurrent.TimeUnit
import static java.lang.System.currentTimeMillis
#Issue("https://stackoverflow.com/a/60610944/1082681")
class StartupTest extends Specification {
static final int SLEEP_MILLIS = 5000
static final int TIMEOUT_MILLIS = 3000
def startTime = currentTimeMillis()
def timeElapsed() {
currentTimeMillis() - startTime
}
void checkConnectedProducts() {
printf "%6d | checkConnectedProducts, sleeping %d ms%n", timeElapsed(), SLEEP_MILLIS
// Interruptable
Thread.sleep SLEEP_MILLIS
// Non-interruptable
// sleep SLEEP_MILLIS
// Interruptable
// sleep SLEEP_MILLIS, { true }
printf "%6d | checkConnectedProducts finished%n", timeElapsed()
}
int countError() {
printf "%6d | countError, sleeping %d ms%n", timeElapsed(), SLEEP_MILLIS
// Interruptable, but will not be interrupted by '#Timeout' when called from method 'cleanup'
Thread.sleep SLEEP_MILLIS
printf "%6d | countError finished%n", timeElapsed(), SLEEP_MILLIS
return 3
}
#Timeout(value = TIMEOUT_MILLIS, unit = TimeUnit.MILLISECONDS)
def 'Start_test'() {
expect: 'Validate_something'
checkConnectedProducts()
}
/**
* Even if a feature method (including its 'cleanup:' block) times out and gets aborted,
* the 'cleanup' method will be executed.
*/
def cleanup() {
countError()
printf "%6d | cleanup, sleeping %d ms%n", timeElapsed(), SLEEP_MILLIS
// Interruptable, but will not be interrupted by '#Timeout' within method 'cleanup'
Thread.sleep SLEEP_MILLIS
printf "%6d | cleanup finished%n", timeElapsed()
// Verify that really as much time has elapsed as we expect, i.e. 'cleanup()' has not been interrupted
assert timeElapsed() >= TIMEOUT_MILLIS + SLEEP_MILLIS + SLEEP_MILLIS
}
}
The console log says:
143 | checkConnectedProducts, sleeping 5000 ms
3138 | countError, sleeping 5000 ms
8147 | countError finished
8151 | cleanup, sleeping 5000 ms
13157 | cleanup finished
Method timed out after 3,00 seconds
at app//org.codehaus.groovy.vmplugin.v7.IndyInterface.selectMethod(IndyInterface.java:234)
at app//de.scrum_master.stackoverflow.q60601740.StartupTest.checkConnectedProducts(StartupTest.groovy:25)
at de.scrum_master.stackoverflow.q60601740.StartupTest.Start_test(StartupTest.groovy:44)
Try in in the Groovy web console.
See? The test method gets interrupted after 3 seconds, but the 5 + 5 = 10 extra seconds in cleanup() fully elapse, i.e. after cleanup we have a total of 13 elapsed seconds in the log.
If you want to speed up the test, simply change the static constants from 5000/3000 to 500/300.
BTW, you can also add a separate #Timeout to cleanup() or any other fixture method, but that is a bit out of scope here.
Original answer
I cannot reproduce your problem, given the code snippets you have provided instead of an MCVE. I replicated a simplified version of your situation like this, just replacing the operations consuming time in your example by Groovy sleep or Java Thread.sleep statements:
package de.scrum_master.stackoverflow.q60601740
import spock.lang.Specification
import spock.lang.Timeout
import static java.lang.System.currentTimeMillis
class StartupTest extends Specification {
def startTime = currentTimeMillis()
def timeElapsed() {
currentTimeMillis() - startTime
}
void checkConnectedProducts() {
for (int i = 1; i <= 5; i++) {
println "${timeElapsed()} | checkConnectedProducts #$i, sleeping 1 s"
Thread.sleep(1000)
}
}
int countError() {
println "${timeElapsed()} | countError, sleeping 4 s"
sleep 4000
return 3
}
#Timeout(3)
def 'Start_test'() {
setup:
true
when: 'Test_started'
true
and: 'Check_something'
true
then: 'Validate_something'
checkConnectedProducts()
cleanup:
countError()
println "${timeElapsed()} | cleanup, sleeping 4 s"
sleep 4000
println "${timeElapsed()} | cleanup finished"
}
}
The console log looks as expected:
64 | checkConnectedProducts #1, sleeping 1 s
1112 | checkConnectedProducts #2, sleeping 1 s
2114 | checkConnectedProducts #3, sleeping 1 s
3011 | countError, sleeping 4 s
[spock.lang.Timeout] Method 'Start_test' has not yet returned - interrupting. Next try in 0,50 seconds.
[spock.lang.Timeout] Method 'Start_test' has not yet returned - interrupting. Next try in 1,00 seconds.
[spock.lang.Timeout] Method 'Start_test' has not yet returned - interrupting. Next try in 2,00 seconds.
[spock.lang.Timeout] Method 'Start_test' has not yet returned - interrupting. Next try in 4,00 seconds.
7012 | cleanup, sleeping 4 s
[spock.lang.Timeout] Method 'Start_test' has not yet returned - interrupting. Next try in 8,00 seconds.
11012 | cleanup finished
Method timed out after 3,00 seconds
at de.scrum_master.stackoverflow.q60601740.StartupTest.checkConnectedProducts(StartupTest.groovy:18)
at de.scrum_master.stackoverflow.q60601740.StartupTest.Start_test(StartupTest.groovy:40)
As you can see, the first 3 iterations of the for loop, each expending ~1 s, are being executed before the 3 s timeout interrupts the test in the method called from the then: block. After that, the cleanup block runs completely, both the called method and the direct sleep, each spending ~4 s in addition to the 3 elapsed seconds. All in all we have 3 + 4 + 4 = 11 seconds, so everything works as expected.
Unless you can provide an MCVE reproducing your problem as Tim asked you to already, I would think there is no problem in Spock but rather something you misinterpret from your log output or another problem in your code which you did not show to us, such as a cleanup or zip operation done in an extra thread.

How Can I Establish UART Communication between 2 Stm32 and produce PWM signal

Edit: I solved UART communication problem but I have new problem getting pwm signal after receiving Transmit Data. I can blink led I can drive relay with transmitted data but I could not produce PWM signal.
maps(120, 1, 1, 250, RxData[4]);
ADC_Left = Yx; __HAL_TIM_SET_COMPARE(&htim2,TIM_CHANNEL_1,ADC_Left);
I used __HAL_TIM_SET_COMPARE function but it doesnt work. I can observe ADC_Left’s value on Debug site but its not work.
I am trying to realize UART communication between 2 stm32. I know there are several topic related with but my question focused another one.
I am reading 2 adc value on stm32 which is only transmit these value and other one only receive these 2 adc value. To do this
MX_USART1_UART_Init();
__HAL_UART_ENABLE_IT(&huart1, UART_IT_RXNE); // Interrupt Enable
__HAL_UART_ENABLE_IT(&huart1, UART_IT_TC);
char TxData1[10];
..............
TxData1[0] = 0xEA;
TxData1[1] = wData.Byte_1;
TxData1[2] = wData.Byte_2;
TxData1[3] = wData.Byte_3;
TxData1[4] = wData.Right_Adc_Val;
TxData1[5] = wData.Left_Adc_Val;
TxData1[6] = wData.Byte_6;
for(uint8_t i = 1 ; i < 7; i++)
{
wData.Checksum = wData.Checksum + TxData1[i];
}
wData.Checksum_H = (wData.Checksum >> 8)&0xFF;
wData.Checksum_L = (wData.Checksum)&0xFF;
TxData1[7] = wData.Checksum_H;
TxData1[8] = wData.Checksum_L;
TxData1[9] = 0xAE;
HAL_UART_Transmit_IT(&huart1,(uint8_t*) &TxData1,10);
............
This block sent them I can observate them on Debug screen and using TTL module's Tx Rx pins.
MX_USART1_UART_Init();
__HAL_UART_ENABLE_IT(&huart1, UART_IT_RXNE); // Interrupt Enable
__HAL_UART_ENABLE_IT(&huart1, UART_IT_TC);
char RxData[10];
while(1){
HAL_UART_Receive_IT(&huart1,(uint8_t*) &RxData,10);
}
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
if(huart->Instance == USART1)
{
HAL_UART_Receive_IT(&huart1,(uint8_t*) &RxData,10);
}
There is no problem up to here but when i getting RxData 0. index , it gives EA . Of course it should be give EA. When the adc data change all the ranking is changing. RxData[0] gives meaningless data. adc value is jumping over the all RxData array.
data locations must always be in the same index. How Can I get these data in stability for ex.
RxData[0]=EA
.
.
RxData[4]= should give adc value. so on.
..
Edit: I tried other mode of UART, DMA (in circular mode) and direct mode were used. I cant receive even 1 byte with DMA .
In your example code, you have an extra & that needs to be removed from both the transmit and receive HAL method calls. Example:
HAL_UART_Transmit_IT(&huart1,(uint8_t*) &TxData1,10);
HAL_UART_Transmit_IT(&huart1,(uint8_t*) TxData1,10);
To avoid this type of error in the future, recommend not using the cast and try something like the following:
uint8_t TxData1[10];
...
HAL_UART_Transmit_IT(&huart1, TxData1, sizeof(TxData1);

CAPL Canoe wait for a specific can message

I'm currently trying to Test Auto-Generated-Code for a Controller.
The test will be done in CANoe with Capl.
I've already tried a lot of things out and it's working good, but now I want to
test a "message lost".
I need something like this.
CAN 1 is sending a test message 10 Times. 3 Times there will be a Message lost.
CAN 2 which is receiving the Signals has to react to this with a specific value.
I Need something like WaitForMessage(int aTimeOut, Message yourMessage) which gives for example 0 for succesfully accessing the Message or -1 for timeOut.
on timer sendMessage
{
if(anzahlAnBotschaften > 0) // amount of sent Messages
{
if(anzahlAnBotschaften % 3 == 0) // 3 times message lost
{
botschaftWirdGesendet = 0;
lRet = ???? here is the part where i want to wait for a an answer from CAN2
if(lRet != 0)
{
TestStepPass("010.1", "SNA was triggered");
}
else
{
TestStepFail("010.1", "Timeout was triggered, but no SNA was found");
}
}
else
{
botschaftWirdGesendet = 1;
output(sendingCan_BrkSys);
lRet = TestGetWaitEventMsgData(receivingCan_aMessage);
if(lRet == 0)
{
// same for the positive case
}
}
anzahlAnBotschaften -- ;
setTimer(botschaftsAusfall,20);
}
}
What's the Problem? Just use CAPL-function testWaitForMessage as described in help.
You are using Test-Node as there is TestStepFail/Pass call in your code, so everything you need in terms of control your test-sequence begins with test...
p.s. something else, I doubt that with this code you can detect what is described in comment
if(anzahlAnBotschaften % 3 == 0) // 3 times message lost
anzahlAnBotschaften = in german this means the count of received messages. So when, as described above, you will receive 7 from 10 messages (anzahlAnBotschaften == 7) than this condition is false.

how to suspend for 200 ticks while delay 400 ticks in vxworks

I'm trying to code a program in vxworks. When a task total delay is 400 ticks, it was suspended at the 100th tick for 20 ticks, then resume to delay.
My main code is like the following:
void DelaySuspend (int level)
{
int tid, suspend_start,suspend_end,i;
suspend_start = vxTicks + 100;
suspend_end = vxTicks + 120;
i = vxTicks;
/* myfunction has taskDelay(400)*/
tid = taskSpawn("tMytask",200,0,2000,(FUNCPTR)myfunction,0,0,0,0,0,0,0,0,0,0);
/* tick between vxTicks+100 and vxTicks+120,suspend tMytask*/
while (i<suspend_start)
{
i=tickGet();
}
while (i <= suspend_end &&i >= suspend_start)
{
i = tickGet();
taskSuspend(tid);
}
}
What I want is to verify total delay time(or tick) doesn't change even I suspend the task for some time. I know the answer but just try to program it to show how vxWorks does it.
I am still not 100% clear on what you are trying to do, but calling taskSuspend in a loop like that isn't going to suspend the task any more. I am guessing you want something like this:
void DelaySuspend (int level)
{
int tid, suspend_start,suspend_end,i;
suspend_start = vxTicks + 100;
suspend_end = vxTicks + 120;
i = vxTicks;
/* myfunction has taskDelay(400)*/
tid = taskSpawn("tMytask",200,0,2000,(FUNCPTR)myfunction,0,0,0,0,0,0,0,0,0,0);
/* tick between vxTicks+100 and vxTicks+120,suspend tMytask*/
while (i<suspend_start)
{
i=tickGet();
}
taskSuspend(tid);
while (i <= suspend_end &&i >= suspend_start)
{
i = tickGet();
}
}
I just pulled the taskSuspend out of the loop, maybe you also want a taskResume in there after the loop or something? I am not sure what you are attempting to accomplish.
Whatever the case, there are probably better ways to do whatever you want, in general using taskSuspend is a bad idea because you have no idea what the task is doing when you suspend it. So for example if the suspended task is doing File I/O when you suspend it, and it has the file system mutex, then you cannot do any file I/O until you resume that task...
In general it is much better to block on a taskDelay/semaphore/mutex/message queue than use taskSuspend. I understand that this is just a test, and as such doing this may be ok, but if this test becomes production code, then you are asking for problems.

Using a Filter Audio Unit Effect in iOS5

I'm trying to use a remote IO connection and route the audio input through the built in filter effect (iOS 5 only) and then back out of the hardware. I can make it route straight from the input to the output but I can't get the filter to work. I'm not sure whether it's the filter Audio Unit or the routing that I've got wrong.
This bit is just my attempt at setting up the filter and changing the routing so that the data is processed by it.
Any help is appreciated.
// ******* BEGIN FILTER ********
NSLog(#"Begin filter");
// Creates Audio Component Description - Output Filter
AudioComponentDescription filterCompDesc;
filterCompDesc .componentType = kAudioUnitType_Effect;
filterCompDesc.componentSubType = kAudioUnitSubType_LowPassFilter;
filterCompDesc.componentManufacturer = kAudioUnitManufacturer_Apple;
filterCompDesc.componentFlags = 1;
filterCompDesc.componentFlagsMask = 1;
// Create Filter Unit
AudioUnit lpFilterUnit;
AudioComponent filterComponent = AudioComponentFindNext(NULL, &filterCompDesc);
setupErr = AudioComponentInstanceNew(filterComponent, &lpFilterUnit);
NSAssert(setupErr == noErr, #"No instance of filter");
AudioUnitElement bus2 = 2;
setupErr = AudioUnitSetProperty(lpFilterUnit, kAudioUnitSubType_LowPassFilter, kAudioUnitScope_Output, bus2, &oneFlag, sizeof(oneFlag));
AudioUnitElement bus3 = 3;
setupErr = AudioUnitSetProperty(lpFilterUnit, kAudioUnitSubType_LowPassFilter, kAudioUnitScope_Input, bus3, &oneFlag, sizeof(oneFlag));
// ******** END FILTER ******** //
AudioUnitConnection hardInToLP;
hardInToLP.sourceAudioUnit = remoteIOunit;
hardInToLP.sourceOutputNumber = 1;
hardInToLP.destInputNumber = 3;
setupErr = AudioUnitSetProperty (
remoteIOunit, // connection destination
kAudioUnitProperty_MakeConnection, // property key
kAudioUnitScope_Input, // destination scope
bus3, // destination element
&hardInToLP, // connection definition
sizeof (hardInToLP)
);
AudioUnitConnection LPToHardOut;
LPToHardOut.sourceAudioUnit = lpFilterUnit;
LPToHardOut.sourceOutputNumber = 1;
LPToHardOut.destInputNumber = 3;
setupErr = AudioUnitSetProperty (
remoteIOunit, // connection destination
kAudioUnitProperty_MakeConnection, // property key
kAudioUnitScope_Input, // destination scope
bus3, // destination element
&hardInToLP, // connection definition
sizeof (hardInToLP)
);
/*
// Sets up the Audio Units Connection - new instance called connection
AudioUnitConnection connection;
// Connect Audio Input's out to Audio Out's in
connection.sourceAudioUnit = remoteIOunit;
connection.sourceOutputNumber = bus1;
connection.destInputNumber = bus0;
setupErr = AudioUnitSetProperty(remoteIOunit, kAudioUnitProperty_MakeConnection, kAudioUnitScope_Input, bus0, &connection, sizeof(connection));
*/
NSAssert(setupErr == noErr, #"No RIO connection");
A couple things going on here:
You're gonna help yourself a lot if you do an assert (or some sort of check-error-and-log-it) after every call that can return an OSStatus. That way you'll figure out how far you're getting. Probably also want to log the actual OSStatus value when it's != noErr, and then look it up (start in "Audio Unit Component Services Reference" in Xcode documentation viewer).
After you create the filter AudioUnit, I don't get what you're doing with the AudioUnitSetProperty() calls. The second parameter should be the name of a property (something that starts with kAudioUnitProperty...). That's almost certainly returning an error right there.
remoteIOunit only has two buses, and they have special meanings. bus 1 is input from the mic, bus 0 is output to hardware. Trying to connect to remote io input scope bus 3 is probably going to be another error
Suggest you roll back to when you had audio pass-through working. That would mean you had just remoteIO, and a connection from output scope / bus 1 to input scope / bus 0.
Then create the filter unit. Change your connections so you connect:
remoteIO output scope bus 1 to filter input scope bus 0
filter output scope bus 0 to remoteIO input scope bus 0
The other thing that's going to be a problem is that all these iOS 5 filters seem to want to use floating-point LPCM formats, which is not the canonical format your other units will default to. You may have to get the stream format from the filter unit (input or output scope are probably the same?) and then set that as the format that remoteIO output scope / bus 1 produces and remoteIO input scope / bus 0 accepts. Another option would be to introduce AUConverter units before and after the filter unit.
The first answer given here just saved me a lot more frustration. No where does the Apple documentation tell you that the file formats for the Effect units require floating point. I couldn't figure out why it kept failing to play my audio properly until I read this post. I followed the advice above and retrieved the stream format from the low pass filter unit, and used that to set up two converter units that I created (ie. set the output format of the pre filter converter, and the input format of the post filter converter. Once I did that and connected all the nodes together it started working as expected.
im trying to use a low pass filter and when trying to do as suggested aka set the format i keep getting an error "the operation could not be completed" what in this code is faulty?
After retrieving the lowpassUnit I also check for errors but there are none.
result = AudioUnitSetProperty(lowpassUnit, kAudioUnitProperty_StreamFormat, kAudioUnitScope_Input, 0, &stereoStreamFormat, sizeof (stereoStreamFormat));
if (noErr != result)
{
NSLog(#"%#", [NSError errorWithDomain:NSOSStatusErrorDomain code:result userInfo:nil]);
return;
}
PS: If anyone knows of proper Audio unit documentation please share as the official documentation is really lacking